{"id":16040701,"url":"https://github.com/eliot-akira/pattern-manager","last_synced_at":"2025-03-17T21:31:03.237Z","repository":{"id":57320852,"uuid":"74806728","full_name":"eliot-akira/pattern-manager","owner":"eliot-akira","description":"Tool for managing code patterns","archived":false,"fork":false,"pushed_at":"2016-11-28T05:07:08.000Z","size":38,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-09T23:21:00.762Z","etag":null,"topics":["pattern","scaffold"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eliot-akira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-26T05:29:07.000Z","updated_at":"2017-03-24T00:42:02.000Z","dependencies_parsed_at":"2022-08-26T01:11:06.442Z","dependency_job_id":null,"html_url":"https://github.com/eliot-akira/pattern-manager","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliot-akira%2Fpattern-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliot-akira%2Fpattern-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliot-akira%2Fpattern-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eliot-akira%2Fpattern-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eliot-akira","download_url":"https://codeload.github.com/eliot-akira/pattern-manager/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221700738,"owners_count":16866113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pattern","scaffold"],"created_at":"2024-10-08T23:20:58.643Z","updated_at":"2024-10-27T15:48:41.635Z","avatar_url":"https://github.com/eliot-akira.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Pattern manager\n\nTool for managing code patterns\n\n## Description\n\n`pattern-manager` provides a way to manage a folder of code patterns and their generators, which can be application-specific or shared among projects.\n\nIt 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.\n\nA 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.\n\nTo simplify the scaffolding process, the pattern generator function is provided with a set of utilities: [`inquirer`](https://github.com/SBoudrias/Inquirer.js),  [`handlebars`](https://github.com/wycats/handlebars.js), [`shell`](https://github.com/shelljs/shelljs), and [`chalk`](https://github.com/chalk/chalk).\n\nThis tool is inspired by [`plop`](https://github.com/amwmedia/plop).\n\n## Install\n\nGlobal\n\n```bash\nnpm install pattern-manager -g\n```\n\nLocal (for use in NPM scripts)\n\n```bash\nnpm install pattern-manager -D\n```\n\n## Run\n\n```bash\npat\n```\n\nIt searches for a `.patterns` folder, displays a list of patterns, and runs the selected pattern.\n\n```bash\npat [pattern name] [...pattern options]\n```\n\nIf a pattern name is specified, it runs that pattern.\n\n## Pattern\n\nIn the `.patterns` folder, there can be one or more pattern folders. These can be nested.\n\n- Each pattern is named after its folder\n  - This includes the relative path, for example: `react/state`\n- Each pattern folder contains `pattern.js` and any template files\n  - Any folder that doesn't have `pattern.js` will be ignored\n\nThe 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.\n\n```js\nfunction pattern(config) {\n\n  const { src, dest } = config\n\n  // Create new pattern here\n\n}\n\npattern.description = 'Desciption of pattern'\n\nmodule.exports = pattern\n```\n\nIf the function has a `description` property, it will be displayed when selecting patterns.\n\n\n#### Config object\n\nThe pattern generator function is provided with a set of properties and utility methods.\n\n- `src` - Source path: the path of the pattern folder\n- `dest` - Destination path: current working folder\n- `argv` - Command line arguments via [`minimist`](https://github.com/substack/minimist)\n- [`inquirer`](https://github.com/SBoudrias/Inquirer.js) - Get different types of user input\n- [`handlebars`](https://github.com/wycats/handlebars.js) - Compile templates\n- [`shell`](https://github.com/shelljs/shelljs) - Collection of shell commands\n- [`chalk`](https://github.com/chalk/chalk) - Colorful logging\n\nShortcuts\n\n- `prompt` - Shortcut for `inquirer.prompt`\n- `compile` - Shortcut for `handlebars.compile`\n- `compileFile` - Compile a template file and write to another file\n  - Arguments: input file path, data object, output file path\n- `error` - Display an error message and exit\n- `confirm` - Ask for confirmation then return true/false\n  - Arguments: a message and optional default value (default: true)\n- `command` - Shortcut for [`child_process.spawnSync`](https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options) with streaming output (stdio: inherit)\n  - Arguments: command to run, array of arguments, spawnSync options\n- `fileExists` - Shortcut for `fs.existsSync`\n- `readFile` - Shortcut for `fs.readFileSync` with `utf8` encoding\n- `writeFile` - Shortcut for `fs.writeFileSync`\n- `writeJsonFile` - Write object to human-readable JSON file\n  - Arguments: file path, data object\n\n#### Series of promises\n\nIf the pattern generator function returns an array of functions, they will be run as a series of promises.\n\n## Basic example\n\nThe following is a basic example of `pattern.js`.\n\n- Get user input\n- Compile a template and copy it to current folder\n\n```js\nconst path = require('path')\n\nfunction pattern(config) {\n\n  const { src, dest, prompt, compileFile } = config\n\n  return [\n    () =\u003e prompt([\n      {\n        name: 'message', default: 'Hello, world',\n        message: 'Message to display'\n      }\n    ]),\n\n    data =\u003e {\n\n      const srcFile = path.join(src, 'example.js')\n      const destFile = path.join(dest, 'example.js')\n\n      compileFile(srcFile, data, destFile)\n\n      console.log(`Wrote to ${destFile}`)\n    }\n  ]\n}\n\npattern.description = 'Basic pattern'\n\nmodule.exports = pattern\n```\n\nThe `example.js` template:\n\n```js\nconsole.log('{{message}}')\n```\n\n## Advanced example\n\nThe following is an advanced example of `pattern.js`.\n\n- Take user input for the app name and description\n- If the destination exists, display error and quit\n- Copy all files in the pattern folder to its destination, using `rsync`\n  - Ignore `pattern.js` itself, and everything in `.gitignore`\n- Replace name and description in `package.json`\n- Finally, it confirms to run `git init` and `npm install`\n\nIf `--dry` is passed in the command line, it will do a dry run without copying anything.\n\n```js\nconst path = require('path')\n\nfunction pattern(config) {\n\n  const {\n    src, dest, argv, prompt, error, chalk,\n    writeJsonFile, fileExists, quit\n  } = config\n\n  let name, destPath\n\n  return [\n    () =\u003e prompt([\n      {\n        name: 'name', default: 'app',\n        message: 'Name of app',\n        validate: function (value) {\n          if (value) return true\n          return 'App name is required'\n        }\n      },\n      { name: 'description', default: '', message: 'Description' }\n    ]),\n\n    data =\u003e {\n\n      name = data.name\n      destPath = path.join(dest, name)\n      const { description } = data\n\n      if (fileExists(destPath)) {\n        return error(`Destination \"${name}\" already exists`)\n      }\n\n      // ------------ Copy pattern ------------\n\n      command('rsync', [\n        '-vrlptz'+(argv.dry ? 'n' : ''), // -n for dry run\n        '--delete',\n        '--exclude', '.git',\n        '--exclude', '/pattern.js', // Exclude this file\n        '--filter', ':- .gitignore',\n        '.', // Source\n        destPath\n      ], { cwd: __dirname })\n\n      if (argv.dry) quit()\n\n      // ------------ Search \u0026 replace ------------\n\n      const packagePath = path.join(destPath, 'package.json')\n      let packageData = require(packagePath)\n\n      packageData.name = name\n      packageData.description = description\n\n      writeJsonFile(packagePath, packageData)\n    },\n\n    // ------------ Git init ------------\n\n    () =\u003e confirm('Init .git repo?').then(confirmed =\u003e {\n      if (!confirmed) return\n      command('git', ['init'], { cwd: destPath })\n    }),\n\n    // ------------ npm install ------------\n\n    () =\u003e confirm('Install NPM packages?').then(confirmed =\u003e {\n      if (!confirmed) return\n      command('npm', ['install'], { cwd: destPath })\n    }),\n\n    () =\u003e console.log(chalk.green(`Created \"${name}\"`))\n  ]\n}\n\npattern.description = 'Advanced pattern'\n\nmodule.exports = pattern\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feliot-akira%2Fpattern-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feliot-akira%2Fpattern-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feliot-akira%2Fpattern-manager/lists"}