Skip to content
tonythethompson edited this page Jul 10, 2026 · 1 revision

Contribution & Local Setup

Numan is a cross-platform package manager for Nushell written in Rust. The project follows a strict architecture centered around the principle that installations should be inert, only modifying the Nushell environment during an explicit activation step. Contributors are expected to maintain these boundaries and adhere to high-quality gates, including linting, formatting, and extensive unit and integration testing.

This guide outlines the technical requirements, development workflow, and architectural invariants necessary to set up a local development environment and contribute to the project. It covers the prerequisites for building the CLI, the testing strategy—including the use of injectable seams to avoid spawning real processes in unit tests—and the rules governing state mutation and file ownership.

Local Environment Setup

To begin contributing, developers must have the Rust toolchain and Nushell installed. The project relies on standard Rust tooling for building, testing, and linting.

Prerequisites

  • Rust: 1.88+ (stable recommended), with cargo, clippy, and rustfmt
  • Nushell: Required on PATH for activation commands and real-Nu acceptance tests (Nu 0.113+ for acceptance tests)
  • Git: For cloning the repository and managing branches

Initial Commands

The following commands are used to prepare the environment and verify the build:

git clone https://github.com/tonythethompson/numan.git
cd numan
cargo build
cargo test                    # 376 unit + integration tests
cargo clippy -- -D warnings   # CI-enforced
cargo fmt

# Real-Nu acceptance (requires Nu 0.113+ on PATH)
cargo test -- --ignored

Canonical contributor guide: CONTRIBUTING.md.

Project Initialization

After building, the CLI must be initialized to probe the local Nu installation and create the necessary state directories under the platform-specific root (e.g., ~/.local/share/numan on Linux).

numan init
numan registry sync

Development Workflow

The project follows a standard feature-branch workflow with specific requirements for pull requests and code quality.

Branching and Commits

  • Branching: Create branches from master using feature/<description> or fix/<description>.
  • Commit Messages: Use the imperative mood and keep subjects under 72 characters. Examples include fix(activate): ... or feat(nupm): ....
  • Merge Policy: Squash merges are utilized for feature branches.

Testing Strategy

Numan utilizes a multi-layered testing approach to ensure stability across Windows, Linux, and macOS.

Test Type Command Description
Unit Tests cargo test <module> Inline tests within source modules using injectable seams.
Integration Tests cargo test Located in tests/, covering multi-module flows.
Acceptance Tests cargo test -- --ignored Real-Nu tests that spawn actual Nushell processes to verify activation.

Testing Seams

To avoid spawning real processes in unit tests, developers MUST use injectable seams such as FakeCandidateRunner for modules and registrars for plugins. Spawning a real nu binary in a unit test is strictly prohibited.

Flow of a Feature Implementation

The following diagram illustrates the standard cycle for implementing a new feature in Numan.

flowchart TD
    Start[Create Feature Branch] --> TestFirst[Write Failing Test]
    TestFirst --> Implement[Implement Feature]
    Implement --> Quality{Quality Gates?}
    Quality -- Fail --> Implement
    Quality -- Pass --> PR[Open Pull Request]
    PR --> Review{Code Review}
    Review -- Changes --> Implement
    Review -- Approve --> Merge[Squash Merge to Master]
Loading

The diagram shows the iterative development process, emphasizing the "test-first" approach and mandatory quality gates.

Architectural Invariants

Contributors must adhere to non-negotiable architecture rules. Violations are treated as high-severity (P0/P1) findings during review.

Mandatory Rules

  1. Install is Inert: The install command only writes to $NUMAN_ROOT. It must never invoke Nu or register plugins/autoloads.
  2. Separate Activation: Only activate and deactivate are permitted to modify Nushell integration state.
  3. Lockfile as Truth: The JSON lockfile is the authoritative source for installation and activation state. Derived projections (like autoload-state.json) are not authoritative.
  4. Mutation Locking: Any command that modifies state (e.g., install, remove, gc) must acquire a mutation lock via acquire_mutation_lock(root).
  5. Atomic Writes: All state updates (lockfiles, journals) must use write_json_atomic to prevent corruption.

Data Structures and Serialization

The following table summarizes key data structures relevant to local state and configuration.

Structure File Path Purpose
NuPaths src/nu/paths.rs Caches detected Nu executable, version, and vendor paths.
Lockfile src/state/lockfile.rs Authoritative record of versions, hashes, and activation status.
Config src/config.rs Handles root resolution and registry configuration.
MutationLock src/util/fs_safety.rs RAII guard for serializing destructive operations.

Code Style and Standards

  • Rust Edition: 2021.
  • Error Handling: Use anyhow::Result with .context() for application logic. Use thiserror for library types that require pattern matching.
  • Path Handling: Function parameters should use &Path instead of &PathBuf (enforced by Clippy).
  • Platform Detection: Use #[cfg(target_env)] rather than std::env::consts to ensure correct platform triple resolution at compile time.

Mutation Lock Sequence

The following sequence diagram represents how Numan ensures only one process mutates the state at a time.

sequenceDiagram
    participant CLI as "Numan CLI"
    participant Lock as "Mutation Lock (fs_safety)"
    participant State as "Lockfile / Payload"

    CLI->>Lock: acquire_mutation_lock(root)
    alt Lock Available
        Lock-->>CLI: MutationLock RAII Guard
        CLI->>State: Snapshot Lockfile
        CLI->>State: Perform Mutation (Install/Remove)
        CLI->>State: Write Atomic JSON
        CLI->>Lock: Drop Guard (Automatic)
    else Lock Held
        Lock-xCLI: Error: Mutation in progress
    end
Loading

This diagram demonstrates the safety mechanism used to prevent concurrent modifications to the $NUMAN_ROOT.

Conclusion

By following these guidelines, contributors ensure that Numan remains a reliable, cross-platform tool for the Nushell community. The combination of strict architectural boundaries, mandatory atomic operations, and a robust testing suite allows the project to scale while maintaining the integrity of the user's shell environment. Always verify changes against the cargo test suite and perform a numan doctor check locally before submitting a pull request.

Clone this wiki locally