Skip to main content

Fleet-level modelling and operations for OSS package repos, in Rust.

Project description

nave

uv PyPI Supported Python versions License pre-commit.ci status

Fleet-level operations for OSS package repos.

If you maintain multiple repos, each with its own pyproject.toml, CI workflows, dependabot config, pre-commit hooks, and so on, nave lets you query and manage these as a fleet.

Examples of questions nave is built to answer:

  • Which of my repos use maturin and have pytest in CI?
  • What's the shared skeleton across all my dependabot configs, and where do they diverge?
  • Which repos still pin an old Python version in pyproject.toml?

If you have one repo, or a monorepo, this isn't for you. If you have a sprawl of related-but-drifting configs and you've written shell loops over the GitHub API to keep track of them, read on.

nave logo

Nave is built in Rust (nave-rs) with a Python package as a command line entry point (nave). Background on the design is in the Fleet Ops blog series.

Install

pip install nave      # or: uv tool install nave

You'll also want the gh CLI authenticated, or a NAVE_GITHUB_TOKEN in your environment. Anonymous access works but hits the 60 req/hr rate limit quickly on first nave scan.

What it does

Structural simplification of configs

nave build finds the shared skeleton across all tracked configs of the same kind and shows you which fields vary, how often, and with what values. It's a way to see drift, and to work out which fields are worth standardising.

nave build --filter dependabot
━━ .github/dependabot.yml ━━
  instances: 9

  template:
    updates:
      - cooldown?: ⟨?0⟩
        directory: "/"
        package-ecosystem: ⟨?1⟩
        schedule:
          interval: ⟨?2⟩
    version: 2

  holes:
    updates[0].cooldown  [optionalkey]  3/9 optional  [constant when present]
        3× {"default-days":7}
    updates[0].package-ecosystem  [string]  9/9
        8× "github-actions"
        1× "cargo"
    updates[0].schedule.interval  [string]  9/9
        6× "weekly"
        3× "monthly"

This is read as: across 9 dependabot configs, they all have the same shape; the ecosystem and interval vary, and 3 of the 9 set a cooldown. Under the hood this is anti-unification over the parsed YAML/TOML trees, but you don't need to care about that to use it.

JSON output is available with --json for scripting.

Search across tracked files

nave search looks for patterns across your cache of tracked configs.

Plain terms match substrings anywhere; workflow: scopes a term to CI workflow files.

nave search maturin workflow:pytest
lmmx/comrak
lmmx/polars-fastembed
lmmx/page-dewarp
lmmx/polars-luxical

To see where in each file a term matched — particularly useful for pyproject.toml where you often want to know which field, not just which file:

nave search maturin workflow:pytest --output holes | rg -v workflows
pyproject.toml  build-system.build-backend  (2 hits)
pyproject.toml  build-system.requires[0]    (2 hits)
pyproject.toml  dependency-groups.build[0]  (2 hits)
pyproject.toml  dependency-groups.dev[0]    (2 hits)
pyproject.toml  tool.maturin                (2 hits)

Other useful flags: --explain (show matched files and terms), --json, --count, --sort pushed-at --limit N (most recently touched first).

Setup commands

Three plumbing commands you'll run in order on first use:

nave init            # write ~/.config/nave.toml (one-shot)
nave scan        # enumerate repos and index tracked files
nave pull           # sparse-checkout tracked files into ~/.cache/nave/

By default, scan only looks at repos that have changed since the previous scan.

To re-examine every repo (e.g. after narrowing tracked_paths, or to remove cached repos that no longer match), delete ~/.cache/nave/meta.toml and use nave scan --prune.

There's also nave check, which verifies that every tracked config parses without errors.

Verbose logging: NAVE_LOG=debug nave <cmd>.

Configuration

All settings live in ~/.config/nave.toml. nave init writes a commented default you can edit. The knob most people will want is tracked_paths:

[scan]
tracked_paths = [
    "pyproject.toml",
    "Cargo.toml",
    ".pre-commit-config.yaml",
    ".pre-commit-config.yml",
    ".github/workflows/*.yml",
    ".github/workflows/*.yaml",
    ".github/dependabot.yml",
    ".github/dependabot.yaml",
]
case_insensitive = true
exclude_forks = true

Glob semantics follow gitignore syntax for *, **, ? and [abc].

Any field can be overridden via env var using double-underscore as the section separator: NAVE_GITHUB__USERNAME=foo, NAVE_DISCOVERY__EXCLUDE_FORKS=false.

Scope and privacy

  • nave scan queries GET /users/{username}/repos, which returns only public repos even when authenticated.
  • Forks and archived repos are filtered out by default. To configure this, edit the user-level config which is written on nave init or by setting the corresponding environment variables.
  • Private repos aren't included (supporting them is a non-goal).

Architecture

A Rust workspace split across four concerns:

  • CLI & shimnave (binary, subcommand routing) and a thin maturin-packaged Python entry point that execs the Rust binary (same pattern as uv and ruff).
  • Config & cachenave_config handles layered config via figment2, cache layout, and path matching.
  • GitHub I/Onave_github (REST client with auth probing), nave_scan (repo listing and tree walking), nave_pull (sparse checkout).
  • Modellingnave_parse (YAML/TOML de/serialisation), nave_check (WIP), nave_build (anti-unification to find minimal template groupings).

Contributing

See CONTRIBUTING.md for dev setup, the just task list, and git hooks.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nave-0.0.3.tar.gz (60.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nave-0.0.3-py3-none-win_amd64.whl (4.3 MB view details)

Uploaded Python 3Windows x86-64

nave-0.0.3-py3-none-win32.whl (3.7 MB view details)

Uploaded Python 3Windows x86

nave-0.0.3-py3-none-musllinux_1_2_x86_64.whl (4.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

nave-0.0.3-py3-none-musllinux_1_2_i686.whl (4.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ i686

nave-0.0.3-py3-none-musllinux_1_2_armv7l.whl (3.8 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARMv7l

nave-0.0.3-py3-none-musllinux_1_2_aarch64.whl (4.3 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

nave-0.0.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

nave-0.0.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (4.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ s390x

nave-0.0.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (4.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ppc64le

nave-0.0.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (4.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

nave-0.0.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

nave-0.0.3-py3-none-macosx_11_0_arm64.whl (4.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

nave-0.0.3-py3-none-macosx_10_12_x86_64.whl (4.5 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page