lib.sh 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #!/bin/bash
  2. # Module containing code shared across various shell scripts
  3. # Execute functions from this module via the script do.sh
  4. # shellcheck disable=SC2034 # Unused variables
  5. # This block is a safe-guard since in CI calling tput will fail and abort scripts
  6. if [ -z "${CI+x}" ]; then
  7. bold="$(tput bold)"
  8. red="$(tput setaf 1)"
  9. green="$(tput setaf 2)"
  10. yellow="$(tput setaf 3)"
  11. reset="$(tput sgr0)"
  12. fi
  13. # NOTE: This file is sourced in CI across different repos (e.g. snuba),
  14. # so renaming this file or any functions can break CI!
  15. # Check if a command is available
  16. require() {
  17. command -v "$1" >/dev/null 2>&1
  18. }
  19. configure-sentry-cli() {
  20. if [ -n "${SENTRY_DSN+x}" ] && [ -z "${SENTRY_DEVENV_NO_REPORT+x}" ]; then
  21. if ! require sentry-cli; then
  22. curl -sL https://sentry.io/get-cli/ | bash
  23. fi
  24. eval "$(sentry-cli bash-hook)"
  25. fi
  26. }
  27. query-mac() {
  28. [[ $(uname -s) = 'Darwin' ]]
  29. }
  30. query-big-sur() {
  31. if require sw_vers && sw_vers -productVersion | grep -E "11\." >/dev/null; then
  32. return 0
  33. fi
  34. return 1
  35. }
  36. query-apple-m1() {
  37. query-mac && [[ $(uname -m) = 'arm64' ]]
  38. }
  39. get-pyenv-version() {
  40. local PYENV_VERSION
  41. PYENV_VERSION=3.6.13
  42. if query-apple-m1; then
  43. PYENV_VERSION=3.8.11
  44. fi
  45. echo "${PYENV_VERSION}"
  46. }
  47. query-valid-python-version() {
  48. python_version=$(python3 -V 2>&1 | awk '{print $2}')
  49. if [ "${python_version}" == 3.6.13 ] || [ "${python_version}" == 3.8.11 ]; then
  50. return 0
  51. else
  52. return 1
  53. fi
  54. }
  55. sudo-askpass() {
  56. if [ -z "${sudo-askpass-x}" ]; then
  57. sudo --askpass "$@"
  58. else
  59. sudo "$@"
  60. fi
  61. }
  62. # After using homebrew to install docker, we need to do some magic to remove the need to interact with the GUI
  63. # See: https://github.com/docker/for-mac/issues/2359#issuecomment-607154849 for why we need to do things below
  64. init-docker() {
  65. # Need to start docker if it was freshly installed or updated
  66. # You will know that Docker is ready for devservices when the icon on the menu bar stops flashing
  67. if query-mac && ! require docker && [ -d "/Applications/Docker.app" ]; then
  68. echo "Making some changes to complete Docker initialization"
  69. # allow the app to run without confirmation
  70. xattr -d -r com.apple.quarantine /Applications/Docker.app
  71. # preemptively do docker.app's setup to avoid any gui prompts
  72. # This path is not available for brand new MacBooks
  73. sudo-askpass /bin/mkdir -p /Library/PrivilegedHelperTools
  74. sudo-askpass /bin/chmod 754 /Library/PrivilegedHelperTools
  75. sudo-askpass /bin/cp /Applications/Docker.app/Contents/Library/LaunchServices/com.docker.vmnetd /Library/PrivilegedHelperTools/
  76. sudo-askpass /bin/chmod 544 /Library/PrivilegedHelperTools/com.docker.vmnetd
  77. # This file used to be generated as part of brew's installation
  78. if [ -f /Applications/Docker.app/Contents/Resources/com.docker.vmnetd.plist ]; then
  79. sudo-askpass /bin/cp /Applications/Docker.app/Contents/Resources/com.docker.vmnetd.plist /Library/LaunchDaemons/
  80. else
  81. sudo-askpass /bin/cp .github/workflows/files/com.docker.vmnetd.plist /Library/LaunchDaemons/
  82. fi
  83. sudo-askpass /bin/chmod 644 /Library/LaunchDaemons/com.docker.vmnetd.plist
  84. sudo-askpass /bin/launchctl load /Library/LaunchDaemons/com.docker.vmnetd.plist
  85. fi
  86. start-docker
  87. }
  88. # This is mainly to be used by CI
  89. # We need this for Mac since the executable docker won't work properly
  90. # until the app is opened once
  91. start-docker() {
  92. if query-mac && ! docker system info &>/dev/null; then
  93. echo "About to open Docker.app"
  94. # At a later stage in the script, we're going to execute
  95. # ensure_docker_server which waits for it to be ready
  96. if ! open -g -a Docker.app; then
  97. # If the step above fails, at least we can get some debugging information to determine why
  98. sudo-askpass ls -l /Library/PrivilegedHelperTools/com.docker.vmnetd
  99. ls -l /Library/LaunchDaemons/
  100. cat /Library/LaunchDaemons/com.docker.vmnetd.plist
  101. ls -l /Applications/Docker.app
  102. fi
  103. fi
  104. }
  105. upgrade-pip() {
  106. pip install --upgrade "pip==21.1.2" "wheel==0.36.2"
  107. }
  108. install-py-dev() {
  109. upgrade-pip
  110. # It places us within top src dir to be at the same path as setup.py
  111. # This helps when getsentry calls into this script
  112. cd "${HERE}/.." || exit
  113. echo "--> Installing Sentry (for development)"
  114. # SENTRY_LIGHT_BUILD=1 disables webpacking during setup.py.
  115. # Webpacked assets are only necessary for devserver (which does it lazily anyways)
  116. # and acceptance tests, which webpack automatically if run.
  117. SENTRY_LIGHT_BUILD=1 pip install -e '.[dev]'
  118. }
  119. setup-git-config() {
  120. git config --local branch.autosetuprebase always
  121. git config --local core.ignorecase false
  122. git config --local blame.ignoreRevsFile .git-blame-ignore-revs
  123. }
  124. setup-git() {
  125. setup-git-config
  126. echo "--> Installing git hooks"
  127. mkdir -p .git/hooks && cd .git/hooks && ln -sf ../../config/hooks/* ./ && cd - || exit
  128. # shellcheck disable=SC2016
  129. python3 -c '' || (
  130. echo 'Please run `make setup-pyenv` to install the required Python 3 version.'
  131. exit 1
  132. )
  133. pip install -r requirements-pre-commit.txt
  134. pre-commit install --install-hooks
  135. echo ""
  136. }
  137. node-version-check() {
  138. # Checks to see if node's version matches the one specified in package.json for Volta.
  139. node -pe "process.exit(Number(!(process.version == 'v' + require('./package.json').volta.node )))" ||
  140. (
  141. echo 'Unexpected node version. Recommended to use https://github.com/volta-cli/volta'
  142. exit 1
  143. )
  144. }
  145. install-js-dev() {
  146. node-version-check
  147. echo "--> Installing Yarn packages (for development)"
  148. # Use NODE_ENV=development so that yarn installs both dependencies + devDependencies
  149. NODE_ENV=development yarn install --frozen-lockfile
  150. # A common problem is with node packages not existing in `node_modules` even though `yarn install`
  151. # says everything is up to date. Even though `yarn install` is run already, it doesn't take into
  152. # account the state of the current filesystem (it only checks .yarn-integrity).
  153. # Add an additional check against `node_modules`
  154. yarn check --verify-tree || yarn install --check-files
  155. }
  156. develop() {
  157. setup-git
  158. install-js-dev
  159. install-py-dev
  160. }
  161. init-config() {
  162. sentry init --dev
  163. }
  164. run-dependent-services() {
  165. sentry devservices up
  166. }
  167. create-db() {
  168. # shellcheck disable=SC2155
  169. local CREATEDB=$(command -v createdb 2>/dev/null)
  170. if [[ -z "$CREATEDB" ]]; then
  171. CREATEDB="docker exec sentry_postgres createdb"
  172. fi
  173. echo "--> Creating 'sentry' database"
  174. ${CREATEDB} -h 127.0.0.1 -U postgres -E utf-8 sentry || true
  175. }
  176. apply-migrations() {
  177. echo "--> Applying migrations"
  178. sentry upgrade --noinput
  179. }
  180. create-user() {
  181. if [[ -n "${GITHUB_ACTIONS+x}" ]]; then
  182. sentry createuser --superuser --email foo@tbd.com --no-password
  183. else
  184. sentry createuser --superuser
  185. fi
  186. }
  187. build-platform-assets() {
  188. echo "--> Building platform assets"
  189. echo "from sentry.utils.integrationdocs import sync_docs; sync_docs(quiet=True)" | sentry exec
  190. }
  191. bootstrap() {
  192. develop
  193. init-config
  194. run-dependent-services
  195. create-db
  196. apply-migrations
  197. create-user
  198. build-platform-assets
  199. }
  200. clean() {
  201. echo "--> Cleaning static cache"
  202. rm -rf dist/* src/sentry/static/sentry/dist/*
  203. echo "--> Cleaning integration docs cache"
  204. rm -rf src/sentry/integration-docs
  205. echo "--> Cleaning pyc files"
  206. find . -name "*.pyc" -delete
  207. echo "--> Cleaning python build artifacts"
  208. rm -rf build/ dist/ src/sentry/assets.json
  209. echo ""
  210. }
  211. drop-db() {
  212. # shellcheck disable=SC2155
  213. local DROPDB=$(command -v dropdb 2>/dev/null)
  214. if [[ -z "$DROPDB" ]]; then
  215. DROPDB="docker exec sentry_postgres dropdb"
  216. fi
  217. echo "--> Dropping existing 'sentry' database"
  218. ${DROPDB} -h 127.0.0.1 -U postgres sentry || true
  219. }
  220. reset-db() {
  221. drop-db
  222. create-db
  223. apply-migrations
  224. }
  225. direnv-help() {
  226. cat >&2 <<EOF
  227. If you're a Sentry employee and you're stuck or have questions, ask in #discuss-dev-tooling.
  228. If you're not, please file an issue under https://github.com/getsentry/sentry/issues/new/choose and mention @getsentry/owners-sentry-dev
  229. You can configure the behaviour of direnv by adding the following variables to a .env file:
  230. - SENTRY_DIRENV_DEBUG=1: This will allow printing debug messages
  231. - SENTRY_DEVENV_NO_REPORT=1: Do not report development environment errors to Sentry.io
  232. EOF
  233. }