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
248 changes: 210 additions & 38 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,58 @@ Written in Ada for safety-critical reliability.

toc::[]

== Overview
== Deliverable

Modshells transforms monolithic shell configuration files (`.bashrc`, `.zshrc`, etc.) into a modular directory structure. Instead of maintaining a single, sprawling configuration file, Modshells organises configurations into logical categories that are automatically sourced.
**Modshells** is a command-line tool that transforms monolithic shell configuration files into a modular, maintainable directory structure. The tool:

=== The Problem
1. **Creates** a standardised directory hierarchy for shell configurations
2. **Detects** installed shells on your system (Bash, Zsh, Fish, Nushell, and 6 others)
3. **Injects** sourcing logic into shell configuration files (with backup)
4. **Ensures idempotency** - safe to run multiple times without side effects

Traditional shell configuration becomes unwieldy:
=== Current Status

* Single files grow to hundreds of lines
* Related configurations scattered throughout
* Difficult to share configurations across shells
* No clear separation of concerns
* Risky manual editing of critical dotfiles
[cols="1,1"]
|===
| Aspect | Status

| Directory creation | ✓ Working
| Shell detection | ✓ Working (checks /usr/bin, /bin, /usr/local/bin, /opt/homebrew/bin)
| Config backup | ✓ Working (timestamped backups before modification)
| Source injection | ✓ Working (shell-specific syntax for all 10 shells)
|===

=== The Solution
*Version 0.1* - Core functionality complete. The tool detects installed shells, backs up configs, and injects modular sourcing blocks.

Modshells creates a standardised modular structure:
=== What You Get

After running `modshells`, your shell configurations are organised into:

[source]
----
~/.config/nushell/modshells/
├── core/ # Essential shell settings, prompts, paths
├── tools/ # Tool-specific configs (git, fzf, starship)
├── misc/ # Miscellaneous aliases and functions
├── os/ # OS-specific configurations
└── ui/ # Visual customisations, themes
├── core/ # PATH, prompt, history, shell options
├── tools/ # git, fzf, starship, direnv configs
├── misc/ # Custom aliases and functions
├── os/ # Linux vs macOS differences
└── ui/ # Themes and visual settings
----

Each directory contains shell-agnostic or shell-specific configuration snippets that are automatically sourced in order.
Each shell's config file (`.bashrc`, `.zshrc`, etc.) sources these directories automatically. Add a new alias? Drop a file into `misc/`. OS-specific tweak? Put it in `os/`. Done.

== The Problem

Traditional shell configuration becomes unwieldy:

* Single files grow to hundreds of lines
* Related configurations scattered throughout
* Difficult to share configurations across shells
* No clear separation of concerns
* Risky manual editing of critical dotfiles

== The Solution

Modshells creates a standardised modular structure with shell-agnostic or shell-specific configuration snippets that are automatically sourced in order.

== Features

Expand Down Expand Up @@ -152,21 +175,59 @@ nix profile install github:hyperpolymath/modshells

== Usage

=== Basic Initialisation
=== Basic Usage

[source,bash]
----
# Initialise modular structure in default location
modshells
# Build and run
gprbuild -p -j0 modshells.gpr
./bin/modshells
----

Example output:
[source]
----
=== Modshells v0.1 ===
Configuration path: /home/user/.config/nushell/modshells

Creating modular directory structure...
Directories ready: core, tools, misc, os, ui

Detecting installed shells...
bash: [installed]
dash: [not found]
fish: [installed]
ion: [not found]
nushell: [installed]
tcsh: [not found]
zsh: [installed]
oils: [not found]
pwsh: [not found]
ksh: [not found]

Modularising shell configurations...
Modularising bash...
Backup created: /home/user/.bashrc.modshells-backup-20250101-120000
Injected modshells sourcing block.
Modularising fish...
Injected modshells sourcing block.
...

=== Modshells complete ===
----

=== Custom Configuration Path

[source,bash]
----
# Use custom configuration path
export MODSHELLS_CONFIG_PATH="$HOME/.config/shells/modular"
modshells
----

=== Directory Structure
=== Populating Your Configuration

After initialisation, populate directories with configuration snippets:
After initialisation, add configuration snippets:

[source,bash]
----
Expand Down Expand Up @@ -215,29 +276,140 @@ core/
| Visual customisations: colours, themes, terminal-specific settings
|===

== Examples

The `examples/` directory contains ready-to-use configuration snippets:

[source,bash]
----
# Copy all examples to your modshells directory
cp -r examples/* ~/.config/nushell/modshells/

# Or copy individual files
cp examples/tools/git.sh ~/.config/nushell/modshells/tools/
cp examples/misc/aliases.sh ~/.config/nushell/modshells/misc/
----

=== Available Examples

[cols="1,2"]
|===
| File | Description

| `core/00-path.sh`
| PATH modifications for ~/.local/bin, Cargo, Go, Deno

| `core/10-history.sh`
| History size, deduplication, timestamps, ignore patterns

| `core/20-options.sh`
| Shell options (extglob, cdspell, globstar), editor, locale

| `tools/git.sh`
| Git aliases (gs, ga, gc, gp, gl, glog, etc.)

| `tools/fzf.sh`
| Fuzzy finder setup with fd integration

| `tools/starship.sh`
| Starship prompt initialisation

| `misc/aliases.sh`
| Navigation (.., ...), ls variants, safety nets (rm -i)

| `misc/functions.sh`
| Utility functions: mkcd, extract, ff, fd, backup

| `os/linux.sh`
| Package manager aliases, systemd shortcuts

| `os/macos.sh`
| Homebrew setup, macOS-specific utilities

| `ui/colours.sh`
| Terminal colours, GCC colours, man page colours

| `ui/prompt.sh`
| Custom bash prompt with git branch (fallback for non-starship)
|===

== Testing

=== Smoke Test

Run the shell-based smoke test to verify the build:

[source,bash]
----
# From the repository root
./tests/smoke_test.sh
----

The smoke test verifies:

* Source files exist
* Examples have correct structure
* SPDX license headers present
* Binary runs (if built)
* Directory creation works
* Idempotency check passes

=== Unit Tests

Build and run the Ada unit tests:

[source,bash]
----
# Build tests
gprbuild -p -j0 -P tests/tests.gpr

# Run tests
./bin/test_shell_manager
----

== Development Status

Current version: **v0.0 (Alpha)**
Current version: **v0.1**

=== Implemented
=== Implemented Features

* [x] Core Ada package structure
* [x] Idempotent directory creation
* [x] Configuration path resolution
* [x] Environment variable support
* [x] Shell type enumeration (10 shells)
* [x] Signature-based modularisation check
* [x] GNAT project build configuration
* [x] CI/CD pipeline (GitHub Actions)
[cols="1,2"]
|===
| Feature | Description

| Directory creation
| Idempotently creates `core/`, `tools/`, `misc/`, `os/`, `ui/` structure

| Path resolution
| Reads `MODSHELLS_CONFIG_PATH` or defaults to `~/.config/nushell/modshells`

| Shell detection
| Checks `/usr/bin`, `/bin`, `/usr/local/bin`, `/opt/homebrew/bin` for shell binaries

| Config file backup
| Creates timestamped backups (`.modshells-backup-YYYYMMDD-HHMMSS`) before modification

| Source injection
| Appends shell-specific sourcing blocks with `MODSHELLS_START`/`END` markers

| Shell-specific syntax
| Generates correct sourcing code for all 10 shells (POSIX, Fish, Nushell, Tcsh, Ion, PowerShell)

| Idempotency
| Signature-based detection prevents duplicate injections

| Build system
| GPRBuild project files with CI/CD (GitHub Actions)
|===

=== In Progress
=== Future Enhancements

* [ ] Actual shell detection (currently stubbed)
* [ ] Configuration file backup
* [ ] Source injection logic
* [ ] Shell-specific sourcing syntax
See link:ROADMAP.adoc[ROADMAP.adoc] for planned features including:

See link:ROADMAP.adoc[ROADMAP.adoc] for detailed development plans.
* Command-line arguments (`--shell=bash,zsh`, `--dry-run`)
* Shell-agnostic `.modshells` config format
* Configuration drift detection
* Snippet management commands

== Contributing

Expand Down
69 changes: 69 additions & 0 deletions examples/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
= Modshells Example Configurations
:toc:

Example shell configuration snippets for use with Modshells.

== Usage

Copy the snippets you want into your modshells directory:

[source,bash]
----
# Copy all examples
cp -r examples/* ~/.config/nushell/modshells/

# Or copy individual files
cp examples/tools/git.sh ~/.config/nushell/modshells/tools/
----

== Directory Structure

[cols="1,3"]
|===
| Directory | Purpose

| `core/`
| Essential settings loaded first (PATH, history, shell options)

| `tools/`
| Tool-specific configurations (git, fzf, starship)

| `misc/`
| General aliases and utility functions

| `os/`
| Operating system specific settings (Linux, macOS)

| `ui/`
| Visual customisations (colours, prompt)
|===

== File Naming

Files are sourced alphabetically. Use numeric prefixes to control load order:

* `00-*.sh` - Load first (PATH, critical settings)
* `10-*.sh` - Load early (history, options)
* `20-*.sh` - Load later (depends on earlier settings)
* No prefix - Load in alphabetical order

== Customisation

These examples are starting points. Modify them to suit your workflow:

1. Copy the file to your modshells directory
2. Edit to add/remove aliases and settings
3. Restart your shell or run `source ~/.bashrc`

== Shell Compatibility

These examples use POSIX-compatible syntax and work with:

* Bash
* Zsh
* Ksh
* Dash (limited)
* Oils (OSH/YSH)

For Fish, Nushell, or PowerShell, you'll need to translate the syntax.
See the main README for shell-specific sourcing blocks.
16 changes: 16 additions & 0 deletions examples/core/00-path.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: AGPL-3.0-or-later OR MIT
# core/00-path.sh - PATH modifications (loaded first)
#
# Add custom directories to PATH. Use numeric prefix to control load order.

# Local binaries
export PATH="$HOME/.local/bin:$PATH"

# Cargo (Rust)
[ -d "$HOME/.cargo/bin" ] && export PATH="$HOME/.cargo/bin:$PATH"

# Go
[ -d "$HOME/go/bin" ] && export PATH="$HOME/go/bin:$PATH"

# Deno
[ -d "$HOME/.deno/bin" ] && export PATH="$HOME/.deno/bin:$PATH"
Loading
Loading