Merge remote-tracking branch 'nomic/master'

This commit is contained in:
lassulus 2015-06-15 01:24:22 +02:00
commit 2874f6ed04
2 changed files with 100 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;
@ -168,28 +201,56 @@ in
findutils findutils
gawk gawk
git git
gnugrep
gnused
])} ])}
dataDir=${escapeShellArg cfg.dataDir} dataDir=${escapeShellArg cfg.dataDir}
mkdir -p "$dataDir" mkdir -p "$dataDir"
for reponame in ${toShellArgs (reponames cfg.rules)}; do # Notice how the presence of hooks symlinks determine whether
repodir=$dataDir/$reponame # we manage a repositry or not.
if ! test -d "$repodir"; then
mkdir -m 0700 "$repodir" # Make sure that no existing repository has hooks. We can delete
git init --bare --template=/var/empty "$repodir" # symlinks because we assume we created them.
chown -R git: "$repodir" find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks -type l -delete
# branches/ bad_hooks=$(find "$dataDir" -mindepth 2 -maxdepth 2 -name hooks)
# description if echo "$bad_hooks" | grep -q .; then
# hooks/ printf 'error: unknown hooks:\n%s\n' \
# info/ "$(echo "$bad_hooks" | sed 's/^/ /')" \
fi >&2
ln -snf ${hooks} "$repodir/hooks" exit -1
done fi
# Initialize repositories.
${concatMapStringsSep "\n" (repo:
let
hooks = scriptFarm "git-ssh-hooks" (makeHooks repo);
in
''
reponame=${escapeShellArg repo.name}
repodir=$dataDir/$reponame
if ! test -d "$repodir"; then
mkdir -m 0700 "$repodir"
git init --bare --template=/var/empty "$repodir"
chown -R git: "$repodir"
fi
ln -s ${hooks} "$repodir/hooks"
''
) (attrValues cfg.repos)}
# Warn about repositories that exist but aren't mentioned in the
# current configuration (and thus didn't receive a hooks symlink).
unknown_repos=$(find "$dataDir" -mindepth 1 -maxdepth 1 \
-type d \! -exec test -e '{}/hooks' \; -print)
if echo "$unknown_repos" | grep -q .; then
printf 'warning: stale repositories:\n%s\n' \
"$(echo "$unknown_repos" | sed 's/^/ /')" \
>&2
fi
''; '';
# 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 +304,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
''; '';
}; };