noya-cli 0.0.1

Command-line tools for noyalib (noyafmt, noyavalidate)
Documentation

Contents


Install

Channel Command
Cargo (crates.io) cargo install noya-cli --locked
Cargo (from source) cargo install --locked --path .
Homebrew (personal tap) brew tap sebastienrousseau/tap && brew install noyalib
Arch (AUR) yay -S noyalib-bin (binary) or yay -S noyalib (source)
Scoop (Windows) scoop bucket add sebastienrousseau https://github.com/sebastienrousseau/scoop-bucket && scoop install noyalib
Nix nix run github:sebastienrousseau/noyalib
Container (GHCR) docker run --rm -v "$(pwd):/work" -w /work ghcr.io/sebastienrousseau/noyafmt:latest --check ci/*.yaml

Pre-built tarballs for 14 targets (Linux gnu + musl, macOS Intel + Apple Silicon + universal, Windows x86_64 + i686 + aarch64) are attached to every GitHub Release. Each artefact is signed with cosign keyless and carries a SLSA L3 build provenance attestation — see Verification for the verify commands or pkg/VERIFY.md for the full cookbook.

MSRV: Rust 1.85.0. The clap dep tree pulls clap_builder 4.6 (edition 2024); the noyalib core library itself stays at 1.75.


Quick Start

# Format a file in-place; comments + indentation preserved.
noyafmt --write config.yaml

# CI gate — exits 1 if any file would change.
noyafmt --check ci/*.yaml

# Validate syntax + JSON Schema 2020-12.
noyavalidate --schema schema.yaml deploy.yaml

# Validate + auto-fix obvious type slips (port: "8080" → 8080).
noyavalidate --schema schema.yaml --fix deploy.yaml

noyafmt

YAML formatter mirroring the rustfmt / prettier ergonomics:

noyafmt config.yaml                # print formatted source to stdout (default)
noyafmt --write config.yaml        # rewrite in place
noyafmt --check ci/*.yaml          # CI gate
noyafmt --indent 4 config.yaml     # override default 2-space indent
cat foo.yaml | noyafmt --stdin     # editor pipe (Vim, Emacs, …)
git ls-files '*.yaml' | xargs noyafmt --check

The formatter runs through noyalib's lossless CST: comments, anchor positions, and document structure are preserved byte-for-byte; only whitespace and quoting are normalised.

Flag Effect
--check Verify each FILE is formatted; print files that need formatting; exit 1 if any do. Non-destructive.
--write Rewrite each FILE in place. Default is to print to stdout. Mutually exclusive with --check.
--stdin Read from stdin, write to stdout. Mutually exclusive with FILE arguments.
--indent N Indentation width in spaces (default: 2).

noyavalidate

YAML syntax checker with optional JSON Schema 2020-12 enforcement and schema-driven autofix.

noyavalidate manifest.yaml                          # syntax only
noyavalidate --schema schema.yaml deploy.yaml       # + schema check
noyavalidate --schema schema.yaml --fix deploy.yaml # + autofix
cat manifest.yaml | noyavalidate                    # stdin

The autofix engine (coerce_to_schema) rewrites string-shaped scalars into the schema's expected type when the parse succeeds. Loops until convergence; unparseable inputs (port: "abc" against type: integer) are left in place so a follow-up validate_against_schema call surfaces the residue.

Diagnostics use miette for rustc-style source pointers:

× schema violation: "8080" is not of type "integer"
   ╭─[deploy.yaml:3:7]
 2 │ replicas: 3
 3 │ port: "8080"
   ·       ─┬───
   ·        ╰── here
 4 │ host: api
   ╰────
   help: pass --fix to coerce string-shaped scalars to the
         schema's declared type.
Flag Effect
-s, --schema PATH Validate each document against JSON Schema 2020-12 at PATH (the schema may itself be YAML or JSON).
--fix Rewrite FILE in place via the CST formatter (lossless: byte-faithful for everything except normalised whitespace / line endings). With stdin input, the formatted bytes go to stdout.
-q, --quiet Suppress success output.

Exit codes

Code noyafmt noyavalidate
0 success (or no changes if --check) all valid
1 parse / I/O error, or --check found unformatted file(s) parse error or schema violation
2 invalid usage (bad arg combination) invalid usage
3 I/O error (read / write)

Examples

End-to-end runnable demos under crates/noya-cli/examples/:

Script What it shows
format-precommit.sh Drop-in git pre-commit hook gating commits on noyafmt --check.
validate-k8s.sh CI step that runs noyavalidate --schema over a directory of Kubernetes manifests.
fix-quoted-numbers.sh Walkthrough of the --fix autofix flow: quoted scalar → schema-typed integer, with the surrounding comment preserved.
chmod +x crates/noya-cli/examples/*.sh
crates/noya-cli/examples/fix-quoted-numbers.sh

Shell completions and man pages

Tarball releases ship pre-built completions for bash, fish, zsh, and PowerShell, plus roff man pages. Distro packages drop them into the standard system locations (/usr/share/bash-completion/completions/, /usr/share/man/man1/, …).

If installing via cargo install, regenerate locally:

git clone https://github.com/sebastienrousseau/noyalib
cd noyalib
cargo xtask completions    # writes complete/{noyafmt,noyavalidate}.{bash,fish,zsh,ps1}
cargo xtask manpages       # writes doc/{noyafmt,noyavalidate}.1

Verification

Every release artefact ships with a cosign keyless signature (<artefact>.sig + <artefact>.pem) and a SLSA L3 build provenance attestation. Verify before trusting a downloaded binary:

COSIGN_EXPERIMENTAL=1 cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/sebastienrousseau/noyalib/' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --certificate <artefact>.pem \
  --signature   <artefact>.sig \
  <artefact>

gh attestation verify --owner sebastienrousseau <artefact>

Full cookbook including the offline / FIPS-bound flow: pkg/VERIFY.md.


When not to use these tools

  • You need to format YAML faster than human-perceivable latency. noyafmt runs end-to-end on a 1 MiB document in ~10 ms; for <100 KB documents that's already invisible. But for a streaming editor pipeline that wants per-keystroke formatting, the LSP server (noyalib-lsp) issues incremental TextEdit[]s instead.
  • You need YAML 1.1-only behaviour, top to bottom. noyavalidate follows YAML 1.2; the legacy_booleans opt-in is exposed at the library level but not yet plumbed through the CLI.
  • You need to embed the formatter or validator in your own Rust binary. Use the noyalib library directly — every CLI feature flows through public library APIs (cst::format_with_config, validate_against_schema, coerce_to_schema).

Documentation


License

Dual-licensed under Apache 2.0 or MIT, at your option.