X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=scripts%2Ftools%2Ffg-submit;h=9ca695ff803d6abd9dbbb68d6b5ae8c549c94cd2;hb=991beb0b5ecf08df56ad77f6a49b0e20c191be11;hp=f113f6b6db811356041d43fb54b62d0237214c5b;hpb=9a1d1e389ae924d76a4b69518647857c0eafd068;p=flightgear.git diff --git a/scripts/tools/fg-submit b/scripts/tools/fg-submit index f113f6b6d..9ca695ff8 100755 --- a/scripts/tools/fg-submit +++ b/scripts/tools/fg-submit @@ -1,77 +1,279 @@ #!/bin/bash # -# This script called in a CVS directory generates an archive in that -# same directory, which contains all locally added new files (except -# those rejected by the script) and a diff with all local changes. -# This archive can then be offered to one of the CVS maintainers for -# committing. +# This script called in a CVS directory compares local files with +# the repository, and prepares an update package containing all +# changes and new files for submission to a CVS maintainer. If there +# are only changes in text files, then a compressed unified diff is +# made (foo.diff.bz2). If there are also changed binary or new files, +# then an archive is made instead (foo.tar.bz2). The base name ("foo") +# can be given as command line argument. Otherwise the directory name +# is used. The script also leaves a diff in uncompressed/unpackaged +# form. This is only for developer convenience -- for a quick check +# of the diff correctness. It is not to be submitted. The script will +# not overwrite any file, but rather rename conflicting files. # -# Usage: -# $ cd $FG_ROOT/Aircraft/foo -# $ fg-submit # generates foo.tar.bz2 and foo.diff +# Usage: fg-submit [-v] [] # -# The archive contains a copy of the diff, so the extra diff file -# shouldn't be sumitted. It's only left for convenience. +# Options: +# -v ... verbose output +# +# Example: +# $ cd $FG_ROOT/Aircraft/bo105 +# $ fg-submit # -> bo105.diff.bz2 or bo105.tar.bz2 +# +# $ fg-submit update # -> update.diff.bz2 or update.tar.bz2 +# +# +# Spaces in the basename are replaced with "%20". People who prefer +# to have the date in the archive name can conveniently achieve this +# by defining a shell alias in ~/.bashrc: +# +# alias submit='fg-submit "${PWD##*/}-$(date +%Y-%m-%d)"' +# +# +# +# If the script finds an application named "fg-upload", then it calls +# this at the end with two arguments: +# +# $1 ... archive or compressed diff for submission +# $2 ... accessory uncompressed diff, *NOT* for submission! +# +# $1 and $2 are guaranteed not to contain spaces, only $1 is guaranteed +# to actually exist. Such a script can be used to upload the file to an +# ftp-/webserver, and/or to remove one or both files. Example using +# KDE's kfmclient for upload (alternatives: ncftpput, gnomevfs-copy): +# +# $ cat ~/bin/fg-upload +# #!/bin/bash +# echo "uploading $1" +# if kfmclient copy $1 ftp://user:password@server.com; then +# echo "deleting $1 $2" +# rm -f $1 $2 +# +# URL=ftp://server.com/$1 +# +# # copy URL to KDE's clipboard, so that MMB-clicking pastes it +# dcop klipper klipper setClipboardContents $URL +# +# echo "Done. --> $URL" +# else +# echo "$0: uploading failed!" +# fi +# +# +# +# Whether a file should be included in the archive or not, is decided +# by pattern rules. There is a set of reasonable default rules predefined, +# but alternative settings can be defined in a hidden configuration file +# named ".fg-submit". Such a file is searched in the current directory, +# in its parent directory, in its grand-parent directory and so on, +# and finally in the $HOME directory. The first found file is taken. +# +# A file can use a list of three keywords with arguments, each on a +# separate line: +# +# ALLOW ... accept & report matching file +# DENY ... reject & report matching file +# IGNORE ... silently reject matching file +# +# A is a space-separated list of shell pattern. +# It may also be empty, in which case it has no effect. Examples: +# +# DENY test.blend +# ALLOW *.xcf *.blend +# +# The list of pattern is checked in the same order in which it was +# built. The first match causes a file to be accepted or rejected. +# Further matches are not considered. Comments using the hash +# character '#' are allowed and ignored. +# +# Some default rules are always added at the end. If you want to +# bypass them, then finish your configuration with an "ALLOW *" +# or "DENY *", and no file will ever reach the default rules. +# +# +# Example: +# +# DENY test.xcf # throw out the test image, but ... +# ALLOW *.xcf # ... allow all other GIMP images (the default +# # rules would otherwise throw them out) +# +# ALLOW not.old # add this file, but ... +# IGNORE *.old # throw out all other "old" files (and don't +# # report that to the terminal) +# +# +# .fg-submit configuration files are "sourced" bash scripts, the +# keywords are simple shell functions. That means that you can +# also use other bash commands in that file, such as "echo", or +# write several commands on one line, separated with semicolon. +# You can even put all special rules in your ~/.fg-submit file, +# with rules depending on the working directory: +# +# case "$PWD" in +# */bo105*) DENY *.osg; ALLOW livery.xcf ;; +# */ufo*) DENY *.tiff ;; +# esac + + + +SELF=${0##*/} +DIR=${PWD##*/} + +if [ "$1" == "-v" ]; then + DBG=1 + shift +fi -SELF=$(basename $0) -AIRCRAFT=$(basename $PWD) +BASE=${1:-$DIR} +BASE=${BASE// /%20} -CVS=/usr/bin/cvs -ARCHIVE=$AIRCRAFT.tar.bz2 -DIFF=$AIRCRAFT.diff +CVS=/usr/bin/cvs # avoid colorcvs wrapper from +[ -x $CVS ] || CVS=cvs # http://www.hakubi.us/colorcvs/ +UPLOAD=$(which fg-upload 2>/dev/null) +CONFIG_FILE=".fg-submit" +ARCHIVE=$BASE.tar.bz2 +DIFF=$BASE.diff +CDIFF=$DIFF.bz2 -function ERROR { echo -e "\e[31;1m$*\e[m"; } -function LOG { echo -e "\e[35m$*\e[m"; } -function ADD { echo -e "\e[32m\t+ $*\e[m"; } -function REJECT { echo -e "\e[31m\t- $*\e[m"; } +# these rules are always prepended; the first letter decides if the +# rule accepts (+), rejects (-), or ignores (!) a matching file. +PREFIX_RULES=" + !$DIFF* !$CDIFF* !$ARCHIVE* + !CVS/* !*/CVS/* +" +# these rules are always appended +DEFAULT_RULES=" + +.cvsignore +*/.cvsignore + -*~ -*. -*.bak -*.orig + -*.RGB -*.RGBA -*.MDL + -*.XCF -*.tga -*.TGA -*.bmp -*.BMP -*.PNG + -*.blend -*.blend[0-9] -*blend[0-9][0-9] -*.blend[0-9][0-9][0-9] + -*.gz -*.tgz -*.bz2 -*.zip -*.tar.gz* -*.tar.bz2* +" +POSTFIX_RULES=" + !.* !*/.* + +* +" + + + +function ERROR { echo -e "\e[31;1m$*\e[m"; } +function LOG { echo -e "\e[35m$*\e[m"; } +function NEW { echo -e "\e[32m\t+ $*\e[m"; } +function CHANGED { echo -e "\e[36m\t+ $*\e[m"; } +function REJECT { echo -e "\e[31m\t- $*\e[m"; } +function DEBUG { [ $DBG ] && echo -e "$*"; } function diffstat { # output diff statistics, similar to the "diffstat" utility awk ' + function line(a, r, c, f) { + print "\t\033[32m"a"\033[m\t\033[31m"r"\033[m\t\033[34m"c"\033[m\t"f + } function dofile() { if (!file) { - return; + return } if (bin) { - print "\t\tbinary\t\t"file; + print "\t. . . . binary . . . . \033[36m"file"\033[m" } else { - print "\t+"a"\t-"r"\t!"c"\t"file - at += a; rt += r; ct += c; + line(a, r, c, file) + at += a; rt += r; ct += c } - a = r = c = 0; + a = r = c = 0 } BEGIN { - print "\tadded___removed_changed___________________________________"; - a = r = c = at = rt = ct = n = bin = 0; + print "\tadded---removed-changed----------------------------------------" + a = r = c = at = rt = ct = n = bin = 0 } - /^Index: / { dofile(); scan = bin = 0; file = $2; n += 1; next } + /^Index: / { dofile(); scan = bin = 0; file = $2; n++; next } /^@@/ { scan = 1; next } - /^Binary/ { if (!scan) { bin = 1 } next } - /^+/ { if (scan) { a += 1 } next } - /^-/ { if (scan) { r += 1 } next } - /^!/ { if (scan) { c += 1 } next } + /^Binary/ { if (!scan) bin = 1; next } + /^\+/ { if (scan) a++; next } + /^-/ { if (scan) r++; next } + /^!/ { if (scan) c++; next } END { - dofile(); - print "\t-----------------------------------total------------------"; - print "\t+"at"\t-"rt"\t!"ct"\tin "n" files" + dofile() + print "\t----------------------------------------total------------------" + line(at, rt, ct, "\033[min "n" files") } - ' < $1 + ' <$1 +} + +function backup_filename { + for ((i = 1; 1; i = i + 1)); do + name=$1.$i + if ! [ -a "$name" ]; then + touch $name + echo $name + return + fi + done +} + + + +# set up accept/reject rules +function ALLOW { for i in $*; do RULES="$RULES +$i"; done } +function DENY { for i in $*; do RULES="$RULES -$i"; done } +function IGNORE { for i in $*; do RULES="$RULES !$i"; done } + + +function search_config { + file="$1/$CONFIG_FILE" + DEBUG "checking for config file $file" + if [ -f "$file" ]; then + CONFIG="$file" + return 0 + elif [ "$1" ]; then + search_config ${1%/${1##*/}} # parent dir + return + fi + return 1 } -# create temporary dir that's automatcally removed on exit -TMP=$(mktemp -d -t $SELF.$AIRCRAFT.XXX) || (echo "$0: can't create temporary dir"; exit 1) +set -f +RULES= +if search_config "$PWD"; then + LOG "loading config file $CONFIG" + source "$CONFIG" +elif [ -f ~/$CONFIG_FILE ]; then + DEBUG "loading config file ~/$CONFIG_FILE" + source ~/$CONFIG_FILE +elif [ -f ~/${CONFIG_FILE}rc ]; then + DEBUG "loading config file ~/${CONFIG}rc" + source ~/${CONFIG_FILE}rc +fi +RULES="$PREFIX_RULES $RULES $DEFAULT_RULES $POSTFIX_RULES" +set +f + + +if [ $DBG ]; then + DEBUG "using these rules: " + for i in $RULES; do echo -n "$i "; done + echo +fi + + + +# create temporary dir that's automatically removed on exit +TMP=$(mktemp -d /tmp/$SELF.$BASE.XXXXXX) || (echo "$0: can't create temporary dir"; exit 1) trap "rm -rf $TMP" 0 1 2 3 13 15 -# move older archive or diff file out of the way -[ -f $DIFF ] && mv $DIFF $(mktemp $DIFF.X) -[ -f $ARCHIVE ] && mv $ARCHIVE $(mktemp $ARCHIVE.X) + +# move old files out of the way adding sequential suffixes +for i in $DIFF $CDIFF $ARCHIVE; do + [ -f $i ] && mv $i $(backup_filename $i) +done + -LOG "updating and checking for changed and new files ..." -$CVS -q up -dP >$TMP/up +LOG "updating and checking for new files ..." +$CVS -q up -dP >$TMP/up || exit 1 if grep "^C " $TMP/up &>/dev/null; then @@ -81,72 +283,84 @@ if grep "^C " $TMP/up &>/dev/null; then fi + LOG "making diff ..." if ! $CVS -q diff -up >$DIFF; then LOG "diff statistics:" diffstat $DIFF + echo # add diff file itself - echo $DIFF >>$TMP/include + echo $DIFF >>$TMP/files # add changed binary files awk ' - /^Index: / { scan = 1; file = $2 } - /^@@/ { scan = 0 } + /^Index: / { scan = 1; file = $2; next } + /^@@/ { scan = 0; next } /^Binary/ { if (scan) { print file } } - ' <$DIFF >>$TMP/include + ' <$DIFF >>$TMP/files else rm -f $DIFF fi -# write list of all files to add -LOG "adding to archive ..." -if [ -f $TMP/include ]; then - cat $TMP/include|while read i; do - ADD "$i" - echo $i >>$TMP/files + +LOG "checking for files to submit ..." +if [ -f $TMP/files ]; then + cat $TMP/files|while read i; do + CHANGED "$i" done fi + grep "^? " $TMP/up|while read i; do - find ${i#? } -type f >>$TMP/files + find ${i#? } -type f >>$TMP/check done -# classify and filter files -if [ -f $TMP/files ]; then - for i in $(cat $TMP/files); do - case "$i" in - $ARCHIVE*|$DIFF*) # don't add files generated by the script - ;; - */.*|.*) # silently drop hidden files - ;; - *~|*.|*.bak|*.orig) - REJECT "$i\t\t(backup file)" - ;; - CVS/*|*/CVS/*) - REJECT "$i\t\t(CVS file)" - ;; - *.blend|*.blend[0-9]|*.blend[0-9][0-9]) - REJECT "$i\t\t(blender file)" - ;; - *.xcf|*.tga|*.bmp|*.BMP|*.png) - REJECT "$i\t\t(graphics file)" - ;; - *) - ADD "$i" - echo "$i" >>$TMP/include - ;; - esac + +# filter files according to the pattern rules +if [ -f $TMP/check ]; then + for i in $(cat $TMP/check); do + DEBUG "checking whether file '$i' matches" + for r in $RULES; do + DEBUG "\t\trule $r" + class=${r:0:1} + rule=${r:1} + case "$i" in $rule) + case $class in + !) DEBUG "$i\t\t\"silently\" rejected\t\t$rule" ;; + -) REJECT "$i\t\t$rule" ;; + +) NEW "$i\t\t$rule" && echo "$i" >>$TMP/files ;; + esac + break + ;; + esac + done done fi -if [ -f $TMP/include ]; then - LOG "creating archive $ARCHIVE" - tar -cjf $ARCHIVE --files-from $TMP/include + +if ! [ -f $TMP/files ]; then + LOG "no changed or new files found" + exit 0 +fi + +echo +numfiles=$(awk '//{n++}END{print n}' <$TMP/files) +if [ -f $DIFF -a $numfiles == 1 ]; then + LOG "only changed non-binary files found" + LOG "creating compressed diff \e[1;37;40m$CDIFF\e[m\e[35m ..." + bzip2 --keep $DIFF + RESULT=$CDIFF else - LOG "no changed or new files detected" + LOG "changed and/or new files found" + LOG "creating archive \e[1;37;40m$ARCHIVE\e[m\e[35m ..." + tar --create --bzip2 --file=$ARCHIVE --files-from $TMP/files + RESULT=$ARCHIVE fi -exit 0 + + +[ -x "$UPLOAD" -a -f $RESULT ] && $UPLOAD $RESULT $DIFF +