etcher/scripts/build/darwin.sh
Juan Cruz Viotti 6348d88c95 chore: add commands to build scripts (#566)
Currently build scripts install dependencies and package everything on
every run. In order to allow more customisation, the build scripts now
accept the following commands:

- `install`: Only install dependencies.
- `package`: Only package the application.
- `all`: Install dependencies and package the application.

The above differentiation allows us to improve the documentation and CI
configuration files to point to the `install` commands instead of having
to explain how to configure NPM correctly, since that's done by the
build scripts by default.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
2016-07-12 10:15:21 -04:00

223 lines
7.0 KiB
Bash
Executable File

#!/bin/bash
###
# Copyright 2016 Resin.io
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###
# See http://www.davidpashley.com/articles/writing-robust-shell-scripts/
set -u
set -e
set -x
OS=`uname`
if [[ "$OS" != "Darwin" ]]; then
echo "This script is only meant to be run in OS X" 1>&2
exit 1
fi
if ! command -v bower 2>/dev/null; then
echo "Dependency missing: bower" 1>&2
exit 1
fi
if ! command -v python 2>/dev/null; then
echo "Dependency missing: python" 1>&2
exit 1
fi
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <command>" 1>&2
exit 1
fi
COMMAND=$1
if [ "$COMMAND" != "install" ] && [ "$COMMAND" != "package" ] && [ "$COMMAND" != "all" ]; then
echo "Unknown command: $COMMAND" 1>&2
exit 1
fi
ELECTRON_OSX_SIGN=./node_modules/.bin/electron-osx-sign
ELECTRON_PACKAGER=./node_modules/.bin/electron-packager
SIGN_IDENTITY_OSX="Developer ID Application: Rulemotion Ltd (66H43P8FRG)"
ELECTRON_VERSION=`node -e "console.log(require('./package.json').devDependencies['electron-prebuilt'])"`
APPLICATION_NAME=`node -e "console.log(require('./package.json').displayName)"`
APPLICATION_COPYRIGHT=`node -e "console.log(require('./package.json').copyright)"`
APPLICATION_VERSION=`node -e "console.log(require('./package.json').version)"`
ELECTRON_NODE_VERSION=`node -e "console.log(require('./package.json').engines.node)"`
if [[ "v$ELECTRON_NODE_VERSION" != "`node -v`" ]]; then
echo "Incompatible NodeJS version. Expected: $ELECTRON_NODE_VERSION" 1>&2
exit 1
fi
function install {
rm -rf node_modules bower_components
npm install --build-from-source
bower install --production
}
function package {
output_directory=$1
$ELECTRON_PACKAGER . $APPLICATION_NAME \
--platform=darwin \
--arch=x64 \
--version=$ELECTRON_VERSION \
--ignore="`node scripts/packageignore.js`" \
--asar \
--app-copyright="$APPLICATION_COPYRIGHT" \
--app-version="$APPLICATION_VERSION" \
--build-version="$APPLICATION_VERSION" \
--helper-bundle-id="io.resin.etcher-helper" \
--app-bundle-id="io.resin.etcher" \
--app-category-type="public.app-category.developer-tools" \
--icon="assets/icon.icns" \
--overwrite \
--out=$output_directory
rm $output_directory/Etcher-darwin-x64/LICENSE
rm $output_directory/Etcher-darwin-x64/LICENSES.chromium.html
rm $output_directory/Etcher-darwin-x64/version
}
function sign {
source_application=$1
$ELECTRON_OSX_SIGN $source_application --platform darwin --verbose --identity "$SIGN_IDENTITY_OSX"
codesign --verify --deep --display --verbose=4 $source_application
spctl --ignore-cache --no-cache --assess --type execute --verbose=4 $source_application
}
function installer_zip {
source_directory=$1
output_directory=$2
mkdir -p $output_directory
sign $source_directory/$APPLICATION_NAME.app
pushd $source_directory
zip -r -9 Etcher-darwin-x64.zip $APPLICATION_NAME.app
popd
mv $source_directory/Etcher-darwin-x64.zip $output_directory
}
function installer_dmg {
source_directory=$1
output_directory=$2
temporal_dmg=$source_directory.dmg
volume_directory=/Volumes/$APPLICATION_NAME
volume_app=$volume_directory/$APPLICATION_NAME.app
# Make sure any previous DMG was unmounted
hdiutil detach $volume_directory || true
# Create temporal read-write DMG image
rm -f $temporal_dmg
hdiutil create \
-srcfolder $source_directory \
-volname "$APPLICATION_NAME" \
-fs HFS+ \
-fsargs "-c c=64,a=16,e=16" \
-format UDRW \
-size 600M $temporal_dmg
# Mount temporal DMG image, so we can modify it
hdiutil attach $temporal_dmg -readwrite -noverify
# Wait for a bit to ensure the image is mounted
sleep 2
# Link to /Applications within the DMG
pushd $volume_directory
ln -s /Applications
popd
# Symlink MacOS/Etcher to MacOS/Electron since for some reason, the Electron
# binary tries to be ran in some systems.
# See https://github.com/Microsoft/vscode/issues/92
cp -p $volume_app/Contents/MacOS/Etcher $volume_app/Contents/MacOS/Electron
# Set the DMG icon image
# Writing this hexadecimal buffer to the com.apple.FinderInfo
# extended attribute does the trick.
# See https://github.com/LinusU/node-appdmg/issues/14#issuecomment-29080500
cp assets/icon.icns $volume_directory/.VolumeIcon.icns
xattr -wx com.apple.FinderInfo \
"0000000000000000040000000000000000000000000000000000000000000000" $volume_directory
# Configure background image.
# We use tiffutil to create a "Multirepresentation Tiff file".
# This allows us to show the retina and non-retina image when appropriate.
mkdir $volume_directory/.background
tiffutil -cathidpicheck assets/osx/installer.png assets/osx/installer@2x.png \
-out $volume_directory/.background/installer.tiff
# This AppleScript performs the following tasks
# - Set the window basic properties.
# - Set the window size and position.
# - Set the icon size.
# - Arrange the icons.
echo '
tell application "Finder"
tell disk "'${APPLICATION_NAME}'"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 944, 530}
set viewOptions to the icon view options of container window
set arrangement of viewOptions to not arranged
set icon size of viewOptions to 110
set background picture of viewOptions to file ".background:installer.tiff"
set position of item "'${APPLICATION_NAME}.app'" of container window to {140, 225}
set position of item "Applications" of container window to {415, 225}
close
open
update without registering applications
delay 2
close
end tell
end tell
' | osascript
sync
sign $volume_app
# Unmount temporal DMG image.
hdiutil detach $volume_directory
# Convert temporal DMG image into a production-ready
# compressed and read-only DMG image.
mkdir -p $output_directory
rm -f $output_directory/Etcher-darwin-x64.dmg
hdiutil convert $temporal_dmg \
-format UDZO \
-imagekey zlib-level=9 \
-o $output_directory/Etcher-darwin-x64.dmg
# Cleanup temporal DMG image.
rm $temporal_dmg
}
if [ "$COMMAND" == "install" ] || [ "$COMMAND" == "all" ]; then
install
fi
if [ "$COMMAND" == "package" ] || [ "$COMMAND" == "all" ]; then
package etcher-release
installer_dmg etcher-release/Etcher-darwin-x64 etcher-release/installers
installer_zip etcher-release/Etcher-darwin-x64 etcher-release/installers
fi