.envrc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #!/not/executable/bash
  2. # This is the .envrc for sentry, for use with direnv.
  3. # It's responsible for enforcing a standard dev environment by checking as much state as possible, and either performing
  4. # initialization (e.g. activating the venv) or giving recommendations on how to reach the desired state.
  5. # It also sets useful environment variables.
  6. # If you'd like to override or set any custom environment variables, this .envrc will read a .env file at the end.
  7. set -e
  8. # Upgrading Mac can uninstall the Command Line Tools, thus, removing our access to git
  9. # The message talks about xcrun, however, we can use the lack of git as a way to know that we need this
  10. # xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),
  11. # missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
  12. if [ "$(uname -s)" == "Darwin" ] && [ ! -f "/Library/Developer/CommandLineTools/usr/bin/git" ]; then
  13. echo -e "$(tput setaf 1)\nERROR: Complete the interactive installation (10+ mins) of the Command Line Tools.$(tput sgr0)"
  14. xcode-select --install
  15. return 1
  16. fi
  17. SENTRY_ROOT="$(
  18. cd "$(dirname "${BASH_SOURCE[0]}")"
  19. pwd -P
  20. )"
  21. source "${SENTRY_ROOT}/scripts/lib.sh"
  22. # XXX: we can't trap bash EXIT, because it'll override direnv's finalizing routines.
  23. # consequently, using "exit" anywhere will skip this notice from showing.
  24. # so need to use set -e, and return 1.
  25. trap notice ERR
  26. # This is used to group issues on Sentry.io.
  27. # If an issue does not call info() or die() it will be grouped under this
  28. error_message="Unknown issue"
  29. # This has to be the same value as what sentry-cli accepts
  30. log_level="info"
  31. help_message() {
  32. cat <<EOF
  33. For more help run: make direnv-help
  34. EOF
  35. }
  36. failure_message() {
  37. cat <<EOF
  38. ${red}${bold}direnv wasn't able to complete execution.
  39. You may have been given some recommendations in the error message.
  40. Follow them, and then you'll need to re-run direnv by running "direnv allow".${reset}
  41. EOF
  42. help_message
  43. }
  44. notice() {
  45. [ $? -eq 0 ] && return
  46. failure_message
  47. [ -z "${SENTRY_DEVENV_NO_REPORT+x}" ] && report_to_sentry
  48. }
  49. report_to_sentry() {
  50. if ! require sentry-cli; then
  51. curl -sL https://sentry.io/get-cli/ | bash
  52. fi
  53. # Report to sentry-dev-env project
  54. SENTRY_DSN="https://9bdb053cb8274ea69231834d1edeec4c@o1.ingest.sentry.io/5723503" \
  55. sentry-cli send-event -m "$error_message" --logfile "$_SENTRY_LOG_FILE" --level "$log_level"
  56. rm "$_SENTRY_LOG_FILE"
  57. }
  58. debug() {
  59. if [ "${SENTRY_DIRENV_DEBUG-}" ]; then
  60. echo -e "${@}"
  61. fi
  62. }
  63. info() {
  64. echo -e "${bold}${*}${reset}"
  65. }
  66. warn() {
  67. echo -e "${yellow}${*}${reset}" >&2
  68. log_level="warning"
  69. }
  70. die() {
  71. echo -e "${red}${bold}FATAL: ${*}${reset}" >&2
  72. # When reporting to Sentry, this will allow grouping the errors differently
  73. # NOTE: The first line of the output is used to group issues
  74. error_message=("${@}")
  75. log_level="error"
  76. return 1
  77. }
  78. prompt_python_venv_creation() {
  79. echo -e "${yellow}You are missing a Python virtualenv and we ${bold}need${reset}${yellow} to run a bootstrapping script (it can take a few minutes)"
  80. info "About to create ${venv_name}..."
  81. echo -e "\nContinue (y/N)?"
  82. read -r resp
  83. case "$resp" in
  84. y | Y) echo "Okay, let's do this." ;;
  85. *)
  86. die "Aborted!"
  87. ;;
  88. esac
  89. }
  90. show_commands_info() {
  91. echo -e "\n${red}Run the following commands to bring your environment up-to-date:"
  92. for cmd in "${commands_to_run[@]}"; do
  93. warn " ${red}$cmd"
  94. done
  95. echo ""
  96. }
  97. ### Environment ###
  98. commands_to_run=()
  99. # Always write stdout immediately. Very helpful for debugging
  100. export PYTHONUNBUFFERED=1
  101. # make sure we don't have any conflicting PYTHONPATH
  102. unset PYTHONPATH
  103. # don't check pypi for a potential new pip version; low-hanging fruit to save a bit of time
  104. export PIP_DISABLE_PIP_VERSION_CHECK=on
  105. # increase node's memory limit, required for our webpacking
  106. export NODE_OPTIONS=--max-old-space-size=4096
  107. # Frontend hot module reloader using `react-refresh`
  108. # Enable this by default for development envs (CI/deploys do not use envrc)
  109. export SENTRY_UI_HOT_RELOAD=1
  110. ### You can override the exported variables with a .env file
  111. # All exports should happen before here unless they're safeguarded (see devenv error reporting below)
  112. if [ -f "${SENTRY_ROOT}/.env" ]; then
  113. info "Loading variables from ${SENTRY_ROOT}/.env"
  114. dotenv "${SENTRY_ROOT}/.env"
  115. fi
  116. ## Notify of reporting to Sentry
  117. if [ -n "${SENTRY_DEVENV_NO_REPORT+x}" ]; then
  118. debug "No development environment errors will be reported (since you've defined SENTRY_DEVENV_NO_REPORT)."
  119. _SENTRY_LOG_FILE=''
  120. else
  121. # Since direnv traps the EXIT signal we place the temp file under /tmp for the odd time
  122. # the script will use the EXIT path
  123. _SENTRY_LOG_FILE=$(mktemp /tmp/sentry.envrc.$$.out || mktemp /tmp/sentry.envrc.XXXXXXXX.out)
  124. exec > >(tee "$_SENTRY_LOG_FILE")
  125. exec 2>&1
  126. debug "Development errors will be reported to Sentry.io. If you wish to opt-out, set SENTRY_DEVENV_NO_REPORT as an env variable."
  127. # This will allow `sentry devservices` errors to be reported
  128. export SENTRY_DEVSERVICES_DSN=https://23670f54c6254bfd9b7de106637808e9@o1.ingest.sentry.io/1492057
  129. fi
  130. # We can remove these lines in few months
  131. if [ "$SHELL" == "/bin/zsh" ]; then
  132. zshrc_path="${HOME}/.zshrc"
  133. header="# Apple M1 environment variables"
  134. if grep -qF "${header}" "${zshrc_path}"; then
  135. echo -e "\n${red}Please delete from ${zshrc_path}, the following three lines:${reset}"
  136. echo -e "${header}
  137. export CPATH=/opt/homebrew/Cellar/librdkafka/1.8.2/include
  138. export LDFLAGS=-L/opt/homebrew/Cellar/gettext/0.21/lib"
  139. echo -e "\nWe have moved exporting of these variables to the right place."
  140. return 1
  141. fi
  142. fi
  143. ### System ###
  144. for pkg in \
  145. make \
  146. docker \
  147. chromedriver \
  148. pkg-config \
  149. pyenv \
  150. openssl; do
  151. if ! require "$pkg"; then
  152. die "You seem to be missing the system dependency: ${pkg}
  153. Please install homebrew, and run brew bundle."
  154. fi
  155. done
  156. ### Git ###
  157. debug "Configuring git..."
  158. make setup-git-config
  159. ### Python ###
  160. venv_name=".venv"
  161. # Use requirements-dev.txt to decide when to cut over to `devenv` tooling.
  162. # This also provides us with a clean-cut rollback procedure.
  163. if grep -Eq "^devenv($|>)" "${SENTRY_ROOT}/requirements-dev.txt"; then
  164. # The new hotness.
  165. echo "Using devenv."
  166. export SENTRY_DEVENV_HOME="${SENTRY_DEVENV_HOME:-$XDG_DATA_HOME/sentry-devenv}"
  167. PATH_add "${SENTRY_DEVENV_HOME}/bin"
  168. if ! command -v devenv >/dev/null; then
  169. die '
  170. Please install the devenv tool:
  171. https://github.com/getsentry/devenv#install
  172. '
  173. fi
  174. devenv sync
  175. else
  176. # Old and busted. (but currently working)
  177. if [ ! -f "${venv_name}/bin/activate" ]; then
  178. prompt_python_venv_creation
  179. # This is time consuming but it has to be done
  180. source "${SENTRY_ROOT}/scripts/bootstrap-py3-venv"
  181. fi
  182. fi
  183. # The user might be cd'ing into sentry with another non-direnv managed
  184. # (in that it would be automatically deactivated) virtualenv active.
  185. deactivate 2>/dev/null || true
  186. # shellcheck disable=SC1091
  187. source "${venv_name}/bin/activate"
  188. # XXX: ideally, direnv is able to export PS1 as modified by sourcing venvs
  189. # but we'd have to patch direnv, and ".venv" isn't descriptive anyways
  190. unset PS1
  191. debug "Ensuring proper virtualenv..."
  192. "${SENTRY_ROOT}/scripts/ensure-venv.sh"
  193. if ! require sentry; then
  194. warn "Your virtualenv is activated, but sentry doesn't seem to be installed."
  195. commands_to_run+=("make install-py-dev")
  196. fi
  197. ### pre-commit ###
  198. debug "Checking pre-commit..."
  199. if ! require pre-commit; then
  200. warn "Looks like you don't have pre-commit installed."
  201. commands_to_run+=("make setup-git")
  202. fi
  203. python3 -m tools.docker_memory_check
  204. ### Node ###
  205. debug "Checking node..."
  206. if ! require node; then
  207. die "You don't seem to have node installed. Install volta (a node version manager): https://develop.sentry.dev/environment/#javascript"
  208. fi
  209. make node-version-check
  210. if [ ! -x "node_modules/.bin/webpack" ]; then
  211. warn "You don't seem to have yarn packages installed."
  212. commands_to_run+=("make install-js-dev")
  213. fi
  214. PATH_add node_modules/.bin
  215. # These are commands that can take a significant amount of time
  216. if [ ${#commands_to_run[@]} -ne 0 ]; then
  217. show_commands_info
  218. fi
  219. if [ "${log_level}" != "info" ]; then
  220. help_message
  221. warn "\nPartial success. The virtualenv is active, however, you're not fully up-to-date (see messages above)."
  222. else
  223. echo "${green}${bold}SUCCESS!${reset}"
  224. fi
  225. # Since we can't use an EXIT routine we need to guarantee we delete the file here
  226. [ -z "$_SENTRY_LOG_FILE" ] || rm -f "$_SENTRY_LOG_FILE"