fix-linux-appimage.sh 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env bash
  2. # NOTE: This script is a post-build task for the Linux AppImage version of
  3. # Pulsar. It's meant to run in Pulsar's CI and almost certainly won't do
  4. # anything useful if run on your local machine.
  5. # Usage: Takes a single argument for the architecture — either `x86_64` or
  6. # `ARM_64` — and “fixes” an AppImage file as emitted by `electron-builder` so
  7. # that it points to `pulsar.sh` internally and runs _that_ when invoked instead
  8. # of the direct binary.
  9. #
  10. # This is important for a couple of reasons:
  11. #
  12. # 1. Some command-line arguments, like `--wait`, don't work properly unless
  13. # they rely on `pulsar.sh` to do some work for them.
  14. # 2. `pulsar.sh` can intercept the `-p`/`--package` switch (signaling that the
  15. # user wants to run `ppm`) and call it more quickly than Pulsar can.
  16. #
  17. # This is pretty easy to do with an AppImage, but `electron-builder` isn't
  18. # customizable enough for us to make that change without it affecting other
  19. # things. Luckily, AppImage is straightforward enough as a tool that we can
  20. # do it manually.
  21. #
  22. # The workflow here is as follows:
  23. #
  24. # * Extract the AppImage (every AppImage has the ability to do this by itself).
  25. # * Modify the `AppRun` script whose purpose is to invoke the Electron
  26. # executable; modify it to invoke our `pulsar.sh` script instead.
  27. # * Download and extract `appimagetool`.
  28. # * Use it to package everything back into an AppImage at the original location
  29. # on disk.
  30. #
  31. # If you're unsure if this modification has worked, the best way to find out is
  32. # to run
  33. #
  34. # ./Pulsar.AppImage --wait foo.txt
  35. #
  36. # and keep an eye on the terminal window after Pulsar launches. It should not
  37. # return to a new prompt until you close `foo.txt` for editing. If you don't
  38. # get a new prompt after closing `foo.txt`, or if you see logging statements in
  39. # your terminal after launch, then it's almost certain that the AppImage hasn't
  40. # been fixed.
  41. # Fail on first error. None of these steps is prone to random failure, except
  42. # _possibly_ the part where we download `appimagetool`; if that's ever the
  43. # cause of failures, we could spin that off into a separate step that uses
  44. # the `retry` action. Otherwise this script is quite straightforward.
  45. set -e
  46. # Use `appimagetool`’s names for our two processor architectures.
  47. if [[ "${1:x86_64}" == "x86_64" ]]; then
  48. APPIMAGE_ARCH="x86_64"
  49. APPIMAGETOOL_ARCH="x86_64"
  50. else
  51. APPIMAGE_ARCH="aarch64"
  52. APPIMAGETOOL_ARCH="arm_aarch64"
  53. fi
  54. echo "Architecture is: ${APPIMAGE_ARCH}"
  55. cd binaries
  56. PULSAR_APPIMAGE="$(ls *.AppImage | xargs)"
  57. echo "Existing binary is ${PULSAR_APPIMAGE}."
  58. chmod +x "${PULSAR_APPIMAGE}"
  59. echo "Extracting ${PULSAR_APPIMAGE} to Pulsar.AppDir…"
  60. "./${PULSAR_APPIMAGE}" "--appimage-extract"
  61. # Will extract to `squashfs-root`. Let's rename it just for sanity.
  62. mv "squashfs-root" "Pulsar.AppDir"
  63. # Move the `AppImage` to a new filename because we'll be replacing it soon.
  64. mv "${PULSAR_APPIMAGE}" "${PULSAR_APPIMAGE%.AppImage}.old.AppImage"
  65. # `AppRun` is the entry point of an `AppImage`. Ours is generated by
  66. # `electron-builder`. We need to customize it to launch a script rather than
  67. # our executable.
  68. # First we'll copy the existing `AppRun` file to a temporary path.
  69. cd "Pulsar.AppDir"
  70. echo "Moving AppRun to AppRun.old…"
  71. mv AppRun AppRun.old
  72. rm -f AppRun
  73. # Next we'll use `awk` to replace the reference to BIN in `AppRun` so that it
  74. # points to `pulsar.sh` rather than the `pulsar` executable.
  75. echo "Making new AppRun…"
  76. awk '{sub(/BIN=(.*?)/,"BIN=\"$APPDIR/resources/pulsar.sh\""); print}' AppRun.old > AppRun
  77. chmod a+x AppRun
  78. # For sanity's sake, show the new line so we know that this was done properly
  79. # just by inspecting the CI job output. This will help if we ever upgrade
  80. # `electron-builder` and find that this generated line has changed somehow.
  81. echo "Rewrote BIN to read:"
  82. cat AppRun | grep "BIN="
  83. # We don't need the old `AppRun` anymore.
  84. echo "Removing AppRun.old…"
  85. rm -f AppRun.old
  86. cd ../..
  87. # Now that we've made the change, we can use `appimagetool` to bundle
  88. # everything up with the original file name.
  89. echo "Downloading appimagetool…"
  90. wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${APPIMAGE_ARCH}.AppImage" -O appimagetool
  91. echo "Making appimagetool executable…"
  92. chmod +x appimagetool
  93. # Docker can't run AppImage apps natively, but we can use the
  94. # `--appimage-extract-and-run` option to extract the app to a location on disk
  95. # instead.
  96. #
  97. # It makes us set an `ARCH` environment variable — no idea why, since these are
  98. # thin binaries, but whatever.
  99. echo "Building new AppImage at: binaries/${PULSAR_APPIMAGE} with ARCH value: ${APPIMAGETOOL_ARCH}…"
  100. ARCH="${APPIMAGETOOL_ARCH}" ./appimagetool --appimage-extract-and-run "binaries/Pulsar.AppDir" "binaries/${PULSAR_APPIMAGE}"
  101. chmod a+x "binaries/${PULSAR_APPIMAGE}"
  102. echo "…done building AppImage."
  103. # Clean up! Remove the old AppImage and the temporary directory.
  104. echo "Removing temporary Pulsar.AppDir and old AppImage…"
  105. rm -rf "binaries/Pulsar.AppDir"
  106. rm -f "binaries/${PULSAR_APPIMAGE%.AppImage}.old.AppImage"
  107. echo "…done! AppImage is fixed!"