JAL-4428 localise function vars. Add -q -q option. Fix detaching volumes for cleanup -C
authorBen Soares <b.soares@dundee.ac.uk>
Mon, 19 Aug 2024 09:30:42 +0000 (10:30 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Mon, 19 Aug 2024 09:30:42 +0000 (10:30 +0100)
utils/osx_signing/sign_and_staple_dmg.sh

index 283e9fb..b8b85ae 100755 (executable)
@@ -19,9 +19,10 @@ VOLUMEICONPATH="utils/channels/release/images/jalview-VolumeIcon.icns"
 NOVOLUMEICON=0
 DEFAULTVOLUMEICONFILE=".VolumeIcon.icns"
 HDIUTILV="-quiet"
+QUIET=0
 
 usage() {
-  echo "Usage: $( basename $0 ) [-h] [[-g gitdir] | [-e entfile]] [-d devid] [[-a appname] [-v appver ] [-j arch] [-w jver] | [-i dmgfile]] [-o outputdmg] [-O] [-t tmpdir] [-s] [-S] [-p] [-P] [-z icnsfile] [-Z] [-y] [-C] [-V]"
+  echo "Usage: $( basename $0 ) [-h] [[-g gitdir] | [-e entfile]] [-d devid] [[-a appname] [-v appver ] [-j arch] [-w jver] | [-i dmgfile]] [-o outputdmg] [-O] [-t tmpdir] [-s] [-S] [-p] [-P] [-z icnsfile] [-Z] [-y] [-C] [-V] [-q]"
   echo "  "
   echo "  This script is used in the signing process of DMG disk image files for macOS."
   echo "  Either -g GITDIR or -e ENTFILE should be given."
@@ -50,13 +51,14 @@ usage() {
   echo "  -y             Assume 'yes' to all confirmation requests."
   echo "  -C             Cleanup temporary folders for the given DMG file or equivalent (Runs INSTEAD of all other activities. Cleanup can be narrowed down with either -i or some/all of -a -v -j -w)."
   echo "  -V             Allow tools such as hdiutil to be more verbose."
+  echo "  -q             Run as quietly as we can.  Sets -y.  Use once (no output from other run commands) or twice (reduce output from this script)."
   echo "  "
   echo "  EXAMPLE:"
   echo "  $( basename $0 ) -g ~/work/git/jalview -i build/install4j/11/Jalview_Develop-2_11_4_0-d20240816-macos-aarch64-java_11.dmg -s -p -z utils/channels/develop/images/jalview_develop-VolumeIcon.icns"
   echo "  will use entitlements.txt from the gitdir (-g), and output a signed (-s) and stapled (-p) DMG file in build/install4j/11/stapled with a volume icon for Jalview Develop (-z)."
 }
 
-while getopts "hg:e:d:a:v:j:w:i:t:sSpPz:Zo:OyCV" opt; do
+while getopts "hg:e:d:a:v:j:w:i:t:sSpPz:Zo:OyCVq" opt; do
   case ${opt} in
     h)
       usage
@@ -123,6 +125,11 @@ while getopts "hg:e:d:a:v:j:w:i:t:sSpPz:Zo:OyCV" opt; do
     V)
       HDIUTILV=""
       ;;
+    q)
+      QUIET=$(( QUIET + 1 ))
+      YES=1
+      HDIUTILV="-quiet"
+      ;;
     *)
       echo "Unrecognised option. Run with -h for help."
       exit 1
@@ -131,62 +138,62 @@ while getopts "hg:e:d:a:v:j:w:i:t:sSpPz:Zo:OyCV" opt; do
 done
 
 if [ "$CLEANUP" != 1 ]; then
-    # Now check GITDIR, ENTITLEMENTSFILE, DEVELOPERID, APPNAME, APPVER, ARCH, JVER, DMGFILE, TMP, TMPDMG
+  # Now check GITDIR, ENTITLEMENTSFILE, DEVELOPERID, APPNAME, APPVER, ARCH, JVER, DMGFILE, TMP, TMPDMG
 
-    # check entitlements setting and file exists
-    if [ -z "$ENTITLEMENTSFILE" ]; then
-        ENTITLEMENTSFILE="${GITDIR}/${GITENTITLEMENTSPATH}"
-    fi
-    if [ -z "$ENTITLEMENTSFILE" ]; then
-        echo "Must set an entitlements file with -e entfile or -g GITDIR (or with GITDIR env variable)."
-        echo ""
-        usage
-        exit 2
-    fi
-    if [ ! -e "$ENTITLEMENTSFILE" ]; then
-        echo "Entitlements file '$ENTITLEMENTSFILE' doesn't exist"
-        exit 3
-    fi
+  # check entitlements setting and file exists
+  if [ -z "$ENTITLEMENTSFILE" ]; then
+    ENTITLEMENTSFILE="${GITDIR}/${GITENTITLEMENTSPATH}"
+  fi
+  if [ -z "$ENTITLEMENTSFILE" ]; then
+    echo "Must set an entitlements file with -e entfile or -g GITDIR (or with GITDIR env variable)."
+    echo ""
+    usage
+    exit 2
+  fi
+  if [ ! -e "$ENTITLEMENTSFILE" -a "$SIGN$DOSIGN" = 11 ]; then
+    echo "Entitlements file '$ENTITLEMENTSFILE' doesn't exist"
+    exit 3
+  fi
 
-    # check developer id
-    if [ -z "$DEVELOPERID" ]; then
-        echo "Must set a Developer ID with -d DEVELOPERID (or with env variable)."
-        echo ""
-        usage
-        exit 4
-    fi
+  # check developer id
+  if [ -z "$DEVELOPERID" -a "$SIGN$DOSIGN" = 11 ]; then
+    echo "Must set a Developer ID with -d DEVELOPERID (or with env variable)."
+    echo ""
+    usage
+    exit 4
+  fi
 
-    # check ARCH is set and valid
-    if [ ! -z "$ARCH" -a "${TESTARCH/|$ARCH|/}" = "$TESTARCH" ]; then # not a valid arch
-        echo "ARCH must be one of${TESTARCH//|/ }. Set with -a ARCH (or with env variable)."
-        echo ""
-        usage
-        exit 5
-    fi
+  # check ARCH is set and valid
+  if [ ! -z "$ARCH" -a "${TESTARCH/|$ARCH|/}" = "$TESTARCH" ]; then # not a valid arch
+    echo "ARCH must be one of${TESTARCH//|/ }. Set with -a ARCH (or with env variable)."
+    echo ""
+    usage
+    exit 5
+  fi
 
-    # check VOLUMEICON
-    USEVOLUMEICON=0
-    if [ ! -z "$VOLUMEICON" ]; then
-        if [ ! -e "$VOLUMEICON" ]; then
-            echo "Volume icon is set to '$VOLUMEICON' but it does not exist.  Use -Z to NOT set a volume icon."
-            exit 6
-        fi
-        USEVOLUMEICON=1
-    else
-        VOLUMEICON="${GITDIR}/${VOLUMEICONPATH}"
-        if [ ! -e "$VOLUMEICON" ]; then
-            VOLUMEICON=""
-        fi
-        USEVOLUMEICON=1
+  # check VOLUMEICON
+  USEVOLUMEICON=0
+  if [ ! -z "$VOLUMEICON" ]; then
+    if [ ! -e "$VOLUMEICON" ]; then
+      echo "Volume icon is set to '$VOLUMEICON' but it does not exist.  Use -Z to NOT set a volume icon."
+      exit 6
     fi
-
-    # check DMGFILE or alternative component args, set DMGFILE and check it exists
-    if [ -z "$DMGFILE" -a \( -z "$APPNAME" -o -z "$APPVER" -o -z "$ARCH" -o -z "$JVER" \) ]; then
-        echo "Must set either -i DMGFILE or all of -a APPNAME -v APPVER -j ARCH -w JVER (or with env variables)."
-        echo ""
-        usage
-        exit 7
+    USEVOLUMEICON=1
+  else
+    VOLUMEICON="${GITDIR}/${VOLUMEICONPATH}"
+    if [ ! -e "$VOLUMEICON" ]; then
+      VOLUMEICON=""
     fi
+    USEVOLUMEICON=1
+  fi
+
+  # check DMGFILE or alternative component args, set DMGFILE and check it exists
+  if [ -z "$DMGFILE" -a \( -z "$APPNAME" -o -z "$APPVER" -o -z "$ARCH" -o -z "$JVER" \) ]; then
+    echo "Must set either -i DMGFILE or all of -a APPNAME -v APPVER -j ARCH -w JVER (or with env variables)."
+    echo ""
+    usage
+    exit 7
+  fi
 fi
 
 if [ -z "$DMGFILE" ]; then
@@ -228,27 +235,42 @@ else
   DMGDIR=$(dirname "$DMGFILE")
 fi
 
+myecho() {
+  local MSG="$1"
+  local LEVEL="$2"
+  [ -z "$LEVEL" ] && LEVEL=0
+  LEVEL=$((LEVEL + 1))
+  if [ "$QUIET" -le "$LEVEL" ]; then
+    echo "$MSG"
+  fi
+}
+
 if [ "$CLEANUP" = 1 ]; then
-  echo "* -- Removing leftover temporary folders for DMG file '$DMGNAME' matching '${TEMPBASE}.*' ."
+  myecho "* -- Removing leftover temporary folders for DMG file '$DMGNAME' matching '${TEMPBASE}.*' ."
   TO_REMOVE=$( ls -1d $TEMPBASE.* 2> /dev/null )
 
   if [ -z "$TO_REMOVE" ]; then
-    echo "* Nothing to remove. Exiting."
+    myecho "* Nothing to remove. Exiting."
     exit
   fi
 
   while IFS= read -r REMOVE; do
-    echo "*    + will remove '${REMOVE}'"
+    myecho "*    + will remove '${REMOVE}'"
   done <<< "$TO_REMOVE"
 else
-  echo "* -- Signing DMG file '$DMGFILE'"
-  echo "* -- Using entitlements file '$ENTITLEMENTSFILE'"
-  if [ "$DOSIGN" != 1 ]; then
-    echo "* -- NOT actually code signing, but will still make new DMG file"
-  else
-    echo "* -- Using key '$DEVELOPERID'"
+  # Not cleaning up, tell user what we're about to do
+
+  myecho "* -- Working with DMG file '$DMGFILE'"
+
+  if [ "$SIGN" = 1 ]; then
+    myecho "* -- Signing DMG file"
+    myecho "* ---- Using entitlements file '$ENTITLEMENTSFILE'"
+    myecho "* ---- Using key '$DEVELOPERID'"
+    if [ "$DOSIGN" != 1 ]; then
+      myecho "* ---- NOT actually code signing, but will still make new DMG file"
+    fi
   fi
-  echo "* -- Working in temp dir '$TEMPDIR'"
+  myecho "* -- Working in temp dir '$TEMPDIR'"
 fi
 
 # Confirmation of what's about to happen
@@ -256,38 +278,45 @@ if [ "${YES}" != 1 ]; then
   read -r -p "* Continue? [y/N] " response
   case $(echo "${response}" | tr '[:upper:]' '[:lower:]') in
     yes|y)
-      echo "* Continuing."
+      myecho "* Continuing."
       ;;
     *)
-      echo "Aborting due to negative confirmation."
+      myecho "Aborting due to negative confirmation."
       exit
       ;;
   esac
 fi
 
+# Keep a list of attached mount points to detach when exiting.
+declare -a ATTACHED=()
 myexit() {
-  MSG=$1
-  CODE=$2
-  echo "$MSG"
+  local MSG=$1
+  local CODE=$2
+  for VOL in "${ATTACHED[@]}"; do
+    if [ ! -z "$VOL" -a -e "$VOL" ]; then
+      myecho "* Detaching '${VOL}'"
+      hdiutil detach $HDIUTILV "$VOL"
+      myecho "* There may be temporary directories (${TEMPDIR}) left.  Clean up with -C."
+    fi
+  done
+  myecho "# ${MSG}"
   exit $CODE
 }
 
-mydetachexit() {
-  MSG=$1
-  CODE=$2
-  if [ ! -z "$VOLDIR" ]; then
-    echo "* First detaching '${VOLDIR}'"
-    hdiutil detach $HDIUTILV "$VOLDIR"
-  fi
-  echo "$MSG"
-  exit $CODE
+mydetached() {
+  local D="$1"
+  local NEWATTACHED=()
+  for A in "${ATTACHED[@]}"; do
+    [ "$A" != "$D" ] && NEWATTACHED+=("$D")
+  done
+  ATTACHED=("${NEWATTACHED[@]}")
 }
 
 myparanoidrm() {
-  REMOVE="$1"
-  MSG="NOT REMOVING '${REMOVE}'"
+  local REMOVE="${1%/}"
+  local MSG="NOT REMOVING '${REMOVE}'"
   # BE PARANOID BEFORE rm -Rf
-  TEST="${REMOVE}"
+  local TEST="${REMOVE}"
   [ -z "$TEST" ] && myexit "${MSG}: Empty string." 20
   [ "$TEST" != "${TEST/../}" ] && myexit "${MSG}: Contains .. ." 21
   [ "$TEST" != "${TEST/\*/}" ] && myexit "${MSG}: Contains * ." 22
@@ -296,94 +325,114 @@ myparanoidrm() {
   [ ! -e "$REMOVE" ] && myexit "${MSG}: Doesn't exist." 25
 
   # check for mounted folders
-  REALPATH=$( realpath "$REMOVE" )
-  MOUNT=$( hdiutil info | grep "Apple_HFS" | grep "$REALPATH" 2>/dev/null | head -1 | sed -e 's/^[^[:space:]]*[[:space:]]*Apple_HFS[[:space:]]*//' )
-  if [ ! -z "$MOUNT" -a -d "$MOUNT" ]; then
-    echo "* First detaching '${MOUNT}'"
-    hdiutil detach $HDIUTILV "$MOUNT"
+  local REALPATH="$( realpath "$REMOVE" )"
+  if [ "$REALPATH" != "$REMOVE" ]; then
+    myecho "* Real path for removal is '${REALPATH}'"
   fi
+  local MOUNT=""
+  local MOUNTS=$( hdiutil info | grep "Apple_HFS" | grep "$REALPATH" 2>/dev/null | sed -e 's/^[^[:space:]]*[[:space:]]*Apple_HFS[[:space:]]*//' )
+  while IFS= read -r MOUNT; do
+    if [ ! -z "$MOUNT" -a -d "$MOUNT" ]; then
+      myecho "* First detaching '${MOUNT}'"
+      hdiutil detach $HDIUTILV "$MOUNT"
+    fi
+  done <<< "$MOUNTS"
 
   rm -Rf "${REMOVE}"
 }
 
 mycommand() {
-  declare -a ARGS=("${@}")
-  RUN=${ARGS[0]}
-  DISPLAY=""
+  local ARGS=("${@}")
+  local RUN=${ARGS[0]}
+  local DISPLAY=""
   i=1
   while [ "$i" -lt "${#ARGS[@]}" ]; do
-    A="${ARGS[i]}"
+    local A="${ARGS[i]}"
     [ "$A" != "${A/ /}" ] && A="\"${A}\""
     [ DISPLAY != "" ] && DISPLAY="${DISPLAY} "
     DISPLAY="${DISPLAY}${A}"
     i=$((i+1))
   done
-  COMMAND=("${ARGS[@]:1}")
+  local COMMAND=("${ARGS[@]:1}")
   if [ "$RUN" = 1 ]; then
-    echo "* Running: $DISPLAY"
-    "${COMMAND[@]}"
-    return $?
+    myecho "+ Running: $DISPLAY"
+    local RET=1
+    if [ "$QUIET" -le 2 ]; then
+      "${COMMAND[@]}"
+      RET=$?
+    else
+      "${COMMAND[@]}" > /dev/null
+      RET=$?
+    fi
   else
-    echo "* NOT running: $DISPLAY"
-    return 0
+    myecho "* NOT running: $DISPLAY"
+    RET=0
   fi
+  return $RET
 }
 
 if [ "$CLEANUP" = 1 ]; then
   # just cleaning up
   while IFS= read -r REMOVE; do
-    echo "* Removing '${REMOVE}'"
+    myecho "* Removing '${REMOVE}'"
     myparanoidrm "${REMOVE}"
   done <<< "$TO_REMOVE"
-  echo "* Finished cleanup. Exiting."
+  myecho "* Finished cleanup. Exiting."
   exit
 fi
 
 MOUNTROOT="${TEMPDIR}/Volume"
 mkdir -p "$MOUNTROOT"
 
-echo "* Mounting disk image '${DMGFILE}' in '${MOUNTROOT}'"
-hdiutil attach $HDIUTILV -mountroot "${MOUNTROOT}" "${DMGFILE}" || myexit "Could not mount '${DMGFILE}' in '${MOUNTROOT}'. Aborting." 10
+myecho "* Mounting disk image '${DMGFILE}' in '${MOUNTROOT}'"
+mycommand 1 hdiutil attach $HDIUTILV -mountroot "${MOUNTROOT}" "${DMGFILE}" || myexit "Could not mount '${DMGFILE}' in '${MOUNTROOT}'. Aborting." 10
 VOLDIR=$(ls -1d "${MOUNTROOT%/}"/* | head -1)
 VOLDIR="${VOLDIR%/}" # remove trailing slash
 if [ -z "$VOLDIR" ]; then
   myexit "Failed to find mounted volume in '${MOUNTROOT}'" 11
 fi
+ATTACHED+=("$VOLDIR")
 VOLNAME=$(basename "$VOLDIR")
 FOUNDAPPNAME=$(ls -1d "${VOLDIR}/"*.app | head -1)
 FOUNDAPPNAME="${FOUNDAPPNAME%/}" # remove trailing slash
 FOUNDAPPNAME="${FOUNDAPPNAME%.app}" # without the ".app"
 FOUNDAPPNAME="$(basename "$FOUNDAPPNAME")"
 
-echo "* -- Found volume name '${VOLNAME}'"
-echo "* -- Found application name '${FOUNDAPPNAME}'"
+# More info for user before confirming continuation
+myecho "* -- Found volume name '${VOLNAME}'"
+myecho "* -- Found application name '${FOUNDAPPNAME}'"
 TEMPDMGDIR="${TEMPDIR%/}/${TMPDMG}"
 if [ -e "$TEMPDMGDIR" ]; then
-  mydetachexit "Folder '${TEMPDMGDIR}' already exists. Please remove it or use -s SIGNINGDMG to set a different dir name." 12
+  myexit "Folder '${TEMPDMGDIR}' already exists. Please remove it or use -s SIGNINGDMG to set a different dir name." 12
   exit 11
 fi
 if [ "$FOUNDAPPNAME" != "$APPNAME" ]; then
   if [ -z "$APPNAME" ]; then
-    echo "* ---- Going to set APPNAME to '${FOUNDAPPNAME}'"
+    myecho "* ---- Going to use APPNAME '${FOUNDAPPNAME}'"
   else
-    echo "* ---- Going to reset APPNAME from '${APPNAME}' to '${FOUNDAPPNAME}'"
+    myecho "* ---- Going to now use APPNAME '${APPNAME}' (was set to '${FOUNDAPPNAME}')"
   fi
 fi
-echo "* ---- Going to copy volume contents to '${TEMPDMGDIR}'"
+myecho "* -- Going to copy volume contents to '${TEMPDMGDIR}'"
 if [ "$VOLUMEICON" = 1 ]; then
-  echo "* ---- Going to try and set a volume icon to '${VOLUMEICON}'"
+  myecho "* -- Going to try and set a volume icon to '${VOLUMEICON}'"
+fi
+if [ "$STAPLE" = 1 ]; then
+  myecho "* -- Stapling '${FOUNDAPPNAME}'.app"
+  if [ "$DOSTAPLE" != 1 ]; then
+    myecho "* ---- NOT actually stapling"
+  fi
 fi
 
-
-# Confirmation of reset to APPNAME
+# Confirmation of final steps
 if [ "${YES}" != 1 ]; then
   read -r -p "* Continue? [y/N] " response
   case $(echo "${response}" | tr '[:upper:]' '[:lower:]') in
     yes|y)
-      echo "* Continuing."
+      myecho "* Continuing."
       ;;
     *)
-      mydetachexit "Aborting due to negative confirmation." 0
+      myexit "Aborting due to negative confirmation." 0
       exit
       ;;
   esac
@@ -392,25 +441,18 @@ fi
 APPNAME="$FOUNDAPPNAME"
 
 # Copy volume contents
-echo "* Copying '${VOLDIR}' to '${TEMPDMGDIR}'"
-ditto "$VOLDIR" "$TEMPDMGDIR"
+myecho "* Copying '${VOLDIR}' to '${TEMPDMGDIR}'"
+mycommand 1 ditto "$VOLDIR" "$TEMPDMGDIR"
 
-echo "* Unmounting '${VOLDIR}' and removing '${TEMPDIR}/Volume'"
-hdiutil detach $HDIUTILV "$VOLDIR"
+myecho "* Unmounting '${VOLDIR}' and removing '${TEMPDIR}/Volume'"
+mycommand 1 hdiutil detach $HDIUTILV "$VOLDIR"
+mydetached "$VOLDIR"
 rmdir "${TEMPDIR}/Volume"
 
-if [ "$DOSIGN" != 1 ]; then
-  echo "* NO actual code signing due to -S flag"
-fi
-
-if [ "$DOSTAPLE" != 1 ]; then
-  echo "* NO actual stapling due to -P flag"
-fi
-
 APPPATH="${TEMPDMGDIR}/${APPNAME}.app"
 
 if [ "$SIGN" = 1 ]; then
-  echo "* Code signing in '${TEMPDMGDIR}'"
+  myecho "* Code signing in '${TEMPDMGDIR}'"
 
   FILE="${APPPATH}/Contents/Resources/app/jre/Contents/MacOS/libjli.dylib"
   mycommand $DOSIGN codesign  --remove-signature --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$FILE"
@@ -425,7 +467,7 @@ OUTPUTDIRNAME="notsigned"
 if [ "$STAPLE" = 1 ]; then
   OUTPUTDIRNAME="stapled"
 
-  echo "* Stapling '${APPNAME}.app'"
+  myecho "* Stapling '${APPNAME}.app'"
   mycommand $DOSTAPLE xcrun stapler staple "${APPPATH}"
 elif [ "$SIGN" = 1 ]; then
   OUTPUTDIRNAME="signed"
@@ -436,7 +478,7 @@ if [ ! -z "$OUTPUTDMGFILE" ]; then
 else
   SIGNEDDIR="${DMGDIR%/}/${OUTPUTDIRNAME}"
   NEWDMGFILE="${SIGNEDDIR}/${DMGNAME}"
-  echo "* Creating folder '${SIGNEDDIR}' for new DMG file '${DMGNAME}'"
+  myecho "* Creating folder '${SIGNEDDIR}' for new DMG file '${DMGNAME}'"
   mkdir -p "$SIGNEDDIR"
 fi
 
@@ -444,63 +486,65 @@ if [ -e "$NEWDMGFILE" ]; then
   if [ "$OVERWRITE" = 1 ]; then
     rm "$NEWDMGFILE"
   else
-    mydetachexit "* New DMG file already exists.  Use -O to overwrite.  Exiting." 13
+    myexit "* New DMG file already exists.  Use -O to overwrite.  Exiting." 13
   fi
 fi
 
 
 if [ "$NOVOLUMEICON" = 1 ]; then
-  echo "* NOT setting a volume icon"
+  myecho "* NOT setting a volume icon"
 
   # without volume icon
 
-  echo "* Creating new DMG file '${NEWDMGFILE}' to sign"
-  mycommand 1 hdiutil create $HDIUTILV -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$NEWDMGFILE" || mydetachexit "Could not create new DMG file '${NEWDMGFILE}'" 15
+  myecho "* Creating new DMG file '${NEWDMGFILE}' to sign"
+  mycommand 1 hdiutil create $HDIUTILV -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$NEWDMGFILE" || myexit "Could not create new DMG file '${NEWDMGFILE}'" 15
 else
   # with volume icon
 
+  GOTVOLUMEICON=0
+  # Copy a given VolumeIcon.icns (if given).  Do this before hdiutil create
+  if [ ! -z "$VOLUMEICON" -a -e "$VOLUMEICON" -a "$USEVOLUMEICON" = 1 ]; then
+    myecho "* Copying the volume icon '${VOLUMEICON}' to the temporary volume"
+    cp -f "$VOLUMEICON" "${TEMPDMGDIR}/${DEFAULTVOLUMEICONFILE}"
+  fi
+
   TEMP_RW_BASE=$(mktemp -d -p "${TEMPDIR}" -t "temp_rw")
   TEMPDMGFILE="${TEMP_RW_BASE}.dmg"
-  TEMPMOUNTDIR="${TEMP_RW_BASE}_mount"
+  TEMPMOUNTDIR="${TEMP_RW_BASE}/Volume"
 
-  echo "* Creating temporary RW DMG file '${TEMPDMGFILE}' to sign"
-  mycommand 1 hdiutil create $HDIUTILV -format UDRW -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$TEMPDMGFILE" || mydetachexit "Could not create temporary DMG file '${TEMPDMGFILE}'" 15
+  myecho "* Creating temporary RW DMG file '${TEMPDMGFILE}' to sign"
+  mycommand 1 hdiutil create $HDIUTILV -format UDRW -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$TEMPDMGFILE" || myexit "Could not create temporary DMG file '${TEMPDMGFILE}'" 15
 
-  echo "* Mounting temporary disk image '${TEMPDMGFILE}' on '${TEMPMOUNTDIR}'"
+  myecho "* Mounting temporary disk image '${TEMPDMGFILE}' on '${TEMPMOUNTDIR}'"
   mycommand 1 hdiutil attach $HDIUTILV -mountpoint "${TEMPMOUNTDIR}" "${TEMPDMGFILE}" || myexit "Could not mount '${TEMPDMGFILE}' on '${TEMPMOUNTDIR}'. Aborting." 16
-
-  VOLDIR="$TEMPMOUNTDIR" # for mydetachexit
-
-  if [ ! -z "$VOLUMEICON" -a -e "$VOLUMEICON" -a "$USEVOLUMEICON" = 1 ]; then
-    echo "* Copying the volume icon '${VOLUMEICON}' to the temporary volume"
-    cp -f "$VOLUMEICON" "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}"
-  fi
+  ATTACHED+=("$TEMPMOUNTDIR")
 
   if [ -e "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}" ]; then
-    echo "* Setting the volume icon '${DEFAULTVOLUMEICONFILE}' to the volume"
+    myecho "* Setting the volume icon '${DEFAULTVOLUMEICONFILE}'"
     mycommand 1 SetFile -c icnC "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}"
     mycommand 1 SetFile -a C "${TEMPMOUNTDIR}"
   else
-    echo "* Could not find volume icon '${VOLUMEICON}'.  Not setting a volume icon."
+    myecho "* Could not find a volume icon '${VOLUMEICON}' in '${TEMPMOUNTDIR}'.  Not setting a volume icon."
   fi
 
-  echo "* Unmounting '${TEMPMOUNTDIR}'"
+  myecho "* Unmounting '${TEMPMOUNTDIR}'"
   mycommand 1 hdiutil detach $HDIUTILV "$TEMPMOUNTDIR"
+  mydetached "$TEMPMOUNTDIR"
 
-  echo "* Converting temporary DMG file to new DMG file '${NEWDMGFILE}' to sign"
-  mycommand 1 hdiutil convert $HDIUTILV "$TEMPDMGFILE" -format UDZO -o "$NEWDMGFILE" || mydetachexit "Could not convert to new DMG file '${NEWDMGFILE}'" 17
+  myecho "* Converting temporary DMG file to new DMG file '${NEWDMGFILE}' to sign"
+  mycommand 1 hdiutil convert $HDIUTILV "$TEMPDMGFILE" -format UDZO -o "$NEWDMGFILE" || myexit "Could not convert to new DMG file '${NEWDMGFILE}'" 17
 
-  echo "* Removing temporary DMG file '${TEMPDMGFILE}'"
+  myecho "* Removing temporary DMG file '${TEMPDMGFILE}'"
   rm "$TEMPDMGFILE"
 fi
 
 if [ "$SIGN" = 1 ]; then
-  echo "* Code signing '${NEWDMGFILE}'"
+  myecho "* Code signing '${NEWDMGFILE}'"
   mycommand $DOSIGN codesign --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$NEWDMGFILE"
   mycommand $DOSIGN codesign --deep -vvvv "$NEWDMGFILE"
 fi
 
-echo "* Removing TEMPDIR '${TEMPDIR}'"
+myecho "* Removing TEMPDIR '${TEMPDIR}'"
 myparanoidrm "${TEMPDIR}"
 
 SIGNED=" Unsigned"
@@ -509,4 +553,4 @@ if [ "$SIGN" = 1 ]; then
   [ "$STAPLE" = 1 ] && AND=" and"
 fi
 [ "$STAPLED" = 1 ] && STAPLED=" stapled"
-echo "***${SIGNED}${AND}${STAPLED} DMG file at '${NEWDMGFILE}'"
+myecho "***${SIGNED}${AND}${STAPLED} DMG file at '${NEWDMGFILE}'"