first commit
This commit is contained in:
366
scripts/tools/fg-submit
Executable file
366
scripts/tools/fg-submit
Executable file
@@ -0,0 +1,366 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# 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: fg-submit [-v] [<basename>]
|
||||
#
|
||||
# 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 <pattern-list> ... accept & report matching file
|
||||
# DENY <pattern-list> ... reject & report matching file
|
||||
# IGNORE <pattern-list> ... silently reject matching file
|
||||
#
|
||||
# A <pattern-list> 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
|
||||
|
||||
BASE=${1:-$DIR}
|
||||
BASE=${BASE// /%20}
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
}
|
||||
if (bin) {
|
||||
print "\t. . . . binary . . . . \033[36m"file"\033[m"
|
||||
} else {
|
||||
line(a, r, c, file)
|
||||
at += a; rt += r; ct += c
|
||||
}
|
||||
a = r = c = 0
|
||||
}
|
||||
BEGIN {
|
||||
print "\tadded---removed-changed----------------------------------------"
|
||||
a = r = c = at = rt = ct = n = bin = 0
|
||||
}
|
||||
/^Index: / { dofile(); scan = bin = 0; file = $2; n++; next }
|
||||
/^@@/ { scan = 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------------------"
|
||||
line(at, rt, ct, "\033[min "n" files")
|
||||
}
|
||||
' <$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
|
||||
}
|
||||
|
||||
|
||||
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 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 new files ..."
|
||||
$CVS -q up -dP >$TMP/up || exit 1
|
||||
|
||||
|
||||
if grep "^C " $TMP/up &>/dev/null; then
|
||||
ERROR "there are conflicts with the following files:"
|
||||
grep "^C " $TMP/up
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
LOG "making diff ..."
|
||||
if ! $CVS -q diff -up >$DIFF; then
|
||||
LOG "diff statistics:"
|
||||
diffstat $DIFF
|
||||
echo
|
||||
|
||||
# add diff file itself
|
||||
echo $DIFF >>$TMP/files
|
||||
|
||||
# add changed binary files
|
||||
awk '
|
||||
/^Index: / { scan = 1; file = $2; next }
|
||||
/^@@/ { scan = 0; next }
|
||||
/^Binary/ { if (scan) { print file } }
|
||||
' <$DIFF >>$TMP/files
|
||||
else
|
||||
rm -f $DIFF
|
||||
fi
|
||||
|
||||
|
||||
|
||||
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/check
|
||||
done
|
||||
|
||||
|
||||
|
||||
# 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/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 "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
|
||||
|
||||
|
||||
[ -x "$UPLOAD" -a -f $RESULT ] && $UPLOAD $RESULT $DIFF
|
||||
|
||||
|
||||
Reference in New Issue
Block a user