diff --git a/.travis/pre_deploy.sh b/.travis/pre_deploy.sh index 7e3e6a7..a5533c3 100755 --- a/.travis/pre_deploy.sh +++ b/.travis/pre_deploy.sh @@ -26,8 +26,8 @@ if [ "$BUILD_DIST" = 'true' ]; then # pyinstaller app image in dmg and zip (cd simple_gui && ./create_icns_on_osx.sh) pyinstaller --noconsole --onefile --name Roman --icon simple_gui/roman.icns --osx-bundle-identifier="$appid" simple_gui/roman_tki.py - hdiutil create dist/roman-gui-$version-mac.dmg -srcfolder dist/ -ov - (cd dist && zip -r roman-gui-$version-mac.zip Roman.app) + ./packaging/osx/create_dmg.sh dist/roman-gui-$version-mac-unsigned.dmg + (cd dist && zip -r roman-gui-$version-mac-unsigned.zip Roman.app) else pip install . simple_gui/ pip install -r requirements_build_linux.txt diff --git a/packaging/osx/README.md b/packaging/osx/README.md new file mode 100644 index 0000000..7b124d7 --- /dev/null +++ b/packaging/osx/README.md @@ -0,0 +1,35 @@ +OS X Packaging +============== + +Packing for OS X is bit interesting. +Here are utilities to manage packaging configuration and to create final disk image. + +Finder background +----------------- + +Disk image is oppened with a Finder window and we use background image to render information texts. +Source file is in `res/dmg-background.svg` and 72DPI and 144DPI renders in `res/dmg-background.png` and `res/dmg-background@2x.png` respectively. + +.DS_Store +--------- + +DMG installer contains Finder window layout and background in a binary file `.DS_Store`. +Apple has not documented this format. + +Tool `setup_volume.sh` is used to create test volume for modifying DS_Store file. +It uses an applescript to create layout. +You can edit the script to test new layout parameters. +Though, resulting DS_Store contains volume mounts and other irrelevant information and thus can not be used for distributing. +For distributable version, there is node script in `createdbstore` directory. + +So, first play with the `setup_volume.sh` and applescript to get window that looks correct and then recreate the configuration with `createdbstore`. +Finally, copy `.DS_Store` to `res/DS_store`. + +Creating final image +-------------------- + +Script `create_dmg.sh` creates compressed read-only disk image. +It uses resources from `res` directory. +It requires the destination as parameter. + +For example `./packaging/osx/create_dmg.sh dist/roman.dmg`. diff --git a/packaging/osx/create_dmg.sh b/packaging/osx/create_dmg.sh new file mode 100755 index 0000000..14b9c01 --- /dev/null +++ b/packaging/osx/create_dmg.sh @@ -0,0 +1,47 @@ +#!/bin/sh -e + +scripts=$(dirname "$0") +res=$scripts/res/ + +out=$1 +[ "$out" ] || { echo "ERROR: missing output file"; exit 1; } +dist=$(dirname "$out") + +name=Roman +bg1=$res/dmg-background.png +bg2=$res/dmg-background@2x.png +dss=$res/DS_Store + +require_dpi() { + f=$1 + i=$2 + if [ ! -e "$f" ]; then + echo "ERROR: missing image $f" + exit 1 + fi + dpi=$(sips -g dpiHeight "$f" | egrep '^\s*dpiHeight' | awk '{print $2}') + if [ "$dpi" != "$i" ]; then + echo "ERROR: wrong dpi $dpi expected $i, file $f" + exit 1 + fi +} + +require_dpi "$bg1" "72.000" +require_dpi "$bg2" "144.000" + +d=$dist/$name + +rm -rf $d +mkdir -p $d/.background/ + +cp -r $dist/$name.app $d/ +cp "$bg1" $d/.background/dmg-background.png +cp "$bg2" $d/.background/dmg-background@2x.png +cp "$dss" $d/.DS_Store + +SetFile -a icnv $d/.background $d/.DS_Store +ln -s /Applications $d/Applications + +hdiutil create $out \ + -format UDZO -imagekey zlib-level=9 \ + -volname $name -srcfolder $d/ -ov diff --git a/packaging/osx/createdsstore/README.md b/packaging/osx/createdsstore/README.md new file mode 100644 index 0000000..3469457 --- /dev/null +++ b/packaging/osx/createdsstore/README.md @@ -0,0 +1,9 @@ +DS_Store creator +================ + +This trivial script creates simple .DS_Store file to be used for a disk image layout. +It tool is only needed when size or icon positions of the Finder window changes. +If that happens, then edit the `cli.js` with the new information. +Execute it to obtain a new .DS_Store file. + +To install, run `npm install` and to execute run `./cli.js`. diff --git a/packaging/osx/createdsstore/cli.js b/packaging/osx/createdsstore/cli.js new file mode 100755 index 0000000..25d0664 --- /dev/null +++ b/packaging/osx/createdsstore/cli.js @@ -0,0 +1,40 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs') +const path = require('path') +const DSStore = require('ds-store') + +const exit_with_error = (err) => { + console.error(err); + process.exit(1) +} + +const create_ds_store = () => { + const ds = new DSStore() + + const w = 760 + const h = 480 + const x = 300 + const y = 200 + const ixpos = 200 + const iypos = 200 + + ds.vSrn(1) + ds.setIconSize(128) + ds.setBackgroundColor(1, 1, 1) + ds.setBackgroundPath('/Volumes/Roman/.background/dmg-background.png') + ds.setWindowSize(w, h) + ds.setWindowPos(x, y) + ds.setIconPos('Roman.app', ixpos, iypos) + ds.setIconPos('Applications', w-ixpos, iypos) + + ds.write('/Volumes/Roman/.DS_Store', (err) => { + if (err) + exit_with_error(err) + else + console.info("Done") + }) +} + +create_ds_store() diff --git a/packaging/osx/createdsstore/package.json b/packaging/osx/createdsstore/package.json new file mode 100644 index 0000000..9399a96 --- /dev/null +++ b/packaging/osx/createdsstore/package.json @@ -0,0 +1,14 @@ +{ + "name": "createdsstore", + "version": "1.0.0", + "description": "Creates .DS_Store file with hard coded values", + "bin": "./cli.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Jaakko Kantojärvi ", + "license": "ISC", + "dependencies": { + "ds-store": "^0.1.6" + } +} diff --git a/packaging/osx/res/DS_Store b/packaging/osx/res/DS_Store new file mode 100644 index 0000000..b7c2aca Binary files /dev/null and b/packaging/osx/res/DS_Store differ diff --git a/packaging/osx/res/dmg-background.png b/packaging/osx/res/dmg-background.png new file mode 100644 index 0000000..26952fd Binary files /dev/null and b/packaging/osx/res/dmg-background.png differ diff --git a/packaging/osx/res/dmg-background.svg b/packaging/osx/res/dmg-background.svg index c23ea90..7a2d244 100644 --- a/packaging/osx/res/dmg-background.svg +++ b/packaging/osx/res/dmg-background.svg @@ -10,15 +10,20 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="1900" - height="1200" - viewBox="0 0 502.70832 317.50001" + width="1520" + height="960" + viewBox="0 0 402.04 253.92" version="1.1" id="svg8" sodipodi:docname="dmg-background.svg" inkscape:version="0.92.1 r15371"> + + inkscape:snap-text-baseline="true" + scale-x="0.26458"> + id="grid4485" + originx="0" + originy="0" + spacingx="1" + spacingy="1" /> @@ -97,24 +107,10 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(0,20.500008)"> - - + transform="translate(0,-58.874993)"> + transform="translate(-36.258497,-104.84132)"> + + On the first time you need to right-click or control-click the app,On the first time, you need to right-click or Control-click the app,then select 'open' in the menu and finally select 'open' in the dialog. + x="201.16614" + y="276.9628" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.16933346px;line-height:150%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#808080;stroke-width:0.21145168px" + id="tspan6090">then select open in the menu and finally open in the dialog. + transform="matrix(0.79937198,0,0,0.79900309,18.714335,114.23659)"> + To install, drag Roman to Applications diff --git a/packaging/osx/res/dmg-background@2x.png b/packaging/osx/res/dmg-background@2x.png new file mode 100644 index 0000000..7b30a53 Binary files /dev/null and b/packaging/osx/res/dmg-background@2x.png differ diff --git a/packaging/osx/res/finder_layout.scpt b/packaging/osx/res/finder_layout.scpt new file mode 100644 index 0000000..cbb3df5 --- /dev/null +++ b/packaging/osx/res/finder_layout.scpt @@ -0,0 +1,38 @@ +tell application "Finder" + tell disk "Roman" + open + + set theX to 300 + set theY to 200 + set theW to 760 + set theH to 480 + set theX2 to (theX + theW) + set theY2 to (theY + theH) + set theI1X to 200 + set theI2X to (theW - theI1X) + set theIY to 200 + + tell container window + set current view to icon view + set toolbar visible to false + set statusbar visible to false + set the bounds to {theX, theY, theX2, theY2} + end tell + + set viewOptions to the icon view options of container window + tell viewOptions + set arrangement to not arranged + set icon size to 128 + set text size to 14 + end tell + + set background picture of viewOptions to file ".background:dmg-background.png" + set position of item "Roman.app" of container window to {theI1X, theIY} + set position of item "Applications" of container window to {theI2X, theIY} + + close + open + update without registering applications + delay 2 + end tell +end tell diff --git a/packaging/osx/setup_volume.sh b/packaging/osx/setup_volume.sh new file mode 100755 index 0000000..8d789ae --- /dev/null +++ b/packaging/osx/setup_volume.sh @@ -0,0 +1,39 @@ +#!/bin/sh -e + +scripts=$(dirname "$0") +res=$scripts/res/ + +name=Roman +vol=$name +dmg=roman-setup.dmg + +if [ ! -e "$dmg" ]; then + if [ ! -d "$name" ]; then + echo "There is no directory $name/" + echo "Create template of dmg content in that before running this (create_dms.sh)." + exit 1 + fi + size=$(du -sm "$name" | awk '{print $1}') + size=$(echo "$size + 5" | bc) + rm -f $name/.DS_Store + hdiutil create -srcfolder "$name" -volname "$name" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}M "$dmg" + echo "Created: $dmg" +fi + +# Detach existing mounts +if [ -d "/Volumes/$vol" ]; then + dev=$(hdiutil info | egrep '^/dev/' | egrep "/Volumes/$vol" | sed 1q | awk '{print $1}' | cut -ds -f1-2) + hdiutil --force detach $dev +fi + +# Mount, run applescript, wait for enter (manual edit) +dev=$(hdiutil attach -readwrite -noverify "$dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') +echo "Editing data in /Volumes/$vol, press ENTER when manual edit is done" +osascript $res/finder_layout.scpt +read +hdiutil detach "$dev" >/dev/null + +# Remount, read .DS_Store +dev=$(hdiutil attach -readwrite -noverify -noautoopen "$dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') +cp -v /Volumes/$vol/.DS_store $res/DS_Store +hdiutil detach "$dev" >/dev/null