# Proplate 🛠⚙
GitHub License CircleCI

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 1. [Installation](#installation) 2. [Use a template to create a project](#use-a-template-to-create-a-project) 3. [Craft your own template](#craft-your-own-template) - [Ref](#ref) - [Learn by doing](#learn-by-doing) - [tiniest template configuration](#tiniest-template-config) - [args](#args) - [context binding](#context-binding) - [Some extras](#some-extras) ## Installation Prerequisites: [git](https://git-scm.com/downloads) #### Github release You can download it from the [release](https://github.com/YumeT023/proplate/releases/tag/0.3.0) page.
I recommend making it globally available in your terminal. (wip: install.sh) #### Cargo If you have cargo installed ```shell cargo install proplate ``` > cargo will make it directly available in your $PATH ## Use a template to create a project ```shell proplate create --template --dest ``` `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](https://github.com/YumeT023/proplate-simple-npm-template)
Run the following command to start your project from the above template: ```shell 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: ```json { "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`. ```json "args": [ { "key": "project_name", "q_type": "Text", "label": "Enter your project name" } ] ``` Text input is rendered as follow: ![text input](examples/learn-by-doing/.proplate_aux_utils/text_input.png) Let's try to add a select input for the license with some `options` ```json "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: ![select input](examples/learn-by-doing/.proplate_aux_utils/select_input.png) ... 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_ ```md # $project_name licensed under $license ``` run proplate ```shell proplate create --template learn-by-doing --dest dynamic-uh ``` Lezz open the output `dynamic-uh/README.md` `...` We actually nailed it ✨ ![dynamic-uh](examples/learn-by-doing/.proplate_aux_utils/dynamic-uh.png) How to i tell proplate that I want to write `$not-binding` as is ? just escape them -uh _README.md_ ```md # $project_name licensed under $license hey proplate, leave this one \$not-binding ``` I mean... ![no-dynamic-uh](examples/learn-by-doing/.proplate_aux_utils/no-dynamic-uh.png) You are free to create as many files as desired and add the bindings, **Proplate** will handle them [more about dynamic files](#some-extras) #### 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. ```json { "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](#some-extras) _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 ```json { "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" } } ] } ... ] } ``` ```shell 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 ```json { "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 ```json { "exclude": [".git", "node_modules"] ... } ``` - `"args"`: Input of type `Text` 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 }_