mirror of the now-defunct rocklinux.org
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.

291 lines
6.2 KiB

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