JGen Chenile code generator

Reference

jgen(1): the manual

Every jgen option, mode, environment variable and file, in the style of a Unix manual page. Run man jgen after a Homebrew or zip install.

This is the manual page installed with JGen (man jgen). Its source is jgen/jgen-cli/src/man/jgen.1.md in the chenile-gen repository. It describes the current development version; features marked "since 2.5.1" are not in the 2.1.35 release (JGen is now versioned on its own; 2.5.1 follows 2.1.35).

NAME

jgen - generate projects from blueprints

SYNOPSIS

jgen [-c config]

jgen -f input.json [-c config] [--trust] [--offline]

jgen -g blueprint [-o file | -e folder] [-c config] [--trust] [--offline]

jgen -e config-file

jgen -r project [--into folder] [--blueprint blueprint] [-c config] [--trust] [--offline]

jgen --fetch reference [--trust] [--offline]

jgen --search [text] [--offline]

jgen --extensions

jgen --completion shell

jgen -h | -V

DESCRIPTION

jgen generates a project from a blueprint. A blueprint is one jar that holds a typed input contract (META-INF/blueprint.json), a template tree, and optional Java hooks. jgen collects the blueprint’s inputs, checks them, copies the template tree into the destination folder, renders it, and runs the blueprint’s hooks.

Template files ending in .mustache are rendered with Mustache. File and folder names carry further instructions:

  • __name__ is replaced by an input value;
  • _DoT_ becomes a dot, so _DoT_gitignore is generated as .gitignore (since 2.5.1);
  • a folder named %%key=value%% is kept only when the input matches;
  • a .filelist file is split into several files;
  • an empty folder named %{{blueprint …}} generates a child blueprint in its place.

jgen ships with blueprints for Chenile services, workflow services, query modules, mini-monoliths, ecosystems, process deployments, interceptors, integration tests and new blueprints. It accepts other blueprints without a rebuild: from blueprint folders (see FILES) or straight from a GitHub release (see BLUEPRINT REFERENCES).

Every input path (prompts, input files, the web portal, child blueprints) goes through the same validator. The validator reports every problem at once, before any file is written.

Since 2.5.1, a blueprint can ask jgen to make the generated project a local Git repository: when the input initGit is true, jgen runs git init (branch main), adds every file and makes one commit. If the blueprint names a GITHUB_REPOSITORY input as its gitRepositoryField and that input has a value, jgen adds it as the origin remote, using SSH, or HTTPS when the configuration sets gitRemoteProtocol to https. jgen never creates the GitHub repository and never pushes.

After generating, jgen writes a generation record into the project (see FILES). jgen -r uses it to regenerate the project with a newer blueprint and report what changed.

MODES

jgen does one thing per run. When several mode options are given, the first of --fetch, -r, -g and -e wins. With none of them, jgen generates a project.

Interactive generation (no mode option)
If a config folder exists in the current directory, jgen offers its files as alternatives to the default configuration. It then lists the installed blueprints, asks you to choose one, and prompts for each input. Each prompt shows the input’s validation rule and default value. Press Enter to accept the default.
Generation from a file (-f)
Reads all inputs from a JSON file and asks nothing. The whole file is validated first, and every error is listed. Keys that the blueprint does not declare are reported as warnings and ignored.
Sample input (-g)
Writes a JSON input file for a blueprint, filled with its default values, ready to edit and pass to -f.
Configuration (-e without -g)
Writes a copy of the default configuration to edit and pass to -c.
Regeneration (-r)
Regenerates a project with the current blueprint, into a separate folder, and classifies every file. The original project is never modified.
Fetch (--fetch)
Fetches, verifies and caches a blueprint from GitHub, and describes it.

OPTIONS

-c, --config file
Use this JGen configuration instead of the bundled default. The configuration sets the Java package segments (com, company, org), the Chenile version used in generated projects, and defaults such as the destination folder. A missing file is an error. With -r, use this configuration instead of the one recorded in the project.
-f, --input-file file
Generate from the inputs in file, a JSON object. Its blueprint key names the blueprint (an installed name or a github: reference); its other keys are the blueprint’s inputs. Values may refer to configuration entries with ${name}.
-g, --generate-blueprint-file blueprint
Emit a sample input file for blueprint, an installed name or a github: reference. The sample keeps the reference in its blueprint key, so -f later resolves the same blueprint. Without -o or -e, the sample is printed on standard output.
-o, --output-file file
With -g: write the sample to file. It cannot be combined with -e folder.
-e, --emit-config [name]

Without -g: write the default configuration to config/name.json. The config/ folder is created if needed, and .json is added if missing.

With -g: name is a folder. jgen writes input-file.json there, together with any companion sample files the blueprint provides (for example a workflow XML or a process definition). It refuses to overwrite existing companion files.

-r, --regenerate project

Regenerate project, a folder that contains .jgen/generation.json. jgen finds the blueprint by its recorded name. If that blueprint is not installed, it fetches exactly the recorded reference and checks it against the recorded hash. jgen then validates the recorded inputs against the blueprint’s current input contract and generates into --into. Each file is reported in one of these classes:

SAFE_UPDATE - you did not change it, the blueprint did: take the new file.
KEEP_USER - you changed it, the blueprint did not: keep yours.
CONFLICT - changed on both sides: merge.
NEW_FILE - new in the blueprint: add it.
SAFE_DELETE - dropped by the blueprint, unchanged by you: delete it.
DELETE_CONFLICT - dropped by the blueprint, changed by you: decide.
USER_DELETED - you deleted it, the blueprint still generates it.

jgen prints the classification, writes it to project.regeneration.json next to the regenerated project, and suggests a git diff --no-index command.

--into folder
With -r: the folder to regenerate into. Default: project.regenerated, next to project.
--blueprint blueprint
With -r: regenerate with this blueprint instead of the recorded one, for example github:acme/jgen-terraform@2.0.0, to see what an upgrade would change. It must have the same name as the recorded blueprint.
--fetch reference
Fetch the blueprint at reference, verify it and cache it. jgen prints its name, description, exact source and SHA-256, and the -g command to use it.
--search [text]
Search the blueprint catalogs (see CATALOGS) for entries whose name, description or tags contain text; without text, list every entry. Each result shows catalog/name, its description, source and tags.
--extensions
List the installed extensions: template engines with the file extension each renders, language packs with their validation rules and helpers, path tags in the order they run, and every template helper. Built-in extensions are marked; added ones show their class and version. See EXTENSIONS.
--trust
Trust every blueprint source used in this run without asking. Use this in scripts and CI only for sources you have reviewed. Prefer listing them in settings.json (see FILES).
--offline
Never contact GitHub. Use only installed and cached blueprints. A reference without a version resolves to the newest cached version.
--completion shell
Print the completion script for shell: bash, zsh or fish (see SHELL COMPLETION).
-h, --help
Print a usage summary and exit.
-V, --version
Print jgen’s version, the Chenile version generated projects target by default, and the Chenile version jgen was built with (see VERSIONS), then exit.

BLUEPRINT REFERENCES

A blueprint is named by its installed name (for example chenile-service), by a catalog name (see CATALOGS) or by a reference:

github:owner/repo[/name][@version][#sha256:hex]

owner/repo
The GitHub repository. If its release carries a blueprint jar (exactly one, or exactly one named repo-*.jar; -sources, -javadoc and -tests jars are ignored), jgen uses the jar. Otherwise, or when the tag has no release, jgen uses the repository’s source archive at that tag as a template-only blueprint (since 2.5.1). A template-only blueprint is laid out like a jar’s resources (src/main/resources/META-INF/blueprint.json and its template folder) and may not declare an init hook.
name
Which blueprint to use, when the jar contains several.
version
A release tag. Without it, jgen uses the latest release, or else the highest version tag (or, with --offline, the newest cached one).
hex
The expected SHA-256, as 64 hexadecimal digits: of the jar, or, for a template-only blueprint, of its files. A mismatch is an error. Pinning is recommended in scripts and CI.

A local folder holding a template-only blueprint is named with dir:folder (since 2.5.1). The folder may be the blueprint’s repository or its src/main/resources. It is not cached, locked or trust-checked, so edits apply on the next run.

Installed blueprints always take precedence. A fetched blueprint whose name is already taken by an installed one is refused.

CATALOGS

Since 2.5.1, a short name that is not installed is looked up in blueprint catalogs: [catalog/]name[@version]. jgen searches the official catalog (github:ajapros/jgen-catalog) first, then the catalogs listed in settings.json, and uses the first match. catalog (the catalog’s alias) picks one catalog; version picks a version, otherwise the latest. The entry’s source is then fetched like any github: reference, and a version the catalog pins to a SHA-256 is checked.

Sources listed in the official catalog are trusted. Sources from other catalogs are trusted only if the catalog is marked trusted in settings.json; otherwise jgen asks as usual. Catalogs are cached for an hour; when GitHub cannot be reached, or with --offline, the cached copy is used.

TRUST

A blueprint can contain Java code, which runs with your permissions. jgen therefore:

  • downloads only from trusted sources. By default these are the official organisations, github:ajapros/* and github:rajakolluru/*. For any other source jgen asks first: allow once, allow always (which adds the repository to settings.json), or refuse. Without a terminal it refuses unless the source is listed or --trust is given. Nothing is downloaded before trust is granted.
  • records the SHA-256 of each fetched version in blueprints.lock.json the first time it is used, and refuses the version if its jar later changes.
  • loads each fetched jar in its own class loader.

EXTENSIONS

Extensions add to what every blueprint can use. There are three kinds:

Template engines
render template files chosen by extension. mustache (.mustache) is built in, and pebble (.peb) ships with jgen.
Language packs
add validation rules and template helpers for a language. python (PYTHON_MODULE, PYTHON_PACKAGE, PYPI_PROJECT) and node (NPM_PACKAGE, JS_IDENTIFIER) are built in.
Path tags
add rules for file and folder names. filelist, placeholder, dot and conditional are built in.

An extension is a jar that lists its classes in META-INF/services/ under the interface’s name. Put the jar in a blueprints folder (see FILES). Extension names are unique, and built-in extensions can’t be replaced.

A blueprint names what it needs in requires, as name or name@minimum-version. jgen refuses a blueprint whose requirements aren’t installed, before reading its fields. A validation name that is neither built in nor defined by an installed language pack is an error. The generation record lists the added extensions a project was generated with, and -r refuses to regenerate a project without them.

SHELL COMPLETION

Homebrew installs completion for bash, zsh and fish. Otherwise, enable it once:

bash (add to ~/.bashrc)
source <(jgen --completion bash)
zsh (add to ~/.zshrc, after compinit)
source <(jgen --completion zsh)
fish
jgen --completion fish > ~/.config/fish/completions/jgen.fish

Zip installs also carry the scripts in completions/.

Tab completes options. For -g, --blueprint and --fetch it offers the installed blueprints, cached github: references and the github: prefix. For -f and -c it offers JSON files, and for -r and --into it offers folders. The blueprint list is cached for ten minutes, or until a jar is added to ~/.jgen/blueprints, so Tab does not start Java each time.

EXIT STATUS

0
Success.
1
An error occurred. This includes invalid inputs (every problem is listed), an unknown or untrusted blueprint, a hash mismatch, a missing configuration file, a destination folder that already exists, and a failure in a blueprint hook. Input and trust errors stop jgen before it writes anything.

ENVIRONMENT

JAVA_HOME
The Java runtime to use (Java 25 or later). Otherwise java is taken from the PATH, or from Homebrew’s OpenJDK.
JAVA_OPTS
Extra JVM options. -Djgen.record=false turns off generation records.
JGEN_BLUEPRINTS
Extra blueprint folders, comma-separated. Every jar in them is loaded at start-up.
JGEN_HOME
The installation folder. The launcher sets it.
JGEN_HOME_DIR
Use this folder instead of ~/.jgen for settings, the lock file and the cache. Useful in CI.
GITHUB_TOKEN, GH_TOKEN
A GitHub token, used to raise the API rate limit when fetching blueprints.

FILES

~/.jgen/blueprints/
Your blueprint jars. They are available to every jgen run, including runs through JBang.
$JGEN_HOME/blueprints/
Blueprint jars shared by everyone using this installation.
~/.jgen/settings.json
trustedSources: a list of trusted blueprint sources, each github:owner/* or github:owner/repo. catalogs: further catalogs, each with source (github:owner/repo), alias and trusted. officialCatalog: false to stop searching the official catalog.
~/.jgen/cache/catalogs/
Cached catalogs.
~/.jgen/blueprints.lock.json
The SHA-256 first seen for each fetched blueprint version.
~/.jgen/cache/github/owner/repo/version/
Cached blueprint jars.
config/
Configuration files, written by -e and offered by interactive generation.
~/.cache/jgen/blueprint-names
The blueprint list used by shell completion (under $XDG_CACHE_HOME if set). It is safe to delete.
project/.jgen/generation.json

The generation record. It holds:

  • the blueprint (name, version, jar coordinates, and for fetched blueprints its reference and SHA-256);
  • the configuration;
  • the validated inputs, with copies of file inputs under .jgen/inputs/;
  • the SHA-256 of every generated file.

Commit it with the project.

project.regeneration.json
The classification written by -r.

EXAMPLES

Generate a Chenile service from an edited sample:

jgen -g chenile-service -o orders.json
jgen -f orders.json

Emit a workflow blueprint’s input together with its sample workflow XML:

jgen -g wfcustom -e specs/
jgen -f specs/input-file.json

Use a blueprint published on GitHub, then pin it for CI (--fetch prints the hash):

jgen --fetch github:acme/jgen-terraform@1.2.0
jgen -g github:acme/jgen-terraform@1.2.0#sha256:<hex> -o tf.json
jgen -f tf.json --trust

Start a new blueprint in its own Git repository, ready to push (set standaloneRepo to y in the input):

jgen -g jgen-blueprint -o new-blueprint.json
jgen -f new-blueprint.json

Find a blueprint in the catalogs and use it by name:

jgen --search terraform
jgen -g terraform@1.2.0 -o tf.json

Write a template-only blueprint and try it from its folder, then use it from GitHub once tagged:

jgen -g dir:./jgen-terraform -o tf.json
jgen -f tf.json
jgen -g github:acme/jgen-terraform@0.1.0 -o tf.json

Install a blueprint jar of your own:

cp target/bp-docs-site-1.0.jar ~/.jgen/blueprints/
jgen -g docs-site -o docs.json

See what a newer blueprint would change in an existing project:

jgen -r ./output/orders
jgen -r ./output/infra --blueprint github:acme/jgen-terraform@2.0.0
git diff --no-index ./output/orders ./output/orders.regenerated/orders

Work without network access:

jgen -g github:acme/jgen-terraform --offline -o tf.json

VERSIONS

Since 2.5.1, jgen has its own version line and release cadence, separate from Chenile’s (2.1.x); 2.5.1 follows 2.1.35. jgen depends only on released Chenile versions. Generated projects target the Chenile version in the configuration’s chenileVersion, which defaults to the latest released Chenile. Change it with a config file (-c, or -e to create one). A blueprint that needs a newer Chenile says so with sinceVersion and refuses an older chenileVersion. jgen’s own libraries are published as org.chenile.jgen:jgen-base and org.chenile.jgen:jgen-ext-pebble.

SEE ALSO

stm-cli(1), java(1), git-diff(1), mvn(1)

The JGen documentation: https://jgen.chenile.org. Chenile: https://chenile.org.

BUGS

Report problems at https://github.com/rajakolluru/chenile-gen/issues.

AUTHOR

Raja Shankar Kolluru and the Chenile contributors.

MIT License. Copyright (c) 2019 Raja Shankar Kolluru.