Pump is an experiment in sparse config hydration for GitOps and declarative configuration.
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.
Homebrew:
brew install adrianmross/tap/pumpShell installer:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/adrianmross/pump/releases/download/v0.2.0/pump-installer.sh | shFrom source:
cargo install --path .For local development:
cargo run -- diff examples/object/source.json --rules examples/object/rules.pump.yamlPrimary 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.yamlShort aliases may be useful once the semantics are stable:
pump in # alias for inflate
pump out # alias for deflateFlags 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.
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: RuntimeDefaultThe match path syntax is intentionally small:
$targets the document root.$.field.nestedtargets 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: IfNotPresentPath syntax:
$targets the document root.$.field.nestedtargets object fields.$.metadata.labels.app\\.kubernetes\\.io/nameescapes dots in keys./spec/template/specuses JSON Pointer.*targets all object children or array items.
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 --fixcheckvalidates that input and rules can be inflated.check --strictfails with a diff if applying the rules would change the file.check --writeinflates the file in place.check --fixis an alias for--write.checkaccepts 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: yamlExplicit 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 --jsonTreat 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 demoThe demo recipe expects vhs and
bat to be installed and writes
docs/assets/pump-demo-diff.gif.
make fmt
make lint
make test
make build
make dist-planThe 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.
- 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.
- 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.
- 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.
deflateremoves values that equal defaults, which is useful for compression but loses whether the value was intentionally authored.
