diff --git a/nix/dev-shell.nix b/nix/dev-shell.nix index 1816fc1d7..1b2120139 100644 --- a/nix/dev-shell.nix +++ b/nix/dev-shell.nix @@ -1,155 +1,153 @@ { 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 , 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 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}/install_homebrew_deps.sh watchman - - ${../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/install_nix.sh b/scripts/install_nix.sh index 05cf9980b..51c94ea8a 100755 --- a/scripts/install_nix.sh +++ b/scripts/install_nix.sh @@ -1,128 +1,133 @@ #!/usr/bin/env bash # Do initial nix install if nix is not available in PATH if ! command -v nix > /dev/null; then sh <(curl -L https://nixos.org/nix/install) --daemon # Source nix-daemon.sh to add nix to PATH if [[ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]]; then # Path doesn't exist in shellcheck CI container # shellcheck source=/dev/null . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' fi fi write_nix_path_to_file() { target_file="$1" # Only write to files if they are missing the entry and writeable if ! grep nix-profile "$target_file" 2>/dev/null \ && [ -w "$target_file" ] || [ ! -f "$target_file" ]; then echo "Adding Nix path entry to $target_file" >&2 # We want this to output $PATH without expansion # shellcheck disable=SC2016 echo 'export PATH="$HOME"/.nix-profile/bin:/nix/var/nix/profiles/default/bin:"${PATH}"' >> "$target_file" fi } # Apple may reset /etc/*rc on system updates which is how Nix exposes itself # Add user entries to avoid Nix "disappearing" from PATH if [[ "$OSTYPE" == 'darwin'* ]]; then write_nix_path_to_file "$HOME/.zshenv" write_nix_path_to_file "$HOME/.bashrc" write_nix_path_to_file "$HOME/.bash_profile" write_nix_path_to_file "$HOME/.profile" fi # Figure out how many cores the system has, and set cache default if [[ "$OSTYPE" == 'darwin'* ]]; then NPROC=$(sysctl -n hw.physicalcpu) ADMIN_GROUP="@admin" elif [[ "$OSTYPE" == 'linux'* ]]; then NPROC=$(nproc) ADMIN_GROUP="@wheel @sudo" fi # Jobs = The number of different nix packages able to be built at the same time # Cores = How many cores an individual job may use. This value is # assigned to $NIX_BUILD_CORES within a nix build environment. jobs=$((NPROC / 2)) # Use only half of cores for individual jobs cores=4 # Just a good default for consumer hardware # NOTE: This has the potential of over-subscribing cores by a factor of 2. # Potential load = jobs * cores = (n/2) * 4 = 2n # However, this is probably the best compromise as most builds are largely # single threaded, with a few exceptions which are massively parrallel. # Check if nix.conf contains a value, append a default if missing. add_if_missing_in_nix_conf() { local key="$1" local value="$2" if ! grep "$key" /etc/nix/nix.conf &> /dev/null; then echo "/etc/nix/nix.conf is missing a value for ${key}. " \ "Appending '${key} = ${value}' to /etc/nix/nix.conf" # Make sure that user can write to file if sudo test -w /etc/nix/nix.conf; then echo "${key} = ${value}" | sudo tee -a /etc/nix/nix.conf &> /dev/null else # nix.conf is read only, which is true for NixOS echo "Unable to write '${key} = ${value}' to nix.conf, " \ "please add the value to your nix.conf" fi fi } # Add value for a given value, append the additional value append_value_in_nix_conf() { local key="$1" local value="$2" # Add value for key if it's missing entirely if ! grep "$key" /etc/nix/nix.conf &> /dev/null; then add_if_missing_in_nix_conf "$key" "$value"; return $? fi # Check that key does not already contain the desired value if ! grep "$key" /etc/nix/nix.conf | grep "$value" &> /dev/null; then echo "/etc/nix/nix.conf is missing '${value}' for '${key}'. " \ "Appending '${value}' to '${key}' in /etc/nix/nix.conf" # Make sure that user can write to file if sudo test -w /etc/nix/nix.conf; then # Find the line with the related setting, then append the new value # Values for nix.conf are space separated sudo sed -i.bak -e "/$key/s|\$| $value|" /etc/nix/nix.conf else # nix.conf is read only, which is true for NixOS echo "Unable to write to nix.conf, please append '$value' to '$key'" \ "in your nix.conf" fi fi } # Check if nix.conf is already configured for a given value. add_if_missing_in_nix_conf "trusted-users" "${ADMIN_GROUP} ${USER}" add_if_missing_in_nix_conf \ "experimental-features" "flakes nix-command" add_if_missing_in_nix_conf "cores" "${cores}" add_if_missing_in_nix_conf "max-jobs" "${jobs}" # Explictly add default cache for older nix versions to prevent custom cache # becoming only trusted cache. append_value_in_nix_conf "substituters" "https://cache.nixos.org" append_value_in_nix_conf "trusted-public-keys" \ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" append_value_in_nix_conf "substituters" "https://comm.cachix.org" append_value_in_nix_conf "trusted-public-keys" \ "comm.cachix.org-1:70RF31rkmCEhQ9HrXA2uXcpqQKGcUK3TxLJdgcUCaA4=" # Ask user if they would like to use Powerline for bash prompt SCRIPT_DIR=$(cd "$(dirname "$0")" || true; pwd -P) + +if [[ "$OSTYPE" == 'darwin'* ]]; then + "$SCRIPT_DIR"/prompt_direnv_macos.sh +fi + # Build the nixified script which is aware of Powerline and dependencies nix build "$SCRIPT_DIR"'/..#better-prompt' # Source file to apply Powerline bootstrap logic # shellcheck source=/dev/null . "$(nix eval --raw "$SCRIPT_DIR"'/..#better-prompt.outPath')/bin/better-prompt" diff --git a/scripts/prompt_direnv_macos.sh b/scripts/prompt_direnv_macos.sh index 18bc56ced..ca9ed5e93 100755 --- a/scripts/prompt_direnv_macos.sh +++ b/scripts/prompt_direnv_macos.sh @@ -1,79 +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 +if [[ ! -t 0 ]]; 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