{"id":46638187,"url":"https://github.com/lnrdll/ymr","last_synced_at":"2026-03-08T02:13:01.842Z","repository":{"id":335557297,"uuid":"1091280960","full_name":"lnrdll/ymr","owner":"lnrdll","description":"Lightweight, spec-driven YAML template tool","archived":false,"fork":false,"pushed_at":"2026-02-21T22:02:16.000Z","size":4843,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-22T01:22:50.074Z","etag":null,"topics":["cli","go","go-cli","golang","template","template-engine","yaml","yaml-configuration"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lnrdll.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-06T20:00:31.000Z","updated_at":"2026-02-21T21:55:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lnrdll/ymr","commit_stats":null,"previous_names":["lnrdll/ymr"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/lnrdll/ymr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnrdll%2Fymr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnrdll%2Fymr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnrdll%2Fymr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnrdll%2Fymr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lnrdll","download_url":"https://codeload.github.com/lnrdll/ymr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnrdll%2Fymr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30242406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:58:18.660Z","status":"online","status_checked_at":"2026-03-08T02:00:06.215Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","go","go-cli","golang","template","template-engine","yaml","yaml-configuration"],"created_at":"2026-03-08T02:12:56.985Z","updated_at":"2026-03-08T02:13:01.825Z","avatar_url":"https://github.com/lnrdll.png","language":"Go","readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg height=\"535\" alt=\"ymr-logo\" src=\"./assets/ymr.png\" /\u003e\n\n\u003cbr /\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cstrong\u003eymr\u003c/strong\u003e (pronounced \u003cstrong\u003eya·mr\u003c/strong\u003e) is a lightweight, spec-driven command-line tool to generate YAML files from templates. It’s ideal for managing configuration across multiple environments or targets by replacing placeholders in your YAML templates with values defined in a central spec file.\n\n\u003cbr /\u003e\n\n\u003ca href=\"https://github.com/lnrdll/ymr/issues/new?labels=bug\u0026template=bug_report.md\"\u003eReport Bug\u003c/a\u003e\n·\n\u003ca href=\"https://github.com/lnrdll/ymr/issues/new?labels=enhancement\u0026template=feature_request.md\"\u003eRequest Feature\u003c/a\u003e\n\u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n**TOC**\n- [Why?](#why)\n- [How it Works](#how-it-works)\n- [Agent Notes](#agent-notes)\n- [Spec-less Mode](#spec-less-mode)\n- [Installation](#installation)\n- [Development](#development)\n- [Usage](#usage)\n- [Template Syntax](#template-syntax)\n- [Examples](#examples)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n### Why?\n\u003ca name=\"why\"\u003e\u003c/a\u003e\n\nExisting YAML templating tools — such as `jtt`, `Helm`, `Kustomize`, or `Kluctl` — are powerful and versatile, but they often come with a steep learning curve and impose specific formatting or structural requirements on your YAML files.\n\n`ymr` takes a simpler, more flexible approach. You simply add comments to your existing YAML configuration, and if they match your defined specifications, `ymr` performs the substitutions keeping the integrity of the YAML file. This means you can use `ymr` with any YAML file, including those already managed by other tools, without modifying your current workflow or file structure, and use any YAML linter you want.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### How it Works\n\u003ca name=\"how-it-works\"\u003e\u003c/a\u003e\n\n`ymr` processes YAML templates by substituting placeholders with values from your spec.yaml. It supports two main types of placeholders:\n\n- `from-param: {{ .var }}` — replaces the entire value with the parameter `{{ .var }}`.\n- `from-param-merge: {{ .var }}` — merges the parameter `{{ .var }}` into the existing YAML structure.\n\nThis allows for dynamic, reusable configuration generation — letting you define shared values once and selectively override them for specific environments or targets.\n\nIn addition, you can pipe the variables to the following functions:\n\n- `lower`: to set all characters to lower case. Example: `from-param: {{ .var | lower }}`\n- `upper`: to set all characters to upper case. Example: `from-param: {{ .var | upper }}`\n- `replace`: to do string substitution. Example: `from-param: {{ .var | replace \".\" \"-\" }}`\n\nValidations are also available if there is a need to enforce requirements. The policy engine uses the Common Expression Language ([CEL](https://cel.dev/)) and it validates every parameter passed.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Agent Notes\n\u003ca name=\"agent-notes\"\u003e\u003c/a\u003e\n\nIf you're using `ymr` from an AI agent / coding assistant, read these first:\n\n- `AGENTS.md`: repo map, architecture, invariants, and quick commands\n- `SKILL.md`: agent-oriented usage rules and reliable invocation patterns\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Spec-less Mode\n\u003ca name=\"spec-less-mode\"\u003e\u003c/a\u003e\n\n`ymr` can be run **without** a `--spec` (`-s`) flag (spec-less mode), which is useful for simple, one-off template rendering. In this mode, you must provide:\n\n- A template file/URL via the `--template` (`-T`) flag.\n- At least one parameter source via `--param` (`-p`), `--param-file`, or `--param-yaml`.\n\nThis mode is ideal for CI/CD pipelines or simple scripts where a full `spec.yaml` is unnecessary.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Installation\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n\n#### `go install`\n\nYou can install `ymr` using `go install`:\n```bash\ngo install github.com/lnrdll/ymr@latest\n```\n\n#### `Mise`\n\nYou can install 'ymr' using `Mise`:\n```bash\n[tools]\n\"github:lnrdll/ymr\" = \"latest\"\n```\n\nAlternatively, you can download the binary from the [releases page](https://github.com/lnrdll/ymr/releases).\n\n#### Build from source\n\nBuild for your current platform:\n```bash\nmkdir -p dist\ngo build -trimpath -o dist/ymr .\n```\n\nBuild release-style artifacts for linux/windows/darwin on amd64 and arm64:\n```bash\nbash scripts/build-all.sh\n```\n\nArtifacts are written to `dist/`.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Development\n\u003ca name=\"development\"\u003e\u003c/a\u003e\n\nUseful commands when working on `ymr` itself:\n\n```bash\ngo test ./...\n\ngo build -trimpath -o dist/ymr .\n\n# If you use mise (optional)\nmise run test\nmise run lint\n```\n\nNote: `mise` task definitions live in `mise.toml`.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Usage\n\u003ca name=\"usage\"\u003e\u003c/a\u003e\n\n`ymr` provides four commands: `init`, `run`, `validate`, and `version`.\n\n#### `ymr init`\n\nGenerates a boilerplate `spec.yaml` file in your current directory. This is a great starting point for new projects.\n\n```bash\nymr init\n\n# Overwrite an existing spec.yaml\nymr init --force\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eExample `spec.yaml` generated by `init`:\u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\n# A list of templates to process.\n# Paths are relative to the location of this spec.yaml.\ntemplates:\n  - base/service.yaml\n  - base/configmap.yaml\n\n# A simple list of target environments.\ntargetIds:\n  - dev\n  - prd\n\n# A list of parameter sets.\nparameters:\n  # --- Shared values ---\n  - targetId: [\"dev\", \"prd\"] # Which targets this value set applies to\n    values:\n      name: \"myapp-name\"\n\n  # --- Dev-specific values ---\n  - targetId: [\"dev\"]\n    values:\n      minScale: 1\n\n  # --- Prod-specific values ---\n  - targetId: [\"prd\"]\n    values:\n      minScale: 3\n      maxScale: 10\n```\n\n\u003c/details\u003e\n\nIn addition to the default boilerplate, the `init` command also accepts parameters so the boilerplate can be customized.\n\n```bash\nymr init --templates service.yaml --target dev --target stg -p 'maxScale: 10' -p 'minScale: 1'\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eCustom `spec.yaml` example:\u003c/strong\u003e\u003c/summary\u003e\n\n```yaml\n# A list of templates to process.\n# Paths are relative to the location of this spec.yaml.\ntemplates:\n  - service.yaml\n\n# A simple list of target environments.\ntargetIds:\n  - dev\n  - stg\n\n# A list of parameter sets.\nparameters:\n  # --- Shared values for all provided targets ---\n  - targetId:\n      - dev\n      - stg\n    values:\n      maxScale: 10\n      minScale: 1\n  # --- Specific values for target 'dev' ---\n  - targetId: [\"dev\"]\n    values:\n      foo: bar\n  # --- Specific values for target 'stg' ---\n  - targetId: [\"stg\"]\n    values:\n      foo: bar\n```\n\n\u003c/details\u003e\n\n#### `ymr run`\n\nProcesses templates based on a `spec.yaml` file and generates output files.\n\n```bash\nymr run [flags]\n```\n\n**Flags:**\n\n*   `-s`, `--spec \u003cpath\u003e`: Source path for `spec.yaml` (local dir/file, http(s) URL, or GitHub). When omitted, `ymr` runs in spec-less mode.\n*   `-T`, `--template \u003cpath\u003e`: A single template file/URL to override the `templates` list in the spec.\n*   `-o`, `--output \u003cdirectory\u003e`: Output directory for rendered files. Use `-` for stdout.\n*   `-p`, `--param \u003ckey=value\u003e`: Override a parameter (e.g., `key=value`). Can be used multiple times.\n*   `--param-file \u003cpath|url\u003e`: Override parameters from a YAML/JSON mapping file (local path or URL). Can be used multiple times.\n*   `--param-yaml \u003cyaml\u003e`: Override parameters from an inline YAML/JSON mapping. Can be used multiple times.\n*   `-t`, `--target \u003cid\u003e`: Override which targets to render. Can be used multiple times.\n*   `--token \u003ctoken\u003e`: GitHub token for accessing private repositories (or use `GITHUB_TOKEN` environment variable).\n*   `--validation \u003cpath\u003e`: Path to a policy file. If provided, this will override any validations in the spec file.\n*   `--strict`: Fail the run if any template/target render step errors. By default, `ymr` runs in best-effort mode and skips failed templates/targets.\n*   `--debug`: Enable debug logging.\n\n**Example `ymr run` usage:**\n\n```bash\n# Spec-less mode\nymr run --template ./example/gcp-cloud-run/service.yaml -p version=111 -o -\n\n# Spec-less mode with a YAML params file\nymr run -T ./example/k8s/deployment.yaml -t dev --param-file ./params.yaml -o -\n\n# Strict mode (fail on any render error)\nymr run -s example/k8s --strict -o -\n\n# Process spec.yaml and output to the 'rendered' directory\nymr run -s spec.yaml -o rendered\n\n# Override a parameter for a specific run\nymr run -s example/gcp-cloud-run -p minScale=5 -o -\n\n# Render only the 'prd' target\nymr run -s example/gcp-cloud-run -t prd -o -\n\n# Use a GitHub repo directly (requires --token or GITHUB_TOKEN env for private repos)\nymr run -s https://github.com/lnrdll/ymr/example/k8s@main -o -\n\n# Run in spec-less mode\nymr run -T https://github.com/lnrdll/ymr/blob/main/example/k8s/deployment.yaml -t dev -p name=example -o -\n\n# Run in spec-less strict mode\nymr run -T ./example/k8s/deployment.yaml -t dev -p name=example --strict -o -\n```\n\nNote: In spec-less mode, if you write to files (i.e. `-o rendered/`), you typically want to pass at least one `--target` so output filenames are stable.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `ymr validate`\n\nValidates a spec (or a single template in spec-less mode) without writing output files.\n\n```bash\n# Validate a spec directory\nymr validate -s example/k8s\n\n# Validate with strict mode (fail on any template load/parse error)\nymr validate -s example/k8s --strict\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n#### `ymr version`\n\nPrint the current version (and commit/date when available):\n\n```bash\nymr version\n```\n\n### Template Syntax\n\u003ca name=\"template-syntax\"\u003e\u003c/a\u003e\n\n`ymr` uses special comments within your YAML templates to identify where parameters should be injected.\n\nTemplates may contain multiple YAML documents separated by `---`; `ymr` processes each document.\n\n*   `# from-param: {{ .var }}`: Replaces the entire value with the value of the parameter `{{ .var }}`.\n\n    **Template:**\n    ```yaml\n    replicas: 1 # from-param: {{ .replicas }}\n    ```\n    **`spec.yaml` parameter:**\n    ```yaml\n    replicas: 3\n    ```\n    **Output:**\n    ```yaml\n    replicas: 3\n    ```\n\n*   `# from-param-merge: {{ .var }}`: Merges the YAML structure defined by the parameter `{{ .var }}` into the current location. This is useful for injecting complex objects or lists.\n\n    **Template:**\n    ```yaml\n    metadata:\n      labels: # from-param-merge: {{ .commonLabels }}\n        app: my-app\n    ```\n    **`spec.yaml` parameter:**\n    ```yaml\n    commonLabels:\n      environment: production\n      version: v1.0.0\n    ```\n    **Output:**\n    ```yaml\n    metadata:\n      labels:\n        app: my-app\n        environment: production\n        version: v1.0.0\n    ```\n\n### Examples\n\u003ca name=\"examples\"\u003e\u003c/a\u003e\n\nThe [`example`](./example) directory contains a few examples of how to use `ymr`.\n\n- [`simple`](./example/simple): A simple example of how to use `ymr` with a single template and a single target.\n- [`k8s`](./example/k8s): A more complex example of how to use `ymr` to generate Kubernetes manifests for multiple targets.\n- [`gcp-cloud-run`](./example/gcp-cloud-run): An example of how to use `ymr` to generate a GCP Cloud Run service definition for multiple targets.\n- [`docker-composer`](./example/docker-composer): An example of how to use `ymr` to generate a Docker Compose file for multiple targets.\n\nTo run the examples, `cd` into the example directory and run `ymr run -o -`:\n\n```bash\ncd example/simple\nymr run -s . -o -\n```\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### Contributing\n\u003ca name=\"contributing\"\u003e\u003c/a\u003e\n\nYou're welcome to open issues or submit pull requests, though responses may take some time.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n### License\n\u003ca name=\"license\"\u003e\u003c/a\u003e\n\nThis project is licensed under the MIT License. See the `LICENSE` file for details.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flnrdll%2Fymr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flnrdll%2Fymr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flnrdll%2Fymr/lists"}