cats-oss / Scaffdog
Programming Languages
Projects that are alternatives of or similar to Scaffdog
scaffdog is Markdown driven scaffolding tool.
scaffdog
Multiple files can be output in a document, and flexible scaffolding is possible with a simple but powerful template syntax π
Table of Contents
- πΆ Features
- πΎ Getting Started
- π Requirements
- π₯ Migration
- π§ Configuration
- π© Commands
- π Templates
- π FAQ
- π Contributing
- π License
Features
- π Markdown driven
- You can define a template with
<h1>
and code block. - It will be a Documetable template !
- Define meta information with extended syntax using Front Matter.
- You can define a template with
- β Simple & Powerful template syntax
- A simple syntax similar to mustache.js. (
{{ inputs.value }}
) - Function execution similar to pipe syntax. (
{{ inputs.value | fn }}
) - Provide minimum necessary functions in built-in.
- A simple syntax similar to mustache.js. (
- π Ready to use
- You can quickly start using
$ scaffdog init
.
- You can quickly start using
Requirements
- Node.js v12.10 +
Getting Started
Installation
scaffdog
can be installed globally, but we recommend installing it locally on the project.
$ npm install --save-dev scaffdog
Quick Start
In the following tutorial you can start using scaffdog
immediately !
Setup
By default, it stores the document file and configuration file in the .scaffdog
directory.
Creating directories, configuration file and initial documents can be done with the init
subcommand.
$ npx scaffdog init
? Please enter a document name. hello
Setup of scaffdog πΆ is complete!
β .scaffdog/config.js
β .scaffdog/hello.md
Now you can do scaffold by running `$ scaffdog generate`.
Please refer to the following documents and customize it.
https://github.com/cats-oss/scaffdog/#templates
After running the command, the .scaffdog/hello.md
file should have been generated.
Let's scaffold using the hello
document!
$ npx scaffdog generate hello
? Please select the output destination directory. .
? Please enter any text. pretty-dog
πΆ Generated 1 file!
β pretty-dog.md
Congratulations π
The first file was generated.
$ cat pretty-dog.md
Let's make a document! See more detail scaffdog repository.
https://github.com/cats-oss/scaffdog/#templates
Please refer to this document and customize the document file π
Migration
There are important changes in the major update.
See Migration Guide.
Configuration
scaffdog uses the object exported in .scaffdog/config.js
as the configuration.
Simple Configuration
In the files
field, specify the path pattern of the document used by scaffdog. The files
field is required.
module.exports = {
files: ['./*'],
};
Global Variables
You can define the global variables available in the template in the variables
field.
module.exports = {
files: ['./*'],
variables: {
key: 'value',
},
};
Custom Helpers
You can define the custom helpers available in the template in the helpers
field.
module.exports = {
files: ['./*'],
helpers: [
// Using Key-Value
{
trim: (context, value) => value.trim(),
},
// Using Helper Registry
(registry) => {
registry.set('padstart', (context, value, size, str) =>
value.padStart(size, str || ' '),
);
registry.set('padend', (context, value, size, str) =>
value.padEnd(size, str || ' '),
);
},
],
};
The context
passed to the first argument of the helper function has the following structure.
type Variable =
| string
| {
[key in string | number]: Variable;
}
| Variable[];
type VariableMap = Map<string, Variable>;
type Helper = (context: Context, ...args: any[]) => string;
type HelperMap = Map<string, Helper>;
type Context = {
cwd: string;
variables: VariableMap;
helpers: HelperMap;
};
Commands
scaffdog init
Prepare to use scaffdog. Create a .scaffdog
directory by default, and create a first document file.
Options:
-p, --project Directory to load the scaffdog project. [string] [default: ".scaffdog"]
-v, --verbose Enable logging. [boolean]
--help Show help [boolean]
--version Output the version number [boolean]
scaffdog generate
Build a scaffold using the specified template. If you do not specify the template name and execute it, interactively select the template.
Positionals:
name [string]
Options:
-p, --project Directory to load the scaffdog project. [string] [default: ".scaffdog"]
-v, --verbose Enable logging. [boolean]
--help Show help [boolean]
--version Output the version number [boolean]
-n, --dry-run Output the result to stdout. [boolean]
scaffdog create
Create a document file with the specified name.
Positionals:
name Specify a document file name. [string]
Options:
-p, --project Directory to load the scaffdog project. [string] [default: ".scaffdog"]
-v, --verbose Enable logging. [boolean]
--help Show help [boolean]
--version Output the version number [boolean]
-y, --yes Use default options. [boolean]
scaffdog list
Print a list of available documents.
Options:
-p, --project Directory to load the scaffdog project. [string] [default: ".scaffdog"]
-v, --verbose Enable logging. [boolean]
--help Show help [boolean]
--version Output the version number [boolean]
Templates
Structure
Template documents are defined with <h1>
and code blocks. <h1>
is interpreted as the file name and code blocks as the template body.
Meta information is defined using Front Matter.
---
name: 'utility'
root: 'src/utils'
output: '**/*'
ignore: []
questions:
name: 'Please enter a filename.'
---
# `{{ inputs.name }}.js`
```javascript
export const {{ inputs.name | camel }} = () => true;
```
# `__tests__/{{ inputs.name }}.test.js`
```javascript
import { {{ inputs.name | camel }} } from '../{{ inputs.name }}';
describe('{{ inputs.name | camel }}', () => {
test('__TODO__', () => {
expect({{ inputs.name | camel }}()).toBe(true);
});
});
```
Syntax
Between {{
and }}
is interpreted as a tag. Whitespace in tag contents is ignored.
Output of variable
The given variable name is output. See the Variables section for the variables that can be used.
{{ <identifier> }}
Example:
{{ inputs.value }}
Whitespaces
Trim the expression to be expanded and the space and line feed around it.
Use {{-
to trim before the tag, and -}}
to trim after the tag.
{{- <expression> -}}
Example:
before {{- "text" }} after
before {{ "text" -}} after
before {{- "text" -}} after
Output:
beforetext after
before textafter
beforetextafter
Comment out
You can use comment out to keep the template readable. Of course, it is not deployed as a template.
{{ /* a comment */ }}
Call helper function
Execute the helper function with the specified name. Arguments are separated by whitespace. See the Helpers section for the helpers that can be used.
{{ <helper> <argument> ... }}
Example:
{{ relative "../" }}
Pipe chain
You can chain output values or helper results with pipes. This is a helper similar to shell.
{{ <identifier> | <helper> }}
{{ <identifier> | <helper> <argument> ... }}
Example:
{{ inputs.value | upper }}
{{ inputs.value | replace "$.ts" ".js" | pascal }}
{{ basename | replace extname ".js" | pascal }}
Attributes
List of attributes that can be specified with Front Matter.
key | required | type | description |
---|---|---|---|
name |
true |
string |
Name of template. |
root |
true |
string |
The directory as the starting point of the output destination. |
output |
true |
string |
Directory starting from root and being a destination candidate. You can use glob syntax. (see globby document) |
ignore |
false |
string[] |
Directory to exclude from candidate output destination. You can use glob syntax. (see globby document) |
questions |
false |
object |
Message to display when accepting input. |
questions
defines the question to be used in prompt with key-value. The values you answer can be used in a variable called inputs
. (e.g. inputs.key1
, inputs.value
)
---
questions:
# Shortest syntax, using `input` prompt.
key1: 'Message'
# Using `input` prompt.
key2:
message: 'Message'
# Using `input` prompt, with default value.
key3:
message: 'Message'
initial: 'Initial Value'
# Using `list` prompt.
key4:
message: 'Message'
choices: ['A', 'B', 'C']
---
Variables
List of variables available in the template. You need to be aware that the file name and the variables available in the template body are different.
File name
key | description | example |
---|---|---|
inputs |
The object value received at the prompt. |
Template body
key | description | example |
---|---|---|
inputs |
The object value received at the prompt. | |
output.name |
The name of the output destination file excluding the extension. | scaffdog |
output.base |
The name of the output destination file including the extension. | scaffdog.js |
output.ext |
The destination file name extension. | .js |
output.dir |
The destination directory name. | src |
output.path |
The path of the destination file. | src/scaffdog.js |
output.abs |
The absolute path of the destination file. | /path/to/src/scaffdog.js |
document.name |
The document name. | hello |
document.path |
The path of the document file. | /path/to/.scaffdog/hello.md |
Helpers
When invoked on a pipe, the previous processing result is passed to the first argument.
name | arguments | description |
---|---|---|
camel |
[value: string] |
Conversion to a camel case. |
snake |
[value: string] |
Conversion to a snake case. |
pascal |
[value: string] |
Conversion to a pascal case. |
kebab |
[value: string] |
Conversion to a kebab case. |
constant |
[value: string] |
Conversion to a constant case. |
upper |
[value: string] |
Conversion to a upper case. |
lower |
[value: string] |
Conversion to a lower case. |
replace |
[value: string, pattern: string, replacement: string] |
Replace pattern withreplacement . pattern is specified as a string, but it is treated as a regular expression. |
trim |
[value: string] |
Alias for String.prototype.trim . |
ltrim |
[value: string] |
Alias for String.prototype.trimStart . |
rtrim |
[value: string] |
Alias for String.prototype.trimEnd . |
eval |
[code: string] |
Executes the specified code and returns the result. |
date |
[format?: string] |
See the dayjs documentation for format details. |
noop |
[] |
Returns an empty string. |
define |
[value: string, key: string] |
Defines a local variable in the template scope. |
relative |
[path: string] |
Convert the path from the template file to the path from the destination file. |
read |
[path: string] |
Read the specified file. The contents of the loaded file are also expanded as a template. |
FAQ
Is it possible to define variables in the template?
scaffdog does not support variable definitions syntactically.
However, it is possible to define variables in combination with helper functions π
See the following example.
{{- output.path | replace "^src/" "" | define "out" -}}
{{ output.path }}
{{ out }}
{{ out | replace "/" "-" }}
The output is as follows:
src/utils/input.js
utils/input.js
utils-input.js
Defined a variable called out
which is a processed version of output.path
. This is made up of some magic.
- Save the calculation result to
out
withdefine
helper function. - The variable definition tag trims whitespaces. (use
{{-
and-}}
)
Contributing
We are always welcoming your contribution π
- Fork (https://github.com/cats-oss/scaffdog) π
- Create a feature branch βοΈ
- Run test suite with the
$ yarn test
command and confirm that it passes β‘οΈ - Commit your changes π
- Rebase your local changes against the
canary
branch π‘ - Create new Pull Request π
Bugs, feature requests and comments are more than welcome in the issues.
Development scripts
yarn test
Run Unit test with ava.
$ yarn test
yarn lint
Run lint with ESLint.
$ yarn lint
yarn format
Run formatting with ESLint (--fix
) and Prettier.
$ yarn format