trunk 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. #!/bin/bash
  2. ###############################################################################
  3. # #
  4. # Setup #
  5. # #
  6. ###############################################################################
  7. set -euo pipefail
  8. readonly TRUNK_LAUNCHER_VERSION="1.3.4" # warning: this line is auto-updated
  9. readonly SUCCESS_MARK="\033[0;32m✔\033[0m"
  10. readonly FAIL_MARK="\033[0;31m✘\033[0m"
  11. readonly PROGRESS_MARKS=("⡿" "⢿" "⣻" "⣽" "⣾" "⣷" "⣯" "⣟")
  12. # This is how mktemp(1) decides where to create stuff in tmpfs.
  13. readonly TMPDIR="${TMPDIR:-/tmp}"
  14. TRUNK_FLAKY_TESTS_INVOCATION=false
  15. if [[ ${1:-} =~ ^(flakytests|ft)$ ]]; then
  16. TRUNK_FLAKY_TESTS_INVOCATION=true
  17. fi
  18. readonly TRUNK_FLAKY_TESTS_INVOCATION
  19. KERNEL=$(uname | tr "[:upper:]" "[:lower:]")
  20. if [[ ${KERNEL} == mingw64* || ${KERNEL} == msys* ]]; then
  21. KERNEL="mingw"
  22. fi
  23. readonly KERNEL
  24. MACHINE=$(uname -m)
  25. if [[ $MACHINE == "aarch64" ]]; then
  26. MACHINE="arm64";
  27. fi
  28. readonly MACHINE
  29. PLATFORM="${KERNEL}-${MACHINE}"
  30. PLATFORM_UNDERSCORE="${KERNEL}_${MACHINE}"
  31. readonly PLATFORM_UNDERSCORE
  32. # https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_(Control_Sequence_Introducer)_sequences
  33. # [nF is "cursor previous line" and moves to the beginning of the nth previous line
  34. # [0K is "erase display" and clears from the cursor to the end of the screen
  35. readonly CLEAR_LAST_MSG="\033[1F\033[0K"
  36. if [[ ! -z ${CI:-} && "${CI}" = true && -z ${TRUNK_LAUNCHER_QUIET:-} ]]; then
  37. TRUNK_LAUNCHER_QUIET=1
  38. else
  39. TRUNK_LAUNCHER_QUIET=${TRUNK_LAUNCHER_QUIET:-${TRUNK_QUIET:-false}}
  40. fi
  41. readonly TRUNK_LAUNCHER_DEBUG
  42. if [[ ${TRUNK_LAUNCHER_QUIET} != false ]]; then
  43. exec 3>&1 4>&2 &>/dev/null
  44. fi
  45. TRUNK_CACHE="${TRUNK_CACHE:-}"
  46. if [[ -n ${TRUNK_CACHE} ]]; then
  47. :
  48. elif [[ -n ${XDG_CACHE_HOME:-} ]]; then
  49. TRUNK_CACHE="${XDG_CACHE_HOME}/trunk"
  50. else
  51. TRUNK_CACHE="${HOME}/.cache/trunk"
  52. fi
  53. readonly TRUNK_CACHE
  54. CLI_DIR="${TRUNK_CACHE}/cli"
  55. if [[ ${TRUNK_FLAKY_TESTS_INVOCATION} == true ]]; then
  56. CLI_DIR="${TRUNK_CACHE}/flaky-tests-cli"
  57. fi
  58. readonly CLI_DIR
  59. mkdir -p "${CLI_DIR}"
  60. # platform check
  61. readonly MINIMUM_MACOS_VERSION="10.15"
  62. check_darwin_version() {
  63. local osx_version
  64. osx_version="$(sw_vers -productVersion)"
  65. # trunk-ignore-begin(shellcheck/SC2312): the == will fail if anything inside the $() fails
  66. if [[ "$(printf "%s\n%s\n" "${MINIMUM_MACOS_VERSION}" "${osx_version}" |
  67. sort --version-sort |
  68. head -n 1)" == "${MINIMUM_MACOS_VERSION}"* ]]; then
  69. return
  70. fi
  71. # trunk-ignore-end(shellcheck/SC2312)
  72. echo -e "${FAIL_MARK} Trunk requires at least MacOS ${MINIMUM_MACOS_VERSION}" \
  73. "(yours is ${osx_version}). See https://docs.trunk.io for more info."
  74. exit 1
  75. }
  76. check_os() {
  77. if [[ ${PLATFORM} == "darwin-x86_64" || ${PLATFORM} == "darwin-arm64" ]]; then
  78. check_darwin_version
  79. elif [[ ${PLATFORM} == "linux-x86_64" || ${PLATFORM} == "linux-arm64" || ${PLATFORM} == "windows-x86_64" || ${PLATFORM} == "mingw-x86_64" ]]; then
  80. :
  81. else
  82. echo -e "${FAIL_MARK} Trunk is only supported on Linux (x64_64, arm64), MacOS (x86_64, arm64), and Windows (x86_64)." \
  83. "See https://docs.trunk.io for more info."
  84. exit 1
  85. fi
  86. }
  87. check_os_flaky_tests() {
  88. if [[ ${KERNEL} == "darwin" ]]; then
  89. if [[ ${MACHINE} == "arm64" ]]; then
  90. FLAKY_TESTS_PLATFORM="aarch64-apple-darwin"
  91. elif [[ ${MACHINE} == "x86_64" ]]; then
  92. FLAKY_TESTS_PLATFORM="x86_64-apple-darwin"
  93. fi
  94. elif [[ ${KERNEL} == "linux" ]]; then
  95. if [[ ${MACHINE} == "arm64" ]]; then
  96. FLAKY_TESTS_PLATFORM="aarch64-unknown-linux"
  97. elif [[ ${MACHINE} == "x86_64" ]]; then
  98. FLAKY_TESTS_PLATFORM="x86_64-unknown-linux"
  99. fi
  100. fi
  101. if [[ -z ${FLAKY_TESTS_PLATFORM} ]]; then
  102. echo -e "${FAIL_MARK} Trunk Flaky Tests CLI is only supported on Linux (x86_64, arm64) and MacOS (x86_64, arm64)." \
  103. "See https://docs.trunk.io for more info."
  104. exit 1
  105. fi
  106. PLATFORM=${FLAKY_TESTS_PLATFORM}
  107. }
  108. if [[ ${TRUNK_FLAKY_TESTS_INVOCATION} == true ]]; then
  109. check_os_flaky_tests
  110. else
  111. check_os
  112. fi
  113. readonly PLATFORM
  114. TRUNK_TMPDIR="${TMPDIR}/trunk-$(
  115. set -e
  116. id -u
  117. )/launcher_logs"
  118. readonly TRUNK_TMPDIR
  119. mkdir -p "${TRUNK_TMPDIR}"
  120. # For the `mv $TOOL_TMPDIR/trunk $TOOL_DIR` to be atomic (i.e. just inode renames), the source and destination filesystems need to be the same
  121. TOOL_TMPDIR=$(mktemp -d "${CLI_DIR}/tmp.XXXXXXXXXX")
  122. readonly TOOL_TMPDIR
  123. cleanup() {
  124. rm -rf "${TOOL_TMPDIR}"
  125. if [[ $1 == "0" ]]; then
  126. rm -rf "${TRUNK_TMPDIR}"
  127. fi
  128. }
  129. trap 'cleanup $?' EXIT
  130. # e.g. 2022-02-16-20-40-31-0800
  131. dt_str() { date +"%Y-%m-%d-%H-%M-%S%z"; }
  132. LAUNCHER_TMPDIR="${TOOL_TMPDIR}/launcher"
  133. readonly LAUNCHER_TMPDIR
  134. mkdir -p "${LAUNCHER_TMPDIR}"
  135. if [[ -n ${TRUNK_LAUNCHER_DEBUG:-} ]]; then
  136. set -x
  137. fi
  138. # launcher awk
  139. #
  140. # BEGIN{ORS="";}
  141. # use "" as the output record separator
  142. # ORS defaults to "\n" for bwk, which results in
  143. # $(printf "foo bar" | awk '{print $2}') == "bar\n"
  144. #
  145. # {gsub(/\r/, "", $0)}
  146. # for every input record (i.e. line), the regex "\r" should be replaced with ""
  147. # This is necessary to handle CRLF files in a portable fashion.
  148. #
  149. # Some StackOverflow answers suggest using RS="\r?\n" to handle CRLF files (RS is the record
  150. # separator, i.e. the line delimiter); unfortunately, original-awk only allows single-character
  151. # values for RS (see https://www.gnu.org/software/gawk/manual/gawk.html#awk-split-records).
  152. lawk() {
  153. awk 'BEGIN{ORS="";}{gsub(/\r/, "", $0)}'"${1}" "${@:2}"
  154. }
  155. awk_test() {
  156. # trunk-ignore-begin(shellcheck/SC2310,shellcheck/SC2312)
  157. # SC2310 and SC2312 are about set -e not propagating to the $(); if that happens, the string
  158. # comparison will fail and we'll claim the user's awk doesn't work
  159. if [[ $(
  160. set -e
  161. printf 'k1: v1\n \tk2: v2\r\n' | lawk '/[ \t]+k2:/{print $2}'
  162. ) == 'v2' &&
  163. $(
  164. set -e
  165. printf 'k1: v1\r\n\t k2: v2\r\n' | lawk '/[ \t]+k2:/{print $2}'
  166. ) == 'v2' ]]; then
  167. return
  168. fi
  169. # trunk-ignore-end(shellcheck/SC2310,shellcheck/SC2312)
  170. echo -e "${FAIL_MARK} Trunk does not work with your awk;" \
  171. "please report this at https://slack.trunk.io."
  172. echo -e "Your version of awk is:"
  173. awk --version || awk -Wversion
  174. exit 1
  175. }
  176. awk_test
  177. readonly CURL_FLAGS="${CURL_FLAGS:- -vvv --max-time 120 --retry 3 --fail --location}"
  178. readonly WGET_FLAGS="${WGET_FLAGS:- --verbose --tries=3 --limit-rate=10M}"
  179. TMP_DOWNLOAD_LOG="${TRUNK_TMPDIR}/download-$(
  180. set -e
  181. dt_str
  182. ).log"
  183. readonly TMP_DOWNLOAD_LOG
  184. # Detect whether we should use wget or curl.
  185. if command -v wget &>/dev/null; then
  186. download_cmd() {
  187. local url="${1}"
  188. local output_to="${2}"
  189. # trunk-ignore-begin(shellcheck/SC2312): we don't care if wget --version errors
  190. cat >>"${TMP_DOWNLOAD_LOG}" <<EOF
  191. Using wget to download '${url}' to '${output_to}'
  192. Is Trunk up?: https://status.trunk.io
  193. WGET_FLAGS: ${WGET_FLAGS}
  194. wget --version:
  195. $(wget --version 2>&1)
  196. EOF
  197. # trunk-ignore-end(shellcheck/SC2312)
  198. # Support BusyBox wget
  199. if wget --help 2>&1 | grep BusyBox; then
  200. wget "${url}" -O "${output_to}" 2>>"${TMP_DOWNLOAD_LOG}" &
  201. else
  202. # trunk-ignore(shellcheck/SC2086): we deliberately don't quote WGET_FLAGS
  203. wget ${WGET_FLAGS} "${url}" --output-document "${output_to}" 2>>"${TMP_DOWNLOAD_LOG}" &
  204. fi
  205. }
  206. elif command -v curl &>/dev/null; then
  207. download_cmd() {
  208. local url="${1}"
  209. local output_to="${2}"
  210. # trunk-ignore-begin(shellcheck/SC2312): we don't care if curl --version errors
  211. cat >>"${TMP_DOWNLOAD_LOG}" <<EOF
  212. Using curl to download '${url}' to '${output_to}'
  213. Is Trunk up?: https://status.trunk.io
  214. CURL_FLAGS: ${CURL_FLAGS}
  215. curl --version:
  216. $(curl --version)
  217. EOF
  218. # trunk-ignore-end(shellcheck/SC2312)
  219. # trunk-ignore(shellcheck/SC2086): we deliberately don't quote CURL_FLAGS
  220. curl ${CURL_FLAGS} "${url}" --output "${output_to}" 2>>"${TMP_DOWNLOAD_LOG}" &
  221. }
  222. else
  223. download_cmd() {
  224. echo -e "${FAIL_MARK} Cannot download '${url}'; please install curl or wget."
  225. exit 1
  226. }
  227. fi
  228. download_url() {
  229. local url="${1}"
  230. local output_to="${2}"
  231. local progress_message="${3:-}"
  232. if [[ -n ${progress_message} ]]; then
  233. echo -e "${PROGRESS_MARKS[0]} ${progress_message}..."
  234. fi
  235. download_cmd "${url}" "${output_to}"
  236. local download_pid="$!"
  237. local i_prog=0
  238. while [[ -d "/proc/${download_pid}" && -n ${progress_message} ]]; do
  239. echo -e "${CLEAR_LAST_MSG}${PROGRESS_MARKS[${i_prog}]} ${progress_message}..."
  240. sleep 0.2
  241. i_prog=$(((i_prog + 1) % ${#PROGRESS_MARKS[@]}))
  242. done
  243. local download_log
  244. if ! wait "${download_pid}"; then
  245. download_log="${TRUNK_TMPDIR}/launcher-download-$(
  246. set -e
  247. dt_str
  248. ).log"
  249. mv "${TMP_DOWNLOAD_LOG}" "${download_log}"
  250. echo -e "${CLEAR_LAST_MSG}${FAIL_MARK} ${progress_message}... FAILED (see ${download_log})"
  251. echo -e "Please check your connection and try again." \
  252. "If you continue to see this error message," \
  253. "consider reporting it to us at https://slack.trunk.io."
  254. exit 1
  255. fi
  256. if [[ -n ${progress_message} ]]; then
  257. echo -e "${CLEAR_LAST_MSG}${SUCCESS_MARK} ${progress_message}... done"
  258. fi
  259. }
  260. # sha256sum is in coreutils, so we prefer that over shasum, which is installed with perl
  261. if command -v sha256sum &>/dev/null; then
  262. :
  263. elif command -v shasum &>/dev/null; then
  264. sha256sum() { shasum -a 256 "$@"; }
  265. else
  266. sha256sum() {
  267. echo -e "${FAIL_MARK} Cannot compute sha256; please install sha256sum or shasum"
  268. exit 1
  269. }
  270. fi
  271. ###############################################################################
  272. # #
  273. # CLI resolution functions #
  274. # #
  275. ###############################################################################
  276. trunk_yaml_abspath() {
  277. local repo_head
  278. local cwd
  279. if repo_head=$(git rev-parse --show-toplevel 2>/dev/null); then
  280. echo "${repo_head}/.trunk/trunk.yaml"
  281. elif [[ -f .trunk/trunk.yaml ]]; then
  282. cwd="$(pwd)"
  283. echo "${cwd}/.trunk/trunk.yaml"
  284. else
  285. echo ""
  286. fi
  287. }
  288. read_cli_version_from() {
  289. local config_abspath="${1}"
  290. local cli_version
  291. cli_version="$(
  292. set -e
  293. lawk '/[ \t]+version:/{print $2; exit;}' "${config_abspath}"
  294. )"
  295. if [[ -z ${cli_version} ]]; then
  296. echo -e "${FAIL_MARK} Invalid .trunk/trunk.yaml, no cli version found." \
  297. "See https://docs.trunk.io for more info." >&2
  298. exit 1
  299. fi
  300. echo "${cli_version}"
  301. }
  302. download_cli() {
  303. local dl_version="${1}"
  304. local expected_sha256="${2}"
  305. local actual_sha256
  306. readonly TMP_INSTALL_DIR="${LAUNCHER_TMPDIR}/install"
  307. mkdir -p "${TMP_INSTALL_DIR}"
  308. TRUNK_NEW_URL_VERSION=0.10.2-beta.1
  309. if sort --help 2>&1 | grep BusyBox; then
  310. readonly URL="https://trunk.io/releases/${dl_version}/trunk-${dl_version}-${PLATFORM}.tar.gz"
  311. else
  312. if [[ "$(printf "%s\n%s\n" "${TRUNK_NEW_URL_VERSION}" "${dl_version}" |
  313. sort --version-sort |
  314. head -n 1 || true)" == "${TRUNK_NEW_URL_VERSION}"* ]]; then
  315. readonly URL="https://trunk.io/releases/${dl_version}/trunk-${dl_version}-${PLATFORM}.tar.gz"
  316. else
  317. readonly URL="https://trunk.io/releases/trunk-${dl_version}.${KERNEL}.tar.gz"
  318. fi
  319. fi
  320. readonly DOWNLOAD_TAR_GZ="${TMP_INSTALL_DIR}/download-${dl_version}.tar.gz"
  321. download_url "${URL}" "${DOWNLOAD_TAR_GZ}" "Downloading Trunk ${dl_version}"
  322. if [[ -n ${expected_sha256:-} ]]; then
  323. local verifying_text="Verifying Trunk sha256..."
  324. echo -e "${PROGRESS_MARKS[0]} ${verifying_text}"
  325. actual_sha256="$(
  326. set -e
  327. sha256sum "${DOWNLOAD_TAR_GZ}" | lawk '{print $1}'
  328. )"
  329. if [[ ${actual_sha256} != "${expected_sha256}" ]]; then
  330. echo -e "${CLEAR_LAST_MSG}${FAIL_MARK} ${verifying_text} FAILED"
  331. echo "Expected sha256: ${expected_sha256}"
  332. echo " Actual sha256: ${actual_sha256}"
  333. exit 1
  334. fi
  335. echo -e "${CLEAR_LAST_MSG}${SUCCESS_MARK} ${verifying_text} done"
  336. fi
  337. local unpacking_text="Unpacking Trunk..."
  338. echo -e "${PROGRESS_MARKS[0]} ${unpacking_text}"
  339. tar --strip-components=1 -C "${TMP_INSTALL_DIR}" -xf "${DOWNLOAD_TAR_GZ}"
  340. echo -e "${CLEAR_LAST_MSG}${SUCCESS_MARK} ${unpacking_text} done"
  341. rm -f "${DOWNLOAD_TAR_GZ}"
  342. mkdir -p "${TOOL_DIR}"
  343. readonly OLD_TOOL_DIR="${CLI_DIR}/${version}"
  344. # Create a backwards compatability link for old versions of trunk that want to write their
  345. # crashpad_handlers to that dir.
  346. if [[ ! -e ${OLD_TOOL_DIR} ]]; then
  347. ln -sf "${TOOL_PART}" "${OLD_TOOL_DIR}"
  348. fi
  349. mv -n "${TMP_INSTALL_DIR}/trunk" "${TOOL_DIR}/" || true
  350. rm -rf "${TMP_INSTALL_DIR}"
  351. }
  352. download_flaky_tests_latest_cli() {
  353. readonly TMP_INSTALL_DIR="${LAUNCHER_TMPDIR}/install"
  354. mkdir -p "${TMP_INSTALL_DIR}"
  355. readonly URL="https://github.com/trunk-io/analytics-cli/releases/latest/download/trunk-analytics-cli-${PLATFORM}.tar.gz"
  356. readonly DOWNLOAD_TAR_GZ="${TMP_INSTALL_DIR}/download-latest.tar.gz"
  357. download_url "${URL}" "${DOWNLOAD_TAR_GZ}" "Downloading latest Trunk Flaky Tests CLI"
  358. local unpacking_text="Unpacking Trunk Flaky Tests CLI..."
  359. echo -e "${PROGRESS_MARKS[0]} ${unpacking_text}"
  360. tar -C "${TMP_INSTALL_DIR}" -xf "${DOWNLOAD_TAR_GZ}"
  361. echo -e "${CLEAR_LAST_MSG}${SUCCESS_MARK} ${unpacking_text} done"
  362. rm -f "${DOWNLOAD_TAR_GZ}"
  363. mkdir -p "${TOOL_DIR}"
  364. mv "${TMP_INSTALL_DIR}/trunk-analytics-cli" "${TOOL_DIR}/" || true
  365. rm -rf "${TMP_INSTALL_DIR}"
  366. echo # add newline between launcher and CLI output
  367. }
  368. check_flaky_tests_cli_version() {
  369. local flaky_tests_latest_file="${LAUNCHER_TMPDIR}/flaky-test-latest"
  370. download_cmd "https://api.github.com/repos/trunk-io/analytics-cli/releases/latest" "${flaky_tests_latest_file}"
  371. local download_pid="$!"
  372. { sleep 3; kill "$download_pid"; } &
  373. local timeout_pid="$!"
  374. if ! wait "${download_pid}" 2>/dev/null; then
  375. return 0
  376. fi
  377. kill "$timeout_pid"
  378. wait "$timeout_pid" 2>/dev/null || true
  379. local flaky_tests_latest_version=$(sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' "${flaky_tests_latest_file}")
  380. local flaky_tests_installed_version=$(${TOOL_DIR}/trunk-analytics-cli --version | lawk '{print $NF}')
  381. if [[ "$flaky_tests_installed_version" != "$flaky_tests_latest_version" ]]; then
  382. echo -e "\033[1;33mWARNING\033[0m: You are not using the latest version of Trunk Flaky Tests CLI (current=$flaky_tests_installed_version, latest=$flaky_tests_latest_version)."
  383. echo -e "The product is in constant development. To get the latest version, run: \033[1mtrunk flakytests --upgrade\033[0m\n"
  384. fi
  385. rm -f "${flaky_tests_latest_file}"
  386. }
  387. ###############################################################################
  388. # #
  389. # CLI resolution #
  390. # #
  391. ###############################################################################
  392. CONFIG_ABSPATH="$(
  393. set -e
  394. trunk_yaml_abspath
  395. )"
  396. readonly CONFIG_ABSPATH
  397. version="${TRUNK_CLI_VERSION:-}"
  398. if [[ $TRUNK_FLAKY_TESTS_INVOCATION == true || -n ${version:-} ]]; then
  399. :
  400. elif [[ -f ${CONFIG_ABSPATH} ]]; then
  401. version="$(
  402. set -e
  403. read_cli_version_from "${CONFIG_ABSPATH}"
  404. )"
  405. version_sha256="$(
  406. set -e
  407. lawk "/${PLATFORM_UNDERSCORE}:/"'{print $2}' "${CONFIG_ABSPATH}"
  408. )"
  409. else
  410. readonly LATEST_FILE="${LAUNCHER_TMPDIR}/latest"
  411. download_url "https://trunk.io/releases/latest" "${LATEST_FILE}"
  412. version=$(
  413. set -e
  414. lawk '/version:/{print $2}' "${LATEST_FILE}"
  415. )
  416. version_sha256=$(
  417. set -e
  418. lawk "/${PLATFORM_UNDERSCORE}:/"'{print $2}' "${LATEST_FILE}"
  419. )
  420. fi
  421. TOOL_PART="${version}-${PLATFORM}"
  422. if [[ $TRUNK_FLAKY_TESTS_INVOCATION == true ]]; then
  423. TOOL_PART=$PLATFORM
  424. fi
  425. readonly TOOL_PART
  426. readonly TOOL_DIR="${CLI_DIR}/${TOOL_PART}"
  427. if [[ $TRUNK_FLAKY_TESTS_INVOCATION == false && ! -e ${TOOL_DIR}/trunk ]]; then
  428. download_cli "${version}" "${version_sha256:-}"
  429. echo # add newline between launcher and CLI output
  430. elif [[ $TRUNK_FLAKY_TESTS_INVOCATION == true ]]; then
  431. for arg in "$@"
  432. do
  433. shift
  434. if [[ "$arg" = "--upgrade" ]]; then
  435. download_flaky_tests_latest_cli
  436. else
  437. set -- "$@" "$arg"
  438. fi
  439. done
  440. if [[ ! -e ${TOOL_DIR}/trunk-analytics-cli ]]; then
  441. download_flaky_tests_latest_cli
  442. fi
  443. check_flaky_tests_cli_version
  444. fi
  445. if [[ ${TRUNK_LAUNCHER_QUIET} != false ]]; then
  446. exec 1>&3 3>&- 2>&4 4>&-
  447. fi
  448. ###############################################################################
  449. # #
  450. # CLI invocation #
  451. # #
  452. ###############################################################################
  453. if [[ -n ${LATEST_FILE:-} ]]; then
  454. mv -n "${LATEST_FILE}" "${TOOL_DIR}/version" >/dev/null 2>&1 || true
  455. fi
  456. # NOTE: exec will overwrite the process image, so trap will not catch the exit signal.
  457. # Therefore, run cleanup manually here.
  458. cleanup 0
  459. if [[ $TRUNK_FLAKY_TESTS_INVOCATION == true ]]; then
  460. exec \
  461. env TRUNK_LAUNCHER_VERSION="${TRUNK_LAUNCHER_VERSION}" \
  462. env TRUNK_LAUNCHER_PATH="${BASH_SOURCE[0]}" \
  463. "${TOOL_DIR}/trunk-analytics-cli" "${@:2}"
  464. else
  465. exec \
  466. env TRUNK_LAUNCHER_VERSION="${TRUNK_LAUNCHER_VERSION}" \
  467. env TRUNK_LAUNCHER_PATH="${BASH_SOURCE[0]}" \
  468. "${TOOL_DIR}/trunk" "$@"
  469. fi