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