feat: mise, brew and fastfetch perf

This commit is contained in:
2025-12-24 02:34:10 +02:00
parent be4a723859
commit b51f2e0b09
26 changed files with 178 additions and 324 deletions

View File

@@ -8,29 +8,17 @@
log_info "Environment: DOTS_OS=$DOTS_OS, DOTS_PKG=$DOTS_PKG, DOTS_ENV=$DOTS_ENV"
if [[ "$DOTS_OS" == "macos" ]]; then
# macOS info
sw_vers
log_info "Detected macOS (OSTYPE=$OSTYPE)"
log_info "Package manager: Homebrew (brew)"
log_info "Code path: macOS-only brew scripts will run; Linux package scripts are skipped."
elif [[ "$DOTS_OS" == "linux" ]]; then
# Linux info
if [[ -r /etc/os-release ]]; then
cat /etc/os-release
# shellcheck source=/dev/null
. /etc/os-release
fi
log_info "Detected Linux (OSTYPE=$OSTYPE, ID=${ID:-unknown}, ID_LIKE=${ID_LIKE:-n/a}, NAME=${NAME:-n/a}, VERSION_ID=${VERSION_ID:-n/a})"
log_info "Package manager detected: ${DOTS_PKG:-none}"
if [[ -z "$DOTS_PKG" ]]; then
log_warn "No known package manager (apt-get/pacman/dnf) found on Linux."
log_warn "No known package manager found on Linux"
fi
else
log_error "Unknown OS: $OSTYPE"
log_error "Unknown OS: $DOTS_OS"
fi
if [[ "$DOTS_ENV" == "codespaces" ]]; then

View File

@@ -41,3 +41,6 @@ mkdir -p "$HOME/.ssh"
stow --dir="$root_dir/files" --target="$HOME" home
stow --dir="$root_dir/files" --target="$HOME/.config" dot-config
stow --dir="$root_dir/files" --target="$HOME/.ssh" dot-ssh
# Bust PATH cache to force regeneration with new profile
rm -f "${XDG_CACHE_HOME:-$HOME/.cache}/dots/path"

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Install mise runtime manager (base installation only).
# Individual tools are installed in separate scripts (31-python, 32-node, etc.)
#
# Skip in Codespaces (use pre-installed versions)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
# Install mise
if ! command -v mise &>/dev/null; then
log_info "Installing mise..."
case "$DOTS_PKG" in
brew)
brew install mise
;;
apt)
# https://mise.jdx.dev/getting-started.html#apt-debian-ubuntu
wget -qO - https://mise.jdx.dev/gpg-key.pub | gpg --dearmor | \
sudo tee /etc/apt/keyrings/mise-archive-keyring.gpg 1> /dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.gpg arch=amd64] https://mise.jdx.dev/deb stable main" | \
sudo tee /etc/apt/sources.list.d/mise.list
sudo apt-get update -qq
sudo apt-get install -qq mise
;;
pacman)
yay -S --noconfirm mise
;;
*)
# Fallback: curl install
log_info "Using curl installer..."
curl https://mise.jdx.dev/install.sh | sh
# Add to PATH for current session
export PATH="$HOME/.local/bin:$PATH"
;;
esac
fi
mise --version

View File

@@ -1,57 +0,0 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Configure pyenv.
#
# Skip in Codespaces (use pre-installed Python)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
export PYENV_ROOT="$HOME/.pyenv"
if ! echo "$PATH" | grep -q "$PYENV_ROOT"; then
export PATH="$PYENV_ROOT/bin:$PATH"
fi
if ! command -v pyenv &>/dev/null; then
case "$DOTS_PKG" in
apt)
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
sudo apt-get install -qq build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
# see https://github.com/pyenv/pyenv-installer
bash -c "$(curl -fsSL https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer)"
;;
pacman)
# Prefer native packages if available; otherwise install build deps then use installer
if ! sudo pacman -Qi pyenv >/dev/null 2>&1; then
sudo pacman -S --noconfirm --needed base-devel openssl zlib-ng-compat bzip2 readline sqlite xz tk libffi curl
bash -c "$(curl -fsSL https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer)"
else
sudo pacman -S --noconfirm --needed pyenv pyenv-virtualenv
fi
;;
brew)
brew install pyenv
brew install pyenv-virtualenv
;;
*)
log_warn "Skipping pyenv install: no supported package manager found"
;;
esac
fi
if [[ "$DOTS_OS" == "linux" ]]; then
virtualenv_path="$(pyenv root)/plugins/pyenv-virtualenv"
if [ ! -d "$virtualenv_path" ]; then
git clone \
https://github.com/pyenv/pyenv-virtualenv.git \
"$virtualenv_path"
fi
unset virtualenv_path
fi
eval "$(pyenv init --path)"
pyenv --version

View File

@@ -2,74 +2,30 @@
# -----------------------------------------------------------------------------
# Description:
# Configure Python.
# Install Python via mise and configure poetry.
#
# Skip in Codespaces (use pre-installed Python)
# Skip in Codespaces (use pre-installed versions)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
log_info "Installing Python..."
mise install python@3
mise use -g python@3
local version="3.14.2"
log_info "Installing Poetry..."
mise install poetry@latest
mise use -g poetry@latest
if ! pyenv versions --bare | grep -q "$version"; then
pyenv install "$version"
fi
pyenv global "$version"
pip3 install --quiet --upgrade --user pip
python3 --version
pip3 --version
pip_dependencies=(
# docker-compose
# neovim
# "python-language-server[all]"
# pyvim
)
installed_packages=$(pip3 list --format=freeze | awk -F'==' '{print $1}')
pip_dependencies=($(comm -13 <(printf "%s\n" "${installed_packages[@]}" | sort) <(printf "%s\n" "${pip_dependencies[@]}" | sort)))
if [ ${#pip_dependencies[@]} -gt 0 ]; then
pip3 install --quiet --upgrade --user "${pip_dependencies[@]}"
fi
unset installed_packages pip_dependencies PYTHON_KEYRING_BACKEND
local_bin_path="$HOME/.local/bin"
if [[ ":$PATH:" != *":$local_bin_path:"* ]]; then
export PATH="$local_bin_path:$PATH"
fi
mkdir -p ~/.local/bin
unset local_bin_path
if ! command -v pipx &>/dev/null; then
case "$DOTS_PKG" in
apt)
sudo apt-get install -qq pipx
;;
pacman)
sudo pacman -S --noconfirm python-pipx
;;
brew)
brew install pipx
;;
*)
log_warn "Skipping pipx install: no supported package manager found"
;;
esac
fi
echo "pipx $(pipx --version)"
if ! command -v poetry &>/dev/null; then
pipx install poetry
# Setup Poetry ZSH completions
ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
if [[ -d "$ZSH_CUSTOM/plugins" ]]; then
POETRY_PLUGIN="$ZSH_CUSTOM/plugins/poetry"
if [ ! -d "$POETRY_PLUGIN" ]; then
mkdir -p "$POETRY_PLUGIN"
poetry completions zsh > "$POETRY_PLUGIN/_poetry"
fi
fi
# Verify installations
python --version
poetry --version
POETRY_PLUGIN="$ZSH/custom/plugins/poetry"
if [ ! -d "$POETRY_PLUGIN" ]; then
mkdir -p "$POETRY_PLUGIN"
poetry completions zsh > "$POETRY_PLUGIN/_poetry"
fi

View File

@@ -2,39 +2,16 @@
# -----------------------------------------------------------------------------
# Description:
# Configure Node.js.
# Install Node.js via mise.
#
# Skip in Codespaces (use pre-installed Node.js)
# Skip in Codespaces (use pre-installed versions)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
NVM_DIR=${NVM_DIR:-"$HOME/.nvm"}
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
nvm_version="0.40.3"
if ! command -v nvm &>/dev/null; then
bash -c "$(curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v${nvm_version}/install.sh)"
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
fi
nvm --version
nvm alias default lts/jod
nvm install lts/jod
nvm use lts/jod
echo "Node.js $(node --version)"
log_info "Installing Node.js..."
mise install node@lts
mise use -g node@lts
# Verify installations
echo "node $(node --version)"
echo "npm $(npm --version)"
npm_dependencies=(
"firebase-tools"
"@github/copilot"
)
npm_dependencies=($(comm -23 <(printf "%s\n" "${npm_dependencies[@]}" | sort) <(npm list -g --depth=0 --parseable | awk -F'/' '{print $NF}' | sort)))
if [ ${#npm_dependencies[@]} -gt 0 ]; then
npm install -g "${npm_dependencies[@]}"
fi
unset nvm_version npm_dependencies

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Install Terraform via mise.
#
# Skip in Codespaces (not needed)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
log_info "Installing Terraform..."
mise install terraform@latest
mise use -g terraform@latest
# Verify installation
terraform --version

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Install Firebase CLI via mise.
#
# Skip in Codespaces (not needed)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
log_info "Installing Firebase CLI..."
mise install firebase@latest
mise use -g firebase@latest
# Verify installation
echo "firebase: $(firebase --version)"

View File

@@ -31,3 +31,4 @@ if ! command -v gh &>/dev/null; then
fi
gh --version

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Install GitHub Copilot CLI (globally via npm).
#
if ! command -v npm &>/dev/null; then
log_warn "npm not found, skipping"
return 0
fi
# Install if not present
if ! command -v copilot &>/dev/null; then
log_info "Installing GitHub Copilot CLI..."
npm install -g @github/copilot --silent
fi
# Verify installation
log_info "GitHub Copilot CLI: $(copilot --version 2>&1 | head -1)"

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Install terraform.
#
# Skip in Codespaces (project-specific tool)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
if ! command -v terraform &>/dev/null; then
case "$DOTS_PKG" in
apt)
terraform_keyring_path="/usr/share/keyrings/hashicorp-archive-keyring.gpg"
if [[ ! -f "$terraform_keyring_path" ]]; then
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o "$terraform_keyring_path"
fi
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" |
sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt-get update -qq &&
sudo apt-get install -qq terraform
;;
pacman)
sudo pacman -S --noconfirm terraform
;;
brew)
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
;;
*)
log_warn "Skipping Terraform install: no supported package manager found"
;;
esac
fi
terraform --version

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list --cask iterm2 &>/dev/null; then
if ! echo "$BREW_CASKS" | grep -q "^iterm2$"; then
brew install --cask iterm2
fi
log_pass "iTerm2 installed successfully!"

View File

@@ -13,11 +13,22 @@ fonts_list=(
font-fira-code-nerd-font
)
if ! brew list "${fonts_list[@]}" &> /dev/null; then
# Check if any fonts are missing
fonts_missing=false
for font in "${fonts_list[@]}"; do
if ! echo "$BREW_CASKS" | grep -q "^$font$"; then
fonts_missing=true
break
fi
done
if [[ "$fonts_missing" == "true" ]]; then
brew tap homebrew/cask-fonts
for font in "${fonts_list[@]}"; do
brew install --cask "$font"
if ! echo "$BREW_CASKS" | grep -q "^$font$"; then
brew install --cask "$font"
fi
done
fi
unset fonts_list
unset fonts_list fonts_missing

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list --cask colour-contrast-analyser &> /dev/null; then
if ! echo "$BREW_CASKS" | grep -q "^colour-contrast-analyser$"; then
brew install --cask colour-contrast-analyser
else
echo "Colour Contrast Analyser (CCA) is already installed."

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list --cask rectangle &> /dev/null; then
if ! echo "$BREW_CASKS" | grep -q "^rectangle$"; then
brew install --cask rectangle
else
echo "Rectangle is already installed."

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list --cask meetingbar &> /dev/null; then
if ! echo "$BREW_CASKS" | grep -q "^meetingbar$"; then
brew install --cask meetingbar
else
echo "MeetingBar is already installed."

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list --cask betterdisplay &> /dev/null; then
if ! echo "$BREW_CASKS" | grep -q "^betterdisplay$"; then
brew install --cask betterdisplay
else
echo "BetterDisplay is already installed."

View File

@@ -8,7 +8,7 @@
# macOS only
[[ "$DOTS_OS" != "macos" ]] && { log_warn "Skipping: Not macOS"; return 0; }
if ! brew list dockutil &> /dev/null; then
if ! echo "$BREW_FORMULAE" | grep -q "^dockutil$"; then
brew install dockutil
else
echo "dockutil is already installed."

View File

@@ -2,27 +2,27 @@
# -----------------------------------------------------------------------------
# Description:
# Install neofetch.
# Install fastfetch (fast system information tool).
#
# Skip in Codespaces (cosmetic tool)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
if ! command -v neofetch &>/dev/null; then
if ! command -v fastfetch &>/dev/null; then
case "$DOTS_PKG" in
apt)
sudo apt-get install -qq neofetch &>/dev/null
sudo apt-get install -qq fastfetch &>/dev/null
;;
pacman)
yay -S --noconfirm neofetch &>/dev/null
yay -S --noconfirm fastfetch &>/dev/null
;;
brew)
brew install neofetch
brew install fastfetch
;;
*)
log_warn "Skipping neofetch install: no supported package manager found"
log_warn "Skipping fastfetch install: no supported package manager found"
;;
esac
fi
echo "$(neofetch --version)"
echo "fastfetch: $(fastfetch --version 2>&1 | head -1)"

View File

@@ -37,8 +37,6 @@ defaults write -globalDomain AppleInterfaceStyle -string "Dark"
# #2CB494 -- Highlight color
defaults write -globalDomain AppleHighlightColor -string "0.172549 0.705882 0.580392"
killall SystemUIServer 2>/dev/null || true
# Control Center
# --------------
# off -- Control Center: Show Bluetooth icon in menu bar
@@ -65,8 +63,6 @@ defaults write \
Battery \
-int 24
killall ControlCenter 2>/dev/null || true
# Finder
# ------
# on -- Finder: Add quit option
@@ -121,15 +117,11 @@ defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/"
# list -- Finder: Preferred view style
defaults write com.apple.finder FXPreferredViewStyle -string "nlsv"
killall Finder 2>/dev/null || true
# Spotlight
# ---------
# on -- Spotlight: Hide menu bar icon
defaults write com.apple.Spotlight MenuItemHidden -int 1
killall Spotlight 2>/dev/null || true
# Dock
# ----
# off -- Dock: Show recent applications
@@ -156,7 +148,7 @@ default_apps=(
"Numbers"
"Pages"
)
for default_app in default_apps; do
for default_app in "${default_apps[@]}"; do
dockutil --remove "$default_app" --no-restart 1>/dev/null 2>&1 || true
done
@@ -169,20 +161,20 @@ dock_order=(
"/System/Applications/Utilities/Activity Monitor.app"
"/Applications/iTerm.app"
)
dock_state=$(defaults read com.apple.dock persistent-apps)
dock_state=$(defaults read com.apple.dock persistent-apps 2>/dev/null || echo "")
for i in "${!dock_order[@]}"; do
if [[ $i -ne 0 ]]; then
path="${dock_order[$i]}"
name=$(basename "$path" | sed 's/\.app$//')
if [[ $dock_state == *"$name"* ]]; then
dockutil --move "${path}" --position "$i" --no-restart
dockutil --move "${path}" --position "$i" --no-restart 2>/dev/null || true
else
dockutil --add "${path}" --position "$i" --no-restart
dockutil --add "${path}" --position "$i" --no-restart 2>/dev/null || true
fi
fi
done
if [[ ! $dock_state == *"spacer"* ]]; then
dockutil --add '' --type spacer --section apps --position "${#dock_order[@]}" --no-restart
dockutil --add '' --type spacer --section apps --position "${#dock_order[@]}" --no-restart 2>/dev/null || true
fi
killall Dock 2>/dev/null || true
log_info "macOS settings configured. Restart Finder/Dock to apply: osascript -e 'quit app \"Finder\"'"

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env bash
# -----------------------------------------------------------------------------
# Description:
# Clean up after installation.
#
# Skip in Codespaces (minimal benefit in ephemeral environment)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
case "$DOTS_PKG" in
brew)
brew cleanup
;;
apt)
sudo apt-get autoremove -qq
sudo apt-get clean -qq
;;
pacman)
# Remove orphans if any (ignore error if none)
if pacman -Qtdq >/dev/null 2>&1; then
sudo pacman -Rns --noconfirm $(pacman -Qtdq) || true
fi
# Clear package cache without interactive prompt
yes | sudo pacman -Scc >/dev/null 2>&1 || true
;;
*)
log_warn "Skipping cleanup: no supported package manager found"
return 0
;;
esac
log_pass "Cleanup completed successfully!"

View File

@@ -2,10 +2,10 @@
# -----------------------------------------------------------------------------
# Description:
# Print system information.
# Display system information with fastfetch.
#
# Skip in Codespaces (cosmetic only)
[[ "$DOTS_ENV" == "codespaces" ]] && { log_pass "Skipping in Codespaces"; return 0; }
neofetch
fastfetch --pipe false