Backed out changeset ad0d9f62c29c (bug 206659) for B2G desktop mochitest orange.
[gecko.git] / tools / update-packaging / make_incremental_update.sh
blob03638313116b81ffc4612d0d31c111324b24ea77
1 #!/bin/bash
2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this
4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 # This tool generates incremental update packages for the update system.
8 # Author: Darin Fisher
11 . $(dirname "$0")/common.sh
13 # -----------------------------------------------------------------------------
15 print_usage() {
16 notice "Usage: $(basename $0) [OPTIONS] ARCHIVE FROMDIR TODIR"
17 notice ""
18 notice "The differences between FROMDIR and TODIR will be stored in ARCHIVE."
19 notice ""
20 notice "Options:"
21 notice " -h show this help text"
22 notice " -f clobber this file in the installation"
23 notice " Must be a path to a file to clobber in the partial update."
24 notice ""
27 check_for_forced_update() {
28 force_list="$1"
29 forced_file_chk="$2"
31 local f
33 if [ "$forced_file_chk" = "precomplete" ]; then
34 ## "true" *giggle*
35 return 0;
38 if [ "${forced_file_chk##*.}" = "chk" ]
39 then
40 ## "true" *giggle*
41 return 0;
44 for f in $force_list; do
45 #echo comparing $forced_file_chk to $f
46 if [ "$forced_file_chk" = "$f" ]; then
47 ## "true" *giggle*
48 return 0;
50 done
51 ## 'false'... because this is bash. Oh yay!
52 return 1;
55 if [ $# = 0 ]; then
56 print_usage
57 exit 1
60 requested_forced_updates='Contents/MacOS/firefox'
62 while getopts "hf:" flag
64 case "$flag" in
65 h) print_usage; exit 0
67 f) requested_forced_updates="$requested_forced_updates $OPTARG"
69 ?) print_usage; exit 1
71 esac
72 done
74 # -----------------------------------------------------------------------------
76 let arg_start=$OPTIND-1
77 shift $arg_start
79 archive="$1"
80 olddir="$2"
81 newdir="$3"
82 # Prevent the workdir from being inside the targetdir so it isn't included in
83 # the update mar.
84 if [ $(echo "$newdir" | grep -c '\/$') = 1 ]; then
85 # Remove the /
86 newdir=$(echo "$newdir" | sed -e 's:\/$::')
88 workdir="$newdir.work"
89 updatemanifestv1="$workdir/update.manifest"
90 updatemanifestv2="$workdir/updatev2.manifest"
91 archivefiles="update.manifest updatev2.manifest"
93 mkdir -p "$workdir"
95 # On Mac, the precomplete file added by Bug 386760 will cause OS X to reload the
96 # Info.plist so it launches the right architecture, bug 600098
98 # Generate a list of all files in the target directory.
99 pushd "$olddir"
100 if test $? -ne 0 ; then
101 exit 1
104 list_files oldfiles
105 list_dirs olddirs
107 popd
109 pushd "$newdir"
110 if test $? -ne 0 ; then
111 exit 1
114 if [ ! -f "precomplete" ]; then
115 notice "precomplete file is missing!"
116 exit 1
119 list_dirs newdirs
120 list_files newfiles
122 popd
124 notice ""
125 notice "Adding file patch and add instructions to file 'update.manifest'"
126 > $updatemanifestv1
128 num_oldfiles=${#oldfiles[*]}
129 remove_array=
130 num_removes=0
132 for ((i=0; $i<$num_oldfiles; i=$i+1)); do
133 f="${oldfiles[$i]}"
135 # This file is created by Talkback, so we can ignore it
136 if [ "$f" = "readme.txt" ]; then
137 continue 1
140 # removed-files is excluded by make_incremental_updates.py so it is excluded
141 # here for consistency.
142 if [ `basename $f` = "removed-files" ]; then
143 continue 1
146 # If this file exists in the new directory as well, then check if it differs.
147 if [ -f "$newdir/$f" ]; then
149 if check_for_forced_update "$requested_forced_updates" "$f"; then
150 # The full workdir may not exist yet, so create it if necessary.
151 mkdir -p `dirname "$workdir/$f"`
152 $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
153 copy_perm "$newdir/$f" "$workdir/$f"
154 make_add_instruction "$f" 1 >> $updatemanifestv1
155 archivefiles="$archivefiles \"$f\""
156 continue 1
159 if ! diff "$olddir/$f" "$newdir/$f" > /dev/null; then
160 # Compute both the compressed binary diff and the compressed file, and
161 # compare the sizes. Then choose the smaller of the two to package.
162 dir=$(dirname "$workdir/$f")
163 mkdir -p "$dir"
164 $MBSDIFF "$olddir/$f" "$newdir/$f" "$workdir/$f.patch"
165 $BZIP2 -z9 "$workdir/$f.patch"
166 $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
167 copy_perm "$newdir/$f" "$workdir/$f"
168 patchfile="$workdir/$f.patch.bz2"
169 patchsize=$(get_file_size "$patchfile")
170 fullsize=$(get_file_size "$workdir/$f")
172 if [ $patchsize -lt $fullsize ]; then
173 make_patch_instruction "$f" >> $updatemanifestv1
174 mv -f "$patchfile" "$workdir/$f.patch"
175 rm -f "$workdir/$f"
176 archivefiles="$archivefiles \"$f.patch\""
177 else
178 make_add_instruction "$f" >> $updatemanifestv1
179 rm -f "$patchfile"
180 archivefiles="$archivefiles \"$f\""
183 else
184 # remove instructions are added after add / patch instructions for
185 # consistency with make_incremental_updates.py
186 remove_array[$num_removes]=$f
187 (( num_removes++ ))
189 done
191 # Newly added files
192 notice ""
193 notice "Adding file add instructions to file 'update.manifest'"
194 num_newfiles=${#newfiles[*]}
196 for ((i=0; $i<$num_newfiles; i=$i+1)); do
197 f="${newfiles[$i]}"
199 # removed-files is excluded by make_incremental_updates.py so it is excluded
200 # here for consistency.
201 if [ `basename $f` = "removed-files" ]; then
202 continue 1
205 # If we've already tested this file, then skip it
206 for ((j=0; $j<$num_oldfiles; j=$j+1)); do
207 if [ "$f" = "${oldfiles[j]}" ]; then
208 continue 2
210 done
212 dir=$(dirname "$workdir/$f")
213 mkdir -p "$dir"
215 $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
216 copy_perm "$newdir/$f" "$workdir/$f"
218 make_add_instruction "$f" >> "$updatemanifestv1"
219 archivefiles="$archivefiles \"$f\""
220 done
222 notice ""
223 notice "Adding file remove instructions to file 'update.manifest'"
224 for ((i=0; $i<$num_removes; i=$i+1)); do
225 f="${remove_array[$i]}"
226 notice " remove: $f"
227 echo "remove \"$f\"" >> $updatemanifestv1
228 done
230 # Add the type of update to the beginning of and cat the contents of the version
231 # 1 update manifest to the version 2 update manifest.
232 notice ""
233 notice "Adding type instruction to file 'updatev2.manifest'"
234 > $updatemanifestv2
235 notice " type: partial"
236 echo "type \"partial\"" >> $updatemanifestv2
238 notice ""
239 notice "Concatenating file 'update.manifest' to file 'updatev2.manifest'"
240 cat $updatemanifestv1 >> $updatemanifestv2
242 # Append remove instructions for any dead files.
243 notice ""
244 notice "Adding file and directory remove instructions from file 'removed-files'"
245 append_remove_instructions "$newdir" "$updatemanifestv1" "$updatemanifestv2"
247 notice ""
248 notice "Adding directory remove instructions for directories that no longer exist"
249 num_olddirs=${#olddirs[*]}
251 for ((i=0; $i<$num_olddirs; i=$i+1)); do
252 f="${olddirs[$i]}"
253 # If this dir doesn't exist in the new directory remove it.
254 if [ ! -d "$newdir/$f" ]; then
255 notice " rmdir: $f/"
256 echo "rmdir \"$f/\"" >> $updatemanifestv2
258 done
260 $BZIP2 -z9 "$updatemanifestv1" && mv -f "$updatemanifestv1.bz2" "$updatemanifestv1"
261 $BZIP2 -z9 "$updatemanifestv2" && mv -f "$updatemanifestv2.bz2" "$updatemanifestv2"
263 eval "$MAR -C \"$workdir\" -c output.mar $archivefiles"
264 mv -f "$workdir/output.mar" "$archive"
266 # cleanup
267 rm -fr "$workdir"
269 notice ""
270 notice "Finished"