bundle.sh 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. # /////////////////////////////////////////////////////////////////////////////
  2. # REFCODES.ORG
  3. # =============================================================================
  4. # This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
  5. # under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
  6. # licenses:
  7. # =============================================================================
  8. # GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
  9. # =============================================================================
  10. # Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
  11. # =============================================================================
  12. # Please contact the copyright holding author(s) of the software artifacts in
  13. # question for licensing issues not being covered by the above listed licenses,
  14. # also regarding commercial licensing models or regarding the compatibility
  15. # with other open source licenses.
  16. # /////////////////////////////////////////////////////////////////////////////
  17. #!/bin/bash
  18. # ------------------------------------------------------------------------------
  19. # INIT:
  20. # ------------------------------------------------------------------------------
  21. CURRENT_PATH="$(pwd)"
  22. SCRIPT_PATH="$(dirname $0)"
  23. cd "${SCRIPT_PATH}"
  24. SCRIPT_PATH="$(pwd)"
  25. cd "${CURRENT_PATH}"
  26. SCRIPT_DIR="${SCRIPT_PATH##*/}"
  27. SCRIPT_NAME="$(basename $0 .sh)"
  28. PARENT_PATH="$(realpath $(dirname $0)/..)"
  29. PARENT_DIR="${PARENT_PATH##*/}"
  30. MODULE_NAME="$(echo -e "${SCRIPT_DIR}" | cut -d- -f3- )"
  31. if [ -z "${MODULE_NAME}" ]; then
  32. MODULE_NAME="$(echo -e "${SCRIPT_DIR}" | cut -d- -f2- )"
  33. if [ -z "${MODULE_NAME}" ]; then
  34. MODULE_NAME="${SCRIPT_DIR}"
  35. fi
  36. fi
  37. # ------------------------------------------------------------------------------
  38. # ANSI ESCAPE CODES:
  39. # ------------------------------------------------------------------------------
  40. ESC_BOLD="\E[1m"
  41. ESC_FAINT="\E[2m"
  42. ESC_FG_RED="\E[31m"
  43. ESC_FG_GREEN="\E[32m"
  44. ESC_FG_YELLOW="\E[33m"
  45. ESC_FG_BLUE="\E[34m"
  46. ESC_FG_MAGENTA="\E[35m"
  47. ESC_FG_CYAN="\E[36m"
  48. ESC_FG_WHITE="\E[37m"
  49. ESC_RESET="\E[0m"
  50. # ------------------------------------------------------------------------------
  51. # PRINTLN:
  52. # ------------------------------------------------------------------------------
  53. function printLn {
  54. char="-"
  55. if [[ $# == 1 ]] ; then
  56. char="$1"
  57. fi
  58. echo -en "${ESC_FAINT}"
  59. printf '%*s' "${COLUMNS:-$(tput cols)}" '' | tr ' ' ${char}
  60. echo -en "${ESC_RESET}"
  61. }
  62. # ------------------------------------------------------------------------------
  63. # QUIT:
  64. # ------------------------------------------------------------------------------
  65. function quit {
  66. input=""
  67. while ([ "$input" != "q" ] && [ "$input" != "y" ]); do
  68. echo -ne "> Continue? Enter [${ESC_BOLD}q${ESC_RESET}] to quit, [${ESC_BOLD}y${ESC_RESET}] to continue: ";
  69. read input;
  70. done
  71. # printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
  72. if [ "$input" == "q" ] ; then
  73. printLn
  74. echo -e "> ${ESC_BOLD}Aborting due to user input.${ESC_RESET}"
  75. exit
  76. fi
  77. }
  78. # ------------------------------------------------------------------------------
  79. # BANNER:
  80. # ------------------------------------------------------------------------------
  81. function printBanner {
  82. figlet -w 180 "/${MODULE_NAME}:>>>${SCRIPT_NAME}..." 2> /dev/null
  83. if [ $? -ne 0 ]; then
  84. banner "${SCRIPT_NAME}..." 2> /dev/null
  85. if [ $? -ne 0 ]; then
  86. echo -e "> ${SCRIPT_NAME}:" | tr a-z A-Z
  87. fi
  88. fi
  89. }
  90. printBanner
  91. # ------------------------------------------------------------------------------
  92. # HELP:
  93. # ------------------------------------------------------------------------------
  94. function printHelp {
  95. printLn
  96. echo -e "Usage: ${ESC_BOLD}${SCRIPT_NAME}${ESC_RESET}.sh [ -h | <appName> ]"
  97. printLn
  98. echo -e "Bundles the project creating a self-contained binary carrying its own JRE."
  99. echo -e "In case there is a <${SCRIPT_NAME}.conf> file, then the APP_NAME property is used as <appName> (if not specified other on the command line)."
  100. printLn
  101. echo -e "${ESC_BOLD}-h${ESC_RESET}: Print this help"
  102. printLn
  103. }
  104. if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
  105. printHelp
  106. exit 0
  107. fi
  108. # ------------------------------------------------------------------------------
  109. # BUNDLE:
  110. # ------------------------------------------------------------------------------
  111. function bundle {
  112. os="$1"
  113. flavor="$2"
  114. bundleBasePath="$3"
  115. bundlePath="$3/$1"
  116. jreArchiveURL="$4"
  117. bundleLauncherScript="$5"
  118. jarPath="$6"
  119. targetPath="$7"
  120. bundlerCommand="$8"
  121. bundleName="$9"
  122. bundleJrePath="${bundlePath}/jre"
  123. jreArchiveName="$(basename ${jreArchiveURL})"
  124. launcherScript="${bundleLauncherScript#bundle-}"
  125. mkdir -p "${bundlePath}"
  126. if [ ! -d "${bundleJrePath}" ]; then
  127. if [ ! -f "${bundleBasePath}/${jreArchiveName}" ]; then
  128. echo -e "> Downloading ${ESC_BOLD}${1^}${ESC_RESET} JRE <${ESC_BOLD}${jreArchiveName}${ESC_RESET}>..."
  129. wget -q "${jreArchiveURL}" -P "${bundleBasePath}"
  130. if [ $? -ne 0 ]; then
  131. echo -e "> ${ESC_BOLD}Unable to download JRE <${jreArchiveName}>!${ESC_RESET}>"
  132. cd "${CURRENT_PATH}"
  133. exit 1
  134. fi
  135. fi
  136. echo -e "> Unpacking <${jreArchiveName}>..."
  137. if [[ $jreArchiveName = *.zip ]] ; then
  138. unzip -qq "${bundleBasePath}/${jreArchiveName}" -d "${bundlePath}"
  139. elif [[ $jreArchiveName = *.tar.gz ]] ; then
  140. tar -xzf "${bundleBasePath}/${jreArchiveName}" -C "${bundlePath}"
  141. else
  142. echo -e "> ${ESC_BOLD}Don't know how to extract JRE <${jreArchiveName}>!${ESC_RESET}>"
  143. cd "${CURRENT_PATH}"
  144. exit 1
  145. fi
  146. if [ $? -ne 0 ]; then
  147. echo -e "> Unable to extract JRE <${jreArchiveName}>!"
  148. cd "${CURRENT_PATH}"
  149. exit 1
  150. fi
  151. find "${bundlePath}" -maxdepth 1 -type d -name "*jre*" -exec mv {} "${bundlePath}/jre" \;
  152. if [ ! -d "${bundleJrePath}" ]; then
  153. echo -e "> ${ESC_BOLD}Unable to setup JRE <${jreArchiveName}>!${ESC_RESET}"
  154. cd "${CURRENT_PATH}"
  155. exit 1
  156. fi
  157. fi
  158. if [ ! -f "${bundlePath}/${launcherScript}" ]; then
  159. cp "${SCRIPT_PATH}/${bundleLauncherScript}" "${bundlePath}/${launcherScript}"
  160. fi
  161. echo -e "> Copying JAR <${ESC_BOLD}${jarFile}${ESC_RESET}>..."
  162. cp "${jarFile}" "${bundlePath}/application.jar"
  163. echo -e "> Creating bundle <${ESC_BOLD}${bundleName}${ESC_RESET}> at <${ESC_BOLD}${targetPath}/${bundleName}${ESC_RESET}>..."
  164. if [[ "${flavor}" == "cygwin" ]]; then
  165. ${bundlerCommand} --arch ${os}-x64 --input_dir "$(cygpath -wa "${bundlePath}")" --exec "${launcherScript}" --output "$(cygpath -wa "${targetPath}/${bundleName}")" > /dev/null
  166. else
  167. ${bundlerCommand} --arch ${os}-x64 --input_dir "${bundlePath}" --exec "${launcherScript}" --output "${targetPath}/${bundleName}" > /dev/null
  168. fi
  169. if [ $? -ne 0 ]; then
  170. echo -e "> ${ESC_BOLD}Unable to create bundle <${bundleName}>!${ESC_RESET}"
  171. cd "${CURRENT_PATH}"
  172. exit 1
  173. fi
  174. echo -e "> Bundle <${ESC_BOLD}${bundleName}${ESC_RESET}> created at <${ESC_BOLD}${targetPath}${ESC_RESET}>"
  175. printLn
  176. }
  177. # ------------------------------------------------------------------------------
  178. # MAIN:
  179. # ------------------------------------------------------------------------------
  180. cd "${SCRIPT_PATH}"
  181. TARGET_FOLDER="target"
  182. CONF_PATH="${SCRIPT_PATH}/${SCRIPT_NAME}.conf"
  183. if [ -f "${CONF_PATH}" ]; then
  184. . ${CONF_PATH}
  185. else
  186. echo -e "> ${ESC_BOLD}Cannot find configuration at <${CONF_PATH}>!${ESC_RESET}"
  187. cd "${CURRENT_PATH}"
  188. exit 1
  189. fi
  190. # As of https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux:
  191. unameOut="$(uname -s)"
  192. case "${unameOut}" in
  193. Linux*) machine="Linux"; flavor="bash"; warp="linux-x64.warp-packer";;
  194. CYGWIN*) machine="Windows"; flavor="cygwin"; warp="windows-x64.warp-packer.exe";;
  195. MINGW*) machine="Windows"; flavor="mingw"; warp="windows-x64.warp-packer.exe";;
  196. *) machine=""
  197. esac
  198. if [[ -z "${machine}" ]] ; then
  199. echo -e "> ${ESC_BOLD}Cannot determine the machine's OS, aborting!${ESC_RESET}"
  200. cd "${CURRENT_PATH}"
  201. exit 1
  202. fi
  203. if [[ -z "${machine}" ]] ; then
  204. echo -e "> ${ESC_BOLD}Cannot determine the machine's OS, aborting!${ESC_RESET}"
  205. cd "${CURRENT_PATH}"
  206. exit 1
  207. fi
  208. bundleBasePath="${SCRIPT_PATH}/.bundle"
  209. mkdir -p "${bundleBasePath}"
  210. targetPath="${SCRIPT_PATH}/${TARGET_FOLDER}"
  211. moduleName=$(xml2 < "${SCRIPT_PATH}/pom.xml" 2>/dev/null | grep "/project/artifactId=")
  212. moduleName="${moduleName#/project/artifactId=}"
  213. if [ -z "${moduleName}" ]; then
  214. moduleName=$(mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.artifactId -q -DforceStdout)
  215. fi
  216. binName="$1"
  217. if [ -z "${binName}" ]; then
  218. binName=${APP_NAME}
  219. if [ -z "${binName}" ]; then
  220. binName="$(echo -e "${moduleName}" | cut -d- -f3- )"
  221. if [ -z "${binName}" ]; then
  222. binName="$(echo -e "${moduleName}" | cut -d- -f2- )"
  223. if [ -z "${binName}" ]; then
  224. binName="${moduleName}"
  225. fi
  226. fi
  227. fi
  228. fi
  229. echo -e "> Creating self-contained <${ESC_BOLD}${binName}${ESC_RESET}> binary for <${ESC_BOLD}${machine}${ESC_RESET}> using bundler command <${ESC_BOLD}${warp}${ESC_RESET}>..."
  230. executable="${bundleBasePath}/${warp}"
  231. if [ ! -f "${executable}" ]; then
  232. echo -e "> Downloading bundler <${ESC_BOLD}${warp}${ESC_RESET}> from <${ESC_BOLD}${WARP_PACKER_URL}${ESC_RESET}>..."
  233. wget -q "${WARP_PACKER_URL}/${warp}" -P "${bundleBasePath}"
  234. if [ $? -ne 0 ]; then
  235. echo -e "> ${ESC_BOLD}Unable to download bunlder <${warp}>!${ESC_RESET}"
  236. cd "${CURRENT_PATH}"
  237. exit 1
  238. fi
  239. fi
  240. chmod ug+x "${executable}"
  241. printLn
  242. jarFile=$(find "${targetPath}" -name "${moduleName}*.jar" ! -name "*tests.jar" ! -name "*sources.jar")
  243. if [ ! -f "${jarFile}" ]; then
  244. echo -e "> ${ESC_BOLD}Unable to determine fat JAR for module <${moduleName}>!${ESC_RESET}"
  245. cd "${CURRENT_PATH}"
  246. exit 1
  247. fi
  248. bundle "windows" "${flavor}" "${bundleBasePath}" "${WINDOWS_JRE_URL}" "bundle-launcher.cmd" "${jarFile}" "${targetPath}" "${executable}" "${binName}.exe"
  249. bundle "linux" "${flavor}" "${bundleBasePath}" "${LINUX_JRE_URL}" "bundle-launcher.sh" "${jarFile}" "${targetPath}" "${executable}" "${binName}"
  250. cd "${CURRENT_PATH}"
  251. echo -e "> Done."