Initial commit: modular bash configuration

Reinitialised repo to purge credential history.
Credential files are now gitignored with .example templates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-03-06 11:57:24 +01:00
commit 4cfec0b336
22 changed files with 364 additions and 0 deletions

114
README.md Normal file
View file

@ -0,0 +1,114 @@
# ~/.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
The `~/.bashrc` 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.