Skip to content

Upgrade create-dmg and build DMG disk image with APFS #1409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci-macvim.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,11 @@ jobs:
run: |
# Use the --skip-jenkins flag to skip the prettify osascript calls which could fail due to permission issues in
# CI environment.
make -C src macvim-dmg CREATEDMG_FLAGS=--skip-jenkins
if ${{ matrix.legacy == true }}; then
make -C src macvim-dmg-legacy CREATEDMG_FLAGS=--skip-jenkins
else
make -C src macvim-dmg CREATEDMG_FLAGS=--skip-jenkins
fi

if ${{ matrix.publish_postfix != '' }}; then
mv src/MacVim/build/Release/MacVim.dmg src/MacVim/build/Release/MacVim${{ matrix.publish_postfix }}.dmg
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions src/MacVim/create-dmg/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Content of this directory is copied from https://github.com/create-dmg/create-dmg (c89d743919acb1a16259ed7b98059393978fb639 / 2023-01-23).
5 changes: 3 additions & 2 deletions src/create-dmg/README.md → src/MacVim/create-dmg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ All contents of source\_folder will be copied into the disk image.
- **--eula \<eula_file\>:** attach a license file to the dmg
- **--rez \<rez_path\>:** specify custom path to Rez tool used to include license file
- **--no-internet-enable:** disable automatic mount&copy
- **--format:** specify the final image format (UDZO|UDBZ|ULFO|ULMO) (default is UDZO)
- **--format:** specify the final image format (UDZO|UDBZ|ULFO|ULMO) (default is UDZO)
- **--filesystem:** specify the image filesystem (HFS+|APFS) (default is HFS+, APFS supports macOS 10.13 or newer)
- **--add-file \<target_name\> \<file|folder\> \<x\> \<y\>:** add additional file or folder (can be used multiple times)
- **--disk-image-size \<x\>:** set the disk image size manually to x MB
- **--hdiutil-verbose:** execute hdiutil in verbose mode
Expand All @@ -73,7 +74,7 @@ All contents of source\_folder will be copied into the disk image.
- **--notarize \<credentials>:** notarize the disk image (waits and staples) with the keychain stored credentials
For more information check [Apple's documentation](https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow)
- **--skip-jenkins:** skip Finder-prettifying AppleScript, useful in Sandbox and non-GUI environments, [#72](https://github.com/create-dmg/create-dmg/pull/72)
- **--sandbox-safe:** hdiutil with sandbox compatibility, do not bless and do not execute the cosmetic AppleScript
- **--sandbox-safe:** hdiutil with sandbox compatibility, do not bless and do not execute the cosmetic AppleScript (not supported for APFS disk images)
- **--version:** show tool version number
- **-h, --help:** display the help

Expand Down
89 changes: 64 additions & 25 deletions src/create-dmg/create-dmg → src/MacVim/create-dmg/create-dmg
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@

# Bail out on any unhandled errors
set -e;
# Any command that exits with non-zero code will cause the pipeline to fail
set -o pipefail;

CDMG_VERSION='1.1.0'
CDMG_VERSION='1.1.1'

# 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=""

OS_FULL_VERSION="$(sw_vers | sed -n 2p | cut -d : -f 2 | tr -d '[:space:]' | cut -c1-)"
OS_MAJOR_VERSION="$(echo $OS_FULL_VERSION | cut -d . -f 1)"
OS_MINOR_VERSION="$(echo $OS_FULL_VERSION | cut -d . -f 2)"
WINX=10
WINY=60
WINW=500
WINH=350
ICON_SIZE=128
TEXT_SIZE=16
FORMAT="UDZO"
FILESYSTEM="HFS+"
ADD_FILE_SOURCES=()
ADD_FILE_TARGETS=()
IMAGEKEY=""
Expand All @@ -33,6 +39,26 @@ function pure_version() {
echo "$CDMG_VERSION"
}

function hdiutil_detach_retry() {
# Unmount
unmounting_attempts=0
until
echo "Unmounting disk image..."
(( unmounting_attempts++ ))
hdiutil detach "$1"
exit_code=$?
(( exit_code == 0 )) && break # nothing goes wrong
(( exit_code != 16 )) && exit $exit_code # exit with the original exit code
# The above statement returns 1 if test failed (exit_code == 16).
# It can make the code in the {do... done} block to be executed
do
(( unmounting_attempts == MAXIMUM_UNMOUNTING_ATTEMPTS )) && exit 16 # patience exhausted, exit with code EBUSY
echo "Wait a moment..."
sleep $(( 1 * (2 ** unmounting_attempts) ))
done
unset unmounting_attempts
}

function version() {
echo "create-dmg $(pure_version)"
}
Expand Down Expand Up @@ -76,6 +102,8 @@ Options:
disable automatic mount & copy
--format <format>
specify the final disk image format (UDZO|UDBZ|ULFO|ULMO) (default is UDZO)
--filesystem <filesystem>
specify the disk image filesystem (HFS+|APFS) (default is HFS+, APFS supports macOS 10.13 or newer)
--add-file <target_name> <file>|<folder> <x> <y>
add additional file or folder (can be used multiple times)
--disk-image-size <x>
Expand All @@ -91,7 +119,7 @@ Options:
--notarize <credentials>
notarize the disk image (waits and staples) with the keychain stored credentials
--sandbox-safe
execute hdiutil with sandbox compatibility and do not bless
execute hdiutil with sandbox compatibility and do not bless (not supported for APFS disk images)
--version
show create-dmg version number
-h, --help
Expand Down Expand Up @@ -162,6 +190,9 @@ while [[ "${1:0:1}" = "-" ]]; do
--format)
FORMAT="$2"
shift; shift;;
--filesystem)
FILESYSTEM="$2"
shift; shift;;
--add-file | --add-folder)
ADD_FILE_TARGETS+=("$2")
ADD_FILE_SOURCES+=("$3")
Expand Down Expand Up @@ -230,6 +261,16 @@ if [[ "${DMG_PATH: -4}" != ".dmg" ]]; then
exit 1
fi

if [[ "${FILESYSTEM}" != "HFS+" ]] && [[ "${FILESYSTEM}" != "APFS" ]]; then
echo "Unknown disk image filesystem: ${FILESYSTEM}. Run 'create-dmg --help' for help."
exit 1
fi

if [[ "${FILESYSTEM}" == "APFS" ]] && [[ ${SANDBOX_SAFE} -eq 1 ]]; then
echo "Creating an APFS disk image that is sandbox safe is not supported."
exit 1
fi

# Main script logic

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Expand Down Expand Up @@ -280,7 +321,12 @@ function blocks_to_megabytes() {

function get_size() {
# Get block size in disk
bytes_size=$(du -s "$1" | sed -e 's/ .*//g')
if [[ $OS_MAJOR_VERSION -ge 12 ]]; then
bytes_size=$(du -B 512 -s "$1")
else
bytes_size=$(du -s "$1")
fi
bytes_size=$(echo $bytes_size | sed -e 's/ .*//g')
echo $(blocks_to_megabytes $bytes_size)
}

Expand All @@ -291,9 +337,14 @@ if [[ -n "$DISK_IMAGE_SIZE" ]]; then
fi

if [[ $SANDBOX_SAFE -eq 0 ]]; then
if [[ "$FILESYSTEM" == "APFS" ]]; then
FILESYSTEM_ARGUMENTS=""
else
FILESYSTEM_ARGUMENTS="-c c=64,a=16,e=16"
fi
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
-fs "${FILESYSTEM}" -fsargs "${FILESYSTEM_ARGUMENTS}" -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
Expand Down Expand Up @@ -335,7 +386,7 @@ MOUNT_DIR="/Volumes/${VOLUME_NAME}"
if [[ -d "${MOUNT_DIR}" ]]; then
echo "Unmounting old disk image from $MOUNT_DIR..."
DEV_NAME=$(hdiutil info | grep -E --color=never '^/dev/' | sed 1q | awk '{print $1}')
hdiutil detach "${DEV_NAME}"
hdiutil_detach_retry "${DEV_NAME}"
fi

echo "Mounting disk image..."
Expand Down Expand Up @@ -399,7 +450,7 @@ else
true
else
echo >&2 "Failed running AppleScript"
hdiutil detach "${DEV_NAME}"
hdiutil_detach_retry "${DEV_NAME}"
exit 64
fi
echo "Done running the AppleScript..."
Expand All @@ -416,7 +467,11 @@ echo "Done fixing permissions"
# Make the top window open itself on mount:
if [[ $BLESS -eq 1 && $SANDBOX_SAFE -eq 0 ]]; then
echo "Blessing started"
bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}"
if [ $(uname -m) == "arm64" ]; then
bless --folder "${MOUNT_DIR}"
else
bless --folder "${MOUNT_DIR}" --openfolder "${MOUNT_DIR}"
fi
echo "Blessing finished"
else
echo "Skipping blessing on sandbox"
Expand All @@ -431,23 +486,7 @@ fi
echo "Deleting .fseventsd"
rm -rf "${MOUNT_DIR}/.fseventsd" || true

# Unmount
unmounting_attempts=0
until
echo "Unmounting disk image..."
(( unmounting_attempts++ ))
hdiutil detach "${DEV_NAME}"
exit_code=$?
(( exit_code == 0 )) && break # nothing goes wrong
(( exit_code != 16 )) && exit $exit_code # exit with the original exit code
# The above statement returns 1 if test failed (exit_code == 16).
# It can make the code in the {do... done} block to be executed
do
(( unmounting_attempts == MAXIMUM_UNMOUNTING_ATTEMPTS )) && exit 16 # patience exhausted, exit with code EBUSY
echo "Wait a moment..."
sleep $(( 1 * (2 ** unmounting_attempts) ))
done
unset unmounting_attempts
hdiutil_detach_retry "${DEV_NAME}"

# Compress image
echo "Compressing disk image..."
Expand Down
12 changes: 11 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3633,18 +3633,28 @@ DMGDIR = MacVim/build/dmg
DMGFILE = MacVim.dmg
ENTITLEMENTS = MacVim/MacVim.entitlements

# APFS is supported in 10.13+, ULFO (LZFSE compression) in 10.11+.
DMGFILESYSTEM = APFS
DMGFORMAT = ULFO

macvim: $(VIMTARGET)
xcodebuild -project MacVim/MacVim.xcodeproj $(XCODEFLAGS)

macvim-signed:
MacVim/scripts/sign-developer-id $(RELEASEDIR)/MacVim.app $(ENTITLEMENTS)

macvim-dmg-legacy: DMGFILESYSTEM = HFS+
macvim-dmg-legacy: DMGFORMAT = UDZO
macvim-dmg-legacy: macvim-dmg

macvim-dmg:
rm -rf $(DMGDIR)
mkdir -p $(DMGDIR)
cp -a $(RELEASEDIR)/MacVim.app $(DMGDIR)/
rm -rf $(RELEASEDIR)/$(DMGFILE)
create-dmg/create-dmg \
MacVim/create-dmg/create-dmg \
--filesystem "$(DMGFILESYSTEM)" \
--format "$(DMGFORMAT)" \
--volname "MacVim" \
--volicon MacVim/icons/MacVim.icns \
--background MacVim/dmg/background.png \
Expand Down
1 change: 0 additions & 1 deletion src/create-dmg/README

This file was deleted.