JAL-4428 More coherent command line options and better 'running command' stdout manag...
authorBen Soares <b.soares@dundee.ac.uk>
Sun, 18 Aug 2024 23:50:05 +0000 (00:50 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Sun, 18 Aug 2024 23:50:05 +0000 (00:50 +0100)
utils/osx_signing/sign_and_staple_dmg.sh

index 5609d5e..283e9fb 100755 (executable)
@@ -10,15 +10,18 @@ TESTARCH="|x64|aarch64|"
 YES=0
 CLEANUP=0
 GITENTITLEMENTSPATH="utils/osx_signing/entitlements.txt"
-NOCODESIGNING=0
+SIGN=0
+DOSIGN=1
 STAPLE=0
-NOVOLUMEICON=0
+DOSTAPLE=1
+VOLUMEICON=""
 VOLUMEICONPATH="utils/channels/release/images/jalview-VolumeIcon.icns"
+NOVOLUMEICON=0
 DEFAULTVOLUMEICONFILE=".VolumeIcon.icns"
 HDIUTILV="-quiet"
 
 usage() {
-  echo "Usage: $( basename $0 ) [-h] [[-g gitdir] | [-e entfile]] [-d devid] [[-a appname] [-v appver ] [-j arch] [-w jver] | [-i dmgfile]] [-O] [-o outputdmg] [-t tmpdir] [-s signingdmg] [-S] [-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]"
   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."
@@ -34,25 +37,26 @@ usage() {
   echo "  -v appver      Assume application version appver (also uses APPVER env variable. No default)."
   echo "  -j arch        Use the JVM architecture arch (also uses ARCH env variable. No default, should be one of${TESTARCH//|/ })."
   echo "  -w jver        Assume java version jver (also uses JVER env variable. Defaults to '1.8')."
-  echo "  -i dmgfile     Sign DMGFILE (also uses DMGFILE env variable. Defaults to a combination of GITDIR, APPNAME, APPVER, ARCH and JVER)."
+  echo "  -i dmgfile     The existing DMG file to sign/staple (also uses DMGFILE env variable. Defaults to a combination of GITDIR, APPNAME, APPVER, ARCH and JVER)."
   echo "  -t tmpdir      Use temp directory tmpdir (default '/tmp')."
-  echo "  -s signingdmg  Use signingdmg as the temporary signing folder name in the temporary directory (default 'signingDMG')."
-  echo "  -S             Don't perform any code signing (default is to codesign)."
-  echo "  -p             Run stapling on the APP bundle (default is to NOT staple)."
+  echo "  -s             Run codesigning on the executables and created DMG file."
+  echo "  -S             Don't actually perform any code signing (the command that would be run is output to stdout)."
+  echo "  -p             Run stapling on the APP bundle."
+  echo "  -P             Don't actually run stapling on the APP bundle (the command that would be run is output to stdout)."
   echo "  -z icnsfile    Use icnsfile as the volume icon file (defaults to using existing '$DEFAULTVOLUMEICONFILE' file or 'GITDIR/${VOLUMEICONPATH}'."
-  echo "  -Z             Don't set the volume icon, even if it already exists."
-  echo "  -O             Overwrite the output DMG file if it already exists."
+  echo "  -Z             Don't set the volume icon, even if it already exists in the existing DMG volume (default is to set volume icons if one is there/given)."
   echo "  -o outputdmg   Output DMG file (defaults to existing dmgfile in a 'signed' sub-directory)."
+  echo "  -O             Overwrite the output DMG file if it already exists."
   echo "  -y             Assume 'yes' to all confirmation requests."
-  echo "  -C             Cleanup temporary folders for the given dmgfile (Prevents 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 "  -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 "  "
   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 -t -z utils/channels/develop/images/jalview_develop-VolumeIcon.icns"
-  echo "  will use entitlements.txt from the gitdir (-g), and output a signed and stapled (-t) DMG file in build/install4j/11/stapled with a volume icon for Jalview Develop (-z)."
+  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:s:Spz:ZyCOo:v" opt; do
+while getopts "hg:e:d:a:v:j:w:i:t:sSpPz:Zo:OyCV" opt; do
   case ${opt} in
     h)
       usage
@@ -83,37 +87,40 @@ while getopts "hg:e:d:a:v:j:w:i:t:s:Spz:ZyCOo:v" opt; do
     i)
       DMGFILE="${OPTARG}"
       ;;
-    o)
-      OUTPUTDMGFILE="${OPTARG}"
-      ;;
-    O)
-      OVERWRITE=1
-      ;;
     t)
       TMP="${OPTARG}"
       ;;
     s)
-      TMPDMG="${OPTARG}"
+      SIGN=1
       ;;
     S)
-      NOCODESIGNING=1
+      DOSIGN=0
       ;;
     p)
       STAPLE=1
       ;;
+    P)
+      DOSTAPLE=0
+      ;;
     z)
       VOLUMEICON="${OPTARG}"
       ;;
     Z)
       NOVOLUMEICON=1
       ;;
+    o)
+      OUTPUTDMGFILE="${OPTARG}"
+      ;;
+    O)
+      OVERWRITE=1
+      ;;
     y)
       YES=1
       ;;
     C)
       CLEANUP=1
       ;;
-    v)
+    V)
       HDIUTILV=""
       ;;
     *)
@@ -236,7 +243,7 @@ if [ "$CLEANUP" = 1 ]; then
 else
   echo "* -- Signing DMG file '$DMGFILE'"
   echo "* -- Using entitlements file '$ENTITLEMENTSFILE'"
-  if [ "$NOCODESIGNING" = 1 ]; then
+  if [ "$DOSIGN" != 1 ]; then
     echo "* -- NOT actually code signing, but will still make new DMG file"
   else
     echo "* -- Using key '$DEVELOPERID'"
@@ -299,6 +306,29 @@ myparanoidrm() {
   rm -Rf "${REMOVE}"
 }
 
+mycommand() {
+  declare -a ARGS=("${@}")
+  RUN=${ARGS[0]}
+  DISPLAY=""
+  i=1
+  while [ "$i" -lt "${#ARGS[@]}" ]; do
+    A="${ARGS[i]}"
+    [ "$A" != "${A/ /}" ] && A="\"${A}\""
+    [ DISPLAY != "" ] && DISPLAY="${DISPLAY} "
+    DISPLAY="${DISPLAY}${A}"
+    i=$((i+1))
+  done
+  COMMAND=("${ARGS[@]:1}")
+  if [ "$RUN" = 1 ]; then
+    echo "* Running: $DISPLAY"
+    "${COMMAND[@]}"
+    return $?
+  else
+    echo "* NOT running: $DISPLAY"
+    return 0
+  fi
+}
+
 if [ "$CLEANUP" = 1 ]; then
   # just cleaning up
   while IFS= read -r REMOVE; do
@@ -340,7 +370,7 @@ if [ "$FOUNDAPPNAME" != "$APPNAME" ]; then
   fi
 fi
 echo "* ---- Going to copy volume contents to '${TEMPDMGDIR}'"
-if [ "$NOVOLUMEICON" != 1 ]; then
+if [ "$VOLUMEICON" = 1 ]; then
   echo "* ---- Going to try and set a volume icon to '${VOLUMEICON}'"
 fi
 
@@ -369,51 +399,42 @@ echo "* Unmounting '${VOLDIR}' and removing '${TEMPDIR}/Volume'"
 hdiutil detach $HDIUTILV "$VOLDIR"
 rmdir "${TEMPDIR}/Volume"
 
-TRUE=""
-RUNNING="RUNNING:"
-if [ "$NOCODESIGNING" = 1 ]; then
+if [ "$DOSIGN" != 1 ]; then
   echo "* NO actual code signing due to -S flag"
-  TRUE="true"
-  RUNNING="NOT RUNNING:"
 fi
 
+if [ "$DOSTAPLE" != 1 ]; then
+  echo "* NO actual stapling due to -P flag"
+fi
 
-echo "* Code signing in '${TEMPDMGDIR}'"
-
-
-FILE="${TEMPDMGDIR}/${APPNAME}.app/Contents/Resources/app/jre/Contents/MacOS/libjli.dylib"
-echo "* + '$FILE'"
+APPPATH="${TEMPDMGDIR}/${APPNAME}.app"
 
-echo "${RUNNING} codesign  --remove-signature --force --deep -vvvv -s \"$DEVELOPERID\" --options runtime --entitlements \"$ENTITLEMENTSFILE\" \"$FILE\""
-$TRUE codesign  --remove-signature --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$FILE"
+if [ "$SIGN" = 1 ]; then
+  echo "* Code signing in '${TEMPDMGDIR}'"
 
-echo "${RUNNING} codesign  --verify --deep -v \"$FILE\""
-$TRUE codesign  --verify --deep -v "$FILE"
+  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"
+  mycommand $DOSIGN codesign  --verify --deep -v "$FILE"
 
-APPPATH="${TEMPDMGDIR}/${APPNAME}.app"
-FILE="${APPPATH}/Contents/MacOS/JavaApplicationStub"
-echo "* + '$FILE'"
-
-echo "${RUNNING} codesign  --remove-signature --force --deep -vvvv -s \"$DEVELOPERID\" --options runtime --entitlements \"$ENTITLEMENTSFILE\" \"$FILE\""
-$TRUE codesign  --remove-signature --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$FILE"
+  FILE="${APPPATH}/Contents/MacOS/JavaApplicationStub"
+  mycommand $DOSIGN codesign  --remove-signature --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$FILE"
+fi
 
+OUTPUTDIRNAME="notsigned"
 # stapling
-SIGNEDDIRNAME="signed"
 if [ "$STAPLE" = 1 ]; then
-
-  SIGNEDDIRNAME="stapled"
+  OUTPUTDIRNAME="stapled"
 
   echo "* Stapling '${APPNAME}.app'"
-
-  echo "${RUNNING} xcrun stapler staple \"${APPPATH}\""
-  $TRUE xcrun stapler staple "${APPPATH}"
-
+  mycommand $DOSTAPLE xcrun stapler staple "${APPPATH}"
+elif [ "$SIGN" = 1 ]; then
+  OUTPUTDIRNAME="signed"
 fi
 
 if [ ! -z "$OUTPUTDMGFILE" ]; then
   NEWDMGFILE="$OUTPUTDMGFILE"
 else
-  SIGNEDDIR="${DMGDIR%/}/${SIGNEDDIRNAME}"
+  SIGNEDDIR="${DMGDIR%/}/${OUTPUTDIRNAME}"
   NEWDMGFILE="${SIGNEDDIR}/${DMGNAME}"
   echo "* Creating folder '${SIGNEDDIR}' for new DMG file '${DMGNAME}'"
   mkdir -p "$SIGNEDDIR"
@@ -429,89 +450,63 @@ fi
 
 
 if [ "$NOVOLUMEICON" = 1 ]; then
-
   echo "* NOT setting a volume icon"
 
   # without volume icon
 
   echo "* Creating new DMG file '${NEWDMGFILE}' to sign"
-
-  echo "hdiutil create $HDIUTILV -megabytes 260 -srcfolder \"$TEMPDMGDIR\" -volname \"$VOLNAME\" \"$NEWDMGFILE\""
-  hdiutil create $HDIUTILV -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$NEWDMGFILE" || mydetachexit "Could not create new DMG file '${NEWDMGFILE}'" 15
-
+  mycommand 1 hdiutil create $HDIUTILV -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$NEWDMGFILE" || mydetachexit "Could not create new DMG file '${NEWDMGFILE}'" 15
 else
-
   # with volume icon
 
   TEMP_RW_BASE=$(mktemp -d -p "${TEMPDIR}" -t "temp_rw")
   TEMPDMGFILE="${TEMP_RW_BASE}.dmg"
   TEMPMOUNTDIR="${TEMP_RW_BASE}_mount"
 
-
   echo "* Creating temporary RW DMG file '${TEMPDMGFILE}' to sign"
-
-  echo "hdiutil create $HDIUTILV -format UDRW -megabytes 260 -srcfolder \"$TEMPDMGDIR\" -volname \"$VOLNAME\" \"$TEMPDMGFILE\""
-  hdiutil create $HDIUTILV -format UDRW -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$TEMPDMGFILE" || mydetachexit "Could not create temporary DMG file '${TEMPDMGFILE}'" 15
-
+  mycommand 1 hdiutil create $HDIUTILV -format UDRW -megabytes 260 -srcfolder "$TEMPDMGDIR" -volname "$VOLNAME" "$TEMPDMGFILE" || mydetachexit "Could not create temporary DMG file '${TEMPDMGFILE}'" 15
 
   echo "* Mounting temporary disk image '${TEMPDMGFILE}' on '${TEMPMOUNTDIR}'"
-
-  echo "hdiutil attach $HDIUTILV -mountpoint \"${TEMPMOUNTDIR}\" \"${TEMPDMGFILE}\""
-  hdiutil attach $HDIUTILV -mountpoint "${TEMPMOUNTDIR}" "${TEMPDMGFILE}" || myexit "Could not mount '${TEMPDMGFILE}' on '${TEMPMOUNTDIR}'. Aborting." 16
+  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
-  if [ -e "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}" ]; then
 
+  if [ -e "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}" ]; then
     echo "* Setting the volume icon '${DEFAULTVOLUMEICONFILE}' to the volume"
-
-    echo "SetFile -c icnC \"${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}\""
-    SetFile -c icnC "${TEMPMOUNTDIR}/${DEFAULTVOLUMEICONFILE}"
-
-    echo "SetFile -a C \"${TEMPMOUNTDIR}\""
-    SetFile -a C "${TEMPMOUNTDIR}"
-
+    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."
   fi
 
-
   echo "* Unmounting '${TEMPMOUNTDIR}'"
-
-  echo "hdiutil detach $HDIUTILV \"$TEMPMOUNTDIR\""
-  hdiutil detach $HDIUTILV "$TEMPMOUNTDIR"
-
+  mycommand 1 hdiutil detach $HDIUTILV "$TEMPMOUNTDIR"
 
   echo "* Converting temporary DMG file to new DMG file '${NEWDMGFILE}' to sign"
-
-  echo "hdiutil convert $HDIUTILV \"$TEMPDMGFILE\" -format UDZO -o \"$NEWDMGFILE\""
-  hdiutil convert $HDIUTILV "$TEMPDMGFILE" -format UDZO -o "$NEWDMGFILE" || mydetachexit "Could not convert to new DMG file '${NEWDMGFILE}'" 17
-
+  mycommand 1 hdiutil convert $HDIUTILV "$TEMPDMGFILE" -format UDZO -o "$NEWDMGFILE" || mydetachexit "Could not convert to new DMG file '${NEWDMGFILE}'" 17
 
   echo "* Removing temporary DMG file '${TEMPDMGFILE}'"
   rm "$TEMPDMGFILE"
-
 fi
 
-
-echo "* Code signing '${NEWDMGFILE}'"
-
-echo "${RUNNING} codesign --force --deep -vvvv -s \"$DEVELOPERID\" --options runtime --entitlements \"$ENTITLEMENTSFILE\" \"$NEWDMGFILE\""
-$TRUE codesign --force --deep -vvvv -s "$DEVELOPERID" --options runtime --entitlements "$ENTITLEMENTSFILE" "$NEWDMGFILE"
-
-echo "${RUNNING} codesign --deep -vvvv \"$NEWDMGFILE\""
-$TRUE codesign --deep -vvvv "$NEWDMGFILE"
-
+if [ "$SIGN" = 1 ]; then
+  echo "* 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}'"
 myparanoidrm "${TEMPDIR}"
 
-[ "$STAPLED" = 1 ] && ANDSTAPLED=" and stapled"
-echo "*** Signed${ANDSTAPLED} DMG file at '${NEWDMGFILE}'"
+SIGNED=" Unsigned"
+if [ "$SIGN" = 1 ]; then
+  SIGNED=" Signed"
+  [ "$STAPLE" = 1 ] && AND=" and"
+fi
+[ "$STAPLED" = 1 ] && STAPLED=" stapled"
+echo "***${SIGNED}${AND}${STAPLED} DMG file at '${NEWDMGFILE}'"