From 2e278ebf8d634e7ce3322dc6bdf5a3ff9b579ab7 Mon Sep 17 00:00:00 2001 From: Steve Ruble Date: Mon, 7 Feb 2022 08:26:56 -0500 Subject: [PATCH] more m1 fixes for bobs (#11) * moved m1 logic to install step * Bump version to 0.1.2 Co-authored-by: SteveRuble --- .tool-versions | 1 + VERSION | 2 +- bootstrap | 71 +++++++------------ formula/ih-core.rb | 2 +- lib/bobs/bazel/step.sh | 20 +++--- lib/bobs/go/default/01_bobs_go.sh | 20 ++++++ lib/bobs/go/step.sh | 45 ++++++++++++ lib/bobs/jdk/step.sh | 6 +- lib/bobs/scala/step.sh | 29 ++++++++ lib/core/asdf/.tool-versions | 1 - .../certificates/default/11_certificates.sh | 2 +- lib/core/m1/default/01_m1.sh | 15 ++++ lib/core/m1/step.sh | 56 +++++++++++++++ lib/core/shell/default/00_env.sh | 8 +-- lib/core/shell/default/99_bash.sh | 4 -- lib/core/shell/default/99_zsh.sh | 4 -- lib/core/shell/step.sh | 5 +- lib/utils/arch.sh | 23 ++++++ lib/utils/file.sh | 47 ++++++++++++ 19 files changed, 281 insertions(+), 80 deletions(-) create mode 100644 lib/bobs/go/default/01_bobs_go.sh create mode 100644 lib/bobs/go/step.sh create mode 100644 lib/bobs/scala/step.sh create mode 100644 lib/core/m1/default/01_m1.sh create mode 100644 lib/core/m1/step.sh create mode 100644 lib/utils/arch.sh diff --git a/.tool-versions b/.tool-versions index 4d7f0e6..674f821 100644 --- a/.tool-versions +++ b/.tool-versions @@ -2,3 +2,4 @@ ruby 2.7.2 python 3.9.7 pre-commit 2.15.0 shfmt 3.4.1 +shellcheck 0.8.0 diff --git a/VERSION b/VERSION index 17e51c3..d917d3e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.1.2 diff --git a/bootstrap b/bootstrap index a8ebb4e..1d6bb74 100755 --- a/bootstrap +++ b/bootstrap @@ -1,65 +1,44 @@ #!/bin/bash -#shellcheck disable=SC2034 - -if ! command -v brew &>/dev/null; then - - if [[ $(uname -m) == 'arm64' ]]; then - echo '----------------------------------- -You have an M1 chip and you are not -running in a Rosetta-flavored shell. -There may be a day when all our tools -work correctly on M1, but until that day -you will need to install them in x86 -compatibility mode. I will install brew -in x86 compatibiility mode to support that. - -When you run brew commands in the future -you may run into a message telling you -that you need to install it in another mode. -You can follow those instructions, or just -make a new shell using "arch -x86_64 zsh" -and do your brew install from there. - -Press any key to continue - ' - read -rn 1 - arch -x86_64 /bin/bash -c "$(curl -fsSL https://github.com/raw/Homebrew/install/master/install.sh)" - else - /bin/bash -c "$(curl -fsSL https://github.com/raw/Homebrew/install/master/install.sh)" - fi +if ! command -v brew >/dev/null; then + /bin/bash -c "$(curl -fsSL https://github.com/raw/Homebrew/install/master/install.sh)" fi -eval "$(/usr/local/bin/brew shellenv)" +# Activate the correct brew for the CPU +if [[ "$(uname -m)" == 'arm64' ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" +else + eval "$(/usr/local/bin/brew shellenv)" +fi echo "Installing ih-core formula..." echo "Sometimes the dependency downloads fail, possibly due to the VPN, so \ I will retry installing a couple times if it fails." -if [[ $1 == "local" ]]; then - THIS_DIR=$(dirname "$(realpath "$0")") - - for i in 1 2 3; do brew install --formula -s "$THIS_DIR/formula/ih-core.rb" && break; done +brew update +brew tap ConsultingMD/homebrew-ih-public https://github.com/ConsultingMD/homebrew-ih-public.git -elif [[ ${#} -eq 1 ]]; then - VERSION=$1 - echo "Installing version $VERSION" - TMP_DIR=$(mktemp -d) - FORMULA_PATH="$TMP_DIR/ih-core.rb" - curl -L -o "$FORMULA_PATH" "https://github.com/ConsultingMD/homebrew-ih-public/releases/download/$VERSION/ih-core.rb" +SUCCEEDED=1 +for _ in 1 2 3; do + brew install ih-core + SUCCEEDED=$? + if [ $SUCCEEDED -eq 0 ]; then + break + fi +done - for i in 1 2 3; do brew install --formula -s "$FORMULA_PATH" && break; done - rm -rf "$TMP_DIR" -else - brew update - brew tap ConsultingMD/homebrew-ih-public https://github.com/ConsultingMD/homebrew-ih-public.git - for i in 1 2 3; do brew install ih-core && break; done +if [ $SUCCEEDED -eq 1 ]; then + echo "Install of ih-setup formula failed. Please contact platform support +in the #developer-platform-support stream in Zulip or the #dept-eng_infra channel +in Slack. You can also search Confluence for 'Engineer Onboarding Guide' for +more troubleshooting tips." + exit 1 fi if command -v ih-setup; then ih-setup install else echo "ih-setup is not available in your PATH. Check the logs above to see if there was a fatal error, -and make sure that /usr/local/bin is in your PATH. Then run 'ih-setup install' again." +and make sure that /usr/local/bin is in your PATH" exit 1 fi diff --git a/formula/ih-core.rb b/formula/ih-core.rb index 6e1d4ee..5c9a96d 100644 --- a/formula/ih-core.rb +++ b/formula/ih-core.rb @@ -1,5 +1,5 @@ class IhCore < Formula - VERSION="0.1.1" + VERSION="0.1.2" desc "Brew formula for installing core tools used at Included Health engineering." homepage "https://github.com/ConsultingMD/homebrew-ih-public" license "CC BY-NC-ND 4.0" diff --git a/lib/bobs/bazel/step.sh b/lib/bobs/bazel/step.sh index 79b07f0..59c3403 100644 --- a/lib/bobs/bazel/step.sh +++ b/lib/bobs/bazel/step.sh @@ -3,11 +3,11 @@ # IH_CORE_DIR will be set to the directory containing the bin and lib directories. function ih::setup::bobs.bazel::help() { - echo 'Installs bazelisk for bazel management + echo 'Installs bazel correctly This step will: - - Install bazelisk - - Check that bazel is working + - Install bazelisk in x86 mode + - symlink bazel to bazelisk - Configure bazel keystore to trust DLP certificate ' } @@ -15,11 +15,12 @@ function ih::setup::bobs.bazel::help() { # Check if the step has been installed and return 0 if it has. # Otherwise return 1. function ih::setup::bobs.bazel::test() { - if ! type bazelisk >/dev/null; then + + if ! type bazelisk >/dev/null 2>&1; then return 1 fi - if ! type bazel >/dev/null; then + if ! type bazel >/dev/null 2>&1; then return 1 fi @@ -40,13 +41,10 @@ function ih::setup::bobs.bazel::deps() { function ih::setup::bobs.bazel::install() { set -e - ih::log::info "Installing bazelisk using brew..." - brew install bazelisk - ih::log::info "Checking bazelisk version..." - bazelisk version - ih::log::info "Checking bazel version..." - bazel version + ih::arch::ibrew install bazelisk + + ln -s /usr/local/bin/bazelisk /usr/local/bin/bazel ih::setup::bobs.bazel::private::java-certs "install" } diff --git a/lib/bobs/go/default/01_bobs_go.sh b/lib/bobs/go/default/01_bobs_go.sh new file mode 100644 index 0000000..d3ab08e --- /dev/null +++ b/lib/bobs/go/default/01_bobs_go.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# This file defines the go environment variables you +# should have when working on the bobs repo. +# It was created by `ih-setup install bobs go` + +# ██████╗ ██████╗ ███╗ ██╗ ██████╗ ████████╗ ███████╗██████╗ ██╗████████╗ +# ██╔══██╗██╔═══██╗ ████╗ ██║██╔═══██╗╚══██╔══╝ ██╔════╝██╔══██╗██║╚══██╔══╝ +# ██║ ██║██║ ██║ ██╔██╗ ██║██║ ██║ ██║ █████╗ ██║ ██║██║ ██║ +# ██║ ██║██║ ██║ ██║╚██╗██║██║ ██║ ██║ ██╔══╝ ██║ ██║██║ ██║ +# ██████╔╝╚██████╔╝ ██║ ╚████║╚██████╔╝ ██║ ███████╗██████╔╝██║ ██║ +# ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚══════╝╚═════╝ ╚═╝ ╚═╝ +# Changes to this file will be overwritten if you re-install the step + +export GO111MODULE=on +export GOPATH="${HOME}/go" +export GOBIN="${GOPATH}/bin" +export PATH=$PATH:"${GOBIN}" +export GOPROXY=direct +export GOPRIVATE='github.com/ConsultingMD/*' diff --git a/lib/bobs/go/step.sh b/lib/bobs/go/step.sh new file mode 100644 index 0000000..cae4eab --- /dev/null +++ b/lib/bobs/go/step.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# IH_CORE_DIR will be set to the directory containing the bin and lib directories. +BOBSGOVERSION="1.15.15" + +function ih::setup::bobs.go::help() { + echo "This correctly installs Go for use in the bobs repo + + This step will: + - install an x86 version of go $BOBSGOVERSION for asdf + - configure your shell with required go environment variables + " +} + +# Check if the step has been installed and return 0 if it has. +# Otherwise return 1. +function ih::setup::bobs.go::test() { + + if ! ih::file::check-shell-defaults "$IH_CORE_DIR"/lib/bobs/go/default; then + return 1 + fi + + if ! asdf list golang | grep -q "$BOBSGOVERSION"; then + return 1 + fi + + return 0 +} + +# Echo a space-delimited list of steps which must be installed before this one can be. +function ih::setup::bobs.go::deps() { + # echo "step1 step2" + echo "" +} + +function ih::setup::bobs.go::install() { + + set -e + + ih::arch::x86 asdf install golang "$BOBSGOVERSION" + + ih::file::sync-shell-defaults "$IH_CORE_DIR"/lib/bobs/go/default + + export IH_WANT_RE_SOURCE=1 +} diff --git a/lib/bobs/jdk/step.sh b/lib/bobs/jdk/step.sh index 8452ac3..7a2fd5e 100644 --- a/lib/bobs/jdk/step.sh +++ b/lib/bobs/jdk/step.sh @@ -13,7 +13,7 @@ function ih::setup::bobs.jdk::help() { # Check if the step has been installed and return 0 if it has. # Otherwise return 1. function ih::setup::bobs.jdk::test() { - if brew list --cask adoptopenjdk8 >/dev/null 2>&1; then + if ih::arch::ibrew list --cask adoptopenjdk8 >/dev/null 2>&1; then return 0 fi return 1 @@ -28,8 +28,8 @@ function ih::setup::bobs.jdk::deps() { function ih::setup::bobs.jdk::install() { ih::log::info "Tapping adoptopenjdk/openjdk" - brew tap adoptopenjdk/openjdk + ih::arch::ibrew tap adoptopenjdk/openjdk ih::log::info "Installing adoptopenjdk8" - brew install --cask adoptopenjdk8 + ih::arch::ibrew install --cask adoptopenjdk8 } diff --git a/lib/bobs/scala/step.sh b/lib/bobs/scala/step.sh new file mode 100644 index 0000000..be1fa77 --- /dev/null +++ b/lib/bobs/scala/step.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# IH_CORE_DIR will be set to the directory containing the bin and lib directories. + +function ih::setup::bobs.scala::help() { + echo 'This will install the correct scala + + This step will: + - Install scala 2.12 in x86 mode + ' +} + +# Check if the step has been installed and return 0 if it has. +# Otherwise return 1. +function ih::setup::bobs.scala::test() { + if ! ih::arch::ibrew list scala@2.12 >/dev/null 2>&1; then + return 1 + fi + return 0 +} + +# Echo a space-delimited list of steps which must be installed before this one can be. +function ih::setup::bobs.scala::deps() { + echo "" +} + +function ih::setup::bobs.scala::install() { + ih::arch::ibrew install scala@2.12 +} diff --git a/lib/core/asdf/.tool-versions b/lib/core/asdf/.tool-versions index 33148f7..a8a9a9f 100644 --- a/lib/core/asdf/.tool-versions +++ b/lib/core/asdf/.tool-versions @@ -1,5 +1,4 @@ python 3.9.7 -bazel 3.7.2 buf 0.51.1 golang 1.16.3 helm 3.6.1 diff --git a/lib/core/certificates/default/11_certificates.sh b/lib/core/certificates/default/11_certificates.sh index 95cad3e..7b1614b 100644 --- a/lib/core/certificates/default/11_certificates.sh +++ b/lib/core/certificates/default/11_certificates.sh @@ -3,4 +3,4 @@ # This script adds environment variables needed for # our DLP certificates to be respected -export NODE_EXTRA_CA_CERTS="$HOME/.ih/certs/ga_root_ca.pem" +export NODE_EXTRA_CA_CERTS="$HOME/.ih/certs/grand_rounds_chained_ca.pem" diff --git a/lib/core/m1/default/01_m1.sh b/lib/core/m1/default/01_m1.sh new file mode 100644 index 0000000..8f014dc --- /dev/null +++ b/lib/core/m1/default/01_m1.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Use correct brew and brew path stuff based on shell architecture compatibility +if [[ "$(uname -m)" == 'arm64' ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" +else + eval "$(/usr/local/bin/brew shellenv)" +fi + +# Aliases to switch compatibility mode in shells +alias x86='arch -x86_64 $SHELL' +alias amd64='arch -arm64 $SHELL' + +alias ibrew='arch -x86_64 /usr/local/bin/brew' +alias mbrew='arch -arm64 /opt/homebrew/bin/brew' diff --git a/lib/core/m1/step.sh b/lib/core/m1/step.sh new file mode 100644 index 0000000..86ffee5 --- /dev/null +++ b/lib/core/m1/step.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# IH_CORE_DIR will be set to the directory containing the bin and lib directories. + +function ih::setup::core.m1::help() { + echo 'Installs M1 compatibility fixes if needed + + This step only runs if you have an M1 + CPU. It installs various things that make + it easier to fall back to x86 mode for + tools that do not work on M1. It will: + - Install the x86 version of brew + - Augment your shell setup with some aliases + - x86 will start a new shell in x86 mode + - amd64 will start a new shell in amd64 (M1) mode + - Set up your shell so that if you are + in x86 mode the x86 version of brew will be used. + ' +} + +# Check if the step has been installed and return 0 if it has. +# Otherwise return 1. +function ih::setup::core.m1::test() { + if sysctl -n machdep.cpu.brand_string | grep "M1"; then + + # M1 CPU detected + if [ ! -x /usr/local/bin/brew ]; then + ih::log::debug "Brew is not installed in x86 mode" + return 1 + fi + + if ! ih::file::check-shell-defaults "${IH_CORE_LIB_DIR}/core/m1/default"; then + ih::log::debug "M1 shell script out of date" + return 1 + fi + fi + + return 0 +} + +# Echo a space-delimited list of steps which must be installed before this one can be. +function ih::setup::core.m1::deps() { + # echo "step1 step2" + echo "core.shell" +} + +function ih::setup::core.m1::install() { + + if [ ! -x /usr/local/bin/brew ]; then + arch -x86_64 /bin/bash -c "$(curl -fsSL https://github.com/raw/Homebrew/install/master/install.sh)" + fi + + ih::file::sync-shell-defaults "${IH_CORE_LIB_DIR}/core/m1/default" + + export IH_WANT_RE_SOURCE=1 +} diff --git a/lib/core/shell/default/00_env.sh b/lib/core/shell/default/00_env.sh index ff94d10..ff19af1 100644 --- a/lib/core/shell/default/00_env.sh +++ b/lib/core/shell/default/00_env.sh @@ -15,12 +15,8 @@ # Signals that IH shell augments have been sourced export IH_AUGMENT_SOURCED=yes -# Use correct brew and brew path stuff based on shell architecture compatibility -if [[ "$(uname -m)" == 'arm64' ]]; then - eval "$(/opt/homebrew/bin/brew shellenv)" -else - eval "$(/usr/local/bin/brew shellenv)" -fi +# Activate brew paths +[ -f "/usr/local/bin/brew" ] && eval "$(/usr/local/bin/brew shellenv)" #Make sure home ~/bin is in the path [[ ! "$PATH" =~ ${HOME}/bin ]] && export PATH="${HOME}/bin:${PATH}" diff --git a/lib/core/shell/default/99_bash.sh b/lib/core/shell/default/99_bash.sh index e611d6c..2c84940 100644 --- a/lib/core/shell/default/99_bash.sh +++ b/lib/core/shell/default/99_bash.sh @@ -112,10 +112,6 @@ if type brew &>/dev/null; then fi fi -# Aliases to switch compatibility mode in shells -alias x86='arch -x86_64 bash' -alias m1='arch -arm64 bash' - # ██████╗ ██████╗ ███╗ ██╗ ██████╗ ████████╗ ███████╗██████╗ ██╗████████╗ # ██╔══██╗██╔═══██╗ ████╗ ██║██╔═══██╗╚══██╔══╝ ██╔════╝██╔══██╗██║╚══██╔══╝ # ██║ ██║██║ ██║ ██╔██╗ ██║██║ ██║ ██║ █████╗ ██║ ██║██║ ██║ diff --git a/lib/core/shell/default/99_zsh.sh b/lib/core/shell/default/99_zsh.sh index c562720..20d1b5d 100644 --- a/lib/core/shell/default/99_zsh.sh +++ b/lib/core/shell/default/99_zsh.sh @@ -62,10 +62,6 @@ alias edit-zshrc='eval "$EDITOR $HOME/.zshrc" && source $HOME/.zshrc' alias edit-aliases='eval "$EDITOR $HOME/.ih/custom/99_zsh.sh" && source $HOME/.ih/custom/99_zsh.sh' alias edit-env='eval "$EDITOR $HOME/.ih/custom/00_env.sh" && source $HOME/.ih/custom/00_env.sh' -# Aliases to switch compatibility mode in shells -alias x86='arch -x86_64 zsh' -alias m1='arch -arm64 zsh' - # Wire up completions for things installed by brew if type brew &>/dev/null; then FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" diff --git a/lib/core/shell/step.sh b/lib/core/shell/step.sh index 15386c4..0c0400d 100644 --- a/lib/core/shell/step.sh +++ b/lib/core/shell/step.sh @@ -83,8 +83,7 @@ function ih::setup::core.shell::install() { re_source - green "Shell configuration complete. When you start a new shell you'll have all the Included Health scripts available." - + export IH_WANT_RE_SOURCE=1 } # shellcheck disable=SC2016 @@ -163,6 +162,8 @@ function ih::setup::core.shell::private::configure-profile() { read -r -p "Your EDITOR is unset. What editor do you like to use? (maybe enter vim or nano, or 'code -w' to use VSCode): " EDITOR export EDITOR echo " +# This is the editor that will be used when a command-line tool +# like git needs you to edit a file. export EDITOR=\"$EDITOR\"" >>"$PROFILE_FILE" fi diff --git a/lib/utils/arch.sh b/lib/utils/arch.sh new file mode 100644 index 0000000..a8b5401 --- /dev/null +++ b/lib/utils/arch.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# These are functions for running commands with different architectures + +# Invokes its args as a command in an x86 (intel) shell +ih::arch::x86() { + arch -x86_64 "$SHELL" -c "${*}" +} + +# Invokes its args as a command in an arm64 (M1) shell +ih::arch::amd64() { + arch -arm64 "$SHELL" -c "${*}" +} + +# Invokes the x86 mode of brew +ih::arch::ibrew() { + /usr/local/bin/brew "${@}" +} + +# Invokes the arm64 mode of brew. +ih::arch::mbrew() { + /opt/homebrew/bin/brew "${@}" +} diff --git a/lib/utils/file.sh b/lib/utils/file.sh index 8cb0987..6d45b8c 100644 --- a/lib/utils/file.sh +++ b/lib/utils/file.sh @@ -65,3 +65,50 @@ function ih::file::add-if-not-matched() { echo "$CONTENT" >>"$FILE" } + +# Returns 0 if the directory at $2 has all +# the files from the directory at $1, and +# the files are all the same. Otherwise returns 1. +function ih::file::check-dir-in-sync() { + + local SRC_DIR=${1:?"src is required"} + local DST_DIR=${2:?"dst is required"} + + for SRC in "$SRC_DIR"/*; do + local DST="${SRC/$SRC_DIR/$DST_DIR}" + if [ ! -f "$DST" ]; then + ih::log::debug "File $DST not found." + return 1 + fi + + if ! diff -q "$DST" "$SRC" >/dev/null; then + ih::log::debug "File $DST does not match source" + return 1 + fi + done +} + +# Returns 0 if the shell default directory at ~/.ih/default +# contains exact matches for the files in the directory at $1. +# Otherwise returns 1. +function ih::file::check-shell-defaults() { + + local SRC_DIR=${1:?"src is required"} + local DST_DIR="$IH_DIR"/default + + ih::file::check-dir-in-sync "$SRC_DIR" "$DST_DIR" +} + +# Copies the files from $1 into the shell default directory at ~/.ih/default +# and makes them read/write +function ih::file::sync-shell-defaults() { + + local SRC_DIR=${1:?"src is required"} + local DST_DIR="$IH_DIR"/default + + for SRC in "$SRC_DIR"/*; do + ih::log::debug "Copying $SRC to $DST_DIR" + cp -f "$SRC" "$DST_DIR" + chmod 0600 "${DST_DIR}/$(basename "$SRC")" + done +}