diff --git a/nix/dev-shell.nix b/nix/dev-shell.nix index be0ec784e..a7cb3fb6f 100644 --- a/nix/dev-shell.nix +++ b/nix/dev-shell.nix @@ -1,153 +1,155 @@ { mkShell , stdenv , lib , amqp-cpp , awscli2 , arcanist , aws-sdk-cpp , better-prompt , boost , bundler , c-ares_cmake-config , cmake , cmake-format , cocoapods , corrosion , darwin , double-conversion , folly , fmt , glog , grpc , gtest , libiconv , libuv , localstack , mariadb , mariadb-up , nodejs-16_x-openssl_1_1 , olm , openjdk11 , openssl , pkg-config , protobuf_3_15_cmake , python3 , rabbitmq-server , redis , redis-up , rustup , shellcheck , sqlite , terraform , watchman , rustfmt , yarn }: mkShell { # programs which are meant to be executed should go here nativeBuildInputs = [ # generic development or tools arcanist awscli2 shellcheck terraform # android openjdk11 # node development mariadb nodejs-16_x-openssl_1_1 yarn watchman # react native python3 redis # native dependencies # C/CXX toolchains are already brought in with mkShell # Identity Service rustfmt rustup # Tunnelbroker + CMake amqp-cpp c-ares_cmake-config cmake cmake-format # linting libuv # Localstack is currently broken by partial update # See https://github.com/NixOS/nixpkgs/pull/197572 #localstack pkg-config protobuf_3_15_cmake grpc rabbitmq-server # runtime service ] ++ lib.optionals stdenv.isDarwin [ cocoapods # needed for ios bundler ]; # include any libraries buildInputs buildInputs = [ # protobuf exposes both a library and a command # thus should appear in both inputs protobuf_3_15_cmake aws-sdk-cpp # tunnelbroker corrosion # tunnelbroker double-conversion # tunnelbroker glog # tunnelbroker gtest # testing services folly # cpp tools fmt # needed for folly boost # needed for folly olm # needed for CryptoTools sqlite # needed for sqlite_orm openssl # needed for grpc ] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ CoreFoundation CoreServices Security libiconv # identity service ]); JAVA_HOME = openjdk11.passthru.home; # shell commands to be ran upon entering shell shellHook = '' PRJ_ROOT=$(git rev-parse --show-toplevel) # Set development environment variable defaults source "${../scripts/source_development_defaults.sh}" # Cache development path for some use cases such as XCode "$PRJ_ROOT/scripts/save_path.sh" '' # Darwin condition can be removed once linux services are supported + lib.optionalString stdenv.isDarwin '' # Start MariaDB development services "${mariadb-up}"/bin/mariadb-up & mariadb_pid=$! "${redis-up}"/bin/redis-up & redis_pid=$! wait "$mariadb_pid" "$redis_pid" ${../scripts}/install_homebrew_macos.sh + + ${../scripts}/prompt_direnv_macos.sh '' + '' # Render default configuration for keyserver $PRJ_ROOT/scripts/create_url_facts.sh # Ensure rustup tooling is installed $PRJ_ROOT/scripts/ensure_rustup_setup.sh # Provide decent bash prompt source "${better-prompt}/bin/better-prompt" echo "Welcome to Comm dev environment! :)" ''; } diff --git a/scripts/prompt_direnv_macos.sh b/scripts/prompt_direnv_macos.sh new file mode 100755 index 000000000..ec2a2ee1a --- /dev/null +++ b/scripts/prompt_direnv_macos.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +set -euo pipefail + +COMM_CACHE="${XDG_CACHE_HOME:-$HOME/Library/Caches}/app.comm" +mkdir -p "$COMM_CACHE" +COMM_DIRENV="$COMM_CACHE/install-direnv" + +if command -v direnv >/dev/null || [[ -s "$COMM_DIRENV" ]]; then + # Already using direnv or anwsered no previously. Exit immediately. + exit 0 +fi + +# Currently, this script only works on macOS as it assumes homebrew usage +if ! [[ "$OSTYPE" == 'darwin'* ]]; then + echo "This script is only meant to be ran on macOS" >&2 + exit 1 +fi + +# Check if in an interactive shell +# `test -t` tests if a file descriptor is open, 0 being stdin +# Normally, a non-interactive shell will not have 0 FD bound +# However, Buildkite still has 0 FD bound, so check if PS1 is empty +if [[ ! -t 0 ]] || [[ -z "$PS1" ]]; then + exit 0 +fi + +if [[ ! -e "${COMM_DIRENV}" ]]; then + echo "Direnv is a tool which will automatically setup the development environment upon entering the comm/ directory." + read -r \ + -p "Would you like to install direnv? [y/N]" \ + response + case "$response" in + [yY][eE][sS]|[yY]) + echo "1" > "${COMM_DIRENV}" + ;; + *) + touch "${COMM_DIRENV}" + exit 1 + ;; + esac +fi + +brew install direnv + +# A more recent version of bash is required for nix-direnv to work correctly +# Default version on macOS is bash 3.2. Output taken from '/bin/bash --version' +# shellcheck disable=SC2076 +if [[ "$(bash --version)" =~ "GNU bash, version 3.2" ]]; then + brew install bash +fi + +# Install the hook for a given shell in the related file. +install_direnv_hook() { + local shell="$1" + local source_file="$2" + + # Skip hook installation of shells which don't exist + if ! command -v "$shell" >/dev/null; then + return 0 + fi + + # If the file already mentions direnv, then hook is likely already installed + if [[ ! -e "$source_file" ]] \ + || ! grep "direnv" "$source_file" >/dev/null; then + # shellcheck disable=SC2016 + echo "eval \"\$(direnv hook $shell)\"" >> "$source_file" + fi + +} + +# ~/.zshenv would be preferred location to install the hook, however, it +# gets sourced before ~/.zprofile for login shells; and since +# Homebrew asks you to install its hook in ~/.zprofile, we need to +# follow the same convention. +install_direnv_hook zsh ~/.zprofile +install_direnv_hook zsh ~/.zshrc +install_direnv_hook bash ~/.bash_profile +install_direnv_hook bash ~/.bashrc