Skip to content

sebastienrousseau/noya-cli

Repository files navigation

Noyalib logo

noyalib-cli

noyafmt and noyavalidate — the YAML formatter and validator that ship as the CLI half of the noyalib workspace.

Build Crates.io Docs.rs GitHub Release OpenSSF Scorecard


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.

About

Command-line YAML formatter (noyafmt) + schema validator (noyavalidate) backed by noyalib

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages