1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
//! # Using the scaffolding CLI tool:
//!
//! After having installed it, these are the commands that are available:
//!
//! ```bash
//! // Scaffold an example Holochain app
//! hc-scaffold example
//! ```
//!
//! Or if you want to scaffold your own custom app, for example a to-do app:
//!
//! ```bash
//! // Scaffold an empty web-app, using a built-in template
//! hc-scaffold web-app todos
//!
//! cd todos
//!
//! // Scaffold a dna inside the newly scaffolded app
//! hc-scaffold dna todos
//!
//! // Scaffold a zome inside the newly scaffolded dna
//! hc-scaffold zome todos
//!
//! // Scaffold an entry-type inside the newly scaffolded zome
//! hc-scaffold entry-type todo
//!
//! // Scaffold a collection for the newly scaffolded entry-type
//! hc-scaffold collection global all_todos
//!
//! // Scaffold a new link-type
//! hc-scaffold link-type
//!
//! // Will show all the commands that are available
//! hc-scaffold --help
//! ```
//!
//! # Custom Templates
//!
//! The scaffolding tool comes with 4 built-in templates:
//!
//! - Vue
//! - Svelte
//! - Lit
//!
//! These templates provide most of the skeleton you need to start your own holochain app.
//!
//! But! They are not complete, nor provide good design from the UI/UX perspective. They are trying to be unopinionated in that regard, so that you as the developer can apply your own style of building frontend apps.
//!
//! To allow for more flexibility, the scaffolding tool can be extended and customized using custom templates. This would allow you to create a "React" template, or a "Vue + tailwind" template, or whatever style of frontend code and packaging you want for your app.
//!
//! ## Using custom templates
//!
//! If you know of some already existing template that you want to use, simply scaffold a new web-app pointing to its git repository with:
//!
//! `hc scaffold web-app forum --templates-url https://github.com/holochain-open-dev/templates`
//!
//! If instead, you want to use that template within an already existing repository, you can use this command instead:
//!
//! `hc scaffold template get https://github.com/holochain-open-dev/templates`
//!
//! Both of the previous commands will create a `.templates` folder in the root folder of your repository, with a copy of the template.
//!
//! From this point on, any command that you execute with the scaffolding tool is going to use that custom template instead of the built-in ones.
//!
//! If later on the template adds some new features and you want to include them in your repository, you can just run this command again:
//!
//! `hc scaffold template get https://github.com/holochain-open-dev/templates`
//!
//! And select "Merge with existing template", to overwrite the old one.
//!
//! ## How to create a custom template
//!
//! Creating and maintaining your own template can be challenging at first, so look for existing templates that you can reuse before diving in to create your own.
//!
//! The best way to start creating a custom template is to go from one of the built-in ones, and modify it.
//!
//! To create a custom template, run this command and select the built-in template that you want to go from, and also give a name to your template.
//!
//! `hc scaffold template init`
//!
//! At this point, you'll have a `.templates/<TEMPLATE NAME>` folder. That's where your custom template lives.
//!
//! Templates have this directory structure:
//!
//! coordinator-zome/
//! dna/
//! entry-type/
//! example/
//! field-types/
//! collection/
//! integrity-zome/
//! link-type/
//! web-app/
//!
//! Each folder corresponds to the templates that are going to be created when running a specific command. This is the steps that are executed:
//!
//! 1. The user executes a scaffolding command, like `hc scaffold web-app`.
//! 2. The scaffolding tool asks the user to input all the necessary information.
//! 3. The apropriate **backend** and **testing** code is created automatically, the custom template can't influence it.
//! 4. The scaffolding tool looks for a custom template in the `.templates` folder.
//! 5. If there is one, it will look for a folder inside that custom template that corresponds to the command being run.
//! - Eg. `hc scaffold web-app` will look for a folder named `web-app`.
//! 6. If there is one, it will copy the directory structure inside that folder and select the files with the `.hbs` extension.
//! 7. It will render the contents of each of the files using as context the appropriate data from the command.
//! - Eg. in `hc scaffold web-app`, one of the fields of the context is `app_name`, which is the name of the app that the user input.
//! 8. Lastly, it will merge the resulting directory structure with the existing repository structure. If a file already existed, it will overwrite its contents.
//!
//! You can take a look at [Writing templates](#writing-templates) to learn how to write your own templates.
//!
//! This is the list of commands and the templates they use:
//!
//! - `web-app`: uses the `web-app` folder. [Available data](`crate::templates::web_app::ScaffoldWebAppData`).
//! - `dna`: uses the `dna` folder. [Available data](`crate::templates::dna::ScaffoldDnaData`).
//! - `zome`: uses the `coordinator-zome` folder if scaffolding a coordinator zome, and the `integrity-zome` folder if scaffolding an integrity zome. [Available data](`crate::templates::coordinator::ScaffoldCoordinatorZomeData`).
//! - `entry-type`: uses the `entry-type` folder. [Available data](`crate::templates::entry_type::ScaffoldEntryTypeData`).
//! - `link-type`: uses the `link-type` folder. [Available data](`crate::templates::link_type::ScaffoldLinkTypeData`).
//! - `collection`: uses the `collection` folder. [Available data](`crate::templates::collection::ScaffoldCollectionData`).
//! - `example`: uses the `example` folder. [Available data](`crate::templates::example::ScaffoldExampleData`).
//!
//! ### Field types
//!
//! The `field-types` folder is special. It has the following directory structure:
//!
//! ActionHash/
//! type.hbs
//! AgentPubKey/
//! type.hbs
//! bool/
//! Checkbox/
//! detail/
//! render.hbs
//! edit/
//! imports.hbs
//! render.hbs
//! type.hbs
//! EntryHash/
//! type.hbs
//! String/
//! TextField/
//! detail/
//! render.hbs
//! edit/
//! imports.hbs
//! render.hbs
//! TextArea/
//! detail/
//! render.hbs
//! edit/
//! imports.hbs
//! render.hbs
//! type.hbs
//! Timestamp/
//! DateTimePicker/
//! detail/
//! render.hbs
//! edit/
//! imports.hbs
//! render.hbs
//! type.hbs
//! u32/
//! Slider/
//! detail/
//! render.hbs
//! edit/
//! imports.hbs
//! render.hbs
//! type.hbs
//!
//! As you can see, the top-level folders are the rust types that are possible to use as the field types for an entry. The `type.hbs` file in each of the folders contains the typescript type for that rust type, so that it can be rendered in the frontend.
//!
//! Now, on to the interesting part. Each subfolder in each of the types **corresponds to a frontend widget** that that field can be rendered with. The scaffolding tool will dynamically pick up the folders that exist in that type, and offer the choice to the user to pick a widget from the supported ones in this template. If no widget is found, then the user won't be able to make the field visible in the frontend.
//!
//! After the user has selected a widget, it's up to the templates inside the `entry-type` folder in the root of the template to render the widget, using partials. All the `field-types` directory is registered as partials in the handlebars engine.
//!
//! So for example, if inside the `entry-types` template we have something like this:
//!
//! ```hbs
//! {{> String/TextArea/detail/render }}
//! ```
//!
//! This will get replaced by the contents of the file `field-types/String/TextArea/detail/render.hbs`.
//!
//! ### Instructions
//!
//! Additionally to the folders, you can override the built-in instructions that get shown to the user after each command. The scaffolding tool will look for a file named `<COMMAND>.instructions.hbs` in the folder for the custom template, and if it exists, render its contents and display them to the user. The name of the `COMMAND` for the file matches the names for the folders where the templates for each command exist.
//!
//! This is a great way to guide the users of your template towards next steps that they need to take while using your template.
//!
//! So for example, if there is a `coordinator-zome.instructions.hbs` file in the root folder of your template and the user runs `hc scaffold zome posts --coordinator dnas/forum/zomes/coordinator`, then the scaffolding tool will render its contents and display them to the user when it has finished creating the zome.
//!
//! ### Writing templates
//!
//! The template engine used in the template files is [handlebars](https://handlebarsjs.com/). You can look at its documentation to learn how to write your own templates.
//!
//! Here are the available helpers:
//! - All the built-in helpers described in [the handlebars crate](https://docs.rs/handlebars/latest/handlebars/#built-in-helpers).
//! - Case helpers:
//! - `pascal_case`: converts the string to pascal case.
//! - `title_case`: converts the string to title case.
//! - `lower_case`: converts the string to lower case.
//! - `snake_case`: converts the string to snake case.
//! - `camel_case`: converts the string to camel case.
//! - `plural`: converts the given string to its plural.
//! - `concat`: concatenize strings.
//! - `contains`: check whether list contains an element.
//! - Example usage:
//! ```hbs
//! {{#if (contains entry_type_list "Profile")}}
//! ...
//! {{/if}}
//! ```
//! - `includes`: check whether a string includes a substring.
//! - Example usage:
//! ```hbs
//! {{#if (includes entry_type.name "Profile")}}
//! ...
//! {{/if}}
//! ```
//! - `merge` and `match_scope`: a pair of helpers useful to add some new code to an already existing code structure, respecting their scope (`{` and `}`) structure.
//! - `merge`: takes existing code as its only argument.
//! - `match_scope`: needs to be placed inside a `merge` helper block, and takes the opening of an scope as only argument. It then searches the argument of the `merge` helper for a scope matching that opening of the scope, and replaces its contents with the contents of the `match_scope` block:
//! - Example usage:
//! ```hbs
//! {{#merge previous_file_content}}
//! {{#match_scope "export class ExistingClassA {" }}
//! {{previous_scope_content}} // Variable containing the previous content of the scope
//!
//! newFunction() {
//! // This is a new function that will be added at the end of "ExistingClassA"
//! }
//! {{/match_scope}}
//! {{#match_scope "export class ExistingClassB {" }}
//!
//! {{#merge previous_scope_content}}
//! {{#match_scope "newFunction() {" }}
//! {{previous_scope_content}}
//! // Will add a line at the end of newFunction
//! {{/match_scope}}
//! {{/merge}}
//!
//! {{/match_scope}}
//! {{/merge}}
//! ```
pub mod cli;
pub mod error;
pub mod file_tree;
pub mod reserved_words;
pub mod scaffold;
pub mod templates;
pub mod utils;
pub mod versions;