Files
lux/modules/features/source-control.nix
T
2026-04-22 04:10:29 +02:00

103 lines
2.7 KiB
Nix

{ config, lib, ... }:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.homeManager.source-control =
{
config,
lib,
...
}:
let
host = config.meta.host;
user = config.meta.user;
sourceControl = user.sourceControl;
hostSourceControlUsers = host.sourceControl.users;
hostUserSourceControl = hostSourceControlUsers.${user.name} or { };
scopeEmails = scope: lib.filter (email: email.scope == scope) (builtins.attrValues user.emails);
emailForScope =
scope:
let
emails = scopeEmails scope;
in
if builtins.length emails == 1 then (builtins.head emails).address else null;
scopeConfig = scope: hostUserSourceControl.${scope} or null;
scopeHasSigningKey =
scope:
let
keyConfig = scopeConfig scope;
in
keyConfig != null && keyConfig.publicKey != null;
privateKeyPathForScope =
scope:
let
keyConfig = scopeConfig scope;
in
if keyConfig == null || keyConfig.privateKeyPath == null then
"~/.ssh/id_${scope}"
else
keyConfig.privateKeyPath;
publicKeyForScope =
scope:
let
keyConfig = scopeConfig scope;
in
if keyConfig == null then null else keyConfig.publicKey;
scopesInUse = lib.unique ([
"personal"
sourceControl.projectScope
]);
allowedSignersLines = map (scope: "${emailForScope scope} ${publicKeyForScope scope}") (
builtins.filter (scope: emailForScope scope != null && scopeHasSigningKey scope) scopesInUse
);
gitConfigForScope =
scope:
lib.recursiveUpdate
{
user = {
name = user.realName;
email = emailForScope scope;
};
}
(
lib.optionalAttrs (scopeHasSigningKey scope) {
gpg.ssh.allowedSignersFile = "${config.xdg.configHome}/git/allowed_signers";
user.signingKey = "${privateKeyPathForScope scope}.pub";
}
);
gitRoots = [
{
root = user.nixosConfigurationPath;
scope = "personal";
}
{
root = config.xdg.userDirs.projects;
scope = sourceControl.projectScope;
}
];
in
{
imports = [ homeModules.git ];
xdg.configFile."git/allowed_signers".text = lib.concatStringsSep "\n" (
allowedSignersLines ++ [ "" ]
);
programs.git.includes = map (gitRoot: {
condition = "gitdir:${gitRoot.root}/";
contents = gitConfigForScope gitRoot.scope;
}) gitRoots;
};
}