modules/tv/git: enable repo-specific hooks

This commit is contained in:
tv 2015-06-14 23:55:41 +02:00
parent cb70769a04
commit dcdf12fd0b
2 changed files with 73 additions and 34 deletions

View File

@ -62,7 +62,18 @@
# TODO warn about stale repodirs # TODO warn about stale repodirs
repos = addNames { repos = addNames {
testing = { testing = {
# TODO hooks = { post-receive = ... hooks = {
update = ''
#! /bin/sh
set -euf
echo update hook: $* >&2
'';
post-update = ''
#! /bin/sh
set -euf
echo post-update hook: $* >&2
'';
};
}; };
}; };

View File

@ -2,12 +2,12 @@
let let
inherit (builtins) inherit (builtins)
attrNames concatLists filter hasAttr head lessThan removeAttrs tail toJSON attrNames attrValues concatLists filter hasAttr head lessThan removeAttrs
typeOf; tail toJSON typeOf;
inherit (lib) inherit (lib)
concatStrings concatStringsSep escapeShellArg hasPrefix listToAttrs concatMapStringsSep concatStringsSep escapeShellArg hasPrefix
makeSearchPath mapAttrsToList mkIf mkOption removePrefix singleton literalExample makeSearchPath mapAttrsToList mkIf mkOption optionalString
sort types unique; removePrefix singleton sort types unique;
inherit (pkgs) linkFarm writeScript writeText; inherit (pkgs) linkFarm writeScript writeText;
@ -54,8 +54,6 @@ let
reponames = rules: sort lessThan (unique (map (x: x.repo.name) rules)); reponames = rules: sort lessThan (unique (map (x: x.repo.name) rules));
toShellArgs = xs: toString (map escapeShellArg xs);
# TODO makeGitHooks that uses runCommand instead of scriptFarm? # TODO makeGitHooks that uses runCommand instead of scriptFarm?
scriptFarm = scriptFarm =
farm-name: scripts: farm-name: scripts:
@ -99,7 +97,42 @@ in
type = types.unspecified; type = types.unspecified;
}; };
repos = mkOption { repos = mkOption {
type = types.unspecified; type = types.attrsOf (types.submodule ({
options = {
name = mkOption {
type = types.str;
description = ''
Repository name.
'';
};
hooks = mkOption {
type = types.attrsOf types.str;
description = ''
Repository-specific hooks.
'';
};
};
}));
default = {};
example = literalExample ''
{
testing = {
name = "testing";
hooks.post-update = '''
#! /bin/sh
set -euf
echo post-update hook: $* >&2
''';
};
testing2 = { name = "testing2"; };
}
'';
description = ''
Repositories.
'';
}; };
users = mkOption { users = mkOption {
type = types.unspecified; type = types.unspecified;
@ -173,23 +206,24 @@ in
dataDir=${escapeShellArg cfg.dataDir} dataDir=${escapeShellArg cfg.dataDir}
mkdir -p "$dataDir" mkdir -p "$dataDir"
for reponame in ${toShellArgs (reponames cfg.rules)}; do ${concatMapStringsSep "\n" (repo:
let
hooks = scriptFarm "git-ssh-hooks" (makeHooks repo);
in
''
reponame=${escapeShellArg repo.name}
repodir=$dataDir/$reponame repodir=$dataDir/$reponame
if ! test -d "$repodir"; then if ! test -d "$repodir"; then
mkdir -m 0700 "$repodir" mkdir -m 0700 "$repodir"
git init --bare --template=/var/empty "$repodir" git init --bare --template=/var/empty "$repodir"
chown -R git: "$repodir" chown -R git: "$repodir"
# branches/
# description
# hooks/
# info/
fi fi
ln -snf ${hooks} "$repodir/hooks" ln -snf ${hooks} "$repodir/hooks"
done ''
) (attrValues cfg.repos)}
''; '';
# TODO repo-specific hooks makeHooks = repo: removeAttrs repo.hooks [ "pre-receive" ] // {
hooks = scriptFarm "git-ssh-hooks" {
pre-receive = '' pre-receive = ''
#! /bin/sh #! /bin/sh
set -euf set -euf
@ -243,16 +277,10 @@ in
fi fi
systemd-cat -p info -t git-ssh echo "$accept_string" systemd-cat -p info -t git-ssh echo "$accept_string"
'';
update = '' ${optionalString (hasAttr "post-receive" repo.hooks) ''
#! /bin/sh # custom post-receive hook
set -euf ${repo.hooks.post-receive}''}
echo update hook: $* >&2
'';
post-update = ''
#! /bin/sh
set -euf
echo post-update hook: $* >&2
''; '';
}; };