{"id":15512688,"url":"https://github.com/DannyBen/kojo","last_synced_at":"2025-10-12T09:31:41.326Z","repository":{"id":43257965,"uuid":"143299393","full_name":"DannyBen/kojo","owner":"DannyBen","description":"Command line utility for generating config files from templates and definition files","archived":false,"fork":false,"pushed_at":"2025-08-01T15:31:54.000Z","size":549,"stargazers_count":59,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-07T22:12:57.707Z","etag":null,"topics":["configuration","gem","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/DannyBen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"support/changelog.old.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"DannyBen"}},"created_at":"2018-08-02T13:35:46.000Z","updated_at":"2025-08-12T14:30:24.000Z","dependencies_parsed_at":"2024-01-27T17:28:38.222Z","dependency_job_id":"8ac3f2b0-05bf-4358-b0d4-d7532b9790ea","html_url":"https://github.com/DannyBen/kojo","commit_stats":{"total_commits":214,"total_committers":1,"mean_commits":214.0,"dds":0.0,"last_synced_commit":"2944c66c49d44494c0354c245ae677e88c288302"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/DannyBen/kojo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Fkojo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Fkojo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Fkojo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Fkojo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DannyBen","download_url":"https://codeload.github.com/DannyBen/kojo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DannyBen%2Fkojo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007603,"owners_count":26084334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"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":["configuration","gem","ruby"],"created_at":"2024-10-02T09:53:47.587Z","updated_at":"2025-10-12T09:31:41.321Z","avatar_url":"https://github.com/DannyBen.png","language":"Ruby","readme":"\u003cdiv align='center'\u003e\n\n![kojo](support/kojo.png)\n\n# Kojo Configuration Ninja\n\nKojo helps you generate configuration files from templates, using variables \nand definition files. It is a command line utility, and works on any text file\nformat.\n\n\u003c/div\u003e\n\n---\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Variables](#variables)\n  - [Import](#import)\n  - [Transform an Entire Folder](#transform-an-entire-folder)\n  - [Transform One to Many using Config](#transform-one-to-many-using-config)\n  - [Transform One to Many using Front Matter](#transform-one-to-many-using-front-matter)\n  - [Convert YAML to JSON](#convert-yaml-to-json)\n  - [Interactive Form Templates](#interactive-form-templates)\n  - [Conditions and Loops with ERB](#conditions-and-loops-with-erb)\n- [Interactive Fallback](#interactive-fallback)\n- [Using from Ruby Code](#using-from-ruby-code)\n- [Contributing / Support](#contributing--support)\n\n---\n\n## Installation\n\n```shell\n$ gem install kojo\n```\n\nOr with Homebrew:\n\n```shell\n$ brew install brew-gem    # once only, to enable the brew gem command\n$ brew gem install kojo\n```\n\nOr with Docker:\n\n```shell\n$ alias kojo='docker run --rm -it --user $(id -u):$(id -g) --volume \"$PWD:/app\" dannyben/kojo'\n```\n\n## Usage\n\nIf you prefer to learn by example, see the [examples](examples#examples) folder for \nseveral use cases. Each example subfolder contains the command to run, the \nrelevant files, and the expected output.\n\n### Variables\n\n![kojo](support/features-vars.svg)\n\nInclude variables in your configuration templates by using this syntax: \n`%{varname}`\n\n- Variables can be provided through the command line, or when using `@import`.\n- When one or more variables are not provided, you [will be prompted to provide\n  a value](#interactive-mode).\n- Variables from the top level will be forwarded downstream, and aggregated \n  with any additional variables that are defined in subsequent `@imports`.\n\nNote that since the `%` sign is used for variable replacement, if you want\nyour generated file to include a literal percent sign, you need to escape it\nas `%%` in your template.\n\n### Import\n\n![kojo](support/features-import.svg)\n\nUse the `@import filename` directive anywhere to include another file in the\nresulting configuration file.\n\n- The `@import` directive should be the only thing in the line.\n- The indentation will be respected when importing.\n- The `filename` parameter does not have to include an extension - Kojo will\n  use the same extension as the parent file.\n- The included file will be searched for relative to the file it is included \n  in.\n- Arguments can be passed down to the included template by using this syntax:\n\n```ruby\n@import filename (arg: \"value\", arg2: \"value\")\n```\n\nThe space after `filename` is optional, and the arguments list can be split to\nmultiple lines:\n\n```ruby\n@import filename (\n  arg: \"value\",\n  arg2: \"value\"\n)\n```\n\n### Transform an Entire Folder\n\n![kojo](support/features-dir.svg)\n\nProcess a folder containing templates and `@imports`, and generate a mirror\noutput folder, with all the variables and `@imports` evaluated.\n\nYou may use `%{variables}` in filenames.\n\n### Transform One to Many using Config\n\n![kojo](support/features-config.svg)\n\nUsing the `kojo config` command together with a simple definitions file, you\ncan:\n\n1. Generate multiple output files based on a single template file\n2. Generate multiple output directories, based on a single source directory.\n\nTo achieve this, you need to:\n\n1. Create the configuration template or directory of templates.\n2. Create a configuration YAML file using this syntax:\n\n```yaml\ninput: base-template.yml\n\noutput:\n  outfile1.yml:\n    argument1: value\n    argument2: value\n\n  outfile2.yml:\n    argument1: value\n    argument2: value\n```\n\nWhen using a folder as input, simply provide the folder name in the `input` \nproperty, and instead of providing desired output filenames in the `output`\nproperty, provide desired output directories:\n\n```yaml\ninput: base\n\noutput:\n  app1:\n    argument1: value\n    argument2: value\n\n  app2:\n    argument1: value\n    argument2: value\n```\n\n### Transform One to Many using Front Matter\n\n![kojo](support/features-single.svg)\n\nDefine a template that contains the instructions on how to transform it as a\nYAML front matter.\n\nThe YAML front matter should be structured like this:\n\n```yaml\nfilename1:\n  arg: value\n  another_arg: value\n\nfilename2:\n  arg: value\n  another_arg: value\n---\nYour template that uses %{arg} goes here\n...\n```\n\nAdditional arguments provided to the command line, will also be transferred\nto the template.\n\n### Convert YAML to JSON\n\n![kojo](support/features-tojson.svg)\n\nConvert one or more YAML files to JSON.\n\nThis can be useful when you require JSON files as output, but wish to edit\n(or generate using Kojo) using the less error-prone and more aesthetically\npleasing YAML format.\n\nNote that this Kojo command does not provide any additional preprocessing - the\ninput files should be valid YAML.\n\n### Interactive Form Templates\n\n![kojo](support/features-form.svg)\n\nUsing the `kojo form` command lets you define an ERB or [ERBX][erbx] template, and include interactive prompts to enter the input. \n\n1. Use either ERB tags (`\u003c%= %\u003e`, `\u003c%- -%\u003e`) or ERBX tags (`{{ }}`, `(( ))`).\n2. Use the built in `prompt` object, which is a [TTY::Prompt](tty-prompt) instance, to prompt for input when running the command (for example: `{{ prompt.ask? \"Your Name?\" }}`)\n3. Any unidentified ruby command will be forwarded to the `prompt` object, so `prompt.ask` is the same as just using `ask`.\n4. If there is a file with the same name as the template, and with an `.rb` extension (for example `form.md` and `form.md.rb`), then the ruby file will be loaded into the ERB template as if it was written inside it.\n5. If you prefer using a single template file (without the ruby appendix), you can simply use regular ERB/ERBX tags, like demonstrated below.\n\n![kojo](support/features-form-inline.svg)\n\n### Conditions and Loops with ERB\n\n![kojo](support/features-erb.svg)\n\nTemplate files are evaluated using ERB, so you can use any Ruby code for more\nadvanced templates (for conditions, loops etc.).\n\nUse this syntax for ruby code:\n\n```erb\n\u003c%- ruby code here -%\u003e     # for code that should not be printed\n\u003c%= ruby code here -%\u003e     # for code that should be printed\n```\n## Interactive Fallback\n\nWhen Kojo encounters a variable that was not supplied (either through the command \nline or through a configuration file), it will prompt for a value.\n\n![kojo](support/interactive-mode.gif)\n\nYou can enable or disable interactive mode by setting the environment\nvariable `KOJO_INTERACTIVE` to `yes` or `no`.\n\nBy default, interactivity is enabled when running the CLI, and disabled when\nrunning from within Ruby code.\n\nWhen running from within Ruby code, you can also use `Kojo.interactive = true`\nand `Kojo.interactive?` to get the current state.\n\n## Using from Ruby Code\n\nAlthough Kojo was primarily designed as a command line utility, you can also\nuse it as a library from your Ruby code.\n\nThese are the primary classes:\n\n| Class                       | Description                                  | CLI equivalent |\n| --------------------------- | -------------------------------------------- | -------------- |\n| `Kojo::Template`            | generate from a single template              | `kojo file`    |\n| `Kojo::FrontMatterTemplate` | generate from a template with a front matter | `kojo single`  |\n| `Kojo::Config`              | generate from a config file                  | `kojo config`  |\n| `Kojo::Collection`          | generate from a directory                    | `kojo dir`     |\n| `Kojo::Form`                | generate interactively                       | `kojo form`    |\n\n### Examples\n\n```ruby\n# Template\ntemplate = Kojo::Template.new 'examples/variables/main.yml'\nresult = template.render domain: 'example.com', scale: 2\nputs result\n\n# Collection\ncollection = Kojo::Collection.new 'examples/dir'\ncollection.import_base = 'examples/dir/imports'\n\nparams = { env: 'env', app: 'app' }\nresult = collection.render params do |path, content|\n  # code to handle results here\nend\n\n# Config\nconfig = Kojo::Config.new 'examples/config-from-file/config.yml'\nconfig.import_base = \"examples/config-from-file/imports\"\n\nconfig.generate do |path, content|\n  # code to handle results here\nend\n\n# FrontMatterTemplate\ntemplate = Kojo::FrontMatterTemplate.new 'examples/single/Dockerfile'\nparams = { version: '0.1.1' }\n\ntemplate.render params do |path, content|\n  # code to handle results here\nend\n\n# Form\ntemplate = Kojo::Form.new 'examples/form/movie.md'\nputs template.render\n```\n\nIn addition, Kojo extends Ruby's `File` class with the `File.deep_write`\nmethod, which lets you write the file and create the directory structure as\nneeded. You may use it in your code like this:\n\n```ruby\n# Config\nconfig = Kojo::Config.new 'examples/config-from-file/config.yml'\nconfig.import_base = \"examples/config-from-file/imports\"\n\nconfig.generate do |path, content|\n  File.deep_write path, content\nend\n```\n\n## Contributing / Support\n\nIf you experience any issue, have a question or a suggestion, or if you wish\nto contribute, feel free to [open an issue][issues].\n\n---\n\n[issues]: https://github.com/DannyBen/kojo/issues\n[erbx]: https://github.com/DannyBen/erbx\n[tty-prompt]: https://github.com/piotrmurach/tty-prompt#contents\n","funding_links":["https://github.com/sponsors/DannyBen"],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDannyBen%2Fkojo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDannyBen%2Fkojo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDannyBen%2Fkojo/lists"}