diff --git a/nix/better-prompt.nix b/nix/better-prompt.nix new file mode 100644 index 000000000..ed24b70a8 --- /dev/null +++ b/nix/better-prompt.nix @@ -0,0 +1,31 @@ +{ lib +, stdenv +, powerline +, powerline-fonts +, shellcheck +, writeTextFile +, runtimeShell +}: + +# Normally we would want to use writeShellApplications for scripts, however, +# since file will be sourced, we do not want to inherit 'set -euo pipefail' +# as this will cause the development shell to exit for any failed command +writeTextFile rec { + name = "better-prompt"; + destination = "/bin/${name}"; + text = '' + #!${runtimeShell} + + PATH=${powerline}/bin:$PATH + powerline_fonts=${powerline-fonts} + powerline_root=${powerline} + + source ${./start-powerline.sh} + ''; + + checkPhase = '' + ${stdenv.shellDryRun} $target + # Need to pass -x so that shellcheck will source external files + ${shellcheck}/bin/shellcheck -x $target + ''; +} diff --git a/nix/dev-shell.nix b/nix/dev-shell.nix index 7fc8c6572..bcbe06624 100644 --- a/nix/dev-shell.nix +++ b/nix/dev-shell.nix @@ -1,116 +1,120 @@ { mkShell , stdenv , lib , amqp-cpp , arcanist , aws-sdk-cpp +, better-prompt , boost , cargo , cmake , cmake-format , cocoapods , corrosion , cryptopp , darwin , double-conversion , folly , fmt , glog , grpc , gtest , libiconv , libuv , mariadb , nodejs-16_x , olm , openjdk8 , openssl , pkg-config , protobuf_3_15_cmake , python3 , shellcheck , sqlite , watchman , rustfmt , yarn }: mkShell { # programs which are meant to be executed should go here nativeBuildInputs = [ # generic development arcanist shellcheck # node development mariadb nodejs-16_x yarn watchman # react native python3 # native dependencies # C/CXX toolchains are already brought in with mkShell # Identity Service cargo # includes rustc rustfmt # Tunnelbroker + CMake amqp-cpp cryptopp cmake cmake-format # linting libuv pkg-config protobuf_3_15_cmake grpc ] ++ lib.optionals stdenv.isDarwin [ cocoapods # needed for ios ]; # 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 = openjdk8.passthru.home; # shell commands to be ran upon entering shell shellHook = let socket = "mysql.sock"; in '' if [[ "$OSTYPE" == 'linux'* ]]; then export MYSQL_UNIX_PORT=''${XDG_RUNTIME_DIR:-/run/user/$UID}/${socket} export ANDROID_SDK_ROOT=''${ANDROID_SDK_ROOT:-$HOME/Android/Sdk} fi if [[ "$OSTYPE" == 'darwin'* ]]; then # Many commands for cocoapods expect the native BSD versions of commands export PATH=/usr/bin:$PATH MARIADB_DIR=''${XDG_DATA_HOME:-$HOME/.local/share}/MariaDB export MYSQL_UNIX_PORT="$MARIADB_DIR"/${socket} export ANDROID_SDK_ROOT=''${ANDROID_SDK_ROOT:-$HOME/Library/Android/sdk} fi + # Provide decent bash prompt + source "${better-prompt}/bin/better-prompt" + echo "Welcome to Comm dev environment! :)" ''; } diff --git a/nix/overlay.nix b/nix/overlay.nix index ce365c129..28fa58cea 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -1,100 +1,102 @@ # An overlay allows for a package set to be extended with new or modified packages # `final` refers to the package set with all overlays applied. # This allows for added or modified packages to be referenced with # all relevant changes final: # `prev` refers to the previous package set before this current overlay is applied. # This is cheaper for nix to evaluate, thus should be prefered over final when possible. prev: { # Patch aws-sdk-cpp to automatically pick up header location # specific to nixpkgs, as nixpkgs separates build-time and runtime # depencenies (a saving of 400MB in header + generated files). # In the case of c and c++, this means the header files are # located in a separate directory from the libraries. # # From a developer perspective, this avoids having to manually specify # the header location with `-DAWS_CORE_HEADER_FILE` each time # one invokes `cmake` on the command line when using # `find_package(AWSSDK COMPONENTS [comps])` # # For more information, see: # - aws-sdk-cpp issue: https://github.com/aws/aws-sdk-cpp/issues/2009 # - Nixpkgs fix: https://github.com/NixOS/nixpkgs/pull/182918 aws-sdk-cpp = (prev.aws-sdk-cpp.overrideAttrs(oldAttrs:{ postPatch = oldAttrs.postPatch + '' substituteInPlace cmake/AWSSDKConfig.cmake \ --replace 'C:/AWSSDK/''${AWSSDK_INSTALL_INCLUDEDIR}/aws/core' \ 'C:/AWSSDK/''${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "${placeholder "dev"}/include/aws/core' ''; })).override { # avoid rebuildilng all 300+ apis apis = [ "core" "s3" "dynamodb" ]; }; # add packages meant for just this repository amqp-cpp = prev.callPackage ./amqp-cpp.nix { }; arcanist = prev.callPackage ./arcanist.nix { }; + better-prompt = prev.callPackage ./better-prompt.nix { }; + protobuf_3_15_cmake = prev.callPackage ./protobuf_3_15.nix { }; devShell = final.callPackage ./dev-shell.nix { }; # Make our version of mariadb the default everywhere mariadb = prev.mariadb_108; mariadb-up = prev.callPackage ./mariadb-up-mac.nix { }; mysql-down = prev.callPackage ./mysql-down-linux.nix { }; mysql-up = prev.callPackage ./mysql-up-linux.nix { }; olm = prev.olm.overrideAttrs(oldAttrs: { # *.hh files aren't meant to be used externally # so we patch installation to add it postInstall = '' cp \ $NIX_BUILD_TOP/${oldAttrs.src.name}/include/olm/*.h* \ ''${!outputDev}/include/olm ''; }); # 16.14 now requires experimental import assertions syntax, pin to 16.13 # https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V16.md nodejs-16_x = prev.nodejs-16_x.overrideAttrs (oldAttrs: rec { version = "16.13.0"; name = "nodejs-${version}"; src = prev.fetchurl { url = "https://nodejs.org/dist/v${version}/node-v${version}.tar.xz"; sha256 = "sha256-MhFLPcOUXtD5X4vDO0LGjg7xjECMtWEiVyoWPZB+y8w="; }; # Nixpkgs applies two patches for 16.15. One patch is for finding headers # needed for v8 on darwin using apple_sdk 11; the other patch fixes crashes # related cache dir defaulting to using `$HOME` without asserting that # it exists. # # However, 16.13 doesn't need the second patch, as the regression which # caused it was introduced after 16.13. This ends up being a no-op. But # nix will still try to apply the patch and fail with "this patch has # already been applied". # # For more context, see (https://github.com/npm/cli/pull/5197) # # lib.head will select the first element in an array patches = [ (prev.lib.head oldAttrs.patches) ]; }); # Ensure that yarn is using the pinned version yarn = prev.yarn.override (_: { nodejs = final.nodejs-16_x; }); } diff --git a/nix/start-powerline.sh b/nix/start-powerline.sh new file mode 100644 index 000000000..d6d6532de --- /dev/null +++ b/nix/start-powerline.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Check if shell is using a default BSD or GNU prompt +if [[ ${PS1} != '\s-\v\$'* ]] && \ + [[ ${PS1} != '%n@%m %1~ %#'* ]]; then + # User already has an opinionated PS1, just leave + return 0 +fi + +if test "$(uname)" = "Darwin" ; then + COMM_CACHE="${XDG_CACHE_HOME:-$HOME/Library/Caches}/app.comm" +else + COMM_CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/comm" +fi + +COMM_EMITTED_WARNING="$COMM_CACHE/powerline_warning" +# Only emit this the first time, as it's suprising to the user for the prompt +# to be replaced, but avoid emitting the warning on subsequent invocations +if [[ ! -f "$COMM_EMITTED_WARNING" ]]; then + echo "Default prompt found, attempting to enable powerline" >&2 + + # Create file to ensure it exists for next time this is run + mkdir -p "$COMM_CACHE" + touch "$COMM_EMITTED_WARNING" +fi + +# Check if the powerline fonts are installed +# If the font is missing then many of the glyphs will render as ? +# Adapted from https://github.com/powerline/fonts/blob/master/install.sh +if test "$(uname)" = "Darwin" ; then + # MacOS + font_dir="$HOME/Library/Fonts" +else + # Linux + font_dir="${XDG_DATA_HOME:-$HOME/.local/share}/fonts" + mkdir -p "$font_dir" +fi + +if [[ ! -f "$font_dir/Droid Sans Mono for Powerline.otf" ]]; then + if [[ ! -d "${powerline_fonts:-/doesnt-exist}" ]]; then + echo "Unable to determine powerline fonts location" >&2 + return 1 + fi + + echo "Installing powerline fonts" >&2 + find "$powerline_fonts" \ + \( -name "*.[ot]tf" -or -name "*.pcf.gz" \) -type f -print0 \ + | xargs -0 -n1 -I % cp "%" "$font_dir/" + + if test "$(uname)" = "Darwin" ; then + + if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]]; then + echo "For glyph support, please: + Select Terminal > Preferences > Text > Font > Change > \ +Select font with 'for Powerline' in the name" >&2 + elif [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then + echo "For glyph support, please: + Select iTerm2 > Preferences > Profiles > Text > Font > \ +Select font with 'for Powerline' in the name" >&2 + fi + + elif which fc-cache >/dev/null 2>&1 ; then + # Reset font cache on Linux + echo "Resetting font cache, this may take a moment..." >&2 + fc-cache -f "$font_dir" + fi +fi + +# shellcheck source=/dev/null +source "${powerline_root:-.}/share/bash/powerline.sh"