#!/bin/sh
# PURPOSE
-# package a combination of sfa+sface into a snow leopard dmg install disk
-#
-# NOTES
-# we leverage the first similar packaging initially made by Baris Metin
+# package a combination of sfa+sface into a dmg install disk
+# supports leopard and snow leopard
#
# REQUIREMENTS
-# sface-skel-snow-leopard.dmg is the skeleton that has Qt and all the other third-party software
+# sface-skel-snow-leopard<arch>.dmg is the skeleton that has Qt and all the other third-party software
# it is expected to be found in the local directory
-# otherwise it gets fetched at http://mirror.onelab.eu/third-party/
+# otherwise, or if -f is specified, it gets fetched
+# from http://mirror.onelab.eu/third-party/
# the script expects the taglevels for both sfa and sface,
# in order to retrieve the corresponding code and to label the resulting package properly
-#
+# alternatively, a build-dir and tags file can be used instead
+# Should have the folowing tools installed
+# git: to retrieve code
+# rpm: to retrieve the version numbers in specfiles
+
+# NOTES
+# we initially leveraged the first similar packaging initially made by Baris Metin
+# as of sface-0.1-9 we have bootstrapped our own skeleton images,
+# i.e. you can use vn as a skeleton for vn+1
+# about that, the way the background image gets (or not) found
+# on the final system is as follows
+# before compressing the image, you should open the image through the finder
+# and tweak it, as described in http://el-tramo.be/guides/fancy-dmg
+# that's the raison d'ĂȘtre for the -i option
+# basically: open two finder windows, one on the .backgrounf dir (use cmd-shift G)
+# and one on the image itself; then using Finder->view->show view options
+# drag the background image as appropriate
+# the important point being that the filename for the background must
+# exist - and so be the same - on the target system.
+# that's why the image 'volname' is constant across versions
# the place to search for the skeleton
SKEL_REPO=http://mirror.onelab.eu/third-party
-# hard-wired for snow-leopard for now
-arch=snow-leopard
+# default is snow-leopard
+DEFAULT_ARCH=snow-leopard
+ALL_ARCHS="leopard snow-leopard"
# does not affect final dmg size as it's compressed
DISK_SIZE=100M
function git_url () { echo $1 | cut -d @ -f 1 ; }
function git_tag () { echo $1 | cut -d @ -f 2 ; }
-# go in $dest and retrieve $path part of codebase based on gitpath, e.g.
-# git_retrieve \
-# git://git.onelab.eu/sface.git@sface-0.1-5
-# sface
-# /Volumes/sface-skel-sn/sface.app/Contents/Resources/
-# or, with the -f (-file) option:
-# git_retrieve -f \
-# git://git.onelab.eu/sface.git@sface-0.1-5
-# macos/appIcon.icns
-# /Volumes/sface-skel-sn/sface.app/appIcon.icns
+# go in $dest and retrieve module into provided path
+# git_retrieve git://git.onelab.eu/sface.git@sface-0.1-5 /tmp/sfa-module
function git_retrieve () {
- filemode=""
- case "$1" in -f|--file) filemode=true; shift;; esac
- gitpath=$1; shift
- path=$1; shift
- dest=$1; shift
+ gitpath="$1"; shift
+ dest="$1"; shift
giturl=$(git_url $gitpath)
gittag=$(git_tag $gitpath)
- if [ -z "$filemode" ] ; then
- [ -d $dest ] || mkdir -p $dest
- pushd $dest
- git archive --remote=${giturl} ${gittag} | tar -xf - ${path}
- popd
- else
- destdir=$(dirname $dest)
- [ -d $destdir ] || mkdir -p $destdir
- git archive --remote=${giturl} ${gittag} | tar -xOf - ${path} > ${dest}
- fi
+ [ -d "$dest" ] || mkdir -p "$dest"
+ pushd "$dest" >& /dev/null
+ git archive --remote=${giturl} ${gittag} | tar -xf -
+ popd >& /dev/null
}
function die () {
sface_GITPATH=$1; shift
sfa_GITPATH=$1; shift
+ arch=$1; shift
skel_name=sface-skel-${arch}
skel_dmg=./${skel_name}.dmg
- skel_mnt=/Volumes/${skel_name}
+ skel_mnt="/Volumes/${skel_name}"
sfa_release=sfa-$(git_tag $sfa_GITPATH | sed -e s,sfa-,,)
sface_release=sface-$(git_tag $sface_GITPATH | sed -e s,sface-,,)
img_name=${sface_release}-${sfa_release}-${arch}
img_dmg=./${img_name}.dmg
img_raw_dmg=./${img_name}.raw.dmg
- img_mnt=/Volumes/${img_name}
+ img_mnt_name="sface ($arch)"
+ img_mnt="/Volumes/${img_mnt_name}"
# check we're clear
- [ -f $img_dmg ] && die "output dmg $img_dmg already exists"
- [ -f $img_raw_dmg ] && die "please clean up tmp file $img_raw_dmg"
+ if [ -f $img_dmg ] ; then
+ [ -z "$FORCE_REWRITE" ] && die "output dmg $img_dmg already exists"
+ echo "Trashing (force_rewrite) former output $img_dmg"
+ rm -f $img_dmg
+ fi
+ if [ -f $img_raw_dmg ] ; then
+ [ -z "$FORCE_REWRITE" ] && die "please clean up tmp file $img_raw_dmg"
+ echo "Cleaning (force_rewrite) former tmp file $img_raw_dmg"
+ rm -f $img_raw_dmg
+ fi
+
+ if [ -n "$FORCE_DOWNLOAD" ] ; then
+ [ -d "$skel_mnt" ] && hdiutil unmount "$skel_mnt"
+ [ -f "$skel_dmg" ] && rm -f "$skel_dmg"
+ fi
# mount the skeleton if not yet avail.
- if [ ! -d $skel_mnt ] ; then
+ if [ ! -d "$skel_mnt" ] ; then
# locate skel dmg
if [ ! -f $skel_dmg ] ; then
echo "Retrieving $skel_dmg from $SKEL_REPO"
curl -O $SKEL_REPO/$skel_dmg
fi
# needless to check for existence as curl will have created on anyway
- if ! hdiutil mount $skel_dmg ; then
+ echo "Mounting skeleton"
+ if ! hdiutil mount -quiet -mountpoint $skel_mnt $skel_dmg ; then
die "Could not mount $skel_dmg
Please check it is published at $SKEL_REPO
Also make sure to trash the current one before retrying"
fi
fi
- [ -d $skel_mnt ] || die "Could not mount skeleton $skel_dmg"
+ [ -d "$skel_mnt" ] || die "Could not mount skeleton $skel_dmg"
# if image already mounted, it's an old run
- [ -d $img_mnt ] && die "Image already mounted on $img_mnt"
-
- hdiutil create -size $DISK_SIZE -fs HFS+J -volname ${img_name} $img_raw_dmg
- hdiutil attach -readwrite -mount required $img_raw_dmg
+ [ -d "$img_mnt" ] && die "Image already mounted on $img_mnt"
+ echo "Initializing image ..."
+ hdiutil create -quiet -size $DISK_SIZE -fs HFS -volname "${img_mnt_name}" $img_raw_dmg
+ hdiutil attach -readwrite -mount required "$img_raw_dmg"
+
# copy skeleton as-is
- tar -C $skel_mnt --exclude .Trashes -cf - . | tar -C $img_mnt -xf -
+ echo "Populating from skeleton.."
+ ( cd "$skel_mnt" ; find . 2> /dev/null | cpio --quiet -c -o) | ( cd "$img_mnt" ; cpio -diu )
+
# places relative to mount point
app=sface.app
+ # xxx tmp
+ skelapp_path=$(ls -d "$skel_mnt"/*.app)
+ skelapp=$(basename "$skelapp_path")
+ if [ "$skelapp" != "$app" ] ; then
+ mv "$img_mnt/$skelapp" "$img_mnt/$app"
+ fi
+ # unmount the skeleton
+ hdiutil unmount "$skel_mnt"
+
+ #
resource_path=$app/Contents/Resources
bin_path=$app/Contents/MacOS
- icon_path=$app/Contents/Resources/
- background_path=background
- # retrieve sfa/sfa and sface/sface in the image
- git_retrieve $sfa_GITPATH sfa $img_mnt/$resource_path/
- git_retrieve $sface_GITPATH sface $img_mnt/$resource_path/
- # copy binaries from sface to the bin dir
- for bin in sface.bin sface-run; do
- # don't use the --file mode as this loses the executable bit
- git_retrieve $sface_GITPATH $bin $img_mnt/$bin_path
- done
- # install background and app icons
- git_retrieve --file $sface_GITPATH macos/background.png $img_mnt/$background_path/background.png
- git_retrieve --file $sface_GITPATH macos/appIcon.icns $img_mnt/$icon_path/appIcon.icns
- # xxx ?
- git_retrieve --file $sface_GITPATH macos/appIcon.icns $img_mnt/.VolumeIcon.icns
- # instantiate version
- sed -e "s,@VERSIONTAG@,$sfa_release,g" -e "s,@SCMURL@,${sfa_GITPATH},g" \
- $img_mnt/$resource_path/sfa/util/version.py.in > $img_mnt/$resource_path/sfa/util/version.py
+ # retrieve sfa and sface full repos in a temp dir
+ temp=$(mktemp -d -t sface-dmg)
+
+ git_retrieve $sfa_GITPATH $temp/sfa
+ git_retrieve $sface_GITPATH $temp/sface
+
+ # retrieve version number, and run make version
+ sfa_spec=$temp/sfa/sfa.spec
+ # use newlines and keep only the first line, for multiple packages
+ sfa_version=$(rpm -q --specfile $sfa_spec --qf '%{version}\n' | head -1)
+ # cannot extract taglevel, issues lots of 'error: incorrect format: unknown tag'
+ # turns out release is the same in our case as we haven't computed header.spec
+ sfa_release=$(rpm -q --specfile $sfa_spec --qf '%{release}\n' | head -1 | cut -d. -f1)
+ sfa_tag=${sfa_version}-${sfa_release}
+ make -C $temp/sfa VERSIONTAG="${sfa_tag}" SCMURL="${sfa_GITPATH}" version
- # this apparently requires xcode
- /Developer/Tools/SetFile -a V $img_mnt/$background_path
+ sface_spec=$temp/sface/sface.spec
+ sface_version=$(rpm -q --specfile $sface_spec --qf '%{version}\n' | head -1)
+ sface_release=$(rpm -q --specfile $sface_spec --qf '%{release}\n' | head -1 | cut -d. -f1)
+ sface_tag=${sface_version}-${sface_release}
+ make -C $temp/sface VERSIONTAG="${sface_tag}" SCMURL="${sface_GITPATH}" version
+ # copy sfa/ and sface/ subdirs in image
+ rm -rf "$img_mnt"/$resource_path/{sfa,sface}
+ tar -C $temp/sfa -cf - sfa | tar -C "$img_mnt"/$resource_path/ -xf -
+ tar -C $temp/sface -cf - sface | tar -C "$img_mnt"/$resource_path/ -xf -
+
+ # copy binaries from sface to the bin dir
+ for bin in sface.bin sface-run; do
+ cp $temp/sface/$bin "$img_mnt"/$bin_path
+ done
+ ### install background and app icons
+ # clean up any 'background' dir if exists
+ rm -rf "$img_mnt"/{,.}background
+ mkdir -p "$img_mnt"/.background "$img_mnt"/$resource_path/sface/images
+ cp $temp/sface/macos/graphic-install-background.png "$img_mnt"/.background/background.png
+ cp $temp/sface/macos/graphic-sfa.icns "$img_mnt"/$resource_path/appIcon.icns
+ cp $temp/sface/macos/graphic-sfa.png "$img_mnt"/$resource_path/sface/images
+ cp $temp/sface/macos/graphic-sfa64.png "$img_mnt"/$resource_path/sface/images
+ # the volume icons won't work - who cares
+# cp $temp/sface/macos/graphic-vol-sface.icns "$img_mnt"/.background/volumeIcon.icns
+# cp $temp/sface/macos/graphic-vol-sface.png "$img_mnt"/.background/volumeIcon.png
# clean up just in case
- find $img_mnt -name '*pyc' | xargs rm -f
- find $img_mnt -name '*~' | xargs rm -f
+ find "$img_mnt" -name '*pyc' | xargs rm -f
+ find "$img_mnt" -name '*~' | xargs rm -f
if [ -n "$INTERACTIVE" ] ; then
- echo "Please open $img_mnt under Finder ..."
+ echo "Please tweak icons layout in $img_mnt under Finder, and press enter when done ..."
read _
fi
- hdiutil detach $img_mnt
+ rm -rf $temp
+
+ hdiutil detach "$img_mnt"
rm -f $img_dmg
- hdiutil convert -format UDZO -imagekey zlib-level=9 -o $img_dmg $img_raw_dmg
+ echo "Compressing..."
+ hdiutil convert -quiet -format UDZO -imagekey zlib-level=9 -o $img_dmg $img_raw_dmg
# clean up the raw image
rm -f $img_raw_dmg
- # unmount the skeleton
- hdiutil unmount $skel_mnt
+
+ echo "=================================================="
+ echo "Install image ready in $img_dmg"
+ echo "You may publish it by running e.g."
+ echo "rsync -av $img_dmg root@build.onelab.eu:/build/sface"
+ echo "=================================================="
}
echo "$COMMAND -c <sface-GITPATH> -s <sfa-GITPATH>"
echo ""
echo "Common options"
+ echo " -i : interactive : let you align icons properly in the image before it gets wrapped"
+ echo " -f : force download of the skeleton package"
+ echo " -F : force overwrite if output already exists"
+ echo " -a leopard|snow-leopard"
+ echo " -A : run on all known archs"
echo " -n : dry-run"
- echo " -i : let you open the image before getting wrapped"
+ echo " -v : verbose"
echo " -h : this help"
}
DEFAULT_TAGS_FILE=onelab-k32-tags.mk
function main () {
- while getopts "b:t:c:s:hni" opt ; do
+ while getopts "b:t:c:s:ifFa:Anvh" opt ; do
case $opt in
b) BUILD_DIR=$OPTARG;;
t) TAGS_FILE=$OPTARG;;
c) sface_GITPATH=$OPTARG;;
s) sfa_GITPATH=$OPTARG;;
- n) dry_run=true;;
i) INTERACTIVE=true;;
+ f) FORCE_DOWNLOAD=true;;
+ F) FORCE_REWRITE=true ;;
+ a) ARCHS="$ARCHS $OPTARG";;
+ A) ARCHS="leopard snow-leopard";;
+ n) dry_run=true;;
+ v) set -x;;
h) usage; exit 1 ;;
esac
done
[ -z "$BUILD_DIR" ] && BUILD_DIR=$DEFAULT_BUILD_DIR
[ -z "$TAGS_FILE" ] && TAGS_FILE=$DEFAULT_TAGS_FILE
+ [ -z "$ARCHS" ] && ARCHS=$DEFAULT_ARCH
+ [[ -n "$@" ]] && { usage ; exit 1; }
if [ -z "$sface_GITPATH" ] ; then
sface_GITPATH=$(make -C $BUILD_DIR stage1=true PLDISTROTAGS=$TAGS_FILE +sface-GITPATH 2> /dev/null)
echo "Retrieved from $BUILD_DIR/$TAGS_FILE.."
echo "Retrieved from $BUILD_DIR/$TAGS_FILE.."
echo " sfa_GITPATH=$sfa_GITPATH"
fi
- [ -z "$dry_run" ] && package "$@" $sface_GITPATH $sfa_GITPATH
+ for ARCH in $ARCHS; do
+ if [ -z "$dry_run" ] ; then
+ package $sface_GITPATH $sfa_GITPATH $ARCH
+ else
+ echo "Would run package $sface_GITPATH $sfa_GITPATH $ARCH"
+ fi
+ done
}