0.1.3 • Published 7 years ago

pattern-manager v0.1.3

Weekly downloads
2
License
MIT
Repository
github
Last release
7 years ago

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
  • Each pattern folder contains pattern.js and any template files
    • Any folder that doesn't have pattern.js will be ignored

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.

function pattern(config) {

  const { src, dest } = config

  // Create new pattern here

}

pattern.description = 'Desciption of pattern'

module.exports = 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 folder
  • dest - Destination path: current working folder
  • argv - Command line arguments via minimist
  • inquirer - Get different types of user input
  • handlebars - Compile templates
  • shell - Collection of shell commands
  • chalk - Colorful logging

Shortcuts

  • prompt - Shortcut for inquirer.prompt
  • compile - Shortcut for handlebars.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 exit
  • confirm - Ask for confirmation then return true/false
    • Arguments: a message and optional default value (default: true)
  • command - Shortcut for child_process.spawnSync with streaming output (stdio: inherit)
    • Arguments: command to run, array of arguments, spawnSync options
  • fileExists - Shortcut for fs.existsSync
  • readFile - Shortcut for fs.readFileSync with utf8 encoding
  • writeFile - Shortcut for fs.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 = require('path')

function pattern(config) {

  const { src, dest, prompt, compileFile } = config

  return [
    () => prompt([
      {
        name: 'message', default: 'Hello, world',
        message: 'Message to display'
      }
    ]),

    data => {

      const srcFile = path.join(src, 'example.js')
      const destFile = path.join(dest, 'example.js')

      compileFile(srcFile, data, destFile)

      console.log(`Wrote to ${destFile}`)
    }
  ]
}

pattern.description = 'Basic pattern'

module.exports = pattern

The example.js template:

console.log('{{message}}')

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
  • Replace name and description in package.json
  • Finally, it confirms to run git init and npm install

If --dry is passed in the command line, it will do a dry run without copying anything.

const path = require('path')

function pattern(config) {

  const {
    src, dest, argv, prompt, error, chalk,
    writeJsonFile, fileExists, quit
  } = config

  let name, destPath

  return [
    () => prompt([
      {
        name: 'name', default: 'app',
        message: 'Name of app',
        validate: function (value) {
          if (value) return true
          return 'App name is required'
        }
      },
      { name: 'description', default: '', message: 'Description' }
    ]),

    data => {

      name = data.name
      destPath = path.join(dest, name)
      const { description } = data

      if (fileExists(destPath)) {
        return error(`Destination "${name}" already exists`)
      }

      // ------------ Copy pattern ------------

      command('rsync', [
        '-vrlptz'+(argv.dry ? 'n' : ''), // -n for dry run
        '--delete',
        '--exclude', '.git',
        '--exclude', '/pattern.js', // Exclude this file
        '--filter', ':- .gitignore',
        '.', // Source
        destPath
      ], { cwd: __dirname })

      if (argv.dry) quit()

      // ------------ Search & replace ------------

      const packagePath = path.join(destPath, 'package.json')
      let packageData = require(packagePath)

      packageData.name = name
      packageData.description = description

      writeJsonFile(packagePath, packageData)
    },

    // ------------ Git init ------------

    () => confirm('Init .git repo?').then(confirmed => {
      if (!confirmed) return
      command('git', ['init'], { cwd: destPath })
    }),

    // ------------ npm install ------------

    () => confirm('Install NPM packages?').then(confirmed => {
      if (!confirmed) return
      command('npm', ['install'], { cwd: destPath })
    }),

    () => console.log(chalk.green(`Created "${name}"`))
  ]
}

pattern.description = 'Advanced pattern'

module.exports = pattern
0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago

0.0.9

7 years ago

0.0.8

7 years ago

0.0.7

7 years ago

0.0.6

7 years ago

0.0.4

7 years ago

0.0.3

7 years ago

0.0.2

7 years ago

0.0.1

7 years ago