Package: jinja-tree
jinja-treeWhat is it?jinja-treeis a CLI utility to processjinja (jinja2)templates
recursively in a directory tree.It is very configurable and very easy to extend with its included plugin system.The default behavior is to recursively search for files with a given extension (.templatefor example) and to process the context withJinja (Jinja2)templates engine reading the context variables from:a configuration fileenvironment variablesdotenv filesThen, the processed content is written into another file with the same name/path but with the configured extension (.templateby default) removed. The original file can also be deleted (but this is not the default behavior).Full example about overall operation (in default mode)Note: this is only thedefault behavioras you can tune this with your own plugins!Let's imagine the following directory structure:/foo/
/foo/README.md.template
/foo/bar/baz.py.template
/foo/bar/another.fileAnd executejinja-tree /foowith the default configuration.We get:/foo/
/foo/README.md.template
/foo/README.md <= NEW FILE FROM README.md.template jinja2 processing
/foo/bar/baz.py.template
/foo/bar/baz.py <= NEW FILE FROM baz.py.template jinja2 processing 
/foo/bar/another.fileWhat's it for?Your imagination is your limit 😅 but it's very useful for maintaining DRY documentation (for exampleyour-cli --helpoutput automatically updated in a markdown file), configuration files with default values read in code, including common blocks in different files...So it's a great tool for maintaining repositories in general.[!TIP]
Do you cant real-life examples? You can find some details about how we use it in this repository for:gettingjinja-tree --helpoutput automatically added (and updated) in this READMEgetting a reference TOML configuration file rendered with default values read from code[!NOTE]
Another "action" plugin will be soon 🕒 provided to bootstrap directory trees from templates (like with thecookiecutterproject).Features1️⃣ Easy to extendjinja-treeincludes a plugin system. You can override the default behavior with your own plugins.There are two extension points:context plugins: to provide context variables to Jinja templatesfile plugins: to change the way howjinja-treefinds files to process (including target files)Seethis specification documentation pagefor more details.2️⃣ Very configurablejinja-treeis very configurable. You can configure global options via CLI options or a configuration file.Plugins are configurable via the configuration file.Seethis specification documentation pagefor more details.3️⃣ Embedded extensionsjinja-treeincludes some extensions to Jinja templates engine:to execute some commands (and get the corresponding output)to parse JSON strings into Python objects)..Usage examplesshellextension{{"date"|shell()}}=> will render something like:Sun Jan 28 15:11:44 CET 2024from_jsonextensionexportMYENV='["foo", "bar", "baz"]'(cat<<EOF{% for item in MYENV|from_json() -%}- {{ item }}{% endfor %}EOF)|jinja-stdin=> will render something like:- foo
- bar
- barSeethis directoryfor others4️⃣ Full Jinja / Jinja2 support (including "includes" and "inheritance")jinja-treehas several options for Jinja "search paths". So you can use Jinja "includes" and "inheritance" features.Installationpip install jinja-tree[!TIP]
If you want to get a better readability ofjinja-treeoutput (colors...), you can also usepip install richto install
thisoptionaldependency.[!NOTE]
A docker image is also available. You can use it to avoid any specific installation.
See at the end of the "Usage" section for more details.UsageMain CLIjinja-tree .[!NOTE]
The.in the previous command in the "root directory" (the directoryjinja-treewill explore recursively to find files to process). You can replace it with any directory you want. By using., you will process all files in the current directory and its subdirectories.Main CLI optionsUsage: jinja-tree [OPTIONS] ROOT_DIR

  Process a directory tree with the Jinja / Jinja2 templating system.

Arguments:
  ROOT_DIR  root directory  [required]

Options:
  --config-file TEXT              config file path (default: first '.jinja-
                                  tree.toml' file found up from current
                                  working dir), can also be see with
                                  JINJA_TREE_CONFIG_FILE env var  [env var:
                                  JINJA_TREE_CONFIG_FILE]
  --log-level TEXT                log level (DEBUG, INFO, WARNING or ERROR)
                                  [default: INFO]
  --verbose / --no-verbose        increase verbosity of the DEBUG log level
                                  (note: this forces log-level = DEBUG)
                                  [default: no-verbose]
  --extra-search-path PATH        Search path to jinja (can be used multiple
                                  times)
  --add-cwd-to-search-path / --no-add-cwd-to-search-path
                                  add current working directory (CWD) to jinja
                                  search path
  --add-root-dir-to-search-path / --no-add-root-dir-to-search-path
                                  add root directory to jinja search path
  --jinja-extension TEXT          jinja extension to load
  --context-plugin TEXT           context plugins (full python class path, can
                                  be used multiple times)
  --action-plugin TEXT            action plugin (full python class path, can
                                  be used multiple times)
  --strict-undefined / --no-strict-undefined
                                  if set, raise an error if a variable does
                                  not exist in context
  --blank-run / --no-blank-run    if set, execute a blank run (without
                                  modifying or deleting anything)  [default:
                                  no-blank-run]
  --disable-embedded-jinja-extensions / --no-disable-embedded-jinja-extensions
                                  disable embedded jinja extensions
  --help                          Show this message and exit.Bonus CLI (if you want to process only one file but with the same behavior)cat/path/to/your/file/to/process|jinja-stdin>/path/to/your/processed/fileor (if you want to process only a string):$exportFOO=bar$echo"Hello {{FOO}}"|jinja-stdinHello barBonus CLI optionsUsage: jinja-stdin [OPTIONS]

  Process the standard input with Jinja templating system and return the
  result on the standard output.

Options:
  --config-file TEXT              config file path (default: first '.jinja-
                                  tree.toml' file found up from current
                                  working dir), can also be see with
                                  JINJA_TREE_CONFIG_FILE env var  [env var:
                                  JINJA_TREE_CONFIG_FILE]
  --log-level TEXT                log level (DEBUG, INFO, WARNING or ERROR)
                                  [default: INFO]
  --verbose / --no-verbose        increase verbosity of the DEBUG log level
                                  (note: this forces log-level = DEBUG)
                                  [default: no-verbose]
  --extra-search-path PATH        Search path to jinja (can be used multiple
                                  times)
  --add-cwd-to-search-path / --no-add-cwd-to-search-path
                                  add current working directory (CWD) to jinja
                                  search path
  --jinja-extension TEXT          jinja extension to load
  --context-plugin TEXT           context plugins (full python class path, can
                                  be used multiple times)
  --strict-undefined / --no-strict-undefined
                                  if set, raise an error if a variable does
                                  not exist in context
  --disable-embedded-jinja-extensions / --no-disable-embedded-jinja-extensions
                                  disable embedded jinja extensions
  --help                          Show this message and exit.Docker imageA docker image is also available. You can use it this way:dockerrun-t-v$(pwd):/workdir--user=$(id-u)ghcr.io/fabien-marty/jinja-tree:latest/workdir(we mount the current directory in the/workdirdirectory in the container and executejinja-treein this/workdirdirectory)[!WARNING]
If you plan to use environment variables with the docker image, you will have to use (possibly multiple times) the-e VAR=VALUEoption to pass them to the container.
With docker, it's more practical to use a.env(dotenv) file as it will be automatically mounted in the container.If you want to add some CLI options, you can add them like in this example:dockerrun-t-v$(pwd):/workdir--user=$(id-u)ghcr.io/fabien-marty/jinja-tree:latest--verbose/workdir(we added--verbosejust before the/workdirargument)If you want to use the `jinja-stdin` CLI with docker?echo"FOO {{ BAR }}"|dockerrun-i-v$(pwd):/workdir-eBAR=BAZ--user=$(id-u)--entrypointjinja-stdinghcr.io/fabien-marty/jinja-tree:latest(it will outputFOO BAZ)