122 lines
5.2 KiB
Markdown
122 lines
5.2 KiB
Markdown
# ~/.bash.d — Modular Bash Configuration
|
|
|
|
This directory contains modular shell configuration files that are automatically sourced by `~/.bashrc` on every new shell session. Instead of maintaining one monolithic `.bashrc`, each concern lives in its own file — making the setup easier to understand, maintain, and extend.
|
|
|
|
## How It Works
|
|
|
|
Add the following to the end of your `~/.bashrc`:
|
|
|
|
```bash
|
|
for file in $HOME/.bash.d/*; do
|
|
[[ -x $file ]] && source $file
|
|
done
|
|
```
|
|
|
|
This iterates over all files in `~/.bash.d/` and sources each one that has the **executable bit** set. Non-executable files are silently skipped, which provides a simple way to temporarily disable a configuration (just `chmod -x` the file).
|
|
|
|
Files are sourced in **lexicographic order**, so numeric prefixes control the load sequence. This matters because later files may depend on functions or variables defined by earlier ones.
|
|
|
|
## File Naming Convention
|
|
|
|
| Prefix | Purpose | Example |
|
|
|--------|----------------------------------|---------------------------|
|
|
| `00-` | Helper functions (loaded first) | `00-path-helper` |
|
|
| `10-` | PATH configuration | `10-go-path`, `10-rust-path` |
|
|
| `20-` | Build tool settings | `20-ninja` |
|
|
| `30-` | Shell/prompt setup | `30-starship` |
|
|
| `50-` | Shell completions | `50-claude-completion` |
|
|
| `99-` | Credentials and app config (last)| `99-gemini`, `99-huggingface` |
|
|
|
|
Lower numbers load first, so foundational pieces like helper functions (`00-`) and PATH entries (`10-`) are available before anything that depends on them.
|
|
|
|
## Current Files
|
|
|
|
### Helpers (`00-`)
|
|
|
|
- **`00-path-helper`** — Defines `path_append` and `path_prepend` functions that safely add directories to `$PATH` (checking the directory exists and avoiding duplicates).
|
|
- **`00-credential-guard`** — Defines `require_private`, which warns at shell startup if a credential file has overly permissive permissions (anything beyond owner-only access).
|
|
|
|
### PATH (`10-`)
|
|
|
|
- **`10-bun-path`** — Adds Bun (JavaScript runtime) binaries to PATH.
|
|
- **`10-go-path`** — Sets `$GOPATH` and adds Go binaries to PATH.
|
|
- **`10-rust-path`** — Sets `$CARGO_HOME` and adds Cargo binaries to PATH.
|
|
|
|
### Build Tools (`20-`)
|
|
|
|
- **`20-ninja`** — Configures Ninja as the default CMake generator and enables ccache for C/C++ builds (only when installed).
|
|
- **`20-oneapi`** — Sources the Intel oneAPI environment and adds its libraries to `LD_LIBRARY_PATH`.
|
|
|
|
### Prompt (`30-`)
|
|
|
|
- **`30-starship`** — Initialises the [Starship](https://starship.rs) cross-shell prompt, if installed.
|
|
|
|
### Completions (`50-`)
|
|
|
|
- **`50-asdf-completion`** — Tab completion for the asdf version manager.
|
|
- **`50-claude-completion`** — Tab completion for [Claude Code](https://claude.com/claude-code) CLI.
|
|
- **`50-fj-completion`** — Tab completion for the Forgejo CLI (`fj`).
|
|
- **`50-tailscale-completion`** — Tab completion for Tailscale.
|
|
- **`50-uv-completion`** — Tab completion for [uv](https://github.com/astral-sh/uv) (Python package manager).
|
|
|
|
### Credentials & App Config (`99-`)
|
|
|
|
- **`99-android`** — Sets `$ANDROID_HOME`, `$JAVA_HOME`, and adds Android SDK tools to PATH (only when installed).
|
|
- **`99-claude.example`** — Template for Forgejo issue token for Claude Code integrations.
|
|
- **`99-gemini.example`** — Template for Gemini API key.
|
|
- **`99-google.example`** — Template for Google API key.
|
|
- **`99-huggingface.example`** — Template for HuggingFace token (`$HF_TOKEN`).
|
|
- **`99-replicate.example`** — Template for Replicate API token.
|
|
|
|
## Adding a New File
|
|
|
|
1. Create the file with the appropriate numeric prefix:
|
|
```bash
|
|
vim ~/.bash.d/50-mytool-completion
|
|
```
|
|
|
|
2. Start the file with the shellcheck directive:
|
|
```bash
|
|
# shellcheck shell=bash
|
|
```
|
|
|
|
3. Make it executable (required for it to be sourced):
|
|
```bash
|
|
chmod +x ~/.bash.d/50-mytool-completion
|
|
```
|
|
|
|
4. For credential files, create a `.example` template and the real file:
|
|
```bash
|
|
# Create the template (tracked in git)
|
|
cat > ~/.bash.d/99-mytool.example << 'EOF'
|
|
# shellcheck shell=bash
|
|
# Copy to 99-mytool and fill in your token, then: chmod 700 99-mytool
|
|
require_private "${BASH_SOURCE[0]}"
|
|
export MY_SECRET_TOKEN=your-token-here
|
|
EOF
|
|
|
|
# Create the real file from the template
|
|
cp ~/.bash.d/99-mytool.example ~/.bash.d/99-mytool
|
|
# Edit 99-mytool and fill in your real secret
|
|
chmod 700 ~/.bash.d/99-mytool
|
|
```
|
|
Then add `99-mytool` to `.gitignore`.
|
|
|
|
5. Validate with shellcheck:
|
|
```bash
|
|
shellcheck ~/.bash.d/50-mytool-completion
|
|
```
|
|
|
|
## Security
|
|
|
|
Credential files (`99-*`) are **excluded from git** via `.gitignore` and are never committed. Each credential has a tracked `.example` template with placeholder values. To set up credentials:
|
|
|
|
1. Copy the template: `cp 99-foo.example 99-foo`
|
|
2. Fill in your real secret
|
|
3. Restrict permissions: `chmod 700 99-foo`
|
|
|
|
Additional protections:
|
|
|
|
- **File permissions** — Credential files use mode `700` (owner-only).
|
|
- **Runtime checks** — The `require_private` helper warns on shell startup if a credential file has been accidentally loosened.
|
|
- **Never commit real secrets** — Only `.example` templates are tracked in git.
|