Pattern manager
Tool for managing code patterns
Description
pattern-manager
provides a way to manage a folder of code patterns and their generators, which can be application-specific or shared among projects.
It searches for a folder named .patterns
in the current working directory or one of its ancestors. The .patterns
folder can contain a number of pattern folders.
A pattern folder should contain a pattern.js
, which exports a function to create the pattern, and any related template files. Each pattern is responsible to creating a copy of itself, for example: get options from the command-line or user inputs; copy files and folders; and compile templates.
To simplify the scaffolding process, the pattern generator function is provided with a set of utilities: inquirer
, handlebars
, shell
, and chalk
.
This tool is inspired by plop
.
Install
Global
npm install pattern-manager -g
Local (for use in NPM scripts)
npm install pattern-manager -D
Run
pat
It searches for a .patterns
folder, displays a list of patterns, and runs the selected pattern.
pat [pattern name] [...pattern options]
If a pattern name is specified, it runs that pattern.
Pattern
In the .patterns
folder, there can be one or more pattern folders. These can be nested.
- Each pattern is named after its folder
- This includes the relative path, for example:
react/state
- This includes the relative path, for example:
- Each pattern folder contains
pattern.js
and any template files- Any folder that doesn't have
pattern.js
will be ignored
- Any folder that doesn't have
The job of pattern.js
is to create a copy of the pattern to its destination. It should export a function that receives a config object.
{ const src dest = config // Create new pattern here } patterndescription = 'Desciption of pattern' moduleexports = pattern
If the function has a description
property, it will be displayed when selecting patterns.
Config object
The pattern generator function is provided with a set of properties and utility methods.
src
- Source path: the path of the pattern folderdest
- Destination path: current working folderargv
- Command line arguments viaminimist
inquirer
- Get different types of user inputhandlebars
- Compile templatesshell
- Collection of shell commandschalk
- Colorful logging
Shortcuts
prompt
- Shortcut forinquirer.prompt
compile
- Shortcut forhandlebars.compile
compileFile
- Compile a template file and write to another file- Arguments: input file path, data object, output file path
error
- Display an error message and exitconfirm
- Ask for confirmation then return true/false- Arguments: a message and optional default value (default: true)
command
- Shortcut forchild_process.spawnSync
with streaming output (stdio: inherit)- Arguments: command to run, array of arguments, spawnSync options
fileExists
- Shortcut forfs.existsSync
readFile
- Shortcut forfs.readFileSync
withutf8
encodingwriteFile
- Shortcut forfs.writeFileSync
writeJsonFile
- Write object to human-readable JSON file- Arguments: file path, data object
Series of promises
If the pattern generator function returns an array of functions, they will be run as a series of promises.
Basic example
The following is a basic example of pattern.js
.
- Get user input
- Compile a template and copy it to current folder
const path = { const src dest prompt compileFile = config return { const srcFile = path const destFile = path console } } patterndescription = 'Basic pattern' moduleexports = pattern
The example.js
template:
console
Advanced example
The following is an advanced example of pattern.js
.
- Take user input for the app name and description
- If the destination exists, display error and quit
- Copy all files in the pattern folder to its destination, using
rsync
- Ignore
pattern.js
itself, and everything in.gitignore
- Ignore
- Replace name and description in
package.json
- Finally, it confirms to run
git init
andnpm install
If --dry
is passed in the command line, it will do a dry run without copying anything.
const path = { const src dest argv prompt error chalk writeJsonFile fileExists quit } = config let name destPath return { name = dataname destPath = path const description = data if return // ------------ Copy pattern ------------ if argvdry // ------------ Search & replace ------------ const packagePath = path let packageData = packageDataname = name packageDatadescription = description } // ------------ Git init ------------ // ------------ npm install ------------ console } patterndescription = 'Advanced pattern' moduleexports = pattern