Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions bash_aliases
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# @description
# Default aliases sourced by bashrc when present.

alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
if command -v eza >/dev/null 2>&1; then
alias ls='eza'
alias ll='eza -la --icons'
alias la='eza -a --icons'
alias l='eza -F --icons'
else
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
fi
14 changes: 7 additions & 7 deletions bash_profile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

# Homebrew shellenv (optional)
if command -v brew >/dev/null 2>&1; then
if [[ "$(uname -m)" == "arm64" ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -x /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
else
eval "$(brew shellenv)"
fi
BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")"
export HOMEBREW_PREFIX="$BREW_PREFIX"
export HOMEBREW_CELLAR="$BREW_PREFIX/Cellar"
export HOMEBREW_REPOSITORY="$BREW_PREFIX"
Comment thread
jbdevprimary marked this conversation as resolved.
export PATH="$BREW_PREFIX/bin:$BREW_PREFIX/sbin${PATH+:$PATH}"
export MANPATH="$BREW_PREFIX/share/man${MANPATH+:$MANPATH}:"
export INFOPATH="$BREW_PREFIX/share/info:${INFOPATH:-}"
Comment thread
jbdevprimary marked this conversation as resolved.
fi

# Hand off to interactive rc
Expand Down
4 changes: 2 additions & 2 deletions bashrc.d/00-options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# Runtime module loaded by get-bashed in lexicographic order.

# Shell options, history, editor
shopt -s histappend checkwinsize cmdhist lithist autocd cdspell checkjobs expand_aliases
HISTIGNORE="&:history:ls:ls * ps:ps -A:[bf]g:exit:${HISTIGNORE}"
shopt -s histappend checkwinsize cmdhist lithist autocd cdspell checkjobs expand_aliases globstar
HISTIGNORE="&:history:ls:ls *:ps:ps -A:[bf]g:exit:${HISTIGNORE}"

# Editor default (respect existing)
: "${EDITOR:=vim}"
Expand Down
9 changes: 5 additions & 4 deletions bashrc.d/20-path.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ path_add "$HOME/.asdf/shims"
# Optional: prefer GNU tools on macOS (requires Homebrew coreutils, gnu-sed, etc.)
# Set GET_BASHED_GNU=1 to enable.
if [[ "${GET_BASHED_GNU:-0}" == "1" ]] && command -v brew >/dev/null 2>&1; then
path_add "$(brew --prefix coreutils)/libexec/gnubin"
path_add "$(brew --prefix findutils)/libexec/gnubin"
path_add "$(brew --prefix gnu-sed)/libexec/gnubin"
path_add "$(brew --prefix gnu-tar)/libexec/gnubin"
BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")"
path_add "$BREW_PREFIX/opt/coreutils/libexec/gnubin"
path_add "$BREW_PREFIX/opt/findutils/libexec/gnubin"
path_add "$BREW_PREFIX/opt/gnu-sed/libexec/gnubin"
path_add "$BREW_PREFIX/opt/gnu-tar/libexec/gnubin"
fi

# Deduplicate once at end
Expand Down
60 changes: 50 additions & 10 deletions bashrc.d/30-buildflags.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,55 @@
# Build flags for compiling language runtimes (optional)
# Enable with GET_BASHED_BUILD_FLAGS=1
if [[ "${GET_BASHED_BUILD_FLAGS:-0}" == "1" ]] && command -v brew >/dev/null 2>&1; then
OPENSSL_PREFIX="$(brew --prefix openssl@3 2>/dev/null || brew --prefix openssl 2>/dev/null)"
READLINE_PREFIX="$(brew --prefix readline 2>/dev/null)"
GETTEXT_PREFIX="$(brew --prefix gettext 2>/dev/null)"
ZSTD_PREFIX="$(brew --prefix zstd 2>/dev/null)"
BREW_PREFIX="$(dirname "$(dirname "$(command -v brew)")")"
OPENSSL_PREFIX="$BREW_PREFIX/opt/openssl@3"
[[ -d "$OPENSSL_PREFIX" ]] || OPENSSL_PREFIX="$BREW_PREFIX/opt/openssl"
READLINE_PREFIX="$BREW_PREFIX/opt/readline"
GETTEXT_PREFIX="$BREW_PREFIX/opt/gettext"
ZSTD_PREFIX="$BREW_PREFIX/opt/zstd"
Comment thread
jbdevprimary marked this conversation as resolved.

export LDFLAGS="-L${OPENSSL_PREFIX}/lib -L${READLINE_PREFIX}/lib -L${GETTEXT_PREFIX}/lib -L${ZSTD_PREFIX}/lib ${LDFLAGS}"
export CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${READLINE_PREFIX}/include -I${GETTEXT_PREFIX}/include -I${ZSTD_PREFIX}/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="${OPENSSL_PREFIX}/lib/pkgconfig:${READLINE_PREFIX}/lib/pkgconfig:${GETTEXT_PREFIX}/lib/pkgconfig:${ZSTD_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
export LIBRARY_PATH="${OPENSSL_PREFIX}/lib:${READLINE_PREFIX}/lib:${GETTEXT_PREFIX}/lib:${ZSTD_PREFIX}/lib:${LIBRARY_PATH}"
export CPATH="${OPENSSL_PREFIX}/include:${READLINE_PREFIX}/include:${GETTEXT_PREFIX}/include:${ZSTD_PREFIX}/include:${CPATH}"
export PYTHON_CONFIGURE_OPTS="--with-openssl=${OPENSSL_PREFIX} --with-readline=editline"
_ldflags=""
_cppflags=""
_pkgconfig=""
_libpath=""
_cpath=""
_pyopts=""

[[ -d "$OPENSSL_PREFIX/lib" ]] && {
_ldflags+="-L${OPENSSL_PREFIX}/lib "
_cppflags+="-I${OPENSSL_PREFIX}/include "
_pkgconfig+="${OPENSSL_PREFIX}/lib/pkgconfig:"
_libpath+="${OPENSSL_PREFIX}/lib:"
_cpath+="${OPENSSL_PREFIX}/include:"
_pyopts+="--with-openssl=${OPENSSL_PREFIX} "
}
[[ -d "$READLINE_PREFIX/lib" ]] && {
_ldflags+="-L${READLINE_PREFIX}/lib "
_cppflags+="-I${READLINE_PREFIX}/include "
_pkgconfig+="${READLINE_PREFIX}/lib/pkgconfig:"
_libpath+="${READLINE_PREFIX}/lib:"
_cpath+="${READLINE_PREFIX}/include:"
_pyopts+="--with-readline=editline "
}
[[ -d "$GETTEXT_PREFIX/lib" ]] && {
_ldflags+="-L${GETTEXT_PREFIX}/lib "
_cppflags+="-I${GETTEXT_PREFIX}/include "
_pkgconfig+="${GETTEXT_PREFIX}/lib/pkgconfig:"
_libpath+="${GETTEXT_PREFIX}/lib:"
_cpath+="${GETTEXT_PREFIX}/include:"
}
[[ -d "$ZSTD_PREFIX/lib" ]] && {
_ldflags+="-L${ZSTD_PREFIX}/lib "
_cppflags+="-I${ZSTD_PREFIX}/include "
_pkgconfig+="${ZSTD_PREFIX}/lib/pkgconfig:"
_libpath+="${ZSTD_PREFIX}/lib:"
_cpath+="${ZSTD_PREFIX}/include:"
}

export LDFLAGS="${_ldflags}${LDFLAGS:-}"
export CPPFLAGS="${_cppflags}${CPPFLAGS:-}"
export PKG_CONFIG_PATH="${_pkgconfig}${PKG_CONFIG_PATH:-}"
export LIBRARY_PATH="${_libpath}${LIBRARY_PATH:-}"
export CPATH="${_cpath}${CPATH:-}"
export PYTHON_CONFIGURE_OPTS="${_pyopts}${PYTHON_CONFIGURE_OPTS:-}"
fi
6 changes: 6 additions & 0 deletions bashrc.d/90-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,9 @@
*) echo "'$f' cannot be extracted via ex()" >&2; return 1 ;;
esac
}

# @description Make a directory and immediately cd into it.
# @arg $1 string Directory path.
mkcd() {
mkdir -p "$1" && cd "$1" || return 1

Check warning on line 32 in bashrc.d/90-functions.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=jbcom_get-bashed&issues=AZ14FaPSPOoTlV-9a3eP&open=AZ14FaPSPOoTlV-9a3eP&pullRequest=10

Check warning on line 32 in bashrc.d/90-functions.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Assign this positional parameter to a local variable.

See more on https://sonarcloud.io/project/issues?id=jbcom_get-bashed&issues=AZ14FaPSPOoTlV-9a3eQ&open=AZ14FaPSPOoTlV-9a3eQ&pullRequest=10
}
3 changes: 3 additions & 0 deletions bashrc.d/95-ssh-agent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ if [[ "${GET_BASHED_SSH_AGENT:-0}" == "1" ]] && [[ -t 1 ]]; then
if _ssh_agent_usable "$SSH_AGENT_SOCK"; then
export SSH_AUTH_SOCK="$SSH_AGENT_SOCK"
else
old_umask="$(umask)"
umask 077
eval "$(ssh-agent -a "$SSH_AGENT_SOCK" -s)" >/dev/null
umask "$old_umask"
fi
fi

Expand Down
14 changes: 11 additions & 3 deletions bin/gen_tool_versions
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#!/usr/bin/env bash
# @file gen_tool_versions
# @brief Update all asdf plugins to latest versions.

for plugin in $(asdf plugin list); do
set -euo pipefail

plugins="$(asdf plugin list 2>/dev/null || true)"

for plugin in $plugins; do
[[ -z "$plugin" ]] && continue
asdf install "$plugin" latest
done

for plugin in $(asdf plugin list); do
versions=$(asdf list "$plugin" | sed 's/^[[:space:]]*//' | grep -v '^latest$')
for plugin in $plugins; do
[[ -z "$plugin" ]] && continue
versions=$(asdf list "$plugin" 2>/dev/null | sed 's/^[[:space:]]*//' | grep -v '^latest$' || true)
if [[ -z "$versions" ]]; then
echo "No versions installed for $plugin"
continue
Expand Down
11 changes: 10 additions & 1 deletion bin/get_bashed_component
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,16 @@ if [[ $# -eq 0 ]]; then
exit 1
fi

GET_BASHED_HOME="${GET_BASHED_HOME:-$HOME/.get-bashed}"
# Find true path of script (handling symlinks)
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

GET_BASHED_HOME="$(dirname "$SCRIPT_DIR")"
HELPERS="$GET_BASHED_HOME/installers/_helpers.sh"
if [[ -r "$HELPERS" ]]; then
# shellcheck disable=SC1090
Expand Down
9 changes: 9 additions & 0 deletions docs/MODULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Runtime module loaded by get-bashed in lexicographic order.
* [doppler_shell](#doppler_shell)
* [get_bashed_component](#get_bashed_component)
* [ex](#ex)
* [mkcd](#mkcd)

### _path_add_front

Expand All @@ -38,3 +39,11 @@ Optional bash-it integration.

Runtime module loaded by get-bashed in lexicographic order.

### mkcd

Make a directory and immediately cd into it.

#### Arguments

* **$1** (string): Directory path.

File renamed without changes.
23 changes: 18 additions & 5 deletions install.bash
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ apply_feature() {
fi
;;
git_signing) GET_BASHED_GIT_SIGNING=$v ;;
dev_tools) GROUP_INSTALLS="${GROUP_INSTALLS},rg,fd,bat,fzf,jq,yq,tree,direnv,starship,nodejs,python,bash" ;;
ops_tools) GROUP_INSTALLS="${GROUP_INSTALLS},gh,git_lfs,terraform,awscli,kubectl,helm,stern,doppler,nodejs,python,java,bash" ;;
dev_tools) GROUP_INSTALLS="${GROUP_INSTALLS},rg,fd,bat,eza,fzf,jq,yq,tree,direnv,starship,nodejs,python,bash" ;;
ops_tools) GROUP_INSTALLS="${GROUP_INSTALLS},gh,git_lfs,terraform,awscli,kubectl,helm,stern,doppler,eza,nodejs,python,java,bash" ;;
*) return 1 ;;
esac
}
Expand Down Expand Up @@ -264,6 +264,7 @@ backup_file() {
[[ -e "$file" ]] || return 0
local backup_dir="$PREFIX/backup"
mkdir -p "$backup_dir"
chmod 700 "$backup_dir"
local base
Comment thread
jbdevprimary marked this conversation as resolved.
base="$(basename "$file")"
base="${base#.}"
Expand Down Expand Up @@ -539,11 +540,15 @@ cp -f "$REPO_DIR/gitconfig" "$PREFIX/gitconfig"

# secrets.d bootstrap (only inside GET_BASHED_HOME)
mkdir -p "$PREFIX/secrets.d"
chmod 700 "$PREFIX/secrets.d"
if [[ ! -e "$PREFIX/secrets.d/00-local.sh" ]]; then
cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
(
umask 077
Comment thread
jbdevprimary marked this conversation as resolved.
cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
# Place local secrets here. Example:
# export FOO="bar"
__SECRETS__
)
fi
Comment on lines +543 to 552
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize 00-local.sh mode on every run, not only on creation.

Right now, Line 544 only creates the file if missing. If an existing 00-local.sh has permissive mode from an older install, reruns won’t correct it.

🔧 Proposed fix
 mkdir -p "$PREFIX/secrets.d"
 chmod 700 "$PREFIX/secrets.d"
 if [[ ! -e "$PREFIX/secrets.d/00-local.sh" ]]; then
   (
     umask 077
     cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
 # Place local secrets here. Example:
 # export FOO="bar"
 __SECRETS__
   )
 fi
+chmod 600 "$PREFIX/secrets.d/00-local.sh"

As per coding guidelines: Every script and module must be idempotent and safe to re-run without causing side effects or errors.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
chmod 700 "$PREFIX/secrets.d"
if [[ ! -e "$PREFIX/secrets.d/00-local.sh" ]]; then
cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
(
umask 077
cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
# Place local secrets here. Example:
# export FOO="bar"
__SECRETS__
)
fi
chmod 700 "$PREFIX/secrets.d"
if [[ ! -e "$PREFIX/secrets.d/00-local.sh" ]]; then
(
umask 077
cat <<'__SECRETS__' > "$PREFIX/secrets.d/00-local.sh"
# Place local secrets here. Example:
# export FOO="bar"
__SECRETS__
)
fi
chmod 600 "$PREFIX/secrets.d/00-local.sh"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@install.bash` around lines 543 - 552, The script only sets strict permissions
when creating "$PREFIX/secrets.d/00-local.sh", so reruns won’t fix an existing
file with permissive modes; after the creation block always normalize
permissions by running chmod 600 "$PREFIX/secrets.d/00-local.sh" (leave the
umask 077 + heredoc creation as-is to create safely when missing, then
unconditionally enforce the file mode on every run).


# Write config file
Expand All @@ -558,10 +563,18 @@ fi
echo "export GET_BASHED_GIT_SIGNING=${GET_BASHED_GIT_SIGNING}"
echo "export GET_BASHED_VIMRC_MODE=\"${GET_BASHED_VIMRC_MODE}\""
if [[ -n "$USER_NAME" ]]; then
echo "export GET_BASHED_USER_NAME=\"${USER_NAME}\""
_escaped="${USER_NAME//\\/\\\\}" # escape backslashes first
_escaped="${_escaped//\$/\\\$}" # escape dollar signs
_escaped="${_escaped//\"/\\\"}" # escape double quotes
_escaped="${_escaped//\`/\\\`}" # escape backticks
echo "export GET_BASHED_USER_NAME=\"${_escaped}\""
fi
if [[ -n "$USER_EMAIL" ]]; then
echo "export GET_BASHED_USER_EMAIL=\"${USER_EMAIL}\""
_escaped="${USER_EMAIL//\\/\\\\}" # escape backslashes first
_escaped="${_escaped//\$/\\\$}" # escape dollar signs
_escaped="${_escaped//\"/\\\"}" # escape double quotes
_escaped="${_escaped//\`/\\\`}" # escape backticks
echo "export GET_BASHED_USER_EMAIL=\"${_escaped}\""
fi
Comment thread
jbdevprimary marked this conversation as resolved.
} > "$PREFIX/get-bashedrc.sh"

Expand Down
3 changes: 3 additions & 0 deletions installers/tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ tool_register starship "starship" "" "macos,linux,wsl" "brew"
tool_pkgs starship "starship" "" "" "" ""
tool_bin starship "starship"

tool_register eza "eza (modern ls)" "" "macos,linux,wsl" "brew,apt,dnf,yum,pacman"
tool_pkgs eza "eza" "eza" "eza" "eza" "eza"

tool_register rg "ripgrep" "" "macos,linux,wsl" "brew,apt,dnf,yum,pacman"
tool_pkgs rg "ripgrep" "ripgrep" "ripgrep" "ripgrep" "ripgrep"

Expand Down
3 changes: 2 additions & 1 deletion scripts/gen-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ shdoc < "$ROOT_DIR/installers/tools.sh" > "$ROOT_DIR/docs/INSTALLERS.md"
fix_toc_anchors() {
local file="$1" tmp
tmp="$(mktemp)"
trap 'rm -f "$tmp"' RETURN
awk '
Comment thread
jbdevprimary marked this conversation as resolved.
function anchorize(text, t) {
t = tolower(text)
Expand Down Expand Up @@ -62,6 +63,7 @@ done

# Combine all runtime modules
TMP_MODULES="$(mktemp)"
trap 'rm -f "$TMP_MODULES"' EXIT
shopt -s nullglob
for f in "$ROOT_DIR/bashrc.d"/*.sh; do
{
Expand All @@ -74,7 +76,6 @@ for f in "$ROOT_DIR/bashrc.d"/*.sh; do
done
shopt -u nullglob
shdoc < "$TMP_MODULES" > "$ROOT_DIR/docs/MODULES.md"
rm -f "$TMP_MODULES"
fix_toc_anchors "$ROOT_DIR/docs/MODULES.md"
ensure_eof "$ROOT_DIR/docs/MODULES.md"

Expand Down
1 change: 1 addition & 0 deletions scripts/verify-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
TEST_HOME="$TMPDIR/home"
mkdir -p "$TEST_HOME"

Expand Down
17 changes: 17 additions & 0 deletions tests/config_output.bats
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,20 @@ load test_helper
run grep -F "export GET_BASHED_GNU=1" "$TEST_HOME/.get-bashed/get-bashedrc.sh"
assert_success
}

@test "installer correctly escapes quotes in identity fields" {
TMPDIR="$(mktemp -d)"
HOME="$TMPDIR/home"
mkdir -p "$HOME"
TEST_HOME="$HOME"

USER_NAME='Jane "Danger" Doe'
USER_EMAIL='jane"quote"@example.com'

HOME="$TEST_HOME" bash ./install.sh --auto --name "$USER_NAME" --email "$USER_EMAIL" --prefix "$TEST_HOME/.get-bashed" --force

run grep -F "GET_BASHED_USER_NAME=\"Jane \\\"Danger\\\" Doe\"" "$TEST_HOME/.get-bashed/get-bashedrc.sh"
assert_success
run grep -F "GET_BASHED_USER_EMAIL=\"jane\\\"quote\\\"@example.com\"" "$TEST_HOME/.get-bashed/get-bashedrc.sh"
assert_success
}
2 changes: 1 addition & 1 deletion tests/install.bats
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load test_helper
@test "installer writes to prefix and wires bashrc" {
TMPDIR="$(mktemp -d)"
TEST_HOME="$TMPDIR"
HOME="$TEST_HOME" bash ./install.sh --prefix "$TEST_HOME/.get-bashed" --force
HOME="$TEST_HOME" bash ./install.sh --auto --prefix "$TEST_HOME/.get-bashed" --force

assert_file_exist "$TEST_HOME/.get-bashed/bashrc"
assert_dir_exist "$TEST_HOME/.get-bashed/bashrc.d"
Expand Down
Loading