Skip to content

adrianmross/pump

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pump

Pump is an experiment in sparse config hydration for GitOps and declarative configuration.

Pump terminal demo

The core workflow is:

sparse intent + rules -> inflated manifests
inflated manifests + rules -> deflated intent

Pump should make repetitive JSON/YAML configuration smaller without making the rendered result mysterious. The rendered output must stay ordinary JSON/YAML, and every generated field should be explainable.

Install

Homebrew:

brew install adrianmross/tap/pump

Shell installer:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/adrianmross/pump/releases/download/v0.2.0/pump-installer.sh | sh

From source:

cargo install --path .

For local development:

cargo run -- diff examples/object/source.json --rules examples/object/rules.pump.yaml

CLI shape

Primary commands:

pump inflate app.yaml --rules platform.pump.yaml --out rendered.yaml
pump inflate --config pump.yaml --out-dir rendered/
pump deflate rendered.yaml --rules platform.pump.yaml --out app.yaml
pump explain app.yaml --rules platform.pump.yaml --path '$.spec.template.spec.securityContext'
pump diff app.yaml --rules platform.pump.yaml
pump diff app.yaml --rules platform.pump.yaml --explain
pump check app.yaml --rules platform.pump.yaml
pump check rendered.yaml --rules platform.pump.yaml --strict
pump check app.yaml --rules platform.pump.yaml --write
pump check services/*.yaml --rules platform.pump.yaml --strict
pump suggest inflated/*.yaml --out suggested.pump.yaml

Short aliases may be useful once the semantics are stable:

pump in   # alias for inflate
pump out  # alias for deflate

Flags like -i and -d are best reserved for options or explicit shortcut modes, because subcommands are easier to read in CI logs and GitOps reviews.

Rule format

Pump v1 supports ordered rules. Rules run top-to-bottom, so later rules can override earlier generated values.

rules:
  - name: deployment-platform-defaults
    match: "$.spec.template.spec"
    defaults:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault

The match path syntax is intentionally small:

  • $ targets the document root.
  • $.field.nested targets object fields.
  • * targets all object children or array items, such as $.spec.template.spec.containers.*.

Supported operations:

  • defaults: deep-merge missing fields. Authored values win.
  • overrides: deep-merge and force values even when authored.
  • delete: remove relative or absolute paths from each match.
  • replace: replace the whole matched value. It cannot be combined with other operations in the same rule.

Rules can be limited to Kubernetes-style documents:

rules:
  - name: deployment-runtime-defaults
    match: "$.spec.template.spec.containers.*"
    apiVersion: apps/v1
    kind: Deployment
    metadataName: billing-api
    defaults:
      imagePullPolicy: IfNotPresent

Path syntax:

  • $ targets the document root.
  • $.field.nested targets object fields.
  • $.metadata.labels.app\\.kubernetes\\.io/name escapes dots in keys.
  • /spec/template/spec uses JSON Pointer.
  • * targets all object children or array items.

Examples

Service catalog defaults:

cd examples/object
pump diff
pump diff --explain
pump explain source.json --rules rules.pump.yaml --path '$.api.resources.memory'

The source stays sparse:

{
  "api": {
    "image": "ghcr.io/acme/payments-api:v1.8.0",
    "port": 8080,
    "resources": {
      "cpu": "250m"
    }
  }
}

The diff shows what Pump adds:

 "resources": {
-  "cpu": "250m"
+  "cpu": "250m",
+  "memory": "128Mi"
 },
+"replicas": 1,
+"env": "prod"

Kubernetes-style YAML stream:

cd examples/kubernetes
pump diff
pump diff --explain
pump explain source.yaml --rules rules.pump.yaml --path '$.spec.replicas'

See the Kubernetes example for a small GitOps-style sparse/inflated workflow with generated labels, selectors, replicas, workload defaults, Service defaults, and provenance.

Biome-style checking:

pump check app.yaml --rules platform.pump.yaml
pump check rendered.yaml --rules platform.pump.yaml --strict
pump check app.yaml --rules platform.pump.yaml --write
pump check app.yaml --rules platform.pump.yaml --fix
  • check validates that input and rules can be inflated.
  • check --strict fails with a diff if applying the rules would change the file.
  • check --write inflates the file in place.
  • check --fix is an alias for --write.
  • check accepts one or more input files; multi-file strict mode evaluates every file before failing.

Project config is optional. When pump.yaml, .pump.yaml, pump.yml, .pump.yml, pump.json, or .pump.json exists in the current directory, commands can default rules, inputs, outDir, and format from it:

rules: rules.pump.yaml
inputs:
  - source.yaml
outDir: rendered
format: yaml

Explicit CLI arguments win over config values. Config paths resolve relative to the config file, so examples and CI jobs can run with short paths. Multi-input inflate requires --out-dir or config outDir; --out remains a single-file output.

diff --explain prints a normal unified diff first, then lists the rule operations responsible for generated or changed values.

explain also prints the rule operations related to the inspected path. Add --all to include the full rule trace for the document, including skipped and unchanged rules. Generated values include operation-level rule locations when available. Use --json when that trace needs to feed another tool.

suggest / discover scans inflated or authored input and emits candidate defaults rules for repeated scalar leaf values:

pump suggest inflated/*.yaml --min-occurrences 3 --out suggested.pump.yaml
pump discover inflated/*.yaml --json

Treat suggestions as a starting point for review. Pump intentionally does not infer templates, filters, KRM functions, or programmable logic from examples.

To refresh the README terminal demo after CLI semantics settle:

make demo

The demo recipe expects vhs and bat to be installed and writes docs/assets/pump-demo-diff.gif.

Development

make fmt
make lint
make test
make build
make dist-plan

The CI scaffold runs the same Rust checks on pull requests and main. Release workflows are tag/manual driven and use cargo-dist; nothing should publish on merge.

Product constraints

  • Source files may be plain JSON/YAML.
  • Rendered files must be plain JSON/YAML.
  • Authored values win over defaults unless a rule explicitly overrides.
  • Rule application must be deterministic.
  • Generated values need provenance.
  • CI should be able to verify that rendered output is current.
  • Policy engines should run against the inflated output.

Non-goals for the first version

  • Replacing Jsonnet, CUE, Helm, or Kustomize.
  • Arbitrary programming inside rule files.
  • Hidden mutation without an inspectable rendered artifact.

See provenance for the current explain/provenance model, and adjacent tools for Pump's intended wedge beside Jsonnet, CUE, Kustomize, Helm, ytt, and kpt.

Current limitations

  • YAML comments and original formatting are intentionally not preserved in v1; output is normalized. Format-preserving output is tracked as a later enhancement in issue #2.
  • YAML custom tags are parsed and emitted for YAML output, but formatting around tagged values is still normalized with the rest of the document.
  • Path syntax does not support filters.
  • deflate removes values that equal defaults, which is useful for compression but loses whether the value was intentionally authored.

About

Keep JSON/YAML source lean with inflate/deflate transforms

Topics

Resources

License

Stars

Watchers

Forks

Contributors