bash.d/CLAUDE.md
Ole-Morten Duesund 6a00847d4e Speed up shell startup 9x (1.9s → 0.2s)
Lazy-load Intel oneAPI setvars.sh (~1.5s) via wrapper functions that
source the environment on first use of icc/icx/ifort/etc.

Cache all shell completion outputs to ~/.cache/bash.d/ so they are
sourced from disk instead of regenerated via subprocess on every
shell start.  Cache invalidates automatically when the tool binary
is updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:27:12 +01:00

3.4 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

This is a modular bash configuration directory (~/.bash.d/). Files here are sourced by ~/.bashrc to set up the shell environment. Each file handles a specific concern (PATH additions, environment variables, shell completions). See README.md for a full description of the directory and its contents.

File Naming Convention

Files use numeric prefixes to control load order:

  • 00- : Helper functions (loads first — used by other scripts)
  • 10- : PATH configuration (foundational)
  • 20- : Build tool settings (depends on paths)
  • 30- : Shell/prompt setup
  • 50- : Shell completions (named 50-<tool>-completion)
  • 99- : Application config, credentials (loads last)

Available Helpers (defined in 00-*)

Use these in all scripts — do not manipulate PATH or check permissions manually:

  • path_append <dir> — add directory to end of $PATH (checks existence, prevents duplicates)
  • path_prepend <dir> — add directory to start of $PATH
  • require_private <file> — warn if file is group/world-accessible; use in credential files
  • cached_completion <tool> <gen-cmd...> — cache completion output to ~/.cache/bash.d/; regenerates when the tool binary is updated. Use this for all new completion scripts instead of eval or . <()

Writing Scripts

  • Every file must start with # shellcheck shell=bash
  • Guard external tools with command -v <tool> &>/dev/null before using them
  • Guard directory-dependent exports with [[ -d <path> ]] before exporting
  • Do not suppress stderr from external scripts — only redirect stdout when needed
  • Avoid eval when . <(cmd) (process substitution) works
  • For shell completions, use cached_completion instead of eval or . <() to avoid subprocess overhead on every shell start
  • For slow environment scripts, use lazy-loading (see 20-oneapi for the wrapper-function pattern)
  • Prevent LD_LIBRARY_PATH duplicates with a case guard (see 20-oneapi for example)

Permissions

  • Directory ~/.bash.d/ itself: mode 700
  • Regular scripts (00-* through 50-*): mode 755 (executable is required for sourcing)
  • Credential files (99-* with secrets): mode 700 and must call require_private "${BASH_SOURCE[0]}" as the first functional line
  • Non-credential config files (e.g. 20-android): mode 755 like regular scripts

Validation

Validate all shell scripts with shellcheck before committing:

shellcheck <filename>          # single file
shellcheck [0-9][0-9]-*        # all scripts at once

To test changes, open a new shell or source a single file:

source ~/.bash.d/20-ninja      # reload one file in the current shell

Security

Credential files are excluded from git via .gitignore. Each has a tracked .example template with placeholder values.

To set up a credential:

  1. Copy the template: cp 99-foo.example 99-foo
  2. Fill in your real secret
  3. Restrict permissions: chmod 700 99-foo

When adding new credential files:

  • Create a .example template (mode 644) tracked in git
  • Add the real filename to .gitignore
  • Use mode 700 on the real file: chmod 700 <file>
  • Call require_private "${BASH_SOURCE[0]}" as the first functional line
  • Never commit real secrets
  • Be aware that exported tokens are visible to all child processes