Merge branch 'master' of ssh://git.onelab.eu/git/sface
[sface.git] / macos / build-dmg.sh
1 #!/bin/sh
2
3 # PURPOSE
4 # package a combination of sfa+sface into a snow leopard dmg install disk
5
6 # NOTES
7 # we leverage the first similar packaging initially made by Baris Metin
8
9 # REQUIREMENTS
10 # sface-skel-snow-leopard.dmg is the skeleton that has Qt and all the other third-party software
11 #   it is expected to be found in the local directory
12 #   otherwise it gets fetched at http://mirror.onelab.eu/third-party/ 
13 # the script expects the taglevels for both sfa and sface, 
14 #   in order to retrieve the corresponding code and to label the resulting package properly
15 #
16
17 # the place to search for the  skeleton
18 SKEL_REPO=http://mirror.onelab.eu/third-party
19
20 # hard-wired for snow-leopard for now
21 arch=snow-leopard
22
23 # does not affect final dmg size as it's compressed
24 DISK_SIZE=100M
25
26 ########################################
27 COMMAND=$(basename $0)
28
29 # extract the tag part of a GITPATH
30 function git_url () { echo $1 | cut -d @ -f 1 ; }
31 function git_tag () { echo $1 | cut -d @ -f 2 ; }
32
33 # go in $dest and retrieve $path part of codebase based on gitpath, e.g.
34 # git_retrieve \
35 #     git://git.onelab.eu/sface.git@sface-0.1-5 
36 #     sface 
37 #     /Volumes/sface-skel-sn/sface.app/Contents/Resources/
38 # or, with the -f (-file) option:
39 # git_retrieve -f \
40 #     git://git.onelab.eu/sface.git@sface-0.1-5 
41 #     macos/appIcon.icns 
42 #     /Volumes/sface-skel-sn/sface.app/appIcon.icns 
43 function git_retrieve () {
44     filemode=""
45     case "$1" in -f|--file) filemode=true; shift;; esac
46     gitpath=$1; shift
47     path=$1; shift
48     dest=$1; shift
49
50     giturl=$(git_url $gitpath)
51     gittag=$(git_tag $gitpath)
52     if [ -z "$filemode" ] ; then
53         [ -d $dest ] || mkdir -p $dest
54         pushd $dest
55         git archive --remote=${giturl} ${gittag} | tar -xf - ${path}
56         popd
57     else
58         destdir=$(dirname $dest)
59         [ -d $destdir ] || mkdir -p $destdir
60         git archive --remote=${giturl} ${gittag} | tar -xOf - ${path} > ${dest}
61     fi
62 }
63
64 function die () {
65     echo "$@" "- exiting" 
66     exit 1
67 }
68
69 function package () {
70     
71     sface_GITPATH=$1; shift
72     sfa_GITPATH=$1; shift
73
74     skel_name=sface-skel-${arch}
75     skel_dmg=./${skel_name}.dmg
76     skel_mnt=/Volumes/${skel_name}
77
78     sfa_release=sfa-$(git_tag $sfa_GITPATH | sed -e s,sfa-,,)
79     sface_release=sface-$(git_tag $sface_GITPATH | sed -e s,sface-,,)
80     release=$(git_tag $sfa_GITPATH)-$(git_tag $sface_GITPATH)
81
82     img_name=${sface_release}-${sfa_release}-${arch}
83     img_dmg=./${img_name}.dmg
84     img_raw_dmg=./${img_name}.raw.dmg
85     img_mnt=/Volumes/${img_name}
86
87     # check we're clear
88     [ -f $img_dmg ] && die "output dmg $img_dmg already exists"
89     [ -f $img_raw_dmg ] && die "please clean up tmp file $img_raw_dmg"
90
91     # mount the skeleton if not yet avail.
92     if [ ! -d $skel_mnt ] ; then
93         # locate skel dmg
94         if [ ! -f $skel_dmg ] ; then
95             echo "Retrieving $skel_dmg from $SKEL_REPO"
96             curl -O $SKEL_REPO/$skel_dmg
97         fi
98         # needless to check for existence as curl will have created on anyway
99         if ! hdiutil mount $skel_dmg ; then
100             die "Could not mount $skel_dmg
101 Please check it is published at $SKEL_REPO
102 Also make sure to trash the current one before retrying"
103         fi
104     fi
105     [ -d $skel_mnt ] || die "Could not mount skeleton $skel_dmg"
106
107     # if image already mounted, it's an old run
108     [ -d $img_mnt ] && die "Image already mounted on $img_mnt"
109
110     hdiutil create -size $DISK_SIZE -fs HFS+J -volname ${img_name} $img_raw_dmg
111     hdiutil attach -readwrite -mount required $img_raw_dmg 
112
113     # copy skeleton as-is
114     tar -C $skel_mnt --exclude .Trashes -cf - . | tar -C $img_mnt -xf -
115     # places relative to mount point
116     app=sface.app
117     resource_path=$app/Contents/Resources
118     bin_path=$app/Contents/MacOS
119     icon_path=$app/Contents/Resources/
120     background_path=background
121     # retrieve sfa/sfa and sface/sface in the image
122     git_retrieve $sfa_GITPATH sfa $img_mnt/$resource_path/
123     git_retrieve $sface_GITPATH sface $img_mnt/$resource_path/
124     # copy binaries from sface to the bin dir
125     for bin in sface.bin sface-run; do 
126         # don't use the --file mode as this loses the executable bit
127         git_retrieve $sface_GITPATH $bin $img_mnt/$bin_path
128     done
129     # install background and app icons
130     git_retrieve --file $sface_GITPATH macos/background.png $img_mnt/$background_path/background.png
131     git_retrieve --file $sface_GITPATH macos/appIcon.icns $img_mnt/$icon_path/appIcon.icns
132     # xxx ?
133     git_retrieve --file $sface_GITPATH macos/appIcon.icns $img_mnt/.VolumeIcon.icns
134
135     # instantiate version
136     sed -e "s,@VERSIONTAG@,$sfa_release,g" -e "s,@SCMURL@,${sfa_GITPATH},g" \
137         $img_mnt/$resource_path/sfa/util/version.py.in > $img_mnt/$resource_path/sfa/util/version.py
138
139     # this apparently requires xcode
140     /Developer/Tools/SetFile -a V $img_mnt/$background_path
141
142
143
144     # clean up just in case
145     find $img_mnt -name '*pyc' | xargs rm -f
146     find $img_mnt -name '*~' | xargs rm -f
147
148     if [ -n "$INTERACTIVE" ] ; then
149         echo "Please open $img_mnt under Finder ..."
150         read _
151     fi
152
153     hdiutil detach $img_mnt
154     rm -f $img_dmg
155     hdiutil convert -format UDZO -imagekey zlib-level=9 -o $img_dmg $img_raw_dmg
156     # clean up the raw image
157     rm -f $img_raw_dmg
158     # unmount the skeleton
159     hdiutil unmount $skel_mnt
160
161 }
162
163 ########################################
164 # either provide a build dir and tags file
165 # or sface-GITPATH sfa-GITPATH 
166 function usage () {
167     echo "$COMMAND -b <build-dir> -t <tags-file>"
168     echo " or"
169     echo "$COMMAND -c <sface-GITPATH> -s <sfa-GITPATH>"
170     echo ""
171     echo "Common options"
172     echo " -n : dry-run"
173     echo " -i : let you open the image before getting wrapped"
174     echo " -h : this help"
175 }
176
177 DEFAULT_BUILD_DIR=$HOME/git/build
178 DEFAULT_TAGS_FILE=onelab-k32-tags.mk
179
180 function main () {
181     while getopts "b:t:c:s:hni" opt ; do
182         case $opt in 
183             b) BUILD_DIR=$OPTARG;;
184             t) TAGS_FILE=$OPTARG;;
185             c) sface_GITPATH=$OPTARG;;
186             s) sfa_GITPATH=$OPTARG;;
187             n) dry_run=true;;
188             i) INTERACTIVE=true;;
189             h) usage; exit 1 ;;
190         esac
191     done
192     shift $(($OPTIND - 1))
193
194     [ -z "$BUILD_DIR" ] && BUILD_DIR=$DEFAULT_BUILD_DIR
195     [ -z "$TAGS_FILE" ] && TAGS_FILE=$DEFAULT_TAGS_FILE
196     if [ -z "$sface_GITPATH" ] ; then
197         sface_GITPATH=$(make -C $BUILD_DIR stage1=true PLDISTROTAGS=$TAGS_FILE +sface-GITPATH 2> /dev/null)
198         echo "Retrieved from $BUILD_DIR/$TAGS_FILE.."
199         echo " sface_GITPATH=$sface_GITPATH"
200     fi
201     if [ -z "$sfa_GITPATH" ] ; then
202         sfa_GITPATH=$(make -C $BUILD_DIR stage1=true PLDISTROTAGS=$TAGS_FILE +sfa-GITPATH 2> /dev/null)
203         echo "Retrieved from $BUILD_DIR/$TAGS_FILE.."
204         echo " sfa_GITPATH=$sfa_GITPATH"
205     fi
206     [ -z "$dry_run" ] && package "$@" $sface_GITPATH $sfa_GITPATH
207         
208 }
209
210 main "$@"