Crates.io | ctgen |
lib.rs | ctgen |
version | 0.1.5 |
source | src |
created_at | 2024-02-22 03:17:47.985536 |
updated_at | 2024-08-02 08:25:27.402238 |
description | Code Generator based on Handlebars Templates and Database Reflection |
homepage | https://github.com/cytecbg/ctgen |
repository | https://github.com/cytecbg/ctgen |
max_upload_size | |
id | 1148829 |
size | 178,450 |
Code generation tool meant to reduce repetitive tasks in day-to-day operations.
Generate code or text documents based on pre-defined code templates and a database schema.
Currently supports only MySQL/MariaDB databases with InnoDB table storage engine.
Code templates are written in handlebars
format and support rhai
scripts.
Run cargo install ctgen
(if this project reached the public crate stage).
Or alternatively clone the repository and run cargo build --release
and then
copy target/release/ctgen
to a bin path of your choice.
Or just cargo install --path .
To see some hands-on examples, check ctgen-samples.
There are 3 modes of operation (commands).
init
command is for creating a new configuration profile project.config
command is for managing existing configuration profiles.run
command is for running a generation task inside another project.Under no circumstances should you ever run generation tasks based on templates you are not very well familiar with! This poses a great security threat!
When using ctgen
with templates that you did not create yourself you should read and study the code carefully before running any tasks with
that template! Ctgen can and does modify your local filesystem and has the capability to execute additional shell commands with or without user input!
Under no circumstances should you ever run ctgen
as root
or any other privileged account! As of time of writing ctgen
does NOT have any mechanisms to
predict or prevent any potentially negative outcomes or dangerous operations. Use discretion and study the templates you use before attempting to run any tasks!
To create your first configuration profile go somewhere in your filesystem and run ctgen init
.
Optionally you can create the profile project in a new directory by running ctgen init <dirname>
.
To avoid being prompted for a profile name, use the --name
option: ctgen init --name backend backend_templates
.
This will create a new configuration profile project and register it using the same name.
The default project layout is:
Ctgen.toml
. Describes the profile behavior, templates and build targets.assets/templates
. Contains all handlebars
templates with .hbs
extension. The main part of the filename is the template name.assets/scripts
. Contains all rhai
scripts with .rhai
extension. The main part of the filename is used to register the script as handlebars helper.ctgen config add [path to Ctgen.toml]
. If you are in the profile directory, you can just run ctgen config add
. Optionally you can pass --default
to override your default profile or --name my_name
to override the profile name. Otherwise the name of the profile is used in the registry.ctgen config ls
. If an item in the list is blinking in red, that means that the profile is broken and the config file does not exist.ctgen config rm profile_name
.Assuming you have a valid configuration profile setup already (see above), to run a generation task you need to:
cd my_awesome_project
ctgen run
Check ctgen help run
for extra options like:
default
using --profile=flutter
.env
file, environment variable name, DSN string or target path--prompt
option, for example --prompt "dummy=1"
. Prompts answered with command-line params will be skipped during the run.Example runs:
Let's imagine you are generating flutter code for your mobile project. Your profile is called mobile
. It doesn't know where your database is so you enter it manually. You chose to generate code for table clients
and know that the profile will ask you whether you want to generate a password reset flow and also add login with Google.
Run: ctgen run --profile=mobile --dsn="mysql://root@127.0.0.1:3306/project_db" --prompt "password_reset=1" --prompt "google_auth=1" clients
The Ctgen.toml
file describes the profile behavior and follows this set of rules:
profile
, this section holds these fields:name
: the default profile nameenv-file
: the name of the env file to look for when trying to initialize context, typically .env
env-var
: the name of the env variable to look for in the .env
file, for example DATABASE_CONNECTION
; the value of the variable is expected to be a valid DSNdsn
: if env-file
and env-var
are left empty, the profile could have a hardcoded database DSN instead; otherwise this field could be omitted or left blanktarget-dir
: this is the directory that should hold all build targets. It is relative to current working dir when running a generation task (ctgen run
). CWD is used if left blanktemplates-dir
: this is the directory that holds all handlebars templates. It is relative to the profile containing directory.scripts-dir
: this is the directory that holds all rhai scripts. It is relative to the profile containing directory.prompts
: this is an array of strings. Every string in the array must be a valid prompt ID of a prompt defined in the prompt
sections that follow.targets
: this is an array of strings. Every string in the array must be a valid target ID of a target defined in the target
sections that follow.prompt
sections after the profile
section declare profile prompts by assigning a prompt ID as a dot-nested value to the section name, for example [prompt.dummy]
. A prompt can have the following fields (properties):condition
: optional, containing an inline handlebars template that should render 1
to trigger this promptprompt
: containing plain text or an inline handlebars template that is being rendered to the user as prompt textoptions
: optional, containing either an array or table (object) of available options (for select and multiselect prompts), or string (for input prompts), or an inline handlebars template that renders a comma-separated list of options (for select and multi-select prompts)multiple
: optional, boolean flag indicating a multi-select; default is false
ordered
: optional, boolean flag indicating that order matters for multi-select values; default is false
required
: optional, boolean flag indicating that empty values will not be accepted; default is false
target
sections after the prompt
sections declare profile build targets by assigning a target ID as a dot-nested value to the section name, for example [target.dummy]
. A target can have the following fields (properties):condition
: optional, containing an inline handlebars template that should render 1
to trigger this target to be renderedtemplate
: string containing a template name, which should exist as a file with .hbs
extension in the templates-dir
directory. For example dummy
, or backend/dummy
.target
: string containing an inline handlebars template that should render to a file path inside the target-dir
. Missing path elements will be created. Could also be plain text path like main.rs
.formatter
: optional, containing an inline handlebars template that should render a valid shell command to execute after the target has been rendered and written to disk. Could also be plain text shell command if no context conditional parameters are necessary. NOTE: The only available variable to render is {{target}}
.op.rhai
inside assets/scripts
, then you will have {{op}}
helper available in your handlebars templatesbackend.hbs
inside assets/templates
, to define a target that uses that template, use the name backend
as template name{{inflect}}
handlebars-inflector, {{concat}}
handlebars-concat, {{datetime}}
handlebars-chrono and {{{json}}}
(takes the first argument and turns it into a JSON){
"database": {
"name": "db_name",
"tables": [],
"constraints": [],
"metadata": {}
},
"table_name": "selected_table_name",
"table": {
"name": "selected_table_name",
"primary_key": [],
"columns": [],
"indexes": [],
"metadata": {}
},
"constraints_local": [],
"constraints_foreign": [],
"prompts": {
"dummy": "1"
},
"timestamp": "2024-03-18T21:35:09.750752900+00:00",
"ctgen_ver": "0.1.2"
}
To dump your own context for debugging purposes use {{{json this}}}
in your template.
This tool relies heavily on handlebars-rust and rhai crates. :heart:
database-reflection
(add more adapters)lib
layout and exports and isolate cli
junk better