/etckeeper/pre-commit.d/30store-metadata
http://github.com/brinkman83/bashrc · Shell · 130 lines · 69 code · 17 blank · 44 comment · 19 complexity · 98fa84fa386cd9c0fc210ea8a8009f26 MD5 · raw file
- #!/bin/sh
- set -e
- # Filters out UNKNOWN users and groups, prints a warning on stderr.
- filter_unknown() {
- CMD=$1
- while read line; do
- # if the first n chars of $line equal "$CMD UNKNOWN "...
- if [ "$(printf %.$((9+${#CMD}))s "$line")" = "$CMD UNKNOWN " ]; then
- echo Bad "$2" for "$line" >&2
- else
- echo "$line"
- fi
- done
- }
- filter_ignore() {
- if [ "$VCS" = darcs ]; then
- ignorefile=.darcsignore
- fi
- if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then
- # Spaces embedded into patterns would break it.
- # But really, why would anyone want to use ' ' instead of '\s' ?
- #patterns=$( grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" | xargs -n 1 printf " -e %s" )
- #grep -Ev $patterns
- #unset patterns
- # Alternative using a temp file
- patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
- grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true
- grep -Evf "$patternsfile"
- rm -f "$patternsfile"
- unset patternsfile
- else
- cat -
- fi
- }
- generate_metadata() {
- # This function generates the script commands to fix any files
- # that aren't owner=root, group=root, or mode=0644 or 0755.
- # 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 maintain the permissions on 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!)
- NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o -wholename ./_darcs -prune -o'
- # Keep the sort order the same at all times.
- LC_COLLATE=C
- export LC_COLLATE
- if [ "$VCS" = git ] || [ "$VCS" = hg ]; then
- # These version control systems do not track directories,
- # so empty directories must be stored specially.
- find $NOVCS -type d -empty -print |
- sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/"
- fi
- if [ "$VCS" = darcs ]; then
- # This version control system does not track symlinks,
- # so they must be stored specially.
- find $NOVCS -type l -print | sort | filter_ignore | while read link; do
- dest=$( readlink "$link" )
- printf "ln -sf '%s' '%s'\n" "$dest" "$link"
- done
- fi
- # Find all files and directories that don't have the current user as the owner
- find $NOVCS \! -user "$(id -u)" -exec stat --format="maybe chown %U '{}'" {} \; \
- | sort | filter_unknown 'maybe chown' owner
- # Find all files and directories that don't have root as the group
- find $NOVCS \! -group $(id -g) -exec stat --format="maybe chgrp %G '{}'" {} \; \
- | sort | filter_unknown 'maybe chgrp' group
- # Find all directories that aren't 0755
- find $NOVCS -type d \! -perm 0755 \
- -exec stat --format="maybe chmod %a '{}'" {} \; | sort
- if [ "$VCS" = darcs ]; then
- # Find all files that aren't 0644 (darcs doesn't maintain
- # the executable bit).
- find $NOVCS -type f \! -perm 0644 \
- -exec stat --format="maybe chmod %a '{}'" {} \; | sort
- else
- # Find all files that aren't 0644 or 0755 (we can assume the VCS will
- # maintain the executable bit).
- find $NOVCS -type f \! -perm 0644 \! -perm 0755 \
- -exec stat --format="maybe chmod %a '{}'" {} \; | sort
- fi
- # We don't handle xattrs.
- # Maybe check for getfattr/setfattr and use them if they're available?
- }
- if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
- if [ -f .metadata ]; then
- # remove obsolete .metadata file
- # git allows fully deleting it at this point, other VCS
- # may not (the repo is locked for hg).
- if [ "$VCS" = git ]; then
- $VCS rm .metadata
- else
- rm -f .metadata
- fi
- fi
- echo "# Generated by etckeeper. Do not edit." > .etckeeper
- echo >> .etckeeper
- # Make sure the file is not readable by others, since it can leak
- # information about contents of non-readable directories in /etc.
- chmod 700 .etckeeper
- generate_metadata >> .etckeeper
- # stage the file as part of the current commit
- if [ "$VCS" = git ]; then
- # this will do nothing if the metadata file is unchanged.
- git add .etckeeper
- fi
- # hg, bzr and darcs add not done, they will automatically
- # include the file in the current commit
- fi