diff --git a/packages.txt b/packages.txt index 21a57fb9e..de757084c 100644 --- a/packages.txt +++ b/packages.txt @@ -4,6 +4,8 @@ aws-iam-authenticator@cloudposse bash bash-completion bats@community +# bc is for doing floating point math in the shell +bc # no arm64 cfssl@cloudposse coreutils chamber@cloudposse diff --git a/rootfs/etc/codefresh/require_vars b/rootfs/etc/codefresh/require_vars index fb6e59605..395820a36 100755 --- a/rootfs/etc/codefresh/require_vars +++ b/rootfs/etc/codefresh/require_vars @@ -61,11 +61,11 @@ function require_cfvars() { } function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" + echo "$(tput setaf 1)$*$(tput op)" } function yellow() { - echo "$(tput setaf 3)$*$(tput sgr0)" + echo "$(tput setaf 3)$*$(tput op)" } echo "REQUIRE VARS: checking for presence of required variables" diff --git a/rootfs/etc/profile.d/_07-term-mode.sh b/rootfs/etc/profile.d/_07-term-mode.sh new file mode 100644 index 000000000..5f974c9da --- /dev/null +++ b/rootfs/etc/profile.d/_07-term-mode.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# Files in the profile.d directory are executed by the lexicographical order of their file names. +# This file is named _07-term-mode.sh. The leading underscore is needed to ensure this file executes before +# other files that depend on the functions defined here. The number portion is to ensure proper ordering among +# the high-priority scripts. +# +# This file has no dependencies and should come first. + +# This function determines if the terminal is in dark mode. + +# For now, we use OSC sequences to query the terminal's foreground and background colors. +# See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +# Adapted from https://bugzilla.gnome.org/show_bug.cgi?id=733423#c2 +# +# At some point we may introduce other methods to determine the terminal's color scheme. + +# Normally this function produces no output, but with -b, it outputs "true" or "false", +# with -bb it outputs "true", "false", or "unknown". (Otherwise, unknown assume light mode.) +# and always returns true. With -l it outputs integer luminance values for foreground +# and background colors. With -ll it outputs labels on the luminance values as well. +function _is_term_dark_mode() { + local x fg_rgb bg_rgb fg_lum bg_lum + + # Extract the RGB values of the foreground and background colors via OSC 10 and 11. + # Redirect output to `/dev/tty` in case we are in a subshell where output is a pipe, + # because this output has to go directly to the terminal. + stty -echo + echo -ne '\e]10;?\a\e]11;?\a' >/dev/tty + IFS=: read -t 0.1 -d $'\a' x fg_rgb + IFS=: read -t 0.1 -d $'\a' x bg_rgb + stty echo + + if [[ -z $fg_rgb ]] || [[ -z $bg_rgb ]]; then + if [[ $GEODESIC_TRACE =~ "terminal" ]]; then + echo $(tput setaf 1)* TRACE: "Terminal did not respond to OSC 10 and 11 queries.$(tput sgr0)" >&2 + fi + # If we cannot determine the color scheme, we assume light mode for historical reasons. + if [[ "$*" =~ -b ]]; then + if [[ "$*" =~ -bb ]]; then + echo "unknown" + else + echo "false" + fi + return 0 # when returning text, always return success + fi + return 1 # Assume light mode + fi + + if [[ "${x#*;}" != "rgb" ]]; then + # Always output this error, because we want to hear about + # other color formats users want us to support. + echo "$(tput set bold)($tput setaf 1)Terminal reported unknown color format: ${x#*;}$(tput sgr0)" >&2 + return 1 + fi + + # Convert the RGB values to luminance by summing the values. + fg_lum=$(_srgb_to_luminance "$fg_rgb") + bg_lum=$(_srgb_to_luminance "$bg_rgb") + if [[ "$*" =~ -l ]]; then + if [[ "$*" =~ -ll ]]; then + echo "Foreground luminance: $fg_lum, Background luminance: $bg_lum" + else + echo "$fg_lum $bg_lum" + fi + fi + # If the background luminance is less than the foreground luminance, we are in dark mode. + if ((bg_lum < fg_lum)); then + if [[ "$*" =~ -b ]]; then + echo "true" + fi + return 0 + fi + # If we cannot determine the color scheme, we assume light mode for historical reasons. + if [[ "$*" =~ -b ]]; then + echo "false" + return 0 # when returning text, always return success + fi + return 1 +} + +# Converting RGB to luminance is a lot more complex than summing the values. +# To begin with, you need to know the color space, and if it is not a standard +# one, then you need a full color profile. To start with, we assume sRGB, +# and perhaps can add more color spaces later. +# +# Note: if we just take the simple sum of RGB values, we get in trouble with +# blue backgrounds and foregrounds, which can have very high hex values but still be dark. +# +# To complicate matters, WCAG originally published the wrong formula for +# converting sRGB to luminance. The sRGB space has a linear region, and the switch +# from linear to exponential should be 0.04045, not 0.03928. +# See https://www.w3.org/TR/WCAG21/#dfn-relative-luminance +# +# Unfortunately, many online calculators use the wrong formula, which you can test +# by checking the luminance for #0a570a571010, which should be .0032746029, not .003274534 +# However, there is no difference for 8-bit colors and, as you can see, for 16 bit colors, +# the difference is negligible. +# +# You can use ImageMagick's `convert` command to convert an sRGB color to luminance: +# convert xc: -intensity Rec709Luminance -format "%[fx:intensity]" info: +# For #0a570a571010, this will output 0.00327457, which is slightly off, likely +# due to internal rounding. +# +function _srgb_to_luminance() { + local color="$1" + local red green blue + + if [[ -z $color ]]; then + if [[ $GEODESIC_TRACE =~ "terminal" ]]; then + # Use tput and sgr0 here because this is early in the startup sequence and trace logging + echo "$(tput setaf 1)* TRACE: ${FUNCNAME[0]} called with empty or no argument.$(tput sgr0)" >&2 + fi + echo "0" + return + fi + + # Split the color string into red, green, and blue components + IFS='/' read -r red green blue <<<"$color" + + # Normalize hexadecimal values to [0,1] and linearize them + normalize_and_linearize() { + local hex=${1^^} # Uppercase the hex value, because bc requires it + local float=$(echo "ibase=16; $hex" | bc) + local max=$(echo "ibase=16; 1$(printf '%0*d' ${#hex} 0)" | bc) # Accommodate the number of digits + local normalized=$(echo "scale=10; $float / ($max - 1)" | bc) + + # Apply gamma correction + if (($(echo "$normalized <= 0.04045" | bc))); then + echo "scale=10; $normalized / 12.92" | bc + else + echo "scale=20; e(l(($normalized + 0.055) / 1.055) * 2.4)" | bc -l + fi + } + + # Linearize each color component + local R=$(normalize_and_linearize $red) + local G=$(normalize_and_linearize $green) + local B=$(normalize_and_linearize $blue) + + # Calculate luminance + local luminance=$(echo "scale=10; 0.2126 * $R + 0.7152 * $G + 0.0722 * $B" | bc) + + # Luminance is on a scale of 0 to 1, but we want to be able to + # compare integers in bash, so we multiply by a big enough value + # to get an integer and maintain precision. + echo "scale=0; ($(echo "scale=10; $luminance * 1000000000" | bc) + 0.5) / 1" | bc +} diff --git a/rootfs/etc/profile.d/_10-colors.sh b/rootfs/etc/profile.d/_10-colors.sh index 14f1cf214..3b435a09d 100755 --- a/rootfs/etc/profile.d/_10-colors.sh +++ b/rootfs/etc/profile.d/_10-colors.sh @@ -1,37 +1,152 @@ # Files in the profile.d directory are executed by the lexicographical order of their file names. # This file is named _10-colors.sh. The leading underscore is needed to ensure this file executes before # other files that depend on the functions defined here. The number portion is to ensure proper ordering among -# the high-priority scripts -# This file has no dependencies and should come first. -function red() { - echo "$(tput setaf 1)$*$(tput setaf 0)" +# the high-priority scripts. +# +# This file depends on _07-term-mode.sh and should come second. + +# This file provides functions to colorize text in the terminal. +# It has moderate support for light and dark mode, but it is not perfect. +# The main change is that it uses the terminal's default colors for foreground and background, +# whereas the previous version "reset" the color by setting it to black, which fails in dark mode. + +function update_terminal_mode() { + local dark_mode=$(_is_term_dark_mode -b) + if [[ ! -v _geodesic_tput_cache ]] || [[ "${_geodesic_tput_cache[dark_mode]}" != "$dark_mode" ]]; then + _geodesic_tput_cache_init + else + local mode="light" + if [[ $dark_mode == "true" ]]; then + mode="dark" + fi + echo "Not updating terminal mode from $mode to $mode" + fi } -function green() { - echo "$(tput setaf 2)$*$(tput setaf 0)" +# We call `tput` several times for every prompt, and it can add up, so we cache the results. +function _geodesic_tput_cache_init() { + declare -g -A _geodesic_tput_cache + + local color_off=$(tput op) # reset foreground and background colors to defaults + local bold=$(tput bold) + local bold_off + + if [[ -n "$bold" ]]; then + # Turning on bold is a standard `tput` attribute, but turning it off is not. + # However, turning off bold is an ECMA standard (SGR 22), so it is not + # unreasonable for us to use it. If it causes problems, people can set + # export TERM_BOLD_OFF=$(tput sgr0) + # http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf + bold_off=${TERM_BOLD_OFF:-$'\033[22m'} + fi + + # Set up normal colors for light mode + _geodesic_tput_cache=( + [black]=$(tput setaf 0) + [red]=$(tput setaf 1) + [green]=$(tput setaf 2) + [yellow]=$(tput setaf 3) + [blue]=$(tput setaf 4) + [magenta]=$(tput setaf 5) + [cyan]=$(tput setaf 6) + [white]=$(tput setaf 7) + ) + + if _is_term_dark_mode; then + _geodesic_tput_cache[black]=$(tput setaf 7) # swap black and white + _geodesic_tput_cache[white]=$(tput setaf 0) # 0 is ANSI black, 7 is ANSI white + _geodesic_tput_cache[blue]=${_geodesic_tput_cache[cyan]} # blue is too dark, use cyan instead + else + _geodesic_tput_cache[yellow]=${_geodesic_tput_cache[magenta]} # yellow is too light, use magenta instead + fi + + local key + for key in "${!_geodesic_tput_cache[@]}"; do + if [[ -n ${_geodesic_tput_cache["$key"]} ]]; then + # Note, we cannot use printf for "-off" because command substitution strips trailing newlines + _geodesic_tput_cache["${key}-off"]="$color_off"$'\n' + _geodesic_tput_cache["bold-${key}"]=$(printf "%s%s" "$bold" "${_geodesic_tput_cache["$key"]}") + _geodesic_tput_cache["bold-${key}-off"]="${color_off}${bold_off}"$'\n' + + # Note $'\x01' and $'\x02' are ASCII codes to put around non-printing characters so that + # bash can correctly calculate the visible length of the string. + # They are equivalent to \[ and \] in a bash prompt string. + # Also note that these variants do not include a newline at the end. + _geodesic_tput_cache["${key}-n"]=$(printf "\x01%s\x02" "${_geodesic_tput_cache["$key"]}") + _geodesic_tput_cache["${key}-n-off"]=$(printf "\x01%s\x02" "$color_off") + _geodesic_tput_cache["bold-${key}-n"]=$(printf "\x01%s%s\x02" "$bold" "${_geodesic_tput_cache["$key"]}") + _geodesic_tput_cache["bold-${key}-n-off"]=$(printf "\x01%s%s\x02" "$color_off" "$bold_off") + fi + done + + # Bold is not a color, handle bold without color change separately + if [[ -n "$bold"} ]]; then + _geodesic_tput_cache["bold"]=$(printf "\x01%s\x02" "$bold") + _geodesic_tput_cache["bold-off"]=$(printf "\x01%s\x02" "$bold_off") + fi + + # Save the terminal type so we can invalidate the cache if it changes + _geodesic_tput_cache[TERM]="$TERM" + _geodesic_tput_cache[dark_mode]="$(_is_term_dark_mode -b)" } -function yellow() { - echo "$(tput setaf 3)$*$(tput setaf 0)" +# Colorize text using ANSI escape codes. +# Usage: _geodesic_color style text... +# `style` is defined by the keys of the associative array _geodesic_tput_cache set up above. +# Not intended to be called directly. Use the named style functions below. +function _geodesic_color() { + # The -v test is to see if the variable is set. + # It is required because the associative array syntax does not work with unset variables. + if [[ ! -v _geodesic_tput_cache ]] || [[ "${_geodesic_tput_cache[TERM]}" != "$TERM" ]]; then + _geodesic_tput_cache_init + fi + + local style=$1 + shift + + printf "%s%s%s" "${_geodesic_tput_cache["$style"]}" "$*" "${_geodesic_tput_cache["${style}-off"]}" } -function cyan() { - echo "$(tput setaf 6)$*$(tput setaf 0)" +# Named style helpers +# +# For each color there is "color" and "bold-color", where "bold-color" is the bold version of the color. +# +# These come in 2 flavors. +# - The plain ones include a newline in the end and do not include delimiters around the non-printing text. +# - The ones ending with "-n" do not include a newline and do include delimiters around the non-printing text. +# +# Note that the newline is stripped if run via command substitution, so +# echo "$(red "Hello") World" +# will not have a newline between "Hello" and "World". +# However, you should still use the "-n" variants if your string is or might become part of a PS1 prompt. +# Otherwise, bash will not correctly calculate the visible length of the prompt and editing command history will break. +# +# We intentionally do not define blue or magenta, as blue is problematic in dark mode +# and magenta is too much like red in dark mode, plus it is used as a substitute for yellow in light mode. +# We do not define white or black, either, as we should use the terminal's default for those. +# However, those colors are available via _geodesic_color() if needed, and "white" and "black" are +# swapped in dark mode, so they are more appropriately called "bg" and "fg" respectively. +# Also, "yellow" is not necessarily yellow, it varies with the terminal theme, and +# would be better named "caution" or "info". + +function _generate_color_functions() { + local color + for color in red green yellow cyan; do + eval "function ${color}() { _geodesic_color ${color} \"\$*\"; }" + eval "bold-${color}() { _geodesic_color bold-${color} \"\$*\"; }" + eval "function ${color}-n() { _geodesic_color ${color}-n \"\$*\"; }" + eval "bold-${color}-n() { _geodesic_color bold-${color}-n \"\$*\"; }" + done } -# Turning on bold is a standard `tput` attribute, but turning it off is not. -# However, turning off bold is an ECMA standard (SGR 22), so it is not -# unreasonable for us to use it. If it causes problems, people can set -# export TERM_BOLD_OFF=$(tput sgr0) -# http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf +_generate_color_functions +unset _generate_color_functions + function bold() { - local bold=$(tput bold) - local boldoff=${TERM_BOLD_OFF:-$'\033[22m'} - # If the terminal supports color - if [[ -n $bold ]]; then - printf "%s%s%s\n" "$bold" "$*" "$boldoff" - else - # The terminal does not support color - printf "%s\n" "$*" - fi + _geodesic_color bold "$*" +} + +# Actually, resets all graphics settings to their defaults. +function reset_terminal_colors() { + tput sgr0 } diff --git a/rootfs/etc/profile.d/_30-geodesic-config.sh b/rootfs/etc/profile.d/_30-geodesic-config.sh index 2de7ec37f..e4933b316 100755 --- a/rootfs/etc/profile.d/_30-geodesic-config.sh +++ b/rootfs/etc/profile.d/_30-geodesic-config.sh @@ -85,6 +85,7 @@ function _expand_dir_or_file() { [[ -n $_GEODESIC_TRACE_CUSTOMIZATION ]] && echo trace: looking for resources of type "$resource" in "$dir" + local item for item in "${dir}/$resource" "${dir}/${resource}.d"/*; do if [[ -f $item ]]; then [[ $item =~ $exclude ]] && ([[ -n $_GEODESIC_TRACE_CUSTOMIZATION ]] && echo trace: excluding "$item" || true) && continue diff --git a/rootfs/etc/profile.d/_40-preferences.sh b/rootfs/etc/profile.d/_40-preferences.sh index f3dd8fc0b..084425b09 100755 --- a/rootfs/etc/profile.d/_40-preferences.sh +++ b/rootfs/etc/profile.d/_40-preferences.sh @@ -85,6 +85,7 @@ function _load_geodesic_preferences() { [[ -n $_GEODESIC_TRACE_CUSTOMIZATION ]] && echo trace: LOADING preference files _search_geodesic_dirs preference_list preferences + local file for file in "${preference_list[@]}"; do [[ -n $_GEODESIC_TRACE_CUSTOMIZATION ]] && echo trace: loading preference file "$file" source "$file" diff --git a/rootfs/etc/profile.d/aws.sh b/rootfs/etc/profile.d/aws.sh index ab91d25fa..e462d26c8 100755 --- a/rootfs/etc/profile.d/aws.sh +++ b/rootfs/etc/profile.d/aws.sh @@ -21,11 +21,12 @@ if [ ! -f "${AWS_CONFIG_FILE:=${GEODESIC_AWS_HOME}/config}" ] && [ -d ${GEODESIC fi # Install autocompletion rules for aws CLI v1 and v2 -for aws in aws aws1 aws2; do - if command -v ${aws}_completer >/dev/null; then - complete -C "$(command -v ${aws}_completer)" ${aws} +for __aws in aws aws1 aws2; do + if command -v ${__aws}_completer >/dev/null; then + complete -C "$(command -v ${__aws}_completer)" ${__aws} fi done +unset __aws # This is the default assume-role function, but it can be overridden/replaced later # by aws-okta or aws-vault, etc. or could have already been overridden. diff --git a/rootfs/etc/profile.d/prompt.sh b/rootfs/etc/profile.d/prompt.sh index 584a39dbf..1f66f2f25 100755 --- a/rootfs/etc/profile.d/prompt.sh +++ b/rootfs/etc/profile.d/prompt.sh @@ -37,6 +37,7 @@ _install_prompter unset -f _install_prompter function prompter() { + local hook for hook in ${PROMPT_HOOKS[@]}; do "${hook}" done @@ -63,8 +64,7 @@ function geodesic_prompt() { # Color escapes: 1=red, 2=green, 3=yellow, 6=cyan plain) # 8859-1 codepoints: - # '\[' and '\]' are bash prompt delimiters around non-printing characters - [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK="\["$(tput bold)$(tput setab 2)"\]»\["$(tput sgr0)"\]" # green + [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK="$(green-n »)" [[ -z $ASSUME_ROLE_INACTIVE_MARK ]] && ASSUME_ROLE_INACTIVE_MARK=$'·' [[ -z $BLACK_RIGHTWARDS_ARROWHEAD ]] && BLACK_RIGHTWARDS_ARROWHEAD=$'=>' [[ -z $BANNER_MARK ]] && BANNER_MARK=$'§' @@ -83,17 +83,17 @@ function geodesic_prompt() { # default set, Z NOTATION SCHEMA PIPING, is from the "Supplemental Mathematical Operators" Unicode block # which is not included by default in the Ubuntu terminal font. # See https://github.com/cloudposse/geodesic/issues/417 - [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK=$'\x01'$(tput bold)$(tput setaf 2)$'\x02\u221a\x01'$(tput sgr0)$'\x02' # green bold '√' - [[ -z $ASSUME_ROLE_INACTIVE_MARK ]] && ASSUME_ROLE_INACTIVE_MARK=$'\x01'$(tput bold)$(tput setaf 1)$'\x02\u2717\x01'$(tput sgr0)$'\x02' # red bold '✗' - [[ -z $BLACK_RIGHTWARDS_ARROWHEAD ]] && BLACK_RIGHTWARDS_ARROWHEAD=$'\u27A4' # '➤' - [[ -z $BANNER_MARK ]] && BANNER_MARK='⧉' # \u29c9 TWO JOINED SQUARES + [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK="$(bold-green-n $'\u221a')" # bold green '√' + [[ -z $ASSUME_ROLE_INACTIVE_MARK ]] && ASSUME_ROLE_INACTIVE_MARK="$(bold-red-n $'\u2717')" # red bold '✗' + [[ -z $BLACK_RIGHTWARDS_ARROWHEAD ]] && BLACK_RIGHTWARDS_ARROWHEAD=$'\u27A4' # '➤' + [[ -z $BANNER_MARK ]] && BANNER_MARK='⧉' # \u29c9 TWO JOINED SQUARES ;; *) # default # ASSUME_ROLE_ACTIVE_MARK=$'\x01'$(tput bold)$(tput setaf 2)$'\x02\u2713\x01'$(tput sgr0)$'\x02' # green bold '✓' - [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK=$'\x01'$(tput bold)$(tput setaf 2)$'\x02\u221a\x01'$(tput sgr0)$'\x02' # green bold '√' - [[ -z $ASSUME_ROLE_INACTIVE_MARK ]] && ASSUME_ROLE_INACTIVE_MARK=$'\x01'$(tput bold)$(tput setaf 1)$'\x02\u2717\x01'$(tput sgr0)$'\x02' # red bold '✗' + [[ -z $ASSUME_ROLE_ACTIVE_MARK ]] && ASSUME_ROLE_ACTIVE_MARK="$(bold-green-n $'\u221a')" # bold green '√' + [[ -z $ASSUME_ROLE_INACTIVE_MARK ]] && ASSUME_ROLE_INACTIVE_MARK="$(bold-red-n $'\u2717')" # red bold '✗' # Options for arrow per https://github.com/cloudposse/geodesic/issues/417#issuecomment-477836676 # '»' ($'\u00bb') RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK from the Latin-1 supplement Unicode block # '≫' ($'\u226b') MUCH GREATER-THAN and @@ -108,7 +108,7 @@ function geodesic_prompt() { # "(HOST)" with "HOST" in bold red. Only test for unset ("-") instead of unset or null (":-") so that # the feature can be suppressed by setting PROMPT_HOST_MARK to null. - [[ -z $PROMPT_HOST_MARK ]] && PROMPT_HOST_MARK="${PROMPT_HOST_MARK-$'(\x01'$(tput bold)$(tput setaf 1)$'\x02HOST\x01'$(tput sgr0)$'\x02)'}" + [[ -z $PROMPT_HOST_MARK ]] && PROMPT_HOST_MARK="${PROMPT_HOST_MARK-($(bold-red-n HOST))}" local level_prompt case $SHLVL in @@ -117,7 +117,7 @@ function geodesic_prompt() { 3) level_prompt='⋮' ;; # vertical elipsis \u22ee from Mathematical Symbols *) level_prompt="$SHLVL" ;; esac - level_prompt=$'\x01'$(tput bold)$'\x02'"${level_prompt}"$'\x01'$(tput sgr0)$'\x02' + level_prompt=$(bold "${level_prompt}") if [ -n "$ASSUME_ROLE" ]; then STATUS=${ASSUME_ROLE_ACTIVE_MARK} @@ -163,8 +163,8 @@ function geodesic_prompt() { if [[ -n ${GEODESIC_TF_PROMPT_LINE} ]]; then tf_prompt=" ${tf_mark} ${GEODESIC_TF_PROMPT_LINE}\n" fi - if [[ $GEODESIC_TERRAFORM_WORKSPACE_PROMPT_ENABLED == "true" ]]; then - KUBE_PS1_PREFIX="$(yellow "cluster:")(" + if [[ GEODESIC_TF_PROMPT_ENABLED == "true" ]]; then + KUBE_PS1_PREFIX="$(yellow-n "cluster:")(" fi fi if [[ $old_kube_ps1_prefix != $KUBE_PS1_PREFIX ]]; then @@ -172,8 +172,10 @@ function geodesic_prompt() { fi if [ -n "${BANNER}" ]; then + local nsprompt + [[ $GEODESIC_PROMPT_SHOW_NAMESPACE == true ]] && [[ -n $NAMESPACE ]] && nsprompt=" ($(bold ${NAMESPACE}))" # Intentional 2 spaces between banner mark and banner in order to offset it from level prompt - PS1=$' ${BANNER_MARK}'" ${BANNER} $(kube_ps1)${secrets_active}\n${tf_prompt}${dir_prompt}" + PS1=$' ${BANNER_MARK}'" ${BANNER}${nsprompt} $(kube_ps1)${secrets_active}\n${tf_prompt}${dir_prompt}" else PS1="${tf_prompt}${dir_prompt}" fi diff --git a/rootfs/etc/profile.d/terraform.sh b/rootfs/etc/profile.d/terraform.sh index 2ef6a5eea..dee0faa95 100755 --- a/rootfs/etc/profile.d/terraform.sh +++ b/rootfs/etc/profile.d/terraform.sh @@ -1,25 +1,22 @@ function update_terraform_prompt() { - [[ ${GEODESIC_TF_PROMPT_ENABLED:-false} == "true" ]] || return 0 - # Test if there are any files with names ending in ".tf" - if compgen -G '*.tf' >/dev/null; then - export GEODESIC_TF_PROMPT_ACTIVE=true - if [[ $GEODESIC_TERRAFORM_WORKSPACE_PROMPT_ENABLED != "true" ]]; then - if [ ! -d ".terraform" ]; then - export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=true - export GEODESIC_TF_PROMPT_LINE=" -> Run '$(green init-terraform)' to use this project" - else - export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=false - export GEODESIC_TF_PROMPT_LINE="" - fi - else + if [[ ${GEODESIC_TF_PROMPT_ENABLED:-false} == "true" ]]; then + # Test if there are any files with names ending in ".tf" + if compgen -G '*.tf' >/dev/null; then + export GEODESIC_TF_PROMPT_ACTIVE=true local terraform_workspace=$(terraform workspace show) if [ "$terraform_workspace" == "default" ]; then - export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=true - export GEODESIC_TF_PROMPT_LINE=" -> terraform workspace '$(red "$terraform_workspace")'. Use '$(yellow make workspace/...)' to switch terraform workspaces" + if [[ -d ${TF_DATA_DIR:-.terraform} ]]; then + export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=false + else + export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=true + fi + export GEODESIC_TF_PROMPT_LINE=" terraform workspace:{$(red-n default)}" else export GEODESIC_TF_PROMPT_TF_NEEDS_INIT=false - export GEODESIC_TF_PROMPT_LINE=" workspace:{"$'\x01'$(tput setaf 2)$'\x02'"$terraform_workspace"$'\x01'$(tput sgr0)$'\x02'"}" + export GEODESIC_TF_PROMPT_LINE=" terraform workspace:{$(green-n "$terraform_workspace")}" fi + else + export GEODESIC_TF_PROMPT_ACTIVE=false fi else export GEODESIC_TF_PROMPT_ACTIVE=false diff --git "a/rootfs/etc/profile.d/\316\251_finalize.sh" "b/rootfs/etc/profile.d/\316\251_finalize.sh" index 38adeb02c..2ff73ce31 100644 --- "a/rootfs/etc/profile.d/\316\251_finalize.sh" +++ "b/rootfs/etc/profile.d/\316\251_finalize.sh" @@ -16,6 +16,7 @@ function _dedupe_prompt_command() { local prompt_command=(${PROMPT_COMMAND//;/ }) PROMPT_COMMAND= + local cmd for cmd in "${prompt_command[@]}"; do [[ $PROMPT_COMMAND =~ $cmd ]] || PROMPT_COMMAND="${PROMPT_COMMAND}$cmd;" done diff --git "a/rootfs/etc/profile.d/\316\251_overrides.sh" "b/rootfs/etc/profile.d/\316\251_overrides.sh" index fcb42d025..8252112ef 100644 --- "a/rootfs/etc/profile.d/\316\251_overrides.sh" +++ "b/rootfs/etc/profile.d/\316\251_overrides.sh" @@ -12,6 +12,8 @@ function _load_geodesic_overrides() { local override_list=() _search_geodesic_dirs override_list overrides + + local file for file in "${override_list[@]}"; do [[ -n $_GEODESIC_TRACE_CUSTOMIZATION ]] && echo trace: loading override file "$file" source "$file" diff --git a/rootfs/usr/bin/docker b/rootfs/usr/bin/docker index e6d20a13d..796a7730f 100755 --- a/rootfs/usr/bin/docker +++ b/rootfs/usr/bin/docker @@ -2,11 +2,11 @@ # This script must be installed in /usr/bin, where it will be overwritten by the real docker binary. function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" + echo "$(tput setaf 1)$*$(tput op)" } function green() { - echo "$(tput setaf 2)$*$(tput sgr0)" + echo "$(tput setaf 2)$*$(tput op)" } red docker command not found. diff --git a/rootfs/usr/local/bin/boot b/rootfs/usr/local/bin/boot index d2541b815..7f238b7ff 100755 --- a/rootfs/usr/local/bin/boot +++ b/rootfs/usr/local/bin/boot @@ -3,7 +3,7 @@ [[ -t 1 ]] && (($# == 0)) && exec bash --login if [[ $1 == "install" ]]; then - function color() { echo "$(tput setaf 1)$*$(tput setaf 0)" >&2; } + function color() { echo "$(tput setaf 1)$*$(tput op)" >&2; } color "# EXIT THIS SHELL and on your host computer," color "# run the following to install the script that runs " elif [[ $1 = "wrapper" ]]; then diff --git a/rootfs/usr/local/bin/codefresh-pipeline b/rootfs/usr/local/bin/codefresh-pipeline index d79a7e274..1c8167923 100755 --- a/rootfs/usr/local/bin/codefresh-pipeline +++ b/rootfs/usr/local/bin/codefresh-pipeline @@ -148,11 +148,11 @@ function compare_pipeline() { } function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" 1>&2 + echo "$(tput setaf 1)$*$(tput op)" 1>&2 } function green() { - echo "$(tput setaf 2)$*$(tput sgr0)" 1>&2 + echo "$(tput setaf 2)$*$(tput op)" 1>&2 } function _check_requirements() { diff --git a/rootfs/usr/local/bin/eks-update-kubeconfig b/rootfs/usr/local/bin/eks-update-kubeconfig index dcaf183ec..81b3ddfb4 100755 --- a/rootfs/usr/local/bin/eks-update-kubeconfig +++ b/rootfs/usr/local/bin/eks-update-kubeconfig @@ -71,7 +71,7 @@ function region() { } function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" + echo "$(tput setaf 1)$*$(tput op)" } main() { diff --git a/rootfs/usr/local/bin/grafana-db b/rootfs/usr/local/bin/grafana-db index 6781c1323..36ad0ac73 100755 --- a/rootfs/usr/local/bin/grafana-db +++ b/rootfs/usr/local/bin/grafana-db @@ -170,11 +170,11 @@ function parse_grafana_response() { } function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" + echo "$(tput setaf 1)$*$(tput op)" } function green() { - echo "$(tput setaf 2)$*$(tput sgr0)" + echo "$(tput setaf 2)$*$(tput op)" } # Keep us from exiting the shell if this file is sourced by using return instead of exit diff --git a/rootfs/usr/local/bin/kubectl-auto-select b/rootfs/usr/local/bin/kubectl-auto-select index 7f0177f7c..0fe47f1e9 100755 --- a/rootfs/usr/local/bin/kubectl-auto-select +++ b/rootfs/usr/local/bin/kubectl-auto-select @@ -5,11 +5,11 @@ set -eo pipefail INSTALL=false function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" >&2 + echo "$(tput setaf 1)$*$(tput op)" >&2 } function green() { - echo "$(tput setaf 2)$*$(tput sgr0)" + echo "$(tput setaf 2)$*$(tput op)" } function usage() { diff --git a/rootfs/usr/local/bin/no-arm64-support b/rootfs/usr/local/bin/no-arm64-support index b43f054ef..b3fe9e585 100755 --- a/rootfs/usr/local/bin/no-arm64-support +++ b/rootfs/usr/local/bin/no-arm64-support @@ -12,5 +12,5 @@ if [ -x /usr/bin/$(basename "$0") ]; then exec /usr/bin/$(basename "$0") "$@" fi -printf "$(tput setaf 1)%s is not supported on this platform (arm64)$(tput setaf 0)\n" "$(basename "$0")" >&2 +printf "$(tput setaf 1)%s is not supported on this platform (arm64)$(tput op)\n" "$(basename "$0")" >&2 exit 1 diff --git a/rootfs/usr/local/bin/yaml-diff b/rootfs/usr/local/bin/yaml-diff index 8e1f8c775..1f1878e20 100755 --- a/rootfs/usr/local/bin/yaml-diff +++ b/rootfs/usr/local/bin/yaml-diff @@ -33,11 +33,11 @@ function yaml-diff() { } function red() { - echo "$(tput setaf 1)$*$(tput sgr0)" 1>&2 + echo "$(tput setaf 1)$*$(tput op)" 1>&2 } function green() { - echo "$(tput setaf 2)$*$(tput sgr0)" 1>&2 + echo "$(tput setaf 2)$*$(tput op)" 1>&2 } function _main() {