]> git.xonotic.org Git - xonotic/xonotic.git/blob - misc/tools/zipdiff
mark a bug in zipdiff
[xonotic/xonotic.git] / misc / tools / zipdiff
1 #!/bin/sh
2
3 usage()
4 {
5         cat <<EOF
6 Usage:
7   $0 -o difference.zip -f from.zip -t to.zip
8   $0 -f from.zip -t to.zip
9 EOF
10         exit 1
11 }
12
13 output=
14 from=
15 to=
16 excludes=
17 ziptool="mkzip"
18
19 mkzip()
20 {
21         archive=$1; shift
22         sevenzipflags=-mx=9
23         zipflags=-9
24         ziplist=`mktemp`
25         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
26         7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
27         zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
28         rm -f "$ziplist"
29 }
30
31 while [ $# -gt 0 ]; do
32         o=$1
33         shift
34         case "$o" in
35                 -o)
36                         output=$1
37                         shift
38                         ;;
39                 -f)
40                         from=$1
41                         shift
42                         ;;
43                 -t)
44                         to=$1
45                         shift
46                         ;;
47                 -x)
48                         excludes="$excludes $1"
49                         shift
50                         ;;
51                 -z)
52                         ziptool=$1
53                         shift
54                         ;;
55                 *)
56                         usage
57                         ;;
58         esac
59 done
60
61 [ -n "$from" ] || usage
62 [ -n "$to" ] || usage
63
64 found()
65 {
66         type=$1
67         source=$2
68         echo >&2 "$type: $source"
69         case "$type" in
70                 new|changed|deleted)
71                         echo "$source"
72                         ;;
73                 excluded)
74                         ;;
75                 deleted|*)
76                         echo >&2 " * Sorry, can't handle deletion of $source."
77                         ;;
78         esac
79 }
80
81 tempdir=`mktemp -d -t zipdiff.XXXXXX`
82
83 newline="
84 "
85 fromlist="$(zipinfo -1 "$from" | grep -v /\$)"
86 tolist="$(zipinfo -1 "$to" | grep -v /\$)"
87
88 diffit()
89 {
90         echo "$fromlist" | while IFS= read -r line; do
91                 case "$newline$tolist$newline" in
92                         *$newline$line$newline*)
93                                 ;;
94                         *)
95                                 isexcluded=false
96
97                                 for P in $excludes; do
98                                         case "$line" in
99                                                 $P)
100                                                         found excluded "$line"
101                                                         isexcluded=true
102                                                         break
103                                                         ;;
104                                         esac
105                                 done
106
107                                 if ! $isexcluded; then
108                                         found deleted "$line"
109                                 fi
110                                 ;;
111                 esac
112         done
113         echo "$tolist" | while IFS= read -r line; do
114                 case "$newline$fromlist$newline" in
115                         *$newline$line$newline*)
116                                 # check if equal
117                                 isexcluded=false
118
119                                 for P in $excludes; do
120                                         case "$line" in
121                                                 $P)
122                                                         found excluded "$line"
123                                                         isexcluded=true
124                                                         break
125                                                         ;;
126                                         esac
127                                 done
128
129                                 if ! $isexcluded; then
130                                         unzip -p "$from" "$line" > "$tempdir/v1"
131                                         unzip -p "$to" "$line" > "$tempdir/v2"
132                                         if ! diff --brief "$tempdir/v1" "$tempdir/v2" >/dev/null 2>&1; then
133                                                 found changed "$line"
134                                         fi
135                                         rm "$tempdir/v1"
136                                         rm "$tempdir/v2"
137                                 fi
138                                 ;;
139                         *)
140                                 # check if equal
141                                 isexcluded=false
142
143                                 for P in $excludes; do
144                                         case "$line" in
145                                                 $P)
146                                                         found excluded "$line"
147                                                         isexcluded=true
148                                                         break
149                                                         ;;
150                                         esac
151                                 done
152
153                                 if ! $isexcluded; then
154                                         found new "$line"
155                                 fi
156                                 ;;
157                 esac
158         done
159 }
160
161 result=`diffit`
162
163 case "$output" in
164         '')
165                 ;;
166         *)
167                 rm -f "$output"
168                 if [ -n "$result" ]; then
169                         echo "$result" | while IFS= read -r line; do
170                                 echo >&2 "extracting $line..."
171                                 dline=./$line
172                                 mkdir -p "$tempdir/${dline%/*}"
173                                 unzip -p "$to" "$line" > "$tempdir/$line" # this may create an empty file - don't care, DP handles this as deletion
174                                 # FIXME permissions
175                         done
176                         case "$output" in
177                                 /*)
178                                         ;;
179                                 *)
180                                         output=`pwd`/$output
181                                         ;;
182                         esac
183                         cd "$tempdir"
184                         $ziptool "$output" .
185                         cd ..
186                 fi
187                 ;;
188 esac
189
190 rm -rf "$tempdir"