{"id":46132577,"url":"https://github.com/adam-huganir/yutc","last_synced_at":"2026-03-02T04:04:45.046Z","repository":{"id":226791313,"uuid":"769647549","full_name":"adam-huganir/yutc","owner":"adam-huganir","description":"A flexible CLI for using yaml and json files as input for Go templates. Local, HTTP, and stdin sources. sprig pre-installed :)","archived":false,"fork":false,"pushed_at":"2026-02-28T03:11:16.000Z","size":555,"stargazers_count":1,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-28T09:11:41.075Z","etag":null,"topics":["cli","golang","gotemplate","sprig","templating-tool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adam-huganir.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":null,"dco":null,"cla":null}},"created_at":"2024-03-09T17:00:36.000Z","updated_at":"2026-02-18T02:48:30.000Z","dependencies_parsed_at":"2024-03-23T17:24:21.006Z","dependency_job_id":"2b03ea37-3c61-421c-b17e-d322316f8748","html_url":"https://github.com/adam-huganir/yutc","commit_stats":null,"previous_names":["adam-huganir/yutc"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/adam-huganir/yutc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adam-huganir%2Fyutc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adam-huganir%2Fyutc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adam-huganir%2Fyutc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adam-huganir%2Fyutc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adam-huganir","download_url":"https://codeload.github.com/adam-huganir/yutc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adam-huganir%2Fyutc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29992286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T01:47:34.672Z","status":"online","status_checked_at":"2026-03-02T02:00:07.342Z","response_time":60,"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","golang","gotemplate","sprig","templating-tool"],"created_at":"2026-03-02T04:04:44.417Z","updated_at":"2026-03-02T04:04:45.018Z","avatar_url":"https://github.com/adam-huganir.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `yutc` `/jʌːtsi/`\n\n[![GitHub version](https://badge.fury.io/gh/adam-huganir%2Fyutc.svg)](https://badge.fury.io/gh/adam-huganir%2Fyutc)\n\n`yutc` is a templating command line interface written in (surprise, surprise) Go.\nIt is designed to parse and merge data files (YAML, JSON, TOML), and apply them to templates.\nThe application supports reading data from both local files and URLs,\nand can output the results to a file or stdout.\n\n## Installation\n\nDownload the [latest build](https://github.com/adam-huganir/yutc/releases/latest) or any\nother version from the [releases page](https://github.com/adam-huganir/yutc/releases).\nPut it somewhere on your computer. Add it to your path. If you are using this you probably\nalready know how to do that.\n\n## Usage\n\nYou can use `yutc` by passing it a list of templates along with various options:\n\n```bash\nUsage:\n  yutc [flags] \u003ctemplate_files...\u003e\n\n\n  yutc is a command line tool for rendering complex templates from arbitrary sources.\n\nData \u0026 Templates:\n    --auth string                      Authentication for any URL source. Format: 'user:pass' for Basic Auth or 'token' for Bearer Token.\n    -c, --common-templates stringArray Templates to be shared across all arguments in template list. Can be a file or a URL. Can be specified multiple times.\n    -d, --data stringArray             Data file to parse and merge. Can be a file or a URL. Can be specified multiple times and the inputs will be merged.\n                                       Optionally nest data under a top-level key using: jsonpath=\u003cpath\u003e,src=\u003cpath\u003e  See --help=syntax for more details.\n    --helm                             Enable Helm-specific data processing (Convert keys specified with key=Chart to pascalcase)\n    --include-filenames                Process filenames as templates\n    --set stringArray                  Set a data value via a key path. Can be specified multiple times.\n\nOutput \u0026 Rendering:\n    --drop-extension string       Drop file extension from output filename before outputting (default \"tmpl\")\n    --ignore-empty                Skip writing empty rendered template output to output location\n    -o, --output string           Output file/directory, defaults to stdout (default \"-\")\n    -w, --overwrite               Overwrite existing files\n    --strict                      On missing value, throw error instead of zero\n\nSystem:\n    -h, --help      Show help. A topic may be specified as --help=\u003ctopic\u003e.\n                        Available topics:\n                            syntax  Syntax for advanced file arguments and options\n    -v, --verbose   Verbose output\n    --version      Print the version and exit\n```\n\n## Custom Template Functions\n\n\n### `toYaml` and `mustToYaml`\n\n`toYaml` is a custom template function that converts the input to a yaml representation.\nsimilar to the `toYaml` in `helm`.\n\n`mustToYaml` is also available, which will panic if the input cannot be converted to yaml.\n\n```gotemplate\n{{ . | toYaml }}\n```\n### `fromYaml` and `mustFromYaml`\n\n`fromYaml` is a custom template function that converts the input to a go object.\nsimilar to the `fromYaml` in `helm`.\n\n`mustFromYaml` is also available, which will panic if the input cannot be converted to a go object.\n\n```gotemplate\n{{ fromYaml . | .SomeField | toString }}\n```\n### `yamlOptions`\n\n`yamlOptions` allows you to set options for the yaml encoder. These settings will be global across all calls\nto `toYaml` and `mustToYaml`. See [the documentation for goccy/go-yaml](https://pkg.go.dev/github.com/goccy/go-yaml#EncodeOption) for details.\n`DecodeOption` support will be added in the future.\n\n```gotemplate\n{{ yamlOptions (dict \"indent\" 2) }}\n{{ toYaml $someData }}\n```\n### `wrapText` and `wrapComment`\n\n`wrapText` uses [textwrap](https://github.com/isbm/textwrap) to wrap text to a specified width.\n\n`wrapComment` is a wrapper around `wrapText` that adds a comment character to the beginning of each line.\n\n```gotemplate\n{{ wrapText 80 .SomeText }}\n\n{{ wrapComment \"#\" 80 .SomeText }}\n```\n### `toToml` and `mustToToml`\n\n`toToml` is a custom template function that converts the input to a TOML representation.\nSimilar to `toYaml` but for TOML format.\n\n`mustToToml` is also available, which will panic if the input cannot be converted to TOML.\n\n```gotemplate\n{{ . | toToml }}\n```\n### `fromToml` and `mustFromToml`\n\n`fromToml` is a custom template function that converts TOML input to a go object.\nSimilar to `fromYaml` but for TOML format.\n\n`mustFromToml` is also available, which will panic if the input cannot be converted to a go object.\n\n```gotemplate\n{{ fromToml . | .SomeField | toString }}\n```\n### File Functions: `fileGlob`, `fileStat`, `fileRead`, `fileReadN`\n\n**`fileGlob`** - Returns a list of files matching a glob pattern.\n\n**`fileStat`** - Returns file statistics as a map with keys like Mode, Size, ModTime, etc.\n\n**`fileRead`** - Reads the entire contents of a file as a string.\n\n**`fileReadN`** - Reads the first N bytes of a file as a string.\n\n```gotemplate\n{{- range fileGlob \"*.txt\" }}\nFile: {{ . }}\n{{- end }}\n\n{{- $stat := fileStat \"myfile.txt\" }}\nSize: {{ $stat.Size }} bytes\n\n{{ fileRead \"config.txt\" }}\n\n{{ fileReadN 100 \"largefile.txt\" }}\n```\n### Path Functions: `pathAbsolute`, `pathIsDir`, `pathIsFile`, `pathExists`\n\n**`pathAbsolute`** - Returns the absolute path of the given path.\n\n**`pathIsDir`** - Returns true if the path is a directory.\n\n**`pathIsFile`** - Returns true if the path is a file.\n\n**`pathExists`** - Returns true if the path exists.\n\n```gotemplate\n{{ pathAbsolute \"./relative/path\" }}\n\n{{- if pathExists \"myfile.txt\" }}\n{{- if pathIsFile \"myfile.txt\" }}\nFile exists: {{ pathAbsolute \"myfile.txt\" }}\n{{- end }}\n{{- end }}\n\n{{- if pathIsDir \"mydirectory\" }}\nDirectory found!\n{{- end }}\n```\n### `type`\n\n`type` returns the Go type of the given value as a string.\n\n```gotemplate\n{{ type . }}\n{{ type \"hello\" }}\n{{ type 42 }}\n```\n### `sortList`\n\n`sortList` sorts a list of values and returns a new sorted list. Supports strings, integers, and float64 values.\nThe original list is not modified.\n\n```gotemplate\n{{- $unsorted := list \"zebra\" \"apple\" \"banana\" }}\n{{- range sortList $unsorted }}\n- {{ . }}\n{{- end }}\n\n{{- $numbers := list 3 1 4 1 5 9 2 6 }}\nSorted: {{ sortList $numbers }}\n```\n### `sortKeys`\n\n`sortKeys` returns a new map with keys sorted alphabetically. Useful for consistent output ordering,\nespecially when generating YAML or other formats where key order matters.\n\n```gotemplate\n{{- $config := dict \"zebra\" 1 \"apple\" 2 \"banana\" 3 }}\n{{- range $key, $value := sortKeys $config }}\n{{ $key }}: {{ $value }}\n{{- end }}\n```\n### `include`\n\n`include` allows you to include and render other templates as text within the current template.\nThis is the exact same as the `include` function in Helm.\n\n```gotemplate\n{{ include \"shared-template\" . }}\n```\n### `tpl`\n\n`tpl`, also from Helm\n\n```gotemplate\n{{ tpl $my_template . }}\n```\n\n## Examples\n\n\n### Merging many yaml/json files together and outputting them to\na file\n\n```bash\nyutc -o patch.yaml \\\n     -d ./talosPatches/controlplane-workloads.yaml \\\n     -d talosPatches/disable-cni.yaml \\\n     -d talosPatches/disable-discovery.yaml \\\n     -d talosPatches/install-disk.yaml \\\n     -d talosPatches/kubelet.yaml \\\n     -d talosPatches/local-storage.yaml \\\n     -d talosPatches/names.yaml \\\n      \u003c(echo \"{{ . | toYaml }}\")\n```\n\nalternate form using matching\n\n```bash\n    yutc -o patch.yaml \\\n         --data ./talosPatches \\\n          \u003c(echo \"{{ . | toYaml }}\")\n```\n### Listing files in a directory\n\nFor some reason you want to list the files in a directory and embed them in a file in a custom format:\n\n```template\n{{- $files := fileGlob \"./*/*\" -}}\n{{- range $path := $files }}\n{{- $stat := fileStat $path }}\n{{- $username := (env \"USERNAME\" | default (env \"USER\") )}}\n{{- $usernameFString := printf \"%s%d%s  \" \"%-\" (len $username) \"s\"}}\n {{ printf \"%-12s\" $stat.Mode }}{{ printf $usernameFString $username }}{{ pathAbsolute $path}}\n{{- end }}\n```\n```\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\COMMIT_EDITMSG\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\FETCH_HEAD\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\HEAD\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\ORIG_HEAD\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\config\n -rw-rw-rw-  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\description\n drwxrwxrwx  adam  C:\\Users\\adam\\code\\yet-unnamed-template-cli\\.git\\hooks\n ........\n ```\n### Merging 2 data files and applying them to a template\n\n```pwsh\n yutc --data .\\testFiles\\data\\data1.yaml --data .\\testFiles\\data\\data2.yaml .\\testFiles\\templates\\simpleTemplate.tmpl\n```\n\n```\nJSON representation of the merged input:\n---\n{\n  \"ditto\": [\n    \"woohooo\",\n    \"yipeee\"\n  ],\n  \"dogs\": [],\n  \"thisIsNew\": 1000,\n  \"thisWillMerge\": {\n    \"value23\": 23,\n    \"value24\": 24\n  }\n}\n---\nYaml representation:\n---\nditto:\n    - woohooo\n    - yipeee\ndogs: []\nthisIsNew: 1000\nthisWillMerge:\n    value23: 23\n    value24: 24\n---\n```\n### Using top-level keys to store data from files separately\n\n```bash\n yutc --data \"jsonpath=.data1,src=./testFiles/data/data1.yaml\" \\\n      --data \"jsonpath=.data2,src=./testFiles/data/data3.json\" \\\n       ./testFiles/templates/simpleTemplate.tmpl\n```\nWe see below that we are able to specify a key for each data file, and the data is not merged at the top level.\n```\nUnmerged data from data 1: {\"dogs\":[{\"breed\":\"Labrador\",\"name\":\"Fido\",\"owner\":{\"name\":\"John Doe\"},\"vaccinations\":[\"rabies\"]}],\"thisWillMerge\":{\"value23\":\"not 23\",\"value24\":24}}\nUnmerged data from data 2: {\"ditto\":[\"woohooo\",\"yipeee\"],\"dogs\":[],\"thisIsNew\":1000,\"thisWillMerge\":{\"value23\":23}}\n```\n### Setting data values directly with `--set`\n\nYou can set individual data values directly from the command line using JSONPath syntax:\n\n```bash\n# Set simple values\nyutc --set '$.version=1.2.3' --set '$.name=myapp' template.tmpl\n\n# Convenience: paths starting with . are auto-prefixed with $\nyutc --set '.version=1.2.3' --set '.name=myapp' template.tmpl\n\n# Set nested values\nyutc --set '.config.database.host=localhost' \\\n     --set '.config.database.port=5432' \\\n     template.tmpl\n\n# Override values from data files\nyutc -d config.yaml --set '.env=production' template.tmpl\n\n# Set arrays and objects (JSON format)\nyutc --set '.ports=[8080,8443]' \\\n     --set '.metadata={\"author\":\"me\",\"version\":\"1.0\"}' \\\n     template.tmpl\n```\n\n**Note on value types:** Values are parsed as JSON when possible, otherwise treated as strings.\n- `--set '.count=42'` sets a number\n- `--set '.count=\"42\"'` sets a string\n- `--set '.name=foo'` sets the string \"foo\" (quotes not required for simple strings)\n- `--set '.enabled=true'` sets a boolean\n- `--set '.items=[1,2,3]'` sets an array of numbers\n- `--set '.config={\"key\":\"value\"}'` sets an object\n### Applying JSON Schema defaults / validation with `type=schema`\n\nYou can load JSON Schema documents via `--data` by using a structured argument with `type=schema`. Schemas are applied after all data is merged.\n\n```bash\nyutc \\\n  --data ./testFiles/data/data1.yaml \\\n  --data \"src=./testFiles/schemas/person.yaml,type=schema\" \\\n  ./testFiles/templates/simpleTemplate.tmpl\n```\n### Automatic extension removal with `--drop-extension`\n\nWhen rendering multiple templates, you often want to remove a suffix like `.tmpl` from the output filenames.\n\n```bash\n# If you have:\n#   templates/config.yaml.tmpl\n#   templates/deployment.yaml.tmpl\n#\n# This command will produce:\n#   dist/config.yaml\n#   dist/deployment.yaml\nyutc -o ./dist/ --drop-extension tmpl ./templates/*.tmpl\n```\n### URL Authentication with `--auth` and structured arguments\n\nYou can provide authentication globally or per-source.\n\n```bash\n# Global authentication for all URL sources\nyutc --auth \"my-token\" -d https://api.example.com/data.yaml ./template.tmpl\n\n# Per-source authentication using structured arguments\nyutc -d \"src=https://api.example.com/data.yaml,auth=user:pass\" ./template.tmpl\n```\n### Rendering this documentation\n\nSee README.data.yaml and README.md.tmpl for the source data and template\n\n## Why?\n\nI had very specific requirements\nthat [gomplate](https://github.com/hairyhenderson/gomplate), [gucci](https://github.com/noqcks/gucci), and\nothers weren't quite able to meet.\nBoth of those a great apps, and if you\nSo really i just made this for myself at my day-job, but if anyone else\nfinds it useful, here it is.\nEnjoy those specific features!\n\n\n# Notes\n\nThe name `yutc` is a acronym of `yet-unnamed-template-cli`,\nwhich i guess is now in fact named.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadam-huganir%2Fyutc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadam-huganir%2Fyutc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadam-huganir%2Fyutc/lists"}