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