6 releases
0.5.1 | Apr 1, 2024 |
---|---|
0.5.0 | Mar 14, 2024 |
0.4.1 | Feb 24, 2024 |
0.4.0 | Jan 21, 2024 |
0.3.1 | Jan 8, 2024 |
#537 in Command line utilities
65KB
1.5K
SLoC
Proplate 🛠⚙
Give up setting up the environment each time you begin a project using the same technology; instead, make a template once and utilize it for all upcoming projects.
Table of contents
Installation
Prerequisites: git
Github release
You can download it from the release page.
I recommend making it globally available in your terminal. (wip: install.sh)
Cargo
If you have cargo installed
cargo install proplate
cargo will make it directly available in your $PATH
Use a template to create a project
proplate create --template <location> --dest <output_dir>
location
could be a Github repository or a local directory
For the sake of testing, I'll leave this template https://github.com/YumeT023/proplate-simple-npm-template
Run the following command to start your project from the above template:
proplate create --template https://github.com/YumeT023/proplate-simple-npm-template --dest your-project-name
NB: Add --git
if you'd want proplate to initialize a git repository for you
At this point, ... talk to Proplate:D
Craft your own template
Ref
- Proplate template is a directory that contains a
meta.json
Learn by doing
The template for the example can be found at https://github.com/YumeT023/proplate/tree/master/examples/learn-by-doing
tiniest template config
The tiniest configuration is as follows:
{
"id": "initial-template",
"args": []
}
args
What are "args"
for?
Proplate uses them to create an interactive prompt during template initialization.
There are two variants of input you can get with Proplate: Select
and Text
.
"args": [
{
"key": "project_name",
"q_type": "Text",
"label": "Enter your project name"
}
]
Text input is rendered as follow:
Let's try to add a select input for the license with some options
"args": [
{
"key": "project_name",
"q_type": "Text",
"label": "Enter your project name"
},
{
"key": "license",
"q_type": "Select",
"label": "Select a license for your project",
"options": ["MIT", "BSD-2-Clause", "none"]
}
]
Select input is rendered as follow:
... but now... what ? args
is what:( ?
Context binding
args or context are used to replace the var binding in specific files called dynamic files
How to write dynamic files ?
... pretty straightforward: $var_name, in our case $license
and$project_name
Let's add a file README.md dynamic file, as follows
README.md
# $project_name
licensed under $license
run proplate
proplate create --template learn-by-doing --dest dynamic-uh
Lezz open the output dynamic-uh/README.md
...
We actually nailed it ✨
How to i tell proplate that I want to write $not-binding
as is ?
just escape them -uh
README.md
# $project_name
licensed under $license
hey proplate, leave this one \$not-binding
I mean...
You are free to create as many files as desired and add the bindings, Proplate will handle them
Additional operations
Sometimes, you want to do things beyond just replacing dynamic files. Well, Proplate's got you covered.
At the moment, proplate supports 2 basic fs
operation: Remove
, Copy
, CopyDir
these operations are enumerated under "additional_operations"
... let's say we just want to delete something for no good reason
Add the file SIMPLY_DELETE to your template directory.
{
"additional_operations": [
{
"operations": [
{
"Remove": {
"files": ["SIMPLY_DELETE"]
}
}
]
}
]
}
You are free to add as many operations as desired under the "operations"
... but wait, "additional_operations"
is kinda weird... and why don't you just omit the SIMPLY_DELETE file directly ?
Removing and copying become more practical when executed conditionally right ?? ... Proplate can do that!!
Let's modify our template a bit
add MIT
to the ".proplate_aux_utils"
directory (this directory is ignored by default more info
MIT
add the $author binding;)
MIT License
Copyright (c) 2024 $author
...
Now, only copy the MIT to the LICENSE file when MIT license is selected
{
"args": [
{
"key": "author",
"q_type": "Text",
"label": "Who is da author"
}
...
],
"additional_operations": [
{
"conditions": [
{
"lhs": "$license",
"op": "Eq",
"rhs": "MIT"
}
],
"operations": [
{
"Copy": {
"file": ".proplate_aux_utils/MIT",
"dest": "LICENSE"
}
}
]
}
...
]
}
proplate create --template learn-by-doing --dest additional-op-uh
supported conditional op are: Eq
, NotEq
-You might say-
can't we just run some bash script-uh ? ... for your own security, NO
Some extras
-
"dynamic_files"
: If you don't include this prop, proplate will treat the template files as dynamic.-
For a larger template, you may want to specify exactly what the dynamic files are. You can enumerate them under the
"dynamic_files"
prop as follow you can enumerate "files" or "directories". However, at this point, the rest of the files/directories become static{ "dynamic_files": ["package.json", "directory"] ... }
-
-
"exclude"
: I told you earlier that the".proplate_aux_utils"
. By default, (auxiliary) is ignored, which means it is not included in the template directly But maybe later, during "additional_operations"-
You can also add your own auxiliary directory/file under the
"exclude"
.Note:
"meta.json"
and".proplate_aux_utils"
is pre-excluded{ "exclude": [".git", "node_modules"] ... }
-
-
"args"
: Input of typeText
may have a "default_value" prop, which proplate will use as a placeholder -
"additional_op"
op list:- Copy { file, dest }
- CopyDir { path, dest }
- Remove { files }
Dependencies
~8–18MB
~223K SLoC