You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcpcfg/hooks/pre-commit

109 lines
3.6 KiB

#!/bin/sh
# pre-commit hook for ngcpcfg, to store metadata
# implementation heavily based on etckeeper's pre-commit.d/30store-metadata
set -e
# ensure we're in the appropriate git directory (/etc/ngcp-config/ by default),
# we don't rely on ${NGCPCTL_MAIN} just in case we're invoked directly,
# e.g. via `/etc/ngcp-config/.git/hooks/pre-commit` (outside of ngcpcfg)
cd "$(dirname "${0}")/../../"
if ! git rev-parse --git-dir >/dev/null 2>&1 ; then
echo "Warning: $(pwd) is not a git repository, ignoring $0"
exit 0
fi
filter_ignore() {
if [ -e ".gitignore" ]; then
listfile="$(mktemp -t ngcpcfg-git.XXXXXXXXXX)"
(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | sort | uniq > "$listfile" || true
sed 's/^\.\///' | grep -xFvf "$listfile"
rm -f "$listfile"
unset listfile
else
cat -
fi
}
shellquote() {
# Single quotes text, escaping existing single quotes.
sed -e "s/'/'\"'\"'/g" -e "s/^/'/" -e "s/$/'/"
}
generate_metadata() {
# This function generates the script commands to fix any file
# ownerships that aren't owner=root, group=root, as well as to
# store the permissions of files.
# The script is produced on stdout. Errors go to stderr.
#
# The script can use a 'maybe' function, which only runs a command
# if the file in its last argument exists.
# We want files in the directory containing VCS data
# but we want find to ignore the VCS files themselves.
#
# (Note that when using this, the find expression must end with
# -print or -exec, else the excluded directories will actually be
# printed!)
# Keep the sort order the same at all times.
LC_COLLATE=C
export LC_COLLATE
# git does not track directories,
# so empty directories must be stored specially.
find . -path ./.git -prune -o -type d -empty -print |
sort | shellquote | sed -e "s/^/mkdir -p /"
# Store things that don't have the default user or group.
# Store all file modes, in case the user has an unusual umask.
find . -path ./.git -prune -o \( -type f -or -type d \) -print | filter_ignore | sort | perl -ne '
BEGIN { $q=chr(39) }
sub uidname {
my $want=shift;
if (exists $uidcache{$want}) {
return $uidcache{$want};
}
my $name=scalar getpwuid($want);
return $uidcache{$want}=defined $name ? $name : $want;
}
sub gidname {
my $want=shift;
if (exists $gidcache{$want}) {
return $gidcache{$want};
}
my $name=scalar getgrgid($want);
return $gidcache{$want}=defined $name ? $name : $want;
}
chomp;
my @stat=stat($_);
my $mode = $stat[2];
my $uid = $stat[4];
my $gid = $stat[5];
s/$q/$q"$q"$q/g; # escape single quotes
s/^/$q/;
s/$/$q/;
if ($uid != $>) {
printf "maybe chown $q%s$q %s\n", uidname($uid), $_;
}
if ($gid != $)) {
printf "maybe chgrp $q%s$q %s\n", gidname($gid), $_;
}
printf "maybe chmod %04o %s\n", $mode & 07777, $_;
'
}
ngcpcfg_perms=$(mktemp -t ngcpcfg-perms.XXXXXXXXXX)
chown root:root "${ngcpcfg_perms}"
# Make sure the file is not readable by others, since it can leak
# information about contents of non-readable directories
chmod 700 "${ngcpcfg_perms}"
echo "# Generated by ngcpcfg. Do not edit." > "${ngcpcfg_perms}"
echo >> "${ngcpcfg_perms}"
generate_metadata >> "${ngcpcfg_perms}"
mv "${ngcpcfg_perms}" .ngcpcfg_perms
git add .ngcpcfg_perms