{"id":13539644,"url":"https://github.com/metaory/confsubst","last_synced_at":"2025-03-29T21:25:07.927Z","repository":{"id":215154401,"uuid":"738033857","full_name":"metaory/confsubst","owner":"metaory","description":"Templating and Variable Interpolation CLI Utility -- Substitutes Placeholders • Run Pre/Post Hooks • Self-contained Options with modeline like syntax","archived":false,"fork":false,"pushed_at":"2024-04-06T02:24:04.000Z","size":94,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-04-06T03:24:48.817Z","etag":null,"topics":["awk","cli","command-line","env","environment-variables","envsubst","sed","template","templating"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/metaory.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}},"created_at":"2024-01-02T08:59:55.000Z","updated_at":"2024-04-06T03:24:53.154Z","dependencies_parsed_at":"2024-04-06T03:24:52.681Z","dependency_job_id":"8c6d74a7-cc2d-413e-86b0-cdee7f47009c","html_url":"https://github.com/metaory/confsubst","commit_stats":null,"previous_names":["metaory/system-config-patcher"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fconfsubst","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fconfsubst/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fconfsubst/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaory%2Fconfsubst/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metaory","download_url":"https://codeload.github.com/metaory/confsubst/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246245276,"owners_count":20746615,"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","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":["awk","cli","command-line","env","environment-variables","envsubst","sed","template","templating"],"created_at":"2024-08-01T09:01:29.904Z","updated_at":"2025-03-29T21:25:07.906Z","avatar_url":"https://github.com/metaory.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"CONFSUBST\n=========\n\n```elixir\nNAME\n\tconfsubst - templating \u0026 variable interpolation CLI utility\n\n\nSYNOPSIS\n\tconfsubst [--elVvh] [-o DIR] [--] [-]|DIR|FILE...\n\n\twith no DIR|FILE... or if FILE is [-], read STDIN\n\n.\nDESCRIPTION\n\tconfsubst is a simple cli tool for populating templates with user/system defined variables.\n\n\twith \"-e, --env \u003cFILE\u003e\" it loads variables from a file or the system env if left empty.\n\n\tit loads one or many template files.\n\n\tif the specifed path is a directory it loads all files recursively in that path.\n\n\tconfsubst is \"self-contained\" \u0026 dont require any config file.\n\n\tthe template destination path \u0026 other config are defined in the same template file\n\tit supports a vim modeline like syntax.\n\tthe modeline can be placed anywhere in the file as a comment.\n\teg:\n.\n\t\t\"-- mxc: path=$XDG_CONFIG_HOME/wezterm/color.lua label=wezterm\"\n\t\t\"# mxc: path=$XDG_CONFIG_HOME/kitty/kittheme.conf\"\n\t\t\"! mxc: path=$XDG_CONFIG_HOME/mxc/mxresources.xdefaults\"\n\n\n.\nOPTIONS\n\t-e, --env \u003cFILE\u003e      environment overrides\n\t-l, --log \u003cFILE\u003e      verbose log file\n\t-o, --output \u003cDIR\u003e    output path\n\t-V, --verbose         be more verbose\n\t-q, --quiet, --silent inhibit the usual output\n\t-h, --help            display this help \u0026 exit\n\t-v, --version         display version \u0026 exit\n\n\nEXAMPLES\n\t# substitute all files under templates/\n\tconfsubst templates\n\n\t# substitute two files\n\tconfsubst templates/wezterm-color.lua templates/nvim-colors.lua\n\n\t# substitute all files under templates/ override environment with .env file\n\tconfsubst -e .env -- templates\n\n\t# substitute all files under templates/ with increased verbosity\n\tconfsubst --verbose templates\n\n\t# substitute all files resulted from command \u0026 override output path\n\tconfsubst -o myoutput - \u003c(ls --zero | tr '\\0' ' ')\n\n\t# substitute all files received as stdin \u0026 override log path\n\tfind . -type f -print0 | confsubst -l /tmp/mylog\n\n\nSEE ALSO\n\tenvsubst(1), env(1), environment(5), environ(7), sed(1), awk(1), grep(1), tr(1)\n\n\nAUTHOR\n\tmetaory \u003cmetaory@gmail.com\u003e, Jan 2024\n```\n\n#### Templating \u0026 Variable Interpolation CLI Utility\n\n##### Render `STDIN|DIR|FILE...` with `[-e \u003cFILE\u003e]|env`\n\nSubstitute placeholders in file(s)\n\n###### ● Substitutes Files Placeholders\n###### ● Self-contained Options with vim modeline like syntax\n###### ● ~~Pre/Post Hooks~~\n\n## Features\n-  `[-e \u003cFILE\u003e]` to override environment\n-  `modeline` like syntax for optional _self-contained*_ file settings\n-  `pre`/`post` hooks for other custom pre/post processing\n-  `path` for replacing existing file\n\n---\n\n# Installation\n\n- clone repo\n- give execution permissions\n- place it in your path\n\n```ex\n# Clone the repo\ngit clone git@github.com:metaory/confsubst.git\n\n# Navigate to repo\ncd confsubst\n\n# Give execution permissions\nchmod +x confsubst\n\n# Link it somewhere in your PATH\nln -svf $PWD/confsubst /usr/bin/confsubst\n\n# Use it anywhere\n\n# Usage help\nconfsubst --help\n\n# Render two templates\n# With no -e, --env system environment variable is used\n# With no -o, --output rendered templates will go to /tmp/mxc/*\n# With modeline path present in template file rendered template will be copied\nconfsubst templates/wezterm-color.lua templates/nvim-colors.lua\n\n# Render all files in mytemplate directory rendered with merged variables of ~/dummy/.env\nconfsubst -e ~/dummy/.env  mytemplate/\n```\n\n---\n\n## Example Use Cases\n\n#### Generate Environment Variables at Runtime \u0026 Substitute config file placeholders with it\n\n`Pre Hook` to **generate** some variables at runtime\n\n`Path` to define the **destination** path\n\n`Post Hook` to then **restart** some service or app\n\n#### Update Colorscheme System Wide\nSubstitute colorscheme variables in different applications with different formats\n\nFor example:\n- terminal colorscheme config\n- editor colorscheme config\n- window manager theme\n- tmux theme config\n- xresources\n- icon theme\n- gtk theme\n- ...\n\nThe `Pre Hook` could **generate** some random colorscheme on the fly\n\n_or use system or `.env` values_\n\nThe `Path` would define the **destination** path\n\n_or the output will be only on /tmp_\n\nThe `Post Hook` could then **reload** a terminal or window manager config\n\n---\n\n## Hooks\nHooks can be used to for any pre/post processing; like\n\nA pre hook to produce dynamic values at runtime, Or any other pre steps\n\nA post hook to do clean up, reload apps config, or run any other post steps.\n\n\u003e _hook path must executable_\n\n---\n\n## How it works\n\n#### Source `.env` in current working directory\n\n`if` found _(optional)_\n\n\u003e Syntax: simple \"KEY=VAL\" pairs on separate lines:\n\n\u003e ```ex\n\u003e MY_VAR_NAME=MY_VALUE\n\u003e ```\n\n#### Parse `modeline` in the file\n\n`if` (`mxc:`) is found _(optional)_\n\n\u003e An Optional Vim like syntax to define file settings\n\n\u003e `[text{white}]{mx:|mxc:}[white]{options}`\n\n#### Exec Pre Hook\n\n`if` (`pre=`) is found in `modeline` _(optional)_\n\n\u003e _should have execute permission (x)_\n\n\u003e To handle any custom user **pre processing steps** for a file\n\n\u003e `mxc: pre=~/bin/some_prehook`\n\n#### Populate(substitute) the file(s) with System or `.env` values\n\u003e using [envsubst](https://man.archlinux.org/man/envsubst.1.en)\n\n#### Exec **Post Hook**\n\n`if` (`post=`) is found in `modeline` _(optional)_\n\n\u003e _should have execute permission (x)_\n\n\u003e To handle any custom user **post processing steps** for a file\n\n\u003e `mxc: post=~/bin/my_post_hook`\n\n#### Copy the populated file in tmp with the original name\n\u003e `/tmp/mxc/somename.whatever` for example\n\n\u003e `~/dummy/kitty.conf` would produce `/tmp/kitty.conf`\n\n#### Copy the populated file to a secondary path\n`if` (`path=`) is found in `modeline` _(optional)_\n\n\u003e `mxc: path=~/.config/nvim/lua/my_theme.lua\n\n---\n\n## Config (template) files\n- All provided files (or all files in provided directory) will parsed \u0026 populated\n\n- The file can be any ascii charset file with any name \u0026 extension\n\n- Optionally there can be a **modeline** comment somewhere in the file\n\n#### modeline syntax\nThe **modeline** follows similar syntax to the first form of (n)Vim modeline [:h modeline](https://neovim.io/doc/user/options.html#modeline)\n\nThe **modeline** \u0026 **all** its keys are **optional**\n\n```cpp\n[text{white}]{mx:|mxc:}[white]{options}\n\n[text{white}]       empty or any text followed by at least one blank character (\u003cSpace\u003e or \u003cTab\u003e)\n{mx:|mxc:}          the string \"mx:\" or \"mxc:\"\n[white]             optional white space\n{options}           a list of key-value options, separated with white space\n```\n\n#### modeline can have the following keys _(all are optional)_\n- `label` display label\n- `path`  secondary destination path\n- `pre`   pre hook executable path\n- `post`  post hook executable path\n\n###### Example modeline:\n\n`# mxc: label=[label] path={dest_path} pre=[script_path] post=[script_path]`\n\n`// mxc: label=kitty_theme path=$XDG_CONFIG_HOME/kitty/kitty-theme.conf post=~/bin/reload_kitty.sh`\n\n`; mx: label=xresources path=~/.Xresources post=~/bin/merge_xrdb.sh`\n\n---\n\n## Environments\n\n- You can View your current environment values with `printenv` or `env`\n_from the [coreutils](https://archlinux.org/packages/core/x86_64/coreutils/)_\n\n#### You can Override the environment by providing an file or with `.env` in CWD\n\n## Sample .env file\n\n\u003e Syntax: simple \"KEY=VAL\" pairs on separate lines: _[man pam_env.conf](https://man.archlinux.org/man/pam_env.conf.5.en#:~:text=Now%20some-,simple)_\n\n```ex\n# .env\nSOME_VAR=FOO\nSOME_PATH=\"$HOME/.config/nvim/init.lua\"\nSOME_NUM=2200\nSOME_BOOL=true\n```\n\n## Sample template files\n\n```ex\nls -a .\n# .env\n# wezterm_color.lua\n# kitty_theme.conf\n# nvim_color.lua\n# awesomewm_color.lua\n# meta.tmuxtheme\n# xresources-colors.xdefaults\n# papirus-colors.gtk\n# numix.gtk\n```\n\n`cat .env`\n```ex\nXFG='#668899'\nXBG='#222233'\nC00='#333344'\nC01='#bb4466'\nC02='#11cc99'\nC03='#cc9955'\nC04='#2277dd'\nC05='#7766cc'\nC06='#11bbee'\nC07='#668899'\nC08='#445566'\n```\n\n`cat wezterm_color.lua`\n```lua\n-- mxc: path=~/.config/wezterm/wez_color.lua\nreturn {\n  foreground = \"$XFG\",\n  background = \"$XBG\",\n  ansi= {\n    \"$C00\",\n    \"$C01\",\n    \"$C02\",\n    \"$C03\",\n    \"$C04\",\n    \"$C05\",\n    \"$C06\",\n    \"$C07\",\n    \"$C08\"\n  }\n}\n```\n\n`cat kitty-theme.conf`\n```ex\n# mxc: path=$XDG_CONFIG_HOME/kitty/kitty-theme.conf post=~/bin/reload_kitty.sh\n\nbackground $XBG\nforeground $XFG\ncolor0     $C00\ncolor1     $C01\ncolor2     $C02\ncolor3     $C03\ncolor4     $C04\ncolor5     $C05\ncolor6     $C06\ncolor7     $C07\ncolor8     $C08\n```\n\n---\n\n# Requirements\n\nAll of Current requirements are part of the [base](https://archlinux.org/packages/core/any/base)\n\n- `env` provided by [gnu coreutils](https://archlinux.org/packages/core/x86_64/coreutils)\n- `envsubst` provided by [gnu gettext](https://archlinux.org/packages/core/x86_64/gettext)\n\n# Optional Requirements\n\n- ~~[Pastel](https://github.com/sharkdp/pastel) - color preview~~\n\n---\n\n# TODOs\n\n- [x] variable substitution\n- [x] handle directories\n- [x] parse modeline\n- [ ] pre/post hooks\n- [ ] inline hooks\n\n---\n\n### Environment File POSIX Definition\n\n[8.1 Environment Variable Definition](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html)\n\n\u003e  These strings have the form name=value; names shall not contain the character '='. For values to be portable across systems conforming to POSIX.1-2017, the value shall be composed of characters from the portable character set (except NUL \u0026 as indicated below). There is no meaning associated with the order of strings in the environment. If more than one string in an environment of a process has the same name, the consequences are undefined.\n\n\u003e Environment variable names used by the utilities in the Shell \u0026 Utilities volume of POSIX.1-2017 consist solely of uppercase letters, digits, \u0026 the \u003cunderscore\u003e ( '_' ) from the characters defined in Portable Character Set \u0026 do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase \u0026 lowercase letters shall retain their unique identities \u0026 shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.\n\n---\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaory%2Fconfsubst","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetaory%2Fconfsubst","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaory%2Fconfsubst/lists"}