From f3929c13d9ce2a0d6844923bb8bd250eb783e489 Mon Sep 17 00:00:00 2001 From: Tensor-Programming Date: Mon, 7 Oct 2019 16:03:18 -0400 Subject: [PATCH] Feat(bundler) dmg bundler (#38) * feat(cli) init tauri mode Signed-off-by: Daniel Thompson-Yvetot * feat(cli:init) add force & logging flags, full JSDoc Signed-off-by: Daniel Thompson-Yvetot * feat(cli:init) remove console.log Signed-off-by: Daniel Thompson-Yvetot * feat(cli:dev) get rust compile to finish Signed-off-by: Daniel Thompson-Yvetot * feat(cli:build) get rust compile to finish Signed-off-by: Daniel Thompson-Yvetot * feat(cli) set template with current working defaults Signed-off-by: Daniel Thompson-Yvetot * chore(version) bump Signed-off-by: Daniel Thompson-Yvetot * fix(typo) Signed-off-by: Daniel Thompson-Yvetot * fix(template): missing name warning Signed-off-by: Daniel Thompson-Yvetot * fix(bundler): correct repository link Signed-off-by: Daniel Thompson-Yvetot * feat(lib|cli) read config from tauriDir * chore(cli) remove console.log statement * fix(embedded-server) JS content type * feat(template): add rust2018 flag * chore(docs): remove docs * add bash templates * setup handlebars * output both templates * finish bundle_project logic * comment and cleanup * correct path * fix(bundler): osx not ios * feat(dmg): get it to work and look ok WIP - add background image - link seticon --- tools/rust/cargo-tauri-bundle/Readme.md | 4 + tools/rust/cargo-tauri-bundle/src/bundle.rs | 4 + .../src/bundle/dmg_bundle.rs | 73 +++++++++ .../cargo-tauri-bundle/src/bundle/settings.rs | 3 + .../src/bundle/templates/bundle_dmg | 144 ++++++++++++++++++ .../src/bundle/templates/seticon | Bin 0 -> 58892 bytes 6 files changed, 228 insertions(+) create mode 100644 tools/rust/cargo-tauri-bundle/src/bundle/dmg_bundle.rs create mode 100644 tools/rust/cargo-tauri-bundle/src/bundle/templates/bundle_dmg create mode 100755 tools/rust/cargo-tauri-bundle/src/bundle/templates/seticon diff --git a/tools/rust/cargo-tauri-bundle/Readme.md b/tools/rust/cargo-tauri-bundle/Readme.md index 742b31516..739b6aed0 100644 --- a/tools/rust/cargo-tauri-bundle/Readme.md +++ b/tools/rust/cargo-tauri-bundle/Readme.md @@ -134,3 +134,7 @@ stability. This program is licensed either under the terms of the [Apache Software License](http://www.apache.org/licenses/LICENSE-2.0), or the [MIT License](https://opensource.org/licenses/MIT). + +-> note, for bundle_dmg we have included a BSD 3 licenced binary `seticon`. +https://github.com/sveinbjornt/osxiconutils/blob/master/seticon.m +`tools/rust/cargo-tauri-bundle/src/bundle/templates/seticon` diff --git a/tools/rust/cargo-tauri-bundle/src/bundle.rs b/tools/rust/cargo-tauri-bundle/src/bundle.rs index 5d47989ff..b58387904 100644 --- a/tools/rust/cargo-tauri-bundle/src/bundle.rs +++ b/tools/rust/cargo-tauri-bundle/src/bundle.rs @@ -1,6 +1,7 @@ mod category; mod common; mod deb_bundle; +mod dmg_bundle; mod ios_bundle; mod msi_bundle; mod osx_bundle; @@ -18,9 +19,12 @@ pub fn bundle_project(settings: Settings) -> crate::Result> { paths.append(&mut match package_type { PackageType::OsxBundle => osx_bundle::bundle_project(&settings)?, PackageType::IosBundle => ios_bundle::bundle_project(&settings)?, + // use dmg bundler + // PackageType::OsxBundle => dmg_bundle::bundle_project(&settings)?, PackageType::WindowsMsi => msi_bundle::bundle_project(&settings)?, PackageType::Deb => deb_bundle::bundle_project(&settings)?, PackageType::Rpm => rpm_bundle::bundle_project(&settings)?, + PackageType::Dmg => dmg_bundle::bundle_project(&settings)?, }); } Ok(paths) diff --git a/tools/rust/cargo-tauri-bundle/src/bundle/dmg_bundle.rs b/tools/rust/cargo-tauri-bundle/src/bundle/dmg_bundle.rs new file mode 100644 index 000000000..8ad7c8154 --- /dev/null +++ b/tools/rust/cargo-tauri-bundle/src/bundle/dmg_bundle.rs @@ -0,0 +1,73 @@ +use super::common; +use super::osx_bundle; +use crate::Settings; + +use handlebars::Handlebars; +use lazy_static::lazy_static; + +use std::collections::BTreeMap; +use std::fs::write; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +// Create handlebars template for shell scripts +lazy_static! { + static ref HANDLEBARS: Handlebars = { + let mut handlebars = Handlebars::new(); + + handlebars + .register_template_string("bundle_dmg", include_str!("templates/bundle_dmg")) + .unwrap(); + handlebars + }; +} + +// create script files to bundle project and execute bundle_script. +pub fn bundle_project(settings: &Settings) -> crate::Result> { + // generate the app.app folder + osx_bundle::bundle_project(settings)?; + + // get uppercase string of app name + let upcase = settings.binary_name().to_uppercase(); + + // generate BTreeMap for templates + let mut sh_map = BTreeMap::new(); + sh_map.insert("app_name", settings.binary_name()); + sh_map.insert("app_name_upcase", &upcase); + + let bundle_temp = HANDLEBARS + .render("bundle_dmg", &sh_map) + .or_else(|e| Err(e.to_string()))?; + + // get the target path + let output_path = settings.project_out_directory(); + + // create paths for script + let bundle_sh = output_path.join("bundle_dmg.sh"); + + common::print_bundling(format!("{:?}", &output_path.join(format!("{}.dmg", &upcase))).as_str())?; + + // write the scripts + write(&bundle_sh, bundle_temp).or_else(|e| Err(e.to_string()))?; + + // chmod script for execution + + Command::new("chmod") + .arg("777") + .arg(&bundle_sh) + .current_dir(output_path) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("Failed to chmod script"); + + // execute the bundle script + Command::new(&bundle_sh) + .current_dir(output_path) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .expect("Failed to execute shell script"); + + Ok(vec![bundle_sh]) +} diff --git a/tools/rust/cargo-tauri-bundle/src/bundle/settings.rs b/tools/rust/cargo-tauri-bundle/src/bundle/settings.rs index 5d643f28e..91e45711c 100644 --- a/tools/rust/cargo-tauri-bundle/src/bundle/settings.rs +++ b/tools/rust/cargo-tauri-bundle/src/bundle/settings.rs @@ -17,6 +17,7 @@ pub enum PackageType { WindowsMsi, Deb, Rpm, + Dmg, } impl PackageType { @@ -28,6 +29,7 @@ impl PackageType { "msi" => Some(PackageType::WindowsMsi), "osx" => Some(PackageType::OsxBundle), "rpm" => Some(PackageType::Rpm), + "dmg" => Some(PackageType::Dmg), _ => None, } } @@ -39,6 +41,7 @@ impl PackageType { PackageType::WindowsMsi => "msi", PackageType::OsxBundle => "osx", PackageType::Rpm => "rpm", + PackageType::Dmg => "dmg", } } diff --git a/tools/rust/cargo-tauri-bundle/src/bundle/templates/bundle_dmg b/tools/rust/cargo-tauri-bundle/src/bundle/templates/bundle_dmg new file mode 100644 index 000000000..f2f6371c1 --- /dev/null +++ b/tools/rust/cargo-tauri-bundle/src/bundle/templates/bundle_dmg @@ -0,0 +1,144 @@ +#!/usr/bin/env sh +# using sh because modern MacOS ships with zsh not bash +# some patterns "lifted" from: +# - https://github.com/andreyvit/create-dmg/blob/master/create-dmg +# - https://stackoverflow.com/a/97025 +# - https://github.com/sindresorhus/create-dmg/blob/master/cli.js + +set -e +MACOS_APP_NAME="{{app_name_upcase}}" +MACOS_APP_DIR="bundle/osx/{{app_name}}.app" +ICNS_FILE="app.app/Contents/Resources/icon.icns" +DMG_TEMP_NAME=/tmp/temp.dmg +MOUNT_DIR="/Volumes/${MACOS_APP_NAME}" + +# Create the image +echo "Creating disk image..." +test -f "${DMG_TEMP_NAME}" && rm -f "${DMG_TEMP_NAME}" +test -f "${MACOS_APP_NAME}.dmg" && rm -f "${MACOS_APP_NAME}.dmg" + +hdiutil create ${DMG_TEMP_NAME} -srcfolder bundle/osx -volname "${MACOS_APP_NAME}" -ov -format UDRW -size 10000k -fs HFS+ -fsargs "-c c=64,a=16,e=16" -anyowners -nospotlight + +# mount it +echo "Mounting disk image..." +# try unmount dmg if it was mounted previously (e.g. developer mounted dmg, installed app and forgot to unmount it) +DEV_NAME=$(hdiutil info | egrep --color=never '^/dev/' | sed 1q | awk '{print $1}') +test -d "${MOUNT_DIR}" && hdiutil detach "${DEV_NAME}" + +device=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_TEMP_NAME}" | \ + egrep '^/dev/' | sed 1q | awk '{print $1}') + +sleep 5 + + +bless --folder "${MOUNT_DIR}" -label "${MACOS_APP_NAME}" + +test -d "${MOUNT_DIR}/.background" || mkdir "${MOUNT_DIR}/.background" +cp ../../icons/bg.png "${MOUNT_DIR}"/.background/bg.png + +# I couldn't get DeRez and Rez to work. Leaving it here in case its helpful in the future. +### DeRez -only icns "${MOUNT_DIR}/.VolumeIcon.icns" > "${MOUNT_DIR}/.VolumeIcon.rsrc" +### Rez -append "${MOUNT_DIR}/.VolumeIcon.rsrc" -o my_app.dmg + +# This Works +cp '../../icons/icon.icns' "${MOUNT_DIR}/.VolumeIcon.icns" +VERSION=$(sw_vers -productVersion | cut -d'.' -f2) + +if [ "$VERSION" -gt 12 ]; then + echo "Using SIPS v10.13+" + sips --i "${MOUNT_DIR}/.VolumeIcon.icns" # 10.13+ +else + echo "Using SIPS v10.12-" + sips --addIcon "${MOUNT_DIR}/.VolumeIcon.icns" +fi + +SetFile -c icnC "${MOUNT_DIR}/.VolumeIcon.icns" +SetFile -a C "${MOUNT_DIR}" + +# Doesn't stick after the renaming +### ./seticon "${MOUNT_DIR}/${ICNS_FILE}" "${DMG_TEMP_NAME}" + +# This does not work +### echo "read 'icns' (-16455) \"${MOUNT_DIR}/.VolumeIcon.icns\";" >> Icon.rsrc +### Rez -a Icon.rsrc -o FileName.ext +### DeRez -only icns "${MOUNT_DIR}/.VolumeIcon.icns" > "${MOUNT_DIR}/.Icon.rsrc" +### Rez -a Icon.rsrc -o "${MOUNT_DIR}/Icon$'\r'" +### SetFile -c icnC "${MOUNT_DIR}/.Icon.rsrc" +### SetFile -a C "${MOUNT_DIR}" +### SetFile -a "${MOUNT_DIR}/Icon$'\r'" + + +# this is from +# https://stackoverflow.com/questions/8371790/how-to-set-icon-on-file-or-directory-using-cli-on-os-x#8375093 +### iconSource='../../icons/icon.icns' +### iconDestination="${MOUNT_DIR}" +### icon=/tmp/$(basename $iconSource) +### rsrc=/tmp/icon.rsrc + +# Create icon from the iconSource +### cp $iconSource $icon + +# Add icon to image file, meaning use itself as the icon +### sips -i $icon + +# Take that icon and put it into a rsrc file +### DeRez -only icns $icon > $rsrc + +# Apply the rsrc file to +### SetFile -a C "${iconDestination}" + +# Create the magical Icon\r file +### touch "${iconDestination}/Icon$'\r'" +### Rez -append $rsrc -o "${iconDestination}/Icon?" +### SetFile -a V "${iconDestination}/Icon$'\r'" + +echo ' + tell application "Finder" + tell disk "'${MACOS_APP_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, 885, 430} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 110 + set background picture of theViewOptions to file ".background:'bg.png'" + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + set position of item "'app.app'" of container window to {100, 100} + set position of item "Applications" of container window to {375, 100} + update without registering applications + delay 5 + close + end tell + end tell +' | osascript +chmod -Rf go-w /Volumes/"${MACOS_APP_NAME}" + +sync +sync + +hdiutil detach ${device} + +# Some variations on format: +## UDZO – Compressed image (default) +## UDRO – Read-only image +## UDBZ – Better compressed image +## UDRW – Read/Write image + +hdiutil convert "${DMG_TEMP_NAME}" -format UDBZ -imagekey zlib-level=9 -o "${MACOS_APP_NAME}" + +./seticon ../../icons/icon.icns "${MACOS_APP_NAME}.dmg" + +rm -f ${DMG_TEMP_NAME} + +# This seems not to work as well at maintaining the icons :( +zip -r "${MACOS_APP_NAME}.dmg.zip" "${MACOS_APP_NAME}.dmg" + + +# FUTURE WORK +# SIGNER=$(security find-identity -v -p codesigning) +# codesign --sign 'Mac Developer' "${DMG_TEMP_NAME}" + +# Add a license with Rez +# http://www.owsiak.org/adding-license-to-a-dmg-file-in-5-minutes-or-less/ diff --git a/tools/rust/cargo-tauri-bundle/src/bundle/templates/seticon b/tools/rust/cargo-tauri-bundle/src/bundle/templates/seticon new file mode 100755 index 0000000000000000000000000000000000000000..c58afa2af172b12a6425679d7a76f8f40a5a9c86 GIT binary patch literal 58892 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