diff options
author | Katze Miau <miaukatzemiau@priveasy.de> | 2012-03-02 08:41:04 (GMT) |
---|---|---|
committer | Katze Miau <miaukatzemiau@priveasy.de> | 2012-03-02 08:41:04 (GMT) |
commit | 61a642235abc3cf0f1297f4f386504a110bd0aa5 (patch) | |
tree | 3dadcb773f2d2040d69392cda046f85f127f4ce4 /toolbin/merge_config | |
parent | 754907fd31da80d247432d02128bb4e9c79d31b0 (diff) |
add toolbin/merge_config to compose configs and files
toolbin/merge_config takes a list of basenames and merges them by
applying them from left to right. If the first basename may refer to a
file or a directory; the resulting merge is of the same type.
Usage:
toolbin/merge_config --merge --dst location [--verbose] base base2 ...
For each basename X up to one of three possible files may exist:
$X - copy $X as result of the merge (overwritting any existing $X)
$X.patch - patch an existing $X
$X.delete - delete an existing $X
toolbin/extract_variants decomposes a string like foo/bar-baz/boing-bu
along the dashes into:
foo/bar-baz-boing-bu
foo/bar-baz-boing
foo/bar-baz
foo/bar
It is used to generate all possible sources merge_config should consider.
Diffstat (limited to 'toolbin/merge_config')
-rwxr-xr-x | toolbin/merge_config | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/toolbin/merge_config b/toolbin/merge_config new file mode 100755 index 0000000..88b41e3 --- /dev/null +++ b/toolbin/merge_config @@ -0,0 +1,104 @@ +#!/bin/bash -e + +fail () { + echo "$1" 2>&1 + exit 1 +} + +help () { + fail "Usage: +$0 --merge --dst location [--verbose] base-src diff-src1 diff-src2 ..." +} + +filter_suffix () { + sed -e 's/.patch$//' -e 's/.delete$//' +} + +# exists as file or symbolic link +exfl () { + [ -f "$1" -o -L "$1" ] +} + +merge_file () { + c="$(ls $2{,.patch,.delete} 2>/dev/null | wc -l)" + [ $c -le 1 ] || fail "more than one operation available for $2" + if [ $c -eq 0 ]; then + $quiet || echo " ignoring $2" + return 0 + else + $quiet || echo " using $2" + fi + if exfl "$2"; then + cp --no-dereference "$2" "$1" + else + exfl "$1" || fail "$1 requested but does not exist" + if [ -f "$2.patch" ]; then + [ -f "$1" ] || fail "$1 is no regular file, not patching" + patch $(! $quiet || echo --silent) -B trash/ "$1" <"$2.patch" + elif [ -f "$2.delete" ]; then + rm "$1" + fi + fi +} + +merge_dir () { + if [ -d $2 ]; then + $quiet || echo "from directory $2" + find $2 -printf "%P\n" | grep -v '^$' | filter_suffix | sort -u | ( + while read f; do + if [ -d "$2/$f" ]; then + mkdir -p "$1/$f" + else + merge_file "$1/$f" "$2/$f" + fi + done) + else + $quiet || echo "ignoring $2" + fi +} + +# parse cmd line options (except merge srcs) +[ $# -gt 0 ] || help +quiet=true +while [ $# -gt 0 ]; do + case "$1" in + --merge) + op=merge + ;; + --verbose) + quiet=false + ;; + --dst) + [ $# -gt 1 ] || help + dst="$2" + shift + ;; + *) + break + ;; + esac + shift +done +[ -n "$op" -a -n "$dst" ] || help + +# determine wether merging dirs or files +[ $# -gt 0 ] || help +if [ -f "$1" ]; then + mode=file +elif [ -d "$1" ]; then + mode=dir + [ -d "$dst~" ] && rm -r "$dst~" + mkdir "$dst~" +else + fail "$1 is neiter file nor directory" +fi + +# iterate over all dirs +while [ $# -gt 0 ]; do + ${op}_${mode} "$dst~" "$1" + shift +done + +[ -d "$dst" ] && rm -r "$dst" +mv "$dst~" "$dst" +rm trash/* 2>/dev/null || true
\ No newline at end of file |