OpenSDE Framework (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

305 lines
6.8 KiB

  1. #!/bin/sh
  2. # --- SDE-COPYRIGHT-NOTE-BEGIN ---
  3. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  4. #
  5. # Filename: lib/misc/compare.sh
  6. # Copyright (C) 2008 The OpenSDE Project
  7. # Copyright (C) 2004 - 2006 The T2 SDE Project
  8. #
  9. # More information can be found in the files COPYING and README.
  10. #
  11. # This program is free software; you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation; version 2 of the License. A copy of the
  14. # GNU General Public License can be found in the file COPYING.
  15. # --- SDE-COPYRIGHT-NOTE-END ---
  16. verbose=0
  17. quiet=0
  18. ignspace=0
  19. ignprio=0
  20. ignrepo=0
  21. dopatch=0
  22. source=
  23. targets=
  24. repositories=
  25. packages=
  26. function show_usage() {
  27. echo "usage: $0 [-q[q]] [-v] [-r] {action}"
  28. echo
  29. echo "action: [-p [-P] [-S]] <source> <target> [-repository <repo>|<packages>|]"
  30. echo " -3 <source> <target1> <target2> [-repository <repo>|<packages>|]"
  31. echo
  32. echo " -q: don't show packages with the same version"
  33. echo " -qq: don't show packages missing or with the same version"
  34. echo " -v: show extra info about the packages"
  35. echo " -r: don't show repository name"
  36. echo
  37. echo " -p: show patch to turn \$source into \$target"
  38. echo " -P: ignore [P]s of .desc files on patches"
  39. echo " -S: ignore spaces on patches"
  40. }
  41. # TODO: it would be great to port it to "-n <n>" instead of -3
  42. #
  43. while [ $# -gt 0 ]; do
  44. case "$1" in
  45. -v) verbose=1 ;;
  46. -r) ignrepo=1 ;;
  47. -q) quiet=1 ;;
  48. -qq) quiet=2 ;;
  49. -p) dopatch=1 ;;
  50. -P) ignprio=1 ;;
  51. -S) ignspace=1 ;;
  52. -3) source="$2"
  53. targets="$3 $4"
  54. shift 3 ;;
  55. -repository)
  56. shift
  57. repositories="$*"; set --
  58. ;;
  59. *) if [ "$targets" ]; then
  60. packages="$*"; set --
  61. elif [ "$source" ]; then
  62. targets="$1"
  63. else
  64. source="$1"
  65. fi
  66. esac
  67. shift
  68. done
  69. function remove_header() {
  70. # thanks you blindcoder :)
  71. #
  72. local here=0 count=1
  73. while read line ; do
  74. count=$(( ${count} + 1 ))
  75. [ "${line//COPYRIGHT-NOTE-END/}" != "${line}" ] && here=${count}
  76. done < $1
  77. tail -n +${here} $1
  78. }
  79. function show_nice_diff() {
  80. local diffopt=
  81. [ $ignspace -eq 1 ] && diffopt='-EBb'
  82. diff -u $diffopt "$1" "$2" | sed \
  83. -e 's,^--- .*,--- old/package/'"${3##*/package/}," \
  84. -e 's,^[\+][\+][\+] .*,+++ new/package/'"${3##*/package/},"
  85. }
  86. function diff_package() {
  87. local source="$1"
  88. local target="$2"
  89. local x= y=
  90. # files on source
  91. for x in $source/*; do
  92. if [ -d "$x/" ]; then
  93. diff_package $x $target/${x##*/}
  94. elif [[ "$x" = *.cache ]]; then
  95. continue
  96. elif [ -f "$x" ]; then
  97. remove_header $x > $$.source
  98. if [ -f $target/${x##*/} ]; then
  99. remove_header $target/${x##*/} > $$.target
  100. if [[ "$x" = *.desc ]]; then
  101. y=$( grep -e "^\[P\]" $x )
  102. [ "$y" -a $ignprio -eq 1 ] && sed -i -e "s,^\[P\] .*,$y," $$.target
  103. fi
  104. show_nice_diff $$.source $$.target $x
  105. rm $$.target
  106. else
  107. show_nice_diff $$.source /dev/null $x
  108. fi
  109. rm $$.source
  110. fi
  111. done
  112. # files only on target
  113. for x in $target/*; do
  114. if [ -d $x/ ]; then
  115. [ ! -d $source/${x#$target/} ] && diff_package $source/${x#$target/} $x
  116. elif [[ "$x" = *.cache ]]; then
  117. continue
  118. elif [ -f "$x" ]; then
  119. if [ ! -f "$source/${x#$target/}" ]; then
  120. remove_header $x > $$.target
  121. show_nice_diff /dev/null $$.target $source/${x#$target/}
  122. rm $$.target
  123. fi
  124. fi
  125. done
  126. }
  127. # grabdata confdir field
  128. function grabdata() {
  129. local confdir=$1
  130. local pkg=$2
  131. local field=$3
  132. local output=
  133. case "$field" in
  134. version) output=$( grabdata_desc $confdir/$pkg.desc $field ) ;;
  135. *) output=$( grabdata_cache $confdir/$pkg.cache $field ) ;;
  136. esac
  137. if [ -z "${output// /}" ]; then
  138. echo "UNKNOWN"
  139. else
  140. echo "$output"
  141. fi
  142. }
  143. function grabdata_desc() {
  144. local output=
  145. if [ -f "$1" ]; then
  146. case "$2" in
  147. version) output=$( grep -e "^\[V\]" $1 | cut -d' ' -f2- ) ;;
  148. esac
  149. fi
  150. echo "$output"
  151. }
  152. function grabdata_cache() {
  153. local output=
  154. if [ -f "$1" ]; then
  155. case "$2" in
  156. status) if grep -q -e "^\[.-ERROR\]" $1; then
  157. output=BROKEN
  158. else
  159. output=BUILT
  160. fi ;;
  161. size) output=$( grep -e "^\[SIZE\]" $1 | cut -d' ' -f2- ) ;;
  162. esac
  163. fi
  164. echo "$output"
  165. }
  166. function compare_package() {
  167. local source=$1
  168. local fullpkg=${1##*/package/}
  169. local pkg=${1##*/}
  170. local target= x= missing=0
  171. local info=
  172. local srcver= srcstatus= srcsize=
  173. local tgtver= tgtstatus= tgtsize=
  174. shift;
  175. [ $ignrepo -eq 1 ] && fullpkg=$pkg
  176. srcver=$( grabdata $source $pkg version )
  177. srcstatus=$( grabdata $source $pkg status )
  178. srcsize=$( grabdata $source $pkg size )
  179. tgtver=
  180. tgtstatus=
  181. tgtsize=
  182. for x; do
  183. target=$( echo $x/package/*/$pkg | head -n 1 )
  184. if [ -d "$target" ]; then
  185. tgtver="$tgtver:$( grabdata $target $pkg version )"
  186. tgtstatus="$tgtstatus:$( grabdata $target $pkg status )"
  187. tgtsize="$tgtsize:$( grabdata $target $pkg size )"
  188. else
  189. tgtver="$tgtver:MISSING"
  190. tgtstatus="$tgtstatus:MISSING"
  191. tgtsize="$tgtsize:MISSING"
  192. missing=1
  193. fi
  194. done
  195. tgtver="${tgtver#:}"
  196. tgtstatus="${tgtstatus#:}"
  197. tgtsize="${tgtsize#:}"
  198. # do we have different versions?
  199. #
  200. equalver=1 equalstatus=1
  201. IFS=':' ; for x in $tgtver; do
  202. [ "$x" != "$srcver" ] && equalver=0
  203. done
  204. IFS=':' ; for x in $tgtstatus; do
  205. [ "$x" != "$srcstatus" ] && equalstatus=0
  206. done
  207. # optimize version and status if they are the same
  208. #
  209. if [ $equalver -eq 1 ]; then
  210. version=$srcver
  211. else
  212. version="$srcver -> $tgtver"
  213. fi
  214. if [ $equalstatus -eq 1 ]; then
  215. status="$srcstatus"
  216. else
  217. status="$srcstatus -> $tgtstatus"
  218. fi
  219. # acording to verbosity level, what info should i show?
  220. #
  221. if [ $verbose -eq 0 ]; then
  222. info="($version)"
  223. else
  224. info="($version) ($status) ($srcsize -> $tgtsize)"
  225. fi
  226. if [ $missing -eq 1 ]; then
  227. if [ $quiet -le 1 ]; then
  228. # New - the package is not available at target tree
  229. echo "N $fullpkg $info" 1>&2
  230. [ $dopatch -eq 1 ] && diff_package $source $target
  231. fi
  232. elif [ $equalver -eq 1 ]; then
  233. if [ $quiet -eq 0 ]; then
  234. # Equal - the versions and cache status are the same on both trees
  235. echo "E $fullpkg $info" 1>&2
  236. [ $dopatch -eq 1 ] && diff_package $source $target
  237. fi
  238. else
  239. # Modified - the version on both trees is different
  240. echo "M $fullpkg $info" 1>&2
  241. [ $dopatch -eq 1 ] && diff_package $source $target
  242. fi
  243. }
  244. if [ -z "$source" -o -z "$targets" ]; then
  245. show_usage; exit 1
  246. fi
  247. allexist=1
  248. for x in $source $targets; do
  249. [ ! -d "$x/" ] && allexist=0; break
  250. done
  251. if [ $allexist -eq 1 ]; then
  252. echo -e "from: $source\nto..: $targets" 1>&2
  253. if [ "$repositories" ]; then
  254. for repo in $repositories; do
  255. for x in $source/package/$repo/*; do
  256. [ -d "$x" ] && ( compare_package $x $targets )
  257. done
  258. done
  259. elif [ "$packages" ]; then
  260. for pkg in $packages; do
  261. x=$( echo $source/package/*/$pkg | head -n 1 )
  262. [ -d "$x" ] && compare_package $x $targets
  263. done
  264. else
  265. for repo in $source/package/*; do
  266. for x in $repo/*; do
  267. [ -d "$x" ] && compare_package $x $targets
  268. done
  269. done
  270. fi
  271. else
  272. show_usage
  273. exit 1
  274. fi