install.sh 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. #!/bin/sh
  2. set -e
  3. usage() {
  4. this=$1
  5. cat <<EOF
  6. $this: download latest archive file for AppFlowy-IO/AppFlowy
  7. Usage: $this [-b] bindir [-d] [tag]
  8. -b sets bindir or installation directory, Defaults to /opt
  9. -d turns on debug logging
  10. [tag] is a tag from
  11. https://github.com/AppFlowy-IO/AppFlowy/releases
  12. If tag is missing, then the latest will be used.
  13. EOF
  14. exit 2
  15. }
  16. parse_args() {
  17. #BINDIR is /opt unless set be ENV
  18. # over-ridden by flag below
  19. BINDIR=${BINDIR:-/opt}
  20. while getopts "b:dh?" arg; do
  21. case "$arg" in
  22. b) BINDIR="$OPTARG" ;;
  23. d) log_set_priority 10 ;;
  24. h | \?) usage "$0" ;;
  25. esac
  26. done
  27. shift $((OPTIND - 1))
  28. TAG=$1
  29. }
  30. # this function wraps all the destructive operations
  31. # if a curl|bash cuts off the end of the script due to
  32. # network, either nothing will happen or will syntax error
  33. # out preventing half-done work
  34. execute() {
  35. tmpdir=$(mktmpdir)
  36. log_debug "downloading files into ${tmpdir}"
  37. http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
  38. srcdir="${tmpdir}"
  39. (cd "${tmpdir}" && tar -xzvf "${TARBALL}")
  40. install -d "${BINDIR}"
  41. sudo mv "${srcdir}/${PROJECT_NAME}" /opt
  42. log_info "installed ${BINDIR}/${PROJECT_NAME}"
  43. (cd "/opt/${PROJECT_NAME}" && ./AppFlowy)
  44. }
  45. is_supported_platform() {
  46. platform=$1
  47. found=1
  48. case "$platform" in
  49. windows/amd64) found=0 ;;
  50. darwin/amd64) found=0 ;;
  51. darwin/arm64) found=0 ;;
  52. linux/amd64) found=0 ;;
  53. linux/arm64) found=0 ;;
  54. linux/armv6) found=0 ;;
  55. linux/armv7) found=0 ;;
  56. esac
  57. return $found
  58. }
  59. check_platform() {
  60. if is_supported_platform "$PLATFORM"; then
  61. # optional logging goes here
  62. true
  63. else
  64. log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
  65. exit 1
  66. fi
  67. }
  68. tag_to_version() {
  69. if [ -z "${TAG}" ]; then
  70. log_info "checking GitHub for latest tag"
  71. else
  72. log_info "checking GitHub for tag '${TAG}'"
  73. fi
  74. REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
  75. if test -z "$REALTAG"; then
  76. log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
  77. exit 1
  78. fi
  79. # if version starts with 'v', remove it
  80. TAG="$REALTAG"
  81. VERSION=${TAG#v}
  82. }
  83. adjust_format() {
  84. # change format (tar.gz or zip) based on ARCH
  85. true
  86. }
  87. adjust_os() {
  88. # adjust archive name based on OS
  89. true
  90. }
  91. adjust_arch() {
  92. # adjust archive name based on ARCH
  93. true
  94. }
  95. cat /dev/null <<EOF
  96. ------------------------------------------------------------------------
  97. https://github.com/client9/shlib - portable posix shell functions
  98. Public domain - http://unlicense.org
  99. https://github.com/client9/shlib/blob/master/LICENSE.md
  100. but credit (and pull requests) appreciated.
  101. ------------------------------------------------------------------------
  102. EOF
  103. is_command() {
  104. command -v "$1" >/dev/null
  105. }
  106. echoerr() {
  107. echo "$@" 1>&2
  108. }
  109. log_prefix() {
  110. echo "$0"
  111. }
  112. _logp=6
  113. log_set_priority() {
  114. _logp="$1"
  115. }
  116. log_priority() {
  117. if test -z "$1"; then
  118. echo "$_logp"
  119. return
  120. fi
  121. [ "$1" -le "$_logp" ]
  122. }
  123. log_tag() {
  124. case $1 in
  125. 0) echo "emerg" ;;
  126. 1) echo "alert" ;;
  127. 2) echo "crit" ;;
  128. 3) echo "err" ;;
  129. 4) echo "warning" ;;
  130. 5) echo "notice" ;;
  131. 6) echo "info" ;;
  132. 7) echo "debug" ;;
  133. *) echo "$1" ;;
  134. esac
  135. }
  136. log_debug() {
  137. log_priority 7 || return 0
  138. echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
  139. }
  140. log_info() {
  141. log_priority 6 || return 0
  142. echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
  143. }
  144. log_err() {
  145. log_priority 3 || return 0
  146. echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
  147. }
  148. log_crit() {
  149. log_priority 2 || return 0
  150. echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
  151. }
  152. uname_os() {
  153. os=$(uname -s | tr '[:upper:]' '[:lower:]')
  154. case "$os" in
  155. msys_nt) os="windows" ;;
  156. esac
  157. echo "$os"
  158. }
  159. uname_arch() {
  160. arch=$(uname -m)
  161. case $arch in
  162. x86_64) arch="amd64" ;;
  163. x86) arch="386" ;;
  164. i686) arch="386" ;;
  165. i386) arch="386" ;;
  166. aarch64) arch="arm64" ;;
  167. armv5*) arch="armv5" ;;
  168. armv6*) arch="armv6" ;;
  169. armv7*) arch="armv7" ;;
  170. esac
  171. echo ${arch}
  172. }
  173. uname_os_check() {
  174. os=$(uname_os)
  175. case "$os" in
  176. darwin) return 0 ;;
  177. dragonfly) return 0 ;;
  178. freebsd) return 0 ;;
  179. linux) return 0 ;;
  180. android) return 0 ;;
  181. nacl) return 0 ;;
  182. netbsd) return 0 ;;
  183. openbsd) return 0 ;;
  184. plan9) return 0 ;;
  185. solaris) return 0 ;;
  186. windows) return 0 ;;
  187. esac
  188. log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
  189. return 1
  190. }
  191. uname_arch_check() {
  192. arch=$(uname_arch)
  193. case "$arch" in
  194. 386) return 0 ;;
  195. amd64) return 0 ;;
  196. arm64) return 0 ;;
  197. armv5) return 0 ;;
  198. armv6) return 0 ;;
  199. armv7) return 0 ;;
  200. ppc64) return 0 ;;
  201. ppc64le) return 0 ;;
  202. mips) return 0 ;;
  203. mipsle) return 0 ;;
  204. mips64) return 0 ;;
  205. mips64le) return 0 ;;
  206. s390x) return 0 ;;
  207. amd64p32) return 0 ;;
  208. esac
  209. log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
  210. return 1
  211. }
  212. untar() {
  213. tarball=$1
  214. case "${tarball}" in
  215. *.tar.gz | *.tgz) tar -xzf "${tarball}" ;;
  216. *.tar) tar -xf "${tarball}" ;;
  217. *.zip) unzip "${tarball}" ;;
  218. *)
  219. log_err "untar unknown archive format for ${tarball}"
  220. return 1
  221. ;;
  222. esac
  223. }
  224. mktmpdir() {
  225. test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
  226. mkdir -p "${TMPDIR}"
  227. echo "${TMPDIR}"
  228. }
  229. http_download_curl() {
  230. local_file=$1
  231. source_url=$2
  232. header=$3
  233. if [ -z "$header" ]; then
  234. code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
  235. else
  236. code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
  237. fi
  238. if [ "$code" != "200" ]; then
  239. log_debug "http_download_curl received HTTP status $code"
  240. return 1
  241. fi
  242. return 0
  243. }
  244. http_download_wget() {
  245. local_file=$1
  246. source_url=$2
  247. header=$3
  248. if [ -z "$header" ]; then
  249. wget -q -O "$local_file" "$source_url"
  250. else
  251. wget -q --header "$header" -O "$local_file" "$source_url"
  252. fi
  253. }
  254. http_download() {
  255. log_debug "http_download $2"
  256. if is_command curl; then
  257. http_download_curl "$@"
  258. return
  259. elif is_command wget; then
  260. http_download_wget "$@"
  261. return
  262. fi
  263. log_crit "http_download unable to find wget or curl"
  264. return 1
  265. }
  266. http_copy() {
  267. tmp=$(mktemp)
  268. http_download "${tmp}" "$1" "$2" || return 1
  269. body=$(cat "$tmp")
  270. rm -f "${tmp}"
  271. echo "$body"
  272. }
  273. github_release() {
  274. owner_repo=$1
  275. version=$2
  276. test -z "$version" && version="latest"
  277. giturl="https://github.com/${owner_repo}/releases/${version}"
  278. json=$(http_copy "$giturl" "Accept:application/json")
  279. test -z "$json" && return 1
  280. version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
  281. test -z "$version" && return 1
  282. echo "$version"
  283. }
  284. hash_sha256() {
  285. TARGET=${1:-/dev/stdin}
  286. if is_command gsha256sum; then
  287. hash=$(gsha256sum "$TARGET") || return 1
  288. echo "$hash" | cut -d ' ' -f 1
  289. elif is_command sha256sum; then
  290. hash=$(sha256sum "$TARGET") || return 1
  291. echo "$hash" | cut -d ' ' -f 1
  292. elif is_command shasum; then
  293. hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
  294. echo "$hash" | cut -d ' ' -f 1
  295. elif is_command openssl; then
  296. hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
  297. echo "$hash" | cut -d ' ' -f a
  298. else
  299. log_crit "hash_sha256 unable to find command to compute sha-256 hash"
  300. return 1
  301. fi
  302. }
  303. hash_sha256_verify() {
  304. TARGET=$1
  305. checksums=$2
  306. if [ -z "$checksums" ]; then
  307. log_err "hash_sha256_verify checksum file not specified in arg2"
  308. return 1
  309. fi
  310. BASENAME=${TARGET##*/}
  311. want=$(grep -i "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
  312. if [ -z "$want" ]; then
  313. log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
  314. return 1
  315. fi
  316. got=$(hash_sha256 "$TARGET")
  317. if [ "$want" != "$got" ]; then
  318. log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
  319. return 1
  320. fi
  321. }
  322. cat /dev/null <<EOF
  323. ------------------------------------------------------------------------
  324. End of functions from https://github.com/client9/shlib
  325. ------------------------------------------------------------------------
  326. EOF
  327. PROJECT_NAME="AppFlowy"
  328. SHORTHAND_PROJECT_NAME="AppFlowy"
  329. OWNER=AppFlowy-IO
  330. REPO="AppFlowy"
  331. BINARY=AppFlowy
  332. FORMAT=tar.gz
  333. OS=$(uname_os)
  334. ARCH=$(uname_arch)
  335. LIBC=$(ldd --version | head -n 1)
  336. PREFIX="$OWNER/$REPO"
  337. # use in logging routines
  338. log_prefix() {
  339. echo "$PREFIX"
  340. }
  341. PLATFORM="${OS}/${ARCH}"
  342. GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
  343. uname_os_check "$OS"
  344. uname_arch_check "$ARCH"
  345. parse_args "$@"
  346. check_platform
  347. tag_to_version
  348. adjust_format
  349. adjust_os
  350. adjust_arch
  351. log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
  352. NAME="${SHORTHAND_PROJECT_NAME}_v${VERSION}_${OS}_${ARCH}"
  353. TARBALL=${NAME}.${FORMAT}
  354. if [ "$OS" = "linux" ]; then
  355. OS="unknown-linux-gnu"
  356. ARCH="x86_64"
  357. DISTRO='ubuntu-20.04'
  358. TARBALL="${SHORTHAND_PROJECT_NAME}_${ARCH}-${OS}_${DISTRO}."tar.gz""
  359. fi
  360. TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
  361. execute # line: 38