diff --git a/src/MacVim/dmg/README.md b/src/MacVim/dmg/README.md new file mode 100644 index 0000000000..9245c013c6 --- /dev/null +++ b/src/MacVim/dmg/README.md @@ -0,0 +1 @@ +This folder contains resources used for creating the dmg installation file. diff --git a/src/create-dmg/background.png b/src/MacVim/dmg/background.png similarity index 100% rename from src/create-dmg/background.png rename to src/MacVim/dmg/background.png diff --git a/src/create-dmg/background.pxd b/src/MacVim/dmg/background.pxd similarity index 100% rename from src/create-dmg/background.pxd rename to src/MacVim/dmg/background.pxd diff --git a/src/Makefile b/src/Makefile index f9e5431979..71e04332a2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3752,7 +3752,7 @@ macvim-dmg: create-dmg/create-dmg \ --volname "MacVim" \ --volicon MacVim/icons/MacVim.icns \ - --background create-dmg/background.png \ + --background MacVim/dmg/background.png \ --window-size 650 470 \ --icon-size 80 \ --icon MacVim.app 240 320 \ diff --git a/src/create-dmg/.this-is-the-create-dmg-repo b/src/create-dmg/.this-is-the-create-dmg-repo new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/create-dmg/LICENSE b/src/create-dmg/LICENSE index 349b6d82b3..deb407f2ee 100644 --- a/src/create-dmg/LICENSE +++ b/src/create-dmg/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2008-2014 Andrey Tarantsov +Copyright (c) 2020 Andrew Janke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/create-dmg/README b/src/create-dmg/README index 4557795edb..170da8de1e 100644 --- a/src/create-dmg/README +++ b/src/create-dmg/README @@ -1,2 +1 @@ -Content of this directory (except background.png) is copied from -https://github.com/andreyvit/create-dmg (5acf22f). +Content of this directory is copied from https://github.com/create-dmg/create-dmg (v1.0.8 / 0985398). diff --git a/src/create-dmg/README.md b/src/create-dmg/README.md new file mode 100644 index 0000000000..f71dae337d --- /dev/null +++ b/src/create-dmg/README.md @@ -0,0 +1,102 @@ +create-dmg +========== + +A shell script to build fancy DMGs. + +Status and contribution policy +------------------------------ + +Create-dmg is maintained thanks to the contributors who send pull requests. +As of May 2020, [Andrew Janke](https://github.com/apjanke) is the primary maintainer, and (since September 2018) [@aonez](https://github.com/aonez) has helped with the maintenance. +The project home page is . + +We will merge any pull request that adds something useful and does not break existing things. + +If you're an active user and want to be a maintainer, or just want to chat, please ping us on Gitter at [gitter.im/create-dmg/Lobby](https://gitter.im/create-dmg/Lobby), or [email Andrew directly](floss@apjanke.net). + +Create-dmg was originally created by [Andrey Tarantsov](https://github.com/andreyvit). + +Installation +------------ + +- You can install this script using [Homebrew](https://brew.sh): + + ```sh + brew install create-dmg + ``` + +- You can download the [latest release](https://github.com/create-dmg/create-dmg/releases/latest) and install it from there: + + ```sh + make install + ``` + +- You can also clone the entire repository and run it locally from there: + + ```sh + git clone https://github.com/create-dmg/create-dmg.git + ``` + +Usage +----- + +```sh +create-dmg [options ...] +``` + +All contents of source\_folder will be copied into the disk image. + +**Options:** + +- **--volname \:** set volume name (displayed in the Finder sidebar and window title) +- **--volicon \:** set volume icon +- **--background \:** set folder background image (provide png, gif, jpg) +- **--window-pos \ \:** set position the folder window +- **--window-size \ \:** set size of the folder window +- **--text-size \:** set window text size (10-16) +- **--icon-size \:** set window icons size (up to 128) +- **--icon \ \ \:** set position of the file's icon +- **--hide-extension \:** hide the extension of file +- **--custom-icon \ \ \:** set position and -tom icon +- **--app-drop-link \ \:** make a drop link to Applications, at location x, y +- **--ql-drop-link \ \:** make a drop link to /Library/QuickLook, at location x, y +- **--eula \:** attach a license file to the dmg +- **--rez \:** specify custom path to Rez tool used to include license file +- **--no-internet-enable:** disable automatic mount© +- **--format:** specify the final image format (default is UDZO) +- **--add-file \ \ \ \:** add additional file or folder (can be used multiple times) +- **--disk-image-size \:** set the disk image size manually to x MB +- **--hdiutil-verbose:** execute hdiutil in verbose mode +- **--hdiutil-quiet:** execute hdiutil in quiet mode +- **--sandbox-safe:** execute hdiutil with sandbox compatibility and do not bless +- **--version:** show tool version number +- **-h, --help:** display the help + +Example +------- + +```sh +#!/bin/sh +test -f Application-Installer.dmg && rm Application-Installer.dmg +create-dmg \ + --volname "Application Installer" \ + --volicon "application_icon.icns" \ + --background "installer_background.png" \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --icon "Application.app" 200 190 \ + --hide-extension "Application.app" \ + --app-drop-link 600 185 \ + "Application-Installer.dmg" \ + "source_folder/" +``` + +See the `examples` folder in the source tree for more examples. + +Alternatives +------------ + +- [node-appdmg](https://github.com/LinusU/node-appdmg) +- [dmgbuild](https://pypi.python.org/pypi/dmgbuild) +- see the [StackOverflow question](http://stackoverflow.com/questions/96882/how-do-i-create-a-nice-looking-dmg-for-mac-os-x-using-command-line-tools) diff --git a/src/create-dmg/create-dmg b/src/create-dmg/create-dmg index 3e55dd9742..79185a5a21 100755 --- a/src/create-dmg/create-dmg +++ b/src/create-dmg/create-dmg @@ -1,53 +1,15 @@ -#! /bin/bash +#!/usr/bin/env bash # Create a read-only disk image of the contents of a folder +# Bail out on any unhandled errors set -e; -function pure_version() { - echo '1.0.0.2' -} +CDMG_VERSION='1.0.8' -function version() { - echo "create-dmg $(pure_version)" -} - -function usage() { - version - echo "Creates a fancy DMG file." - echo "Usage: $(basename $0) options... image.dmg source_folder" - echo "All contents of source_folder will be copied into the disk image." - echo "Options:" - echo " --volname name" - echo " set volume name (displayed in the Finder sidebar and window title)" - echo " --volicon icon.icns" - echo " set volume icon" - echo " --background pic.png" - echo " set folder background image (provide png, gif, jpg)" - echo " --window-pos x y" - echo " set position the folder window" - echo " --window-size width height" - echo " set size of the folder window" - echo " --text-size text_size" - echo " set window text size (10-16)" - echo " --icon-size icon_size" - echo " set window icons size (up to 128)" - echo " --icon file_name x y" - echo " set position of the file's icon" - echo " --hide-extension file_name" - echo " hide the extension of file" - echo " --custom-icon file_name custom_icon_or_sample_file x y" - echo " set position and custom icon" - echo " --app-drop-link x y" - echo " make a drop link to Applications, at location x,y" - echo " --eula eula_file" - echo " attach a license file to the dmg" - echo " --no-internet-enable" - echo " disable automatic mount©" - echo " --version show tool version number" - echo " -h, --help display this help" - exit 0 -} +# The full path to the "support/" directory this script is using +# (This will be set up by code later in the script.) +CDMG_SUPPORT_DIR="" WINX=10 WINY=60 @@ -55,176 +17,422 @@ WINW=500 WINH=350 ICON_SIZE=128 TEXT_SIZE=16 +FORMAT="UDZO" +ADD_FILE_SOURCES=() +ADD_FILE_TARGETS=() +IMAGEKEY="" +HDIUTIL_VERBOSITY="" +SANDBOX_SAFE=0 +SKIP_JENKINS=0 -while test "${1:0:1}" = "-"; do - case $1 in - --volname) - VOLUME_NAME="$2" - shift; shift;; - --volicon) - VOLUME_ICON_FILE="$2" - shift; shift;; - --background) - BACKGROUND_FILE="$2" - BACKGROUND_FILE_NAME="$(basename $BACKGROUND_FILE)" - BACKGROUND_CLAUSE="set background picture of opts to file \".background:$BACKGROUND_FILE_NAME\"" - REPOSITION_HIDDEN_FILES_CLAUSE="set position of every item to {theBottomRightX + 100, 100}" - shift; shift;; - --icon-size) - ICON_SIZE="$2" - shift; shift;; - --text-size) - TEXT_SIZE="$2" - shift; shift;; - --window-pos) - WINX=$2; WINY=$3 - shift; shift; shift;; - --window-size) - WINW=$2; WINH=$3 - shift; shift; shift;; - --icon) - POSITION_CLAUSE="${POSITION_CLAUSE}set position of item \"$2\" to {$3, $4} -" - shift; shift; shift; shift;; - --hide-extension) - HIDING_CLAUSE="${HIDING_CLAUSE}set the extension hidden of item \"$2\" to true -" - shift; shift;; - --custom-icon) - shift; shift; shift; shift; shift;; - -h | --help) - usage;; - --version) - version; exit 0;; - --pure-version) - pure_version; exit 0;; - --app-drop-link) - APPLICATION_LINK=$2 - APPLICATION_CLAUSE="set position of item \"Applications\" to {$2, $3} -" - shift; shift; shift;; - --eula) - EULA_RSRC=$2 - shift; shift;; - --no-internet-enable) - NOINTERNET=1 - shift;; - -*) - echo "Unknown option $1. Run with --help for help." - exit 1;; - esac -done - -test -z "$2" && { - echo "Not enough arguments. Invoke with --help for help." - exit 1 +function pure_version() { + echo "$CDMG_VERSION" } -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +function version() { + echo "create-dmg $(pure_version)" +} + +function usage() { + version + cat < + +All contents of will be copied into the disk image. + +Options: + --volname + set volume name (displayed in the Finder sidebar and window title) + --volicon + set volume icon + --background + set folder background image (provide png, gif, or jpg) + --window-pos + set position the folder window + --window-size + set size of the folder window + --text-size + set window text size (10-16) + --icon-size + set window icons size (up to 128) + --icon file_name + set position of the file's icon + --hide-extension + hide the extension of file + --custom-icon + set position and custom icon + --app-drop-link + make a drop link to Applications, at location x,y + --ql-drop-link + make a drop link to user QuickLook install dir, at location x,y + --eula + attach a license file to the dmg (plain text or RTF) + --no-internet-enable + disable automatic mount & copy + --format + specify the final image format (default is UDZO) + --add-file | + add additional file or folder (can be used multiple times) + --disk-image-size + set the disk image size manually to x MB + --hdiutil-verbose + execute hdiutil in verbose mode + --hdiutil-quiet + execute hdiutil in quiet mode + --sandbox-safe + execute hdiutil with sandbox compatibility and do not bless + --rez + use custom path to Rez tool + --version + show create-dmg version number + -h, --help + display this help screen + +EOHELP + exit 0 +} + +# Argument parsing + +while [[ "${1:0:1}" = "-" ]]; do + case $1 in + --volname) + VOLUME_NAME="$2" + shift; shift;; + --volicon) + VOLUME_ICON_FILE="$2" + shift; shift;; + --background) + BACKGROUND_FILE="$2" + BACKGROUND_FILE_NAME="$(basename "$BACKGROUND_FILE")" + BACKGROUND_CLAUSE="set background picture of opts to file \".background:$BACKGROUND_FILE_NAME\"" + REPOSITION_HIDDEN_FILES_CLAUSE="set position of every item to {theBottomRightX + 100, 100}" + shift; shift;; + --icon-size) + ICON_SIZE="$2" + shift; shift;; + --text-size) + TEXT_SIZE="$2" + shift; shift;; + --window-pos) + WINX=$2; WINY=$3 + shift; shift; shift;; + --window-size) + WINW=$2; WINH=$3 + shift; shift; shift;; + --icon) + POSITION_CLAUSE="${POSITION_CLAUSE}set position of item \"$2\" to {$3, $4} + " + shift; shift; shift; shift;; + --hide-extension) + HIDING_CLAUSE="${HIDING_CLAUSE}set the extension hidden of item \"$2\" to true + " + shift; shift;; + --custom-icon) + shift; shift; shift; shift; shift;; + -h | --help) + usage;; + --version) + version; exit 0;; + --pure-version) + pure_version; exit 0;; + --ql-drop-link) + QL_LINK=$2 + QL_CLAUSE="set position of item \"QuickLook\" to {$2, $3} + " + shift; shift; shift;; + --app-drop-link) + APPLICATION_LINK=$2 + APPLICATION_CLAUSE="set position of item \"Applications\" to {$2, $3} + " + shift; shift; shift;; + --eula) + EULA_RSRC=$2 + shift; shift;; + --no-internet-enable) + NOINTERNET=1 + shift;; + --format) + FORMAT="$2" + shift; shift;; + --add-file | --add-folder) + ADD_FILE_TARGETS+=("$2") + ADD_FILE_SOURCES+=("$3") + POSITION_CLAUSE="${POSITION_CLAUSE} + set position of item \"$2\" to {$4, $5} + " + shift; shift; shift; shift; shift;; + --disk-image-size) + DISK_IMAGE_SIZE="$2" + shift; shift;; + --hdiutil-verbose) + HDIUTIL_VERBOSITY='-verbose' + shift;; + --hdiutil-quiet) + HDIUTIL_VERBOSITY='-quiet' + shift;; + --sandbox-safe) + SANDBOX_SAFE=1 + shift;; + --rez) + REZ_PATH="$2" + shift; shift;; + --skip-jenkins) + SKIP_JENKINS=1 + shift;; + -*) + echo "Unknown option: $1. Run 'create-dmg --help' for help." + exit 1;; + esac + case $FORMAT in + UDZO) + IMAGEKEY="-imagekey zlib-level=9";; + UDBZ) + IMAGEKEY="-imagekey bzip2-level=9";; + *) + echo >&2 "Unknown format: $FORMAT" + exit 1;; + esac +done + +if [[ -z "$2" ]]; then + echo "Not enough arguments. Run 'create-dmg --help' for help." + exit 1 +fi + DMG_PATH="$1" +SRC_FOLDER="$(cd "$2" > /dev/null; pwd)" + +# Main script logic + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" DMG_DIRNAME="$(dirname "$DMG_PATH")" DMG_DIR="$(cd "$DMG_DIRNAME" > /dev/null; pwd)" DMG_NAME="$(basename "$DMG_PATH")" DMG_TEMP_NAME="$DMG_DIR/rw.${DMG_NAME}" -SRC_FOLDER="$(cd "$2" > /dev/null; pwd)" -test -z "$VOLUME_NAME" && VOLUME_NAME="$(basename "$DMG_PATH" .dmg)" -AUX_PATH="$SCRIPT_DIR/support" +# Detect where we're running from -test -d "$AUX_PATH" || { - echo "Cannot find support directory: $AUX_PATH" - exit 1 -} +sentinel_file="$SCRIPT_DIR/.this-is-the-create-dmg-repo" +if [[ -f "$sentinel_file" ]]; then + # We're running from inside a repo + CDMG_SUPPORT_DIR="$SCRIPT_DIR/support" +else + # We're running inside an installed location + bin_dir="$SCRIPT_DIR" + prefix_dir=$(dirname "$bin_dir") + CDMG_SUPPORT_DIR="$prefix_dir/share/create-dmg/support" +fi -if [ -f "$SRC_FOLDER/.DS_Store" ]; then - echo "Deleting any .DS_Store in source folder" - rm "$SRC_FOLDER/.DS_Store" +if [[ -z "$VOLUME_NAME" ]]; then + VOLUME_NAME="$(basename "$DMG_PATH" .dmg)" +fi + +if [[ ! -d "$CDMG_SUPPORT_DIR" ]]; then + echo >&2 "Cannot find support/ directory: expected at: $CDMG_SUPPORT_DIR" + exit 1 +fi + +if [[ -f "$SRC_FOLDER/.DS_Store" ]]; then + echo "Deleting .DS_Store found in source folder" + rm "$SRC_FOLDER/.DS_Store" fi # Create the image echo "Creating disk image..." -test -f "${DMG_TEMP_NAME}" && rm -f "${DMG_TEMP_NAME}" -ACTUAL_SIZE=`du -sm "$SRC_FOLDER" | sed -e 's/ .*//g'` -DISK_IMAGE_SIZE=$(expr $ACTUAL_SIZE + 20) -hdiutil create -srcfolder "$SRC_FOLDER" -volname "${VOLUME_NAME}" -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${DISK_IMAGE_SIZE}m "${DMG_TEMP_NAME}" +if [[ -f "${DMG_TEMP_NAME}" ]]; then + rm -f "${DMG_TEMP_NAME}" +fi + +# Use Megabytes since hdiutil fails with very large byte numbers +function blocks_to_megabytes() { + # Add 1 extra MB, since there's no decimal retention here + MB_SIZE=$((($1 * 512 / 1000 / 1000) + 1)) + echo $MB_SIZE +} + +function get_size() { + # Get block size in disk + bytes_size=$(du -s "$1" | sed -e 's/ .*//g') + echo $(blocks_to_megabytes $bytes_size) +} + +# Create the DMG with the specified size or the hdiutil estimation +CUSTOM_SIZE='' +if [[ -n "$DISK_IMAGE_SIZE" ]]; then + CUSTOM_SIZE="-size ${DISK_IMAGE_SIZE}m" +fi + +if [[ $SANDBOX_SAFE -eq 0 ]]; then + hdiutil create ${HDIUTIL_VERBOSITY} -srcfolder "$SRC_FOLDER" -volname "${VOLUME_NAME}" \ + -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW ${CUSTOM_SIZE} "${DMG_TEMP_NAME}" +else + hdiutil makehybrid ${HDIUTIL_VERBOSITY} -default-volume-name "${VOLUME_NAME}" -hfs -o "${DMG_TEMP_NAME}" "$SRC_FOLDER" + hdiutil convert -format UDRW -ov -o "${DMG_TEMP_NAME}" "${DMG_TEMP_NAME}" + DISK_IMAGE_SIZE_CUSTOM=$DISK_IMAGE_SIZE +fi + +# Get the created DMG actual size +DISK_IMAGE_SIZE=$(get_size "${DMG_TEMP_NAME}") + +# Use the custom size if bigger +if [[ $SANDBOX_SAFE -eq 1 ]] && [[ ! -z "$DISK_IMAGE_SIZE_CUSTOM" ]] && [[ $DISK_IMAGE_SIZE_CUSTOM -gt $DISK_IMAGE_SIZE ]]; then + DISK_IMAGE_SIZE=$DISK_IMAGE_SIZE_CUSTOM +fi + +# Estimate the additional soruces size +if [[ -n "$ADD_FILE_SOURCES" ]]; then + for i in "${!ADD_FILE_SOURCES[@]}"; do + SOURCE_SIZE=$(get_size "${ADD_FILE_SOURCES[$i]}") + DISK_IMAGE_SIZE=$(expr $DISK_IMAGE_SIZE + $SOURCE_SIZE) + done +fi + +# Add extra space for additional resources +DISK_IMAGE_SIZE=$(expr $DISK_IMAGE_SIZE + 20) + +# Resize the image for the extra stuff +hdiutil resize ${HDIUTIL_VERBOSITY} -size ${DISK_IMAGE_SIZE}m "${DMG_TEMP_NAME}" + +# Mount the new DMG -# mount it -echo "Mounting disk image..." MOUNT_DIR="/Volumes/${VOLUME_NAME}" -# try unmount dmg if it was mounted previously (e.g. developer mounted dmg, installed app and forgot to unmount it) -echo "Unmounting disk image..." -DEV_NAME=$(hdiutil info | egrep '^/dev/' | sed 1q | awk '{print $1}') -test -d "${MOUNT_DIR}" && hdiutil detach "${DEV_NAME}" +# Unmount leftover dmg if it was mounted previously (e.g. developer mounted dmg, installed app and forgot to unmount it) +if [[ -d "${MOUNT_DIR}" ]]; then + echo "Unmounting old disk image from $MOUNT_DIR..." + DEV_NAME=$(hdiutil info | egrep --color=never '^/dev/' | sed 1q | awk '{print $1}') + hdiutil detach "${DEV_NAME}" +fi + +echo "Mounting disk image..." echo "Mount directory: $MOUNT_DIR" -DEV_NAME=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_TEMP_NAME}" | egrep '^/dev/' | sed 1q | awk '{print $1}') +DEV_NAME=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_TEMP_NAME}" | egrep --color=never '^/dev/' | sed 1q | awk '{print $1}') echo "Device name: $DEV_NAME" -if ! test -z "$BACKGROUND_FILE"; then - echo "Copying background file..." - test -d "$MOUNT_DIR/.background" || mkdir "$MOUNT_DIR/.background" - cp "$BACKGROUND_FILE" "$MOUNT_DIR/.background/$BACKGROUND_FILE_NAME" +if [[ -n "$BACKGROUND_FILE" ]]; then + echo "Copying background file..." + [[ -d "$MOUNT_DIR/.background" ]] || mkdir "$MOUNT_DIR/.background" + cp "$BACKGROUND_FILE" "$MOUNT_DIR/.background/$BACKGROUND_FILE_NAME" fi -if ! test -z "$APPLICATION_LINK"; then - echo "making link to Applications dir" - echo $MOUNT_DIR - ln -s /Applications "$MOUNT_DIR/Applications" +if [[ -n "$APPLICATION_LINK" ]]; then + echo "Making link to Applications dir..." + echo $MOUNT_DIR + ln -s /Applications "$MOUNT_DIR/Applications" fi -if ! test -z "$VOLUME_ICON_FILE"; then - echo "Copying volume icon file '$VOLUME_ICON_FILE'..." - cp "$VOLUME_ICON_FILE" "$MOUNT_DIR/.VolumeIcon.icns" - SetFile -c icnC "$MOUNT_DIR/.VolumeIcon.icns" +if [[ -n "$QL_LINK" ]]; then + echo "Making link to QuickLook install dir..." + echo $MOUNT_DIR + ln -s "/Library/QuickLook" "$MOUNT_DIR/QuickLook" fi -# run applescript -APPLESCRIPT=$(mktemp -t createdmg) -cat "$AUX_PATH/template.applescript" | sed -e "s/WINX/$WINX/g" -e "s/WINY/$WINY/g" -e "s/WINW/$WINW/g" -e "s/WINH/$WINH/g" -e "s/BACKGROUND_CLAUSE/$BACKGROUND_CLAUSE/g" -e "s/REPOSITION_HIDDEN_FILES_CLAUSE/$REPOSITION_HIDDEN_FILES_CLAUSE/g" -e "s/ICON_SIZE/$ICON_SIZE/g" -e "s/TEXT_SIZE/$TEXT_SIZE/g" | perl -pe "s/POSITION_CLAUSE/$POSITION_CLAUSE/g" | perl -pe "s/APPLICATION_CLAUSE/$APPLICATION_CLAUSE/g" | perl -pe "s/HIDING_CLAUSE/$HIDING_CLAUSE/" >"$APPLESCRIPT" +if [[ -n "$VOLUME_ICON_FILE" ]]; then + echo "Copying volume icon file '$VOLUME_ICON_FILE'..." + cp "$VOLUME_ICON_FILE" "$MOUNT_DIR/.VolumeIcon.icns" + SetFile -c icnC "$MOUNT_DIR/.VolumeIcon.icns" +fi -echo "Running Applescript: /usr/bin/osascript \"${APPLESCRIPT}\" \"${VOLUME_NAME}\"" -"/usr/bin/osascript" "${APPLESCRIPT}" "${VOLUME_NAME}" || true -echo "Done running the applescript..." -sleep 4 +if [[ -n "$ADD_FILE_SOURCES" ]]; then + echo "Copying custom files..." + for i in "${!ADD_FILE_SOURCES[@]}"; do + echo "${ADD_FILE_SOURCES[$i]}" + cp -a "${ADD_FILE_SOURCES[$i]}" "$MOUNT_DIR/${ADD_FILE_TARGETS[$i]}" + done +fi -rm "$APPLESCRIPT" +# Run AppleScript to do all the Finder cosmetic stuff +APPLESCRIPT_FILE=$(mktemp -t createdmg.tmp.XXXXXXXXXX) +if [[ $SANDBOX_SAFE -eq 1 ]]; then + echo "Skipping Finder-prettifying AppleScript because we are in Sandbox..." +else + if [[ $SKIP_JENKINS -eq 0 ]]; then + cat "$CDMG_SUPPORT_DIR/template.applescript" \ + | sed -e "s/WINX/$WINX/g" -e "s/WINY/$WINY/g" -e "s/WINW/$WINW/g" \ + -e "s/WINH/$WINH/g" -e "s/BACKGROUND_CLAUSE/$BACKGROUND_CLAUSE/g" \ + -e "s/REPOSITION_HIDDEN_FILES_CLAUSE/$REPOSITION_HIDDEN_FILES_CLAUSE/g" \ + -e "s/ICON_SIZE/$ICON_SIZE/g" -e "s/TEXT_SIZE/$TEXT_SIZE/g" \ + | perl -pe "s/POSITION_CLAUSE/$POSITION_CLAUSE/g" \ + | perl -pe "s/QL_CLAUSE/$QL_CLAUSE/g" \ + | perl -pe "s/APPLICATION_CLAUSE/$APPLICATION_CLAUSE/g" \ + | perl -pe "s/HIDING_CLAUSE/$HIDING_CLAUSE/" \ + > "$APPLESCRIPT_FILE" + sleep 2 # pause to workaround occasional "Can’t get disk" (-1728) issues + echo "Running AppleScript to make Finder stuff pretty: /usr/bin/osascript \"${APPLESCRIPT_FILE}\" \"${VOLUME_NAME}\"" + if /usr/bin/osascript "${APPLESCRIPT_FILE}" "${VOLUME_NAME}"; then + # Okay, we're cool + true + else + echo >&2 "Failed running AppleScript" + hdiutil detach "${DEV_NAME}" + exit 64 + fi + echo "Done running the AppleScript..." + sleep 4 + rm "$APPLESCRIPT_FILE" + fi +fi -# make sure it's not world writeable +# Make sure it's not world writeable echo "Fixing permissions..." chmod -Rf go-w "${MOUNT_DIR}" &> /dev/null || true -echo "Done fixing permissions." +echo "Done fixing permissions" -# make the top window open itself on mount: -echo "Blessing started" -bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}" -echo "Blessing finished" - -if ! test -z "$VOLUME_ICON_FILE"; then - # tell the volume that it has a special file attribute - SetFile -a C "$MOUNT_DIR" +# Make the top window open itself on mount: +if [[ $SANDBOX_SAFE -eq 0 ]]; then + echo "Blessing started" + bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}" + echo "Blessing finished" +else + echo "Skipping blessing on sandbox" fi -# unmount +if [[ -n "$VOLUME_ICON_FILE" ]]; then + # Tell the volume that it has a special file attribute + SetFile -a C "$MOUNT_DIR" +fi + +# Unmount echo "Unmounting disk image..." hdiutil detach "${DEV_NAME}" -# compress image +# Compress image echo "Compressing disk image..." -hdiutil convert "${DMG_TEMP_NAME}" -format UDZO -imagekey zlib-level=9 -o "${DMG_DIR}/${DMG_NAME}" +hdiutil convert ${HDIUTIL_VERBOSITY} "${DMG_TEMP_NAME}" -format ${FORMAT} ${IMAGEKEY} -o "${DMG_DIR}/${DMG_NAME}" rm -f "${DMG_TEMP_NAME}" -# adding EULA resources -if [ ! -z "${EULA_RSRC}" -a "${EULA_RSRC}" != "-null-" ]; then - echo "adding EULA resources" - "${AUX_PATH}/dmg-license.py" "${DMG_DIR}/${DMG_NAME}" "${EULA_RSRC}" +# Adding EULA resources +if [[ -n "${EULA_RSRC}" && "${EULA_RSRC}" != "-null-" ]]; then + echo "Adding EULA resources..." + REZ_ARG="" + if [[ -n "${REZ_PATH}" && "${REZ_PATH}" != "-null-" ]]; then + REZ_ARG="--rez ${REZ_PATH}" + else + xcode_path=$(xcode-select -p) + default_rez="$xcode_path/Tools/Rez" + REZ_ARG="--rez ${default_rez}" + fi + "${CDMG_SUPPORT_DIR}/licenseDMG.py" "${DMG_DIR}/${DMG_NAME}" "${EULA_RSRC}" ${REZ_ARG} fi -if [ ! -z "${NOINTERNET}" -a "${NOINTERNET}" == 1 ]; then - echo "not setting 'internet-enable' on the dmg" +# Enable "internet", whatever that is +if [[ ! -z "${NOINTERNET}" && "${NOINTERNET}" == 1 ]]; then + echo "Not setting 'internet-enable' on the dmg, per caller request" else - hdiutil internet-enable -yes "${DMG_DIR}/${DMG_NAME}" + # Check if hdiutil supports internet-enable + # Support was removed in macOS 10.15. See https://github.com/andreyvit/create-dmg/issues/76 + if hdiutil internet-enable -help >/dev/null 2>/dev/null; then + hdiutil internet-enable -yes "${DMG_DIR}/${DMG_NAME}" + else + echo "hdiutil does not support internet-enable. Note it was removed in macOS 10.15." + fi fi +# All done! echo "Disk image done" exit 0 diff --git a/src/create-dmg/doc-project/Developer Notes.md b/src/create-dmg/doc-project/Developer Notes.md new file mode 100644 index 0000000000..892c0e54c0 --- /dev/null +++ b/src/create-dmg/doc-project/Developer Notes.md @@ -0,0 +1,35 @@ +# create-dmg Developer Notes + +## Repo layout + +- `create-dmg` in the root of the repo is the main program +- `support/` contains auxiliary scripts used by `create-dmg`; it must be at that relative position to `create-dmg` +- `builder/` contains ???? +- `examples/` contains user-facing examples +- `tests/` contains regression tests for developers +- `doc-project/` contains developer-facing documentation about this project + +### tests/ + +The `tests/` folder contains regression tests for developers. + +Each test is in its own subfolder. +Each subfolder name should start with a 3-digit number that is the number of the corresponding bug report in create-dmg's GitHub issue tracker. + +The tests are to be run manually, with the results examined manually. +There's no automated script to run them as a suite and check their results. +That might be nice to have. + +### examples/ + +Each example is in its own subfolder. +The subfolder prefix number is arbitrary; these numbers should roughly be in order of "advancedness" of examples, so it makes sense for users to go through them in order. + +## Versioning + +As of May 2020, we're using SemVer versioning. +The old version numbers were 4-parters, like "1.0.0.7". +Now we use 3-part SemVer versions, like "1.0.8". +This change happened after version 1.0.0.7; 1.0.8 is the next release after 1.0.0.7. + +The suffix "-SNAPSHOT" is used to denote a version that is still under development. diff --git a/src/create-dmg/doc-project/Release Checklist.md b/src/create-dmg/doc-project/Release Checklist.md new file mode 100644 index 0000000000..508392075e --- /dev/null +++ b/src/create-dmg/doc-project/Release Checklist.md @@ -0,0 +1,10 @@ +# Release Checklist + +- Update the version in `create-dmg`'s `pure_version` function + - Remove the "-SNAPSHOT" suffix +- Commit +- Tag the release as `vX.X.X` +- `git push --tags` +- Create a release on the GitHub project page +- Open development on the next release + - Bump the version number and add a "-SNAPSHOT" suffix to it diff --git a/src/create-dmg/examples/01-main-example/installer_background.png b/src/create-dmg/examples/01-main-example/installer_background.png new file mode 100644 index 0000000000..bdfa5ed0d8 Binary files /dev/null and b/src/create-dmg/examples/01-main-example/installer_background.png differ diff --git a/src/create-dmg/examples/01-main-example/sample b/src/create-dmg/examples/01-main-example/sample new file mode 100755 index 0000000000..c18a65bb05 --- /dev/null +++ b/src/create-dmg/examples/01-main-example/sample @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +if [[ -e ../../create-dmg ]]; then + # We're running from the repo + CREATE_DMG=../../create-dmg +else + # We're running from an installation under a prefix + CREATE_DMG=../../../../bin/create-dmg +fi + +# Since create-dmg does not clobber, be sure to delete previous DMG +[[ -f Application-Installer.dmg ]] && rm Application-Installer.dmg + +# Create the DMG +$CREATE_DMG \ + --volname "Application Installer" \ + --background "installer_background.png" \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --icon "Application.app" 200 190 \ + --hide-extension "Application.app" \ + --app-drop-link 600 185 \ + "Application-Installer.dmg" \ + "source_folder/" diff --git a/src/create-dmg/examples/01-main-example/source_folder/Application.app b/src/create-dmg/examples/01-main-example/source_folder/Application.app new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/create-dmg/support/LICENSE-licenseDMG-pyhacker b/src/create-dmg/support/LICENSE-licenseDMG-pyhacker new file mode 100644 index 0000000000..94b7fe934e --- /dev/null +++ b/src/create-dmg/support/LICENSE-licenseDMG-pyhacker @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Jared Hobbs + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/create-dmg/support/README b/src/create-dmg/support/README new file mode 100644 index 0000000000..0ecb9eefce --- /dev/null +++ b/src/create-dmg/support/README @@ -0,0 +1,7 @@ +# create-dmg support files + +## licenseDMG.py + +The licenseDMG.py script is taken from Jared Hobbs' pyhacker library, at . + +See LICENSE-licenseDMG-pyhacker for licensing details. \ No newline at end of file diff --git a/src/create-dmg/support/dmg-license.py b/src/create-dmg/support/dmg-license.py deleted file mode 100755 index 9003a7c5e7..0000000000 --- a/src/create-dmg/support/dmg-license.py +++ /dev/null @@ -1,163 +0,0 @@ -#! /usr/bin/env python -""" -This script adds a license file to a DMG. Requires Xcode and a plain ascii text -license file. -Obviously only runs on a Mac. - -Copyright (C) 2011-2013 Jared Hobbs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" -import os -import sys -import tempfile -import optparse - - -class Path(str): - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - os.unlink(self) - - -def mktemp(dir=None, suffix=''): - (fd, filename) = tempfile.mkstemp(dir=dir, suffix=suffix) - os.close(fd) - return Path(filename) - - -def main(options, args): - dmgFile, license = args - with mktemp('.') as tmpFile: - with open(tmpFile, 'w') as f: - f.write("""data 'TMPL' (128, "LPic") { - $"1344 6566 6175 6C74 204C 616E 6775 6167" - $"6520 4944 4457 5244 0543 6F75 6E74 4F43" - $"4E54 042A 2A2A 2A4C 5354 430B 7379 7320" - $"6C61 6E67 2049 4444 5752 441E 6C6F 6361" - $"6C20 7265 7320 4944 2028 6F66 6673 6574" - $"2066 726F 6D20 3530 3030 4457 5244 1032" - $"2D62 7974 6520 6C61 6E67 7561 6765 3F44" - $"5752 4404 2A2A 2A2A 4C53 5445" -}; - -data 'LPic' (5000) { - $"0000 0002 0000 0000 0000 0000 0004 0000" -}; - -data 'STR#' (5000, "English buttons") { - $"0006 0D45 6E67 6C69 7368 2074 6573 7431" - $"0541 6772 6565 0844 6973 6167 7265 6505" - $"5072 696E 7407 5361 7665 2E2E 2E7A 4966" - $"2079 6F75 2061 6772 6565 2077 6974 6820" - $"7468 6520 7465 726D 7320 6F66 2074 6869" - $"7320 6C69 6365 6E73 652C 2063 6C69 636B" - $"2022 4167 7265 6522 2074 6F20 6163 6365" - $"7373 2074 6865 2073 6F66 7477 6172 652E" - $"2020 4966 2079 6F75 2064 6F20 6E6F 7420" - $"6167 7265 652C 2070 7265 7373 2022 4469" - $"7361 6772 6565 2E22" -}; - -data 'STR#' (5002, "English") { - $"0006 0745 6E67 6C69 7368 0541 6772 6565" - $"0844 6973 6167 7265 6505 5072 696E 7407" - $"5361 7665 2E2E 2E7B 4966 2079 6F75 2061" - $"6772 6565 2077 6974 6820 7468 6520 7465" - $"726D 7320 6F66 2074 6869 7320 6C69 6365" - $"6E73 652C 2070 7265 7373 2022 4167 7265" - $"6522 2074 6F20 696E 7374 616C 6C20 7468" - $"6520 736F 6674 7761 7265 2E20 2049 6620" - $"796F 7520 646F 206E 6F74 2061 6772 6565" - $"2C20 7072 6573 7320 2244 6973 6167 7265" - $"6522 2E" -};\n\n""") - with open(license, 'r') as l: - kind = 'RTF ' if license.lower().endswith('.rtf') else 'TEXT' - f.write('data \'%s\' (5000, "English") {\n' % kind) - def escape(s): - return s.strip().replace('\\', '\\\\').replace('"', '\\"') - - for line in l: - if len(line) < 1000: - f.write(' "' + escape(line) + '\\n"\n') - else: - for liner in line.split('.'): - f.write(' "' + escape(liner) + '. \\n"\n') - f.write('};\n\n') - f.write("""data 'styl' (5000, "English") { - $"0003 0000 0000 000C 0009 0014 0000 0000" - $"0000 0000 0000 0000 0027 000C 0009 0014" - $"0100 0000 0000 0000 0000 0000 002A 000C" - $"0009 0014 0000 0000 0000 0000 0000" -};\n""") - os.system('hdiutil unflatten -quiet "%s"' % dmgFile) - ret = os.system('%s -a %s -o "%s"' % - (options.rez, tmpFile, dmgFile)) - os.system('hdiutil flatten -quiet "%s"' % dmgFile) - if options.compression is not None: - os.system('cp %s %s.temp.dmg' % (dmgFile, dmgFile)) - os.remove(dmgFile) - if options.compression == "bz2": - os.system('hdiutil convert %s.temp.dmg -format UDBZ -o %s' % - (dmgFile, dmgFile)) - elif options.compression == "gz": - os.system('hdiutil convert %s.temp.dmg -format ' % dmgFile + - 'UDZO -imagekey zlib-devel=9 -o %s' % dmgFile) - os.remove('%s.temp.dmg' % dmgFile) - if ret == 0: - print "Successfully added license to '%s'" % dmgFile - else: - print "Failed to add license to '%s'" % dmgFile - -if __name__ == '__main__': - parser = optparse.OptionParser() - parser.set_usage("""%prog [OPTIONS] - This program adds a software license agreement to a DMG file. - It requires Xcode and either a plain ascii text - or a with the RTF contents. - - See --help for more details.""") - parser.add_option( - '--rez', - '-r', - action='store', - default='/Applications/Xcode.app/Contents/Developer/Tools/Rez', - help='The path to the Rez tool. Defaults to %default' - ) - parser.add_option( - '--compression', - '-c', - action='store', - choices=['bz2', 'gz'], - default=None, - help='Optionally compress dmg using specified compression type. ' - 'Choices are bz2 and gz.' - ) - options, args = parser.parse_args() - cond = len(args) != 2 - if not os.path.exists(options.rez): - print 'Failed to find Rez at "%s"!\n' % options.rez - cond = True - if cond: - parser.print_usage() - sys.exit(1) - main(options, args) diff --git a/src/create-dmg/support/licenseDMG.py b/src/create-dmg/support/licenseDMG.py new file mode 100755 index 0000000000..f6eaf98395 --- /dev/null +++ b/src/create-dmg/support/licenseDMG.py @@ -0,0 +1,200 @@ +#! /usr/bin/env python +""" +This script adds a license file to a DMG. Requires Xcode and a plain ascii text +license file or an RTF license file. +Obviously only runs on a Mac. + +Copyright (C) 2011-2019 Jared Hobbs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +""" +from __future__ import unicode_literals +from subprocess import check_call, check_output, call, CalledProcessError +import argparse +import logging as logger +import os +import sys +import tempfile + +logger.basicConfig(format='%(message)s', level=logger.DEBUG) + + +class Path(str): + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + os.unlink(self) + + +def mktemp(dir=None, suffix=''): + fd, filename = tempfile.mkstemp(dir=dir, suffix=suffix) + os.close(fd) + return Path(filename) + + +def escape(s): + return s.strip().replace('\\', '\\\\').replace('"', '\\"') + + +def main(options): + dmg_file = options.dmg_file + output = options.output or dmg_file + license = options.license_file + if dmg_file != output: + check_call(['cp', dmg_file, output]) + dmg_file = output + with mktemp('.') as tmp_file: + with open(tmp_file, 'w') as f: + f.write("""\ +data 'TMPL' (128, "LPic") { + $"1344 6566 6175 6C74 204C 616E 6775 6167" + $"6520 4944 4457 5244 0543 6F75 6E74 4F43" + $"4E54 042A 2A2A 2A4C 5354 430B 7379 7320" + $"6C61 6E67 2049 4444 5752 441E 6C6F 6361" + $"6C20 7265 7320 4944 2028 6F66 6673 6574" + $"2066 726F 6D20 3530 3030 4457 5244 1032" + $"2D62 7974 6520 6C61 6E67 7561 6765 3F44" + $"5752 4404 2A2A 2A2A 4C53 5445" +}; + +data 'LPic' (5000) { + $"0000 0002 0000 0000 0000 0000 0004 0000" +}; + +data 'STR#' (5000, "English buttons") { + $"0006 0D45 6E67 6C69 7368 2074 6573 7431" + $"0541 6772 6565 0844 6973 6167 7265 6505" + $"5072 696E 7407 5361 7665 2E2E 2E7A 4966" + $"2079 6F75 2061 6772 6565 2077 6974 6820" + $"7468 6520 7465 726D 7320 6F66 2074 6869" + $"7320 6C69 6365 6E73 652C 2063 6C69 636B" + $"2022 4167 7265 6522 2074 6F20 6163 6365" + $"7373 2074 6865 2073 6F66 7477 6172 652E" + $"2020 4966 2079 6F75 2064 6F20 6E6F 7420" + $"6167 7265 652C 2070 7265 7373 2022 4469" + $"7361 6772 6565 2E22" +}; + +data 'STR#' (5002, "English") { + $"0006 0745 6E67 6C69 7368 0541 6772 6565" + $"0844 6973 6167 7265 6505 5072 696E 7407" + $"5361 7665 2E2E 2E7B 4966 2079 6F75 2061" + $"6772 6565 2077 6974 6820 7468 6520 7465" + $"726D 7320 6F66 2074 6869 7320 6C69 6365" + $"6E73 652C 2070 7265 7373 2022 4167 7265" + $"6522 2074 6F20 696E 7374 616C 6C20 7468" + $"6520 736F 6674 7761 7265 2E20 2049 6620" + $"796F 7520 646F 206E 6F74 2061 6772 6565" + $"2C20 7072 6573 7320 2244 6973 6167 7265" + $"6522 2E" +};\n\n""") + with open(license, 'r') as l_file: + kind = 'RTF ' if license.lower().endswith('.rtf') else 'TEXT' + f.write('data \'{}\' (5000, "English") {{\n'.format(kind)) + + for line in l_file: + if len(line) < 1000: + f.write(' "{}\\n"\n'.format(escape(line))) + else: + for liner in line.split('.'): + f.write(' "{}. \\n"\n'.format(escape(liner))) + f.write('};\n\n') + f.write("""\ +data 'styl' (5000, "English") { + $"0003 0000 0000 000C 0009 0014 0000 0000" + $"0000 0000 0000 0000 0027 000C 0009 0014" + $"0100 0000 0000 0000 0000 0000 002A 000C" + $"0009 0014 0000 0000 0000 0000 0000" +};\n""") + call(['hdiutil', 'unflatten', '-quiet', dmg_file]) + ret = check_call([options.rez, '-a', tmp_file, '-o', dmg_file]) + call(['hdiutil', 'flatten', '-quiet', dmg_file]) + if options.compression is not None: + tmp_dmg = '{}.temp.dmg'.format(dmg_file) + check_call(['cp', dmg_file, tmp_dmg]) + os.remove(dmg_file) + args = ['hdiutil', 'convert', tmp_dmg, '-quiet', '-format'] + if options.compression == 'bz2': + args.append('UDBZ') + elif options.compression == "gz": + args.extend(['UDZO', '-imagekey', 'zlib-devel=9']) + args.extend(['-o', dmg_file]) + check_call(args) + os.remove(tmp_dmg) + if ret == 0: + logger.info("Successfully added license to '{}'".format(dmg_file)) + else: + logger.error("Failed to add license to '{}'".format(dmg_file)) + + +if __name__ == '__main__': + try: + rez_path = check_output( + ['xcrun', '--find', 'Rez'], + ).strip().decode('utf-8') + except CalledProcessError: + rez_path = '/Library/Developer/CommandLineTools/usr/bin/Rez' + parser = argparse.ArgumentParser( + description="""\ +This program adds a software license agreement to a DMG file. +It requires Xcode and either a plain ascii text +or a with the RTF contents. + +See --help for more details.""", + ) + parser.add_argument( + 'dmg_file', + help='the path to the dmg file which will receive the license', + ) + parser.add_argument( + 'license_file', + help='the path to the plain ascii or RTF license file; for RTF files, ' + 'the file must use a .rtf extension', + ) + parser.add_argument( + '--rez', + '-r', + action='store', + default=rez_path, + help='the path to the Rez tool; defaults to %(default)s', + ) + parser.add_argument( + '--compression', + '-c', + action='store', + choices=('bz2', 'gz'), + default=None, + help='optionally compress dmg using specified compression type; ' + 'choices are bz2 and gz', + ) + parser.add_argument( + '--output', + '-o', + action='store', + default=None, + help='specify an output DMG file; if not given, the license will be ' + 'directly applied to the input DMG file', + ) + options = parser.parse_args() + if not os.path.exists(options.rez): + logger.error('Failed to find Rez at "{}"!\n'.format(options.rez)) + parser.print_usage() + sys.exit(1) + main(options) diff --git a/src/create-dmg/support/template.applescript b/src/create-dmg/support/template.applescript index 2a7f2aa0b6..fee634d319 100644 --- a/src/create-dmg/support/template.applescript +++ b/src/create-dmg/support/template.applescript @@ -2,16 +2,16 @@ on run (volumeName) tell application "Finder" tell disk (volumeName as string) open - + set theXOrigin to WINX set theYOrigin to WINY set theWidth to WINW set theHeight to WINH - + set theBottomRightX to (theXOrigin + theWidth) set theBottomRightY to (theYOrigin + theHeight) set dsStore to "\"" & "/Volumes/" & volumeName & "/" & ".DS_STORE\"" - + tell container window set current view to icon view set toolbar visible to false @@ -20,7 +20,7 @@ on run (volumeName) set statusbar visible to false REPOSITION_HIDDEN_FILES_CLAUSE end tell - + set opts to the icon view options of container window tell opts set icon size to ICON_SIZE @@ -28,44 +28,39 @@ on run (volumeName) set arrangement to not arranged end tell BACKGROUND_CLAUSE - + -- Positioning POSITION_CLAUSE - + -- Hiding HIDING_CLAUSE - - -- Application Link Clause + + -- Application and QL Link Clauses APPLICATION_CLAUSE - close - open - - update without registering applications + QL_CLAUSE + close + open -- Force saving of the size delay 1 - + tell container window set statusbar visible to false set the bounds to {theXOrigin, theYOrigin, theBottomRightX - 10, theBottomRightY - 10} end tell - - update without registering applications end tell - + delay 1 - + tell disk (volumeName as string) tell container window set statusbar visible to false set the bounds to {theXOrigin, theYOrigin, theBottomRightX, theBottomRightY} end tell - - update without registering applications end tell - + --give the finder some time to write the .DS_Store file delay 3 - + set waitTime to 0 set ejectMe to false repeat while ejectMe is false diff --git a/src/create-dmg/tests/007-space-in-dir-name/my files/hello.txt b/src/create-dmg/tests/007-space-in-dir-name/my files/hello.txt new file mode 100644 index 0000000000..802992c422 --- /dev/null +++ b/src/create-dmg/tests/007-space-in-dir-name/my files/hello.txt @@ -0,0 +1 @@ +Hello world diff --git a/src/create-dmg/tests/007-space-in-dir-name/run-test b/src/create-dmg/tests/007-space-in-dir-name/run-test new file mode 100755 index 0000000000..ab7f96ab42 --- /dev/null +++ b/src/create-dmg/tests/007-space-in-dir-name/run-test @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +# Test for https://github.com/create-dmg/create-dmg/issues/7 - spaces in folder names + +../../create-dmg "my disk image.dmg" "my files" \ No newline at end of file