PageRenderTime 103ms CodeModel.GetById 88ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/scripts/hump.sh

https://code.google.com/p/camelbox/
Shell | 257 lines | 183 code | 28 blank | 46 comment | 30 complexity | 8c9d473ae0b2c6ecf201c09f85740a0d MD5 | raw file
  1#!/bin/sh
  2
  3# script to run a before/after diff on the camelbox folder, and generate a
  4# list of files that have been added to the after snapshot
  5
  6# script accepts the following options:
  7# - name of the before filelist
  8# - name of the after filelist
  9# - name of the diff filelist
 10# - whether or not to strip the .cpan directory
 11
 12# psuedocode
 13# - run the find on the camelbox tree
 14#   - save checksums of files
 15# - install some software from CPAN, or the user installs software
 16# - run find on the camelbox tree again
 17#   - get new checksums
 18# - diff the two finds, or diff the two checksum lists
 19# - (optional) filter out .cpan entries 
 20
 21# a starting directory, if the user doesn't pass one in
 22START_DIR="/camelbox"
 23OUTPUT_DIR="${START_DIR}/share/pkglists"
 24TIMESTAMP=$(TZ=GMT date +%Y.%j | tr -d '\n')
 25
 26function find_first_free_filename () {
 27	local FILE_DIR=$1
 28    local FILE_NAME=$2
 29	local FILE_EXT=$3
 30    local FILE_COUNTER=1
 31    while [ -f $FILE_DIR/$FILE_NAME.$TIMESTAMP.$FILE_COUNTER.$FILE_EXT ];
 32    do
 33        echo "$FILE_DIR/$FILE_NAME.$TIMESTAMP.$FILE_COUNTER.$FILE_EXT exists"
 34        FILE_COUNTER=$(($FILE_COUNTER + 1))
 35    done
 36    echo "Output file will be:"
 37   	echo $FILE_DIR/$FILE_NAME.$TIMESTAMP.$FILE_COUNTER.$FILE_EXT
 38
 39    FREE_FILENAME="$FILE_DIR/$FILE_NAME.$TIMESTAMP.$FILE_COUNTER.$FILE_EXT"
 40} # function find_first_free_filename()
 41
 42function exists_check () {
 43	if [ ! -e $1 ]; then
 44		echo "ERROR: file $1 does not exist" 
 45		exit 1
 46	fi # if [ -e $1 ]
 47} # function exists_check ()
 48
 49function overwrite_check () {
 50#echo "overwrite is $OVERWRITE"
 51	if [ "x$OVERWRITE" != "xtrue" ]; then
 52		if [ -e $1 ]; then
 53			echo "ERROR: file $1 exists" 
 54			echo "Cowardly refusing to overwrite existing files"
 55			echo "Use the '-w' overwrite switch to ignore existing files"
 56			exit 1
 57		fi # if [ -e $1 ]
 58	fi # if [ "x$OVERWRITE" != "xtrue" ]
 59} # function overwrite_check ()
 60
 61function show_examples () {
 62	echo "Examples:"
 63	echo "# create a list of files that can be used with GNU tar"
 64	echo '# filelist.txt is created in either C:\\camelbox\\share\\pkglists'
 65	echo "# or the directory specified with '-d'"
 66	echo 
 67	echo '# creates "C:\\camelbox\\share\\pkglists\\filelist.txt"'
 68	echo "sh hump.sh -o filelist.txt"
 69	echo
 70	echo '# creates "C:\\temp\\filelist.txt"'
 71	echo "sh hump.sh -d /temp -o filelist.txt"
 72	echo
 73	echo "# create a filelist and 'after' file from 'before' file"
 74	echo "sh hump.sh -b before.txt -a after.txt -o filelist.txt"
 75	echo
 76	echo "# install a CPAN module, creating 'before/after' files and filelist"
 77	echo "sh hump.sh -i JSON -b before.txt -a after.txt -o filelist.txt"
 78	echo
 79	echo "# create a filelist and and a package from that filelist"
 80	echo "sh hump.sh -b before.txt -a after.txt -o filelist.txt -p pkg_name"
 81	echo
 82	echo "# create an md5sum filelist (list of files with checksums)"
 83	echo "sh hump.sh -m filename -t TIMESTAMP -d /path/to/search"
 84	echo
 85    exit 1
 86} # function show_examples
 87
 88function show_usage () {
 89	echo "Usage:"
 90	echo "  -h show this help text"
 91	echo "  -e show usage examples"
 92	echo
 93    echo "To get a simple list of files that can be used with GNU tar:"
 94	echo "  -o output list - Generate a simple list of files"
 95	echo "Output file has *NIX forward slashes for path separation"
 96    echo
 97    echo "To get a list of files that are installed for an application:"
 98	echo "  -i install this Perl module from CPAN (optional)"
 99	echo "  -b before filelist - An existing 'before install' filelist"
100	echo "  -a after filelist - Generate an 'after install' filelist"
101	echo "(Output file has MS-DOS backslashes for path separation)"
102    echo
103	echo "To get a list of files with MD5 checksums (for verifying downloads)"
104	echo "  -m generate a filelist with MD5 sums"
105	echo "  -t use this timestamp for the output file"
106	echo
107    echo "Miscellaneous Options"
108    echo '  -d start in this directory instead of "C:\\camelbox"'
109	echo "  -p name of a tarball to create using the output filelist"
110	echo "  -c show the .cpan directory in filelist output"
111    echo	
112	echo "NOTE: all files should use full paths to avoid problems"
113	echo "  when the script changes directories" 
114	exit 1
115} # function show_usage ()
116
117function check_empty_var () {
118	echo "checking for $2"
119	if [ -z $2 ]; then
120		echo "ERROR: switch '$1' empty/not used"
121		show_usage
122	fi
123} # function check_empty_var ()
124
125function run_xfind () {
126	local XFIND_OUT=$1
127    # sed removes the 'camelbox/' prefix from all files
128    # and the 'camelbox/' directory itself
129	# seed the output list with the output list file itself
130
131
132    xfind $START_DIR -type f \
133   		| sed -e '{/^\/camelbox$/d; s/\/camelbox[\\]*//; s/\\/\//g;}' \
134	    | tee -a $XFIND_OUT
135} # function run_xfind
136
137#### begin main script ####
138# call getopts with all of the supported options
139while getopts a:b:cd:ehi:m:o:p:s:t:wz VARLIST
140do
141	case $VARLIST in
142		a) 	AFTERLIST=$OPTARG;;
143		b) 	BEFORELIST=$OPTARG;;
144		c)  CPAN="true";;
145		d)  OUTPUT_DIR=$OPTARG;;
146		e)  SHOW_EXAMPLES="true";;
147		h)  SHOW_HELP="true";;
148		i)	CPAN_INSTALL=$OPTARG;;
149		m)  MD5_LIST=$OPTARG;;
150        o)  OUTPUT_FILE=$OPTARG;;
151		p)  PACKAGE_FILE=$OPTARG;;
152        s)  START_DIR=$OPTARG;;
153		t)  TIMESTAMP=$OPTARG;;
154		w)  OVERWRITE="true";;
155	esac
156done
157shift $(expr $OPTIND - 1)
158
159# create the absolute filename used to write the filelist to
160OUTPUT_LIST="$OUTPUT_DIR/$OUTPUT_FILE"
161
162# then verify the output directory exists
163if [ ! -d $OUTPUT_DIR ]; then
164	mkdir -p $OUTPUT_DIR
165	if [ $? -ne 0 ]; then 
166		echo "ERROR: Failed to create output directory $OUTPUT_DIR"
167		exit 1
168	fi # if [ $? -ne 0 
169fi
170
171# for debugging
172#echo "$BEFORELIST:$AFTERLIST:$OUTPUT_LIST:$HELP"
173#sleep 5s
174
175if [ "x$SHOW_HELP" = "xtrue" ]; then show_usage; fi
176if [ "x$SHOW_EXAMPLES" = "xtrue" ]; then show_examples; fi
177
178## BEFORELIST and AFTERLIST; run a diff on the two lists
179if [ "x$BEFORELIST" != "x" -a "x$AFTERLIST" != "x" ]; then
180    # verify beforelist exists
181    check_empty_var "-b (before list)" $BEFORELIST
182    exists_check $BEFORELIST
183    
184	# verify OUTPUT_LIST is not about to be overwritten
185    check_empty_var "-o (output list)" $OUTPUT_LIST
186    overwrite_check $OUTPUT_LIST
187	# write the package metadata, and an entry for the filelist
188	echo "# Package list for: $OUTPUT_FILE $TIMESTAMP" > $OUTPUT_LIST
189	echo "share/pkglists/$OUTPUT_FILE" >> $OUTPUT_LIST
190    
191	# install a module from CPAN?
192    if [ "x$CPAN_INSTALL" != "x" ]; then
193    	perl -MCPAN -e "install $CPAN_INSTALL"
194    	if [ $? -ne 0 ]; then 
195    		echo "Install of $CPAN_INSTALL failed; exiting..."
196    		exit 1
197    	fi # if [ $? -ne 0 ]
198    fi # if [ -n $CPAN_INSTALL ]
199
200	check_empty_var "-a (after list)" $AFTERLIST
201    overwrite_check $AFTERLIST
202    run_xfind $AFTERLIST
203
204    # TODO - the below grep -v "\.cpan" may be redundant, the previous grep in
205    # the pipe may already snag that match; verify!
206
207    # don't strip the .cpan directories
208    # the file list needs to have forward slashes to keep tar happy
209    if [ "x$CPAN" = "xtrue" ]; then
210    	echo "Including .cpan directory in package filelist output"
211    	diff -u $BEFORELIST $AFTERLIST | grep "^+[.a-zA-Z]" \
212			| grep -vE "^#|share\/pkglists" \
213    		| sed '{s/^+//; s/\\/\//g;}' \
214			| tee -a $OUTPUT_LIST
215    else
216    	# get rid of the .cpan directories
217    	echo "Stripping .cpan directory from package filelist output"
218    	diff -u $BEFORELIST $AFTERLIST | grep "^+[a-zA-Z]" \
219			| grep -vE "^#|share\/pkglists" \
220	   		| grep -v "\.cpan" \
221    		| sed '{s/^+//; s/\\/\//g;}' \
222			| tee -a $OUTPUT_LIST
223    fi # if [ "x$NOCPAN" = "xtrue" ]
224
225## OUTPUT_LIST only; just generate a filelist
226elif [ "x$OUTPUT_LIST" != "x" ]; then
227    check_empty_var "-o (output list)" $OUTPUT_LIST
228    overwrite_check $OUTPUT_LIST
229    run_xfind $OUTPUT_LIST
230## MD5_LIST only; just generate a filelist with MD5 checksums
231elif [ "x$MD5_LIST" != "x" ]; then
232  	xfind $START_DIR -maxdepth 1 -type f | xargs md5sum \
233		>> $MD5_LIST.$TIMESTAMP.txt
234## no variables; show usage message
235else
236	# neither -o (output list) or -b/-a (before/after list) passed in
237	show_usage
238fi # if [ $OUTPUT_LIST ]; then
239
240## OUTPUT_LIST and PACKAGE_FILE; generate a package archive file
241if [ "x$OUTPUT_LIST" != "x" -a "x$PACKAGE_FILE" != "x" ]; then
242	# feed the output list to tar, then compress it
243	overwrite_check $PACKAGE_FILE
244	find_first_free_filename "/temp" $PACKAGE_FILE "tar"
245	echo "Creating package lzma tarball '${FREE_FILENAME}' from ${OUTPUT_LIST}"
246	# $FREE_FILENAME comes from find_first_free_filename
247	# replace the generic package metadata with the specific package filename
248	cat $OUTPUT_LIST | sed '{s/$OUTPUT_FILE $TIMESTAMP/$FREE_FILENAME/;}' \
249		> /temp/$OUTPUT_FILE.$$
250	mv -f /temp/$OUTPUT_FILE.$$ $OUTPUT_LIST
251	CURRENT_PWD=$PWD
252	cd $START_DIR
253	grep -v "#" $OUTPUT_LIST | tar -cv -T - | lzma e -si $FREE_FILENAME.lzma
254	cd $CURRENT_PWD
255fi # if [ "x$OUTPUT_LIST" != "x" -a "x$PACKAGE_FILE" != "x" ]; then
256
257exit 0