├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .github └── contributing.md ├── .gitignore ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── docs ├── demo-dest.gif ├── demo-gulp-plugin.gif ├── demo-install.gif ├── demo-minimal.gif ├── demo.gif ├── tasks.md ├── trees.md └── what-will-happen.md ├── generator.js ├── index.js ├── package.json ├── templates ├── base │ └── plugin.js ├── generator │ └── generator.js ├── gulp │ ├── gulpfile.js │ └── plugin.js ├── helper │ └── index.js ├── index.js ├── middleware │ └── index.js ├── regex │ └── index.js └── update │ └── _updaterc.json ├── test ├── plugins.js └── test.js ├── trees.md └── verbfile.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [{**/{actual,fixtures,expected,templates}/**,*.md}] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = false 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "es6": true, 5 | "node": true, 6 | "mocha": true 7 | }, 8 | 9 | "globals": { 10 | "document": false, 11 | "navigator": false, 12 | "window": false 13 | }, 14 | 15 | "rules": { 16 | "accessor-pairs": 2, 17 | "arrow-spacing": [2, { "before": true, "after": true }], 18 | "block-spacing": [2, "always"], 19 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 20 | "comma-dangle": [2, "never"], 21 | "comma-spacing": [2, { "before": false, "after": true }], 22 | "comma-style": [2, "last"], 23 | "constructor-super": 2, 24 | "curly": [2, "multi-line"], 25 | "dot-location": [2, "property"], 26 | "eol-last": 2, 27 | "eqeqeq": [2, "allow-null"], 28 | "generator-star-spacing": [2, { "before": true, "after": true }], 29 | "handle-callback-err": [2, "^(err|error)$" ], 30 | "indent": [2, 2, { "SwitchCase": 1 }], 31 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 32 | "keyword-spacing": [2, { "before": true, "after": true }], 33 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 34 | "new-parens": 2, 35 | "no-array-constructor": 2, 36 | "no-caller": 2, 37 | "no-class-assign": 2, 38 | "no-cond-assign": 2, 39 | "no-const-assign": 2, 40 | "no-control-regex": 2, 41 | "no-debugger": 2, 42 | "no-delete-var": 2, 43 | "no-dupe-args": 2, 44 | "no-dupe-class-members": 2, 45 | "no-dupe-keys": 2, 46 | "no-duplicate-case": 2, 47 | "no-empty-character-class": 2, 48 | "no-eval": 2, 49 | "no-ex-assign": 2, 50 | "no-extend-native": 2, 51 | "no-extra-bind": 2, 52 | "no-extra-boolean-cast": 2, 53 | "no-extra-parens": [2, "functions"], 54 | "no-fallthrough": 2, 55 | "no-floating-decimal": 2, 56 | "no-func-assign": 2, 57 | "no-implied-eval": 2, 58 | "no-inner-declarations": [2, "functions"], 59 | "no-invalid-regexp": 2, 60 | "no-irregular-whitespace": 2, 61 | "no-iterator": 2, 62 | "no-label-var": 2, 63 | "no-labels": 2, 64 | "no-lone-blocks": 2, 65 | "no-mixed-spaces-and-tabs": 2, 66 | "no-multi-spaces": 2, 67 | "no-multi-str": 2, 68 | "no-multiple-empty-lines": [2, { "max": 1 }], 69 | "no-native-reassign": 0, 70 | "no-negated-in-lhs": 2, 71 | "no-new": 2, 72 | "no-new-func": 2, 73 | "no-new-object": 2, 74 | "no-new-require": 2, 75 | "no-new-wrappers": 2, 76 | "no-obj-calls": 2, 77 | "no-octal": 2, 78 | "no-octal-escape": 2, 79 | "no-proto": 0, 80 | "no-redeclare": 2, 81 | "no-regex-spaces": 2, 82 | "no-return-assign": 2, 83 | "no-self-compare": 2, 84 | "no-sequences": 2, 85 | "no-shadow-restricted-names": 2, 86 | "no-spaced-func": 2, 87 | "no-sparse-arrays": 2, 88 | "no-this-before-super": 2, 89 | "no-throw-literal": 2, 90 | "no-trailing-spaces": 0, 91 | "no-undef": 2, 92 | "no-undef-init": 2, 93 | "no-unexpected-multiline": 2, 94 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 95 | "no-unreachable": 2, 96 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 97 | "no-useless-call": 0, 98 | "no-with": 2, 99 | "one-var": [0, { "initialized": "never" }], 100 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 101 | "padded-blocks": [0, "never"], 102 | "quotes": [2, "single", "avoid-escape"], 103 | "radix": 2, 104 | "semi": [2, "always"], 105 | "semi-spacing": [2, { "before": false, "after": true }], 106 | "space-before-blocks": [2, "always"], 107 | "space-before-function-paren": [2, "never"], 108 | "space-in-parens": [2, "never"], 109 | "space-infix-ops": 2, 110 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 111 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 112 | "use-isnan": 2, 113 | "valid-typeof": 2, 114 | "wrap-iife": [2, "any"], 115 | "yoda": [2, "never"] 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary 11 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | 2 | If this project doesn't do what you need, [please let us know]({%= bugs.url %})! 3 | 4 | ## Building docs 5 | {%= include("build-docs") %} 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # always ignore files 2 | *.DS_Store 3 | .idea 4 | *.sublime-* 5 | 6 | # test related, or directories generated by tests 7 | test/actual 8 | actual 9 | coverage 10 | .nyc* 11 | 12 | # npm 13 | node_modules 14 | npm-debug.log 15 | 16 | # yarn 17 | yarn.lock 18 | yarn-error.log 19 | 20 | # misc 21 | _gh_pages 22 | _draft 23 | _drafts 24 | bower_components 25 | vendor 26 | temp 27 | tmp 28 | TODO.md 29 | package-lock.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | os: 3 | - linux 4 | - osx 5 | language: node_js 6 | node_js: 7 | - node 8 | - '8' 9 | - '7' 10 | - '6' 11 | - '5' 12 | - '4' 13 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/.verb.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2017, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 |

7 | 8 | Scaffold out complete code projects from the command line, or use this generator as a plugin in other generators to provide baseline functionality. 9 | 10 | # generate-project 11 | 12 | [![NPM version](https://img.shields.io/npm/v/generate-project.svg?style=flat)](https://www.npmjs.com/package/generate-project) [![NPM monthly downloads](https://img.shields.io/npm/dm/generate-project.svg?style=flat)](https://npmjs.org/package/generate-project) [![Build Status](https://img.shields.io/travis/generate/generate-project.svg?style=flat)](https://travis-ci.org/generate/generate-project) 13 | 14 | ![generate-project demo](https://raw.githubusercontent.com/generate/generate-project/master/docs/demo.gif) 15 | 16 |
17 | Table of Contents 18 | 19 | - [Getting started](#getting-started) 20 | * [Install](#install) 21 | * [CLI](#cli) 22 | * [Help](#help) 23 | - [Next steps](#next-steps) 24 | * [Running unit tests](#running-unit-tests) 25 | * [Publishing your generator](#publishing-your-generator) 26 | - [About](#about) 27 | * [What is "Generate"?](#what-is-generate) 28 | * [Related projects](#related-projects) 29 | * [Community](#community) 30 | * [Contributing](#contributing) 31 | * [Running tests](#running-tests) 32 | * [Author](#author) 33 | * [License](#license) 34 | 35 | _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ 36 | 37 |
38 | 39 | ## Getting started 40 | 41 | ### Install 42 | 43 | **Installing the CLI** 44 | 45 | To run the `default` generator from the command line, you'll need to install [Generate](https://github.com/generate/generate) globally first. You can do that now with the following command: 46 | 47 | ```sh 48 | $ npm install --global generate 49 | ``` 50 | 51 | This adds the `gen` command to your system path, allowing it to be run from any directory. 52 | 53 | **Install generate-project** 54 | 55 | Install this module with the following command: 56 | 57 | ```sh 58 | $ npm install --global generate-project 59 | ``` 60 | 61 | ### CLI 62 | 63 | Run this generator's `default` [task](https://github.com/generate/generate/blob/master/docs/tasks.md#default) with the following command: 64 | 65 | ```sh 66 | $ gen project 67 | # or 68 | $ gen project:default 69 | ``` 70 | 71 | **What will happen?** 72 | 73 | Running `$ gen project` will run this generator's [default task](#default), which will: 74 | 75 | 1. prompt you for any information that's missing 76 | 2. render templates using your answers 77 | 3. generate [the resulting files](#generated-files) to the current working directory. 78 | 79 | **Conflict detection** 80 | 81 | In the case that a file already exists on the file system, you will be [prompted for feedback](https://github.com/node-base/base-fs-conflicts) _before overwrite any files_. 82 | 83 | You can [set the destination](https://github.com/generate/generate/blob/master/docs/customization.md) to a new directory if you want to avoid the prompts, or avoid accidentally overwriting files with unintentional answers. 84 | 85 | **What you should see in the terminal** 86 | 87 | If completed successfully, you should see both `starting` and `finished` events in the terminal, like the following: 88 | 89 | ```sh 90 | [00:44:21] starting ... 91 | ... 92 | [00:44:22] finished ✔ 93 | ``` 94 | 95 | If you do not see one or both of those events, please [let us know about it](../../issues). 96 | 97 | ### Help 98 | 99 | To see a general help menu and available commands for Generate's CLI, run: 100 | 101 | ```sh 102 | $ gen help 103 | ``` 104 | 105 | ### Related projects 106 | 107 | * [generate-dest](https://www.npmjs.com/package/generate-dest): Prompts the user for the destination directory to use. Can be used from the command… [more](https://github.com/generate/generate-dest) | [homepage](https://github.com/generate/generate-dest "Prompts the user for the destination directory to use. Can be used from the command line when installed globally, or as plugin or sub-generator in your generator.") 108 | * [generate-install](https://www.npmjs.com/package/generate-install): Generator that automatically detects the dependencies or devDependencies to install based on the templates or… [more](https://github.com/generate/generate-install) | [homepage](https://github.com/generate/generate-install "Generator that automatically detects the dependencies or devDependencies to install based on the templates or includes that are dynamically used by your generator. This can be used as a sub-generator or plugin in your own generator.") 109 | * [generate-package](https://www.npmjs.com/package/generate-package): Generate a package.json from a pre-defined or user-defined template. This generator can be used from… [more](https://github.com/generate/generate-package) | [homepage](https://github.com/generate/generate-package "Generate a package.json from a pre-defined or user-defined template. This generator can be used from the command line when globally installed, or as a plugin or sub-generator in your own generator.") 110 | 111 | ### Community 112 | 113 | Are you using [Generate](https://github.com/generate/generate) in your project? Have you published a [generator](https://github.com/generate/generate/blob/master/docs/generators.md) and want to share your project with the world? 114 | 115 | Here are some suggestions! 116 | 117 | * If you get like Generate and want to tweet about it, please feel free to mention `@generatejs` or use the `#generatejs` hashtag 118 | * Show your love by starring [Generate](https://github.com/generate/generate) and `generate-project` 119 | * Get implementation help on [StackOverflow](http://stackoverflow.com/questions/tagged/generate) (please use the `generatejs` tag in questions) 120 | * **Gitter** Discuss Generate with us on [Gitter](https://gitter.im/generate/generate) 121 | * If you publish an generator, thank you! To make your project as discoverable as possible, please add the keyword `generategenerator` to package.json. 122 | 123 | ### Contributing 124 | 125 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). 126 | 127 | Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards. 128 | 129 | ### Running tests 130 | 131 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: 132 | 133 | ```sh 134 | $ npm install && npm test 135 | ``` 136 | 137 | ### Author 138 | 139 | **Jon Schlinkert** 140 | 141 | * [github/jonschlinkert](https://github.com/jonschlinkert) 142 | * [twitter/jonschlinkert](https://twitter.com/jonschlinkert) 143 | 144 | ### License 145 | 146 | Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). 147 | Released under the [MIT License](LICENSE). 148 | 149 | *** 150 | 151 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on July 29, 2017._ -------------------------------------------------------------------------------- /docs/demo-dest.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/docs/demo-dest.gif -------------------------------------------------------------------------------- /docs/demo-gulp-plugin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/docs/demo-gulp-plugin.gif -------------------------------------------------------------------------------- /docs/demo-install.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/docs/demo-install.gif -------------------------------------------------------------------------------- /docs/demo-minimal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/docs/demo-minimal.gif -------------------------------------------------------------------------------- /docs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/generate/generate-project/7c44296bc11abd3c6aaf49ee97450a40c31756ba/docs/demo.gif -------------------------------------------------------------------------------- /docs/tasks.md: -------------------------------------------------------------------------------- 1 | ## Options 2 | 3 | ### noskip 4 | 5 | Generate looks for data in package.json and/or user environment to be used in templates. By default, this data is normally only used for hints, but this generator uses the data to render templates, and skips any related prompts. 6 | 7 | You can disable this feature with the following command: 8 | 9 | ```sh 10 | $ gen project --noskip 11 | ``` 12 | 13 | ## Tasks 14 | 15 | ### Running tasks 16 | 17 | In this generator, tasks are used for generating specific files. Some tasks generate a single file, some generate multiple files, and some tasks are just aliases for running "groups" of tasks. At least for this generator, the goal is to make it as easy as possible for you to create your own a-la-carte generator experience. 18 | 19 | **Running tasks** 20 | 21 | To run a task, just run `$ gen project:*`, where `*` is the name of the task to run. For example, the following command will run the `minimal` task: 22 | 23 | ```sh 24 | $ gen project:minimal 25 | ``` 26 | 27 | ### Available tasks 28 | {%= increaseHeadings(apidocs("generator.js")) %} 29 | 30 | ## Files trees 31 | {%= doc('trees.md') %} 32 | 33 | [docs]: {%= platform.docs %}/ 34 | -------------------------------------------------------------------------------- /docs/trees.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | The following files trees are automatically generated by a task in [verbfile.js](verbfile.js). 6 | 7 | - [generated files](#generated-files): trees representing the actual generated "dest" files for each task 8 | - [source files](#source-files): trees representing the source files and templates used by each task 9 | 10 | _(See Generate's [customization docs ][docs]{customization.md} to learn how to override individual templates.)_ 11 | 12 | ### Generated files 13 | 14 | Files generated by each task (e.g. `dest` files). See the Generate [customization docs ][docs]{customization.md} to learn how to override individual templates. 15 | 16 | Note that diffs are base on comparisons against the files generated by the `default` task. Additionally, some tasks generate the same files, but with different contents (for example, the contents of `index.js` differs based on the task). 17 | 18 | {%= increaseHeadings(include("trees-dest")) %} 19 | 20 | ### Source files 21 | 22 | The following trees represent the source files or templates that are used by each task. You'll see that most of the tasks use at least one "micro-generator" to generate a specific file. 23 | 24 | {%= increaseHeadings(include("trees-src")) %} 25 | 26 | 27 | [docs]: {%= platform.docs %}/ 28 | -------------------------------------------------------------------------------- /docs/what-will-happen.md: -------------------------------------------------------------------------------- 1 | **What will happen?** 2 | 3 | Running `$ gen {%= alias %}` will run the generator's [default task](#default), which will: 4 | 5 | 1. prompt you for any information that's missing 6 | 1. render templates using your answers 7 | 1. generate [the resulting files](#generated-files) to the current working directory. 8 | 9 | **Conflict detection** 10 | 11 | In the case that a file already exists on the file system, you will be [prompted for feedback](https://github.com/node-base/base-fs-conflicts) _before overwrite any files_. 12 | 13 | You can [set the destination][docs]{customization.md} to a new directory if you want to avoid the prompts, or avoid accidentally overwriting files with unintentional answers. 14 | -------------------------------------------------------------------------------- /generator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var isValid = require('is-valid-app'); 5 | var Prompt = require('prompt-checkbox'); 6 | var Store = require('data-store'); 7 | 8 | module.exports = function generator(app) { 9 | if (!isValid(app, 'generate-project')) return; 10 | var store = new Store('generate-user-config'); 11 | app.data(store.data); 12 | 13 | /** 14 | * Listen for errors 15 | */ 16 | 17 | app.on('error', console.error); 18 | 19 | /** 20 | * Plugins 21 | */ 22 | 23 | app.use(require('generate-defaults')); 24 | app.use(require('generate-install')); 25 | 26 | /** 27 | * Micro-generators (as plugins) 28 | */ 29 | 30 | app.register('contributing', require('generate-contributing')); 31 | app.register('editorconfig', require('generate-editorconfig')); 32 | app.register('eslint', require('generate-eslint')); 33 | app.register('github', require('generate-gh-repo')); 34 | app.register('git', require('generate-git')); 35 | app.register('gitattributes', require('generate-gitattributes')); 36 | app.register('gitignore', require('generate-gitignore')); 37 | app.register('license', require('generate-license')); 38 | app.register('package', require('generate-package')); 39 | app.register('readme', require('generate-readme')); 40 | app.register('travis', require('generate-travis')); 41 | 42 | /** 43 | * Generates the [necessary files](#default-1) for a basic node.js project. 44 | * 45 | * ```sh 46 | * $ gen project 47 | * ``` 48 | * @name project 49 | * @api public 50 | */ 51 | 52 | app.task('default', ['project']); 53 | app.task('project', ['is-empty', 'prompt', 'rootfiles', 'dotfiles', 'index']); 54 | 55 | /** 56 | * Select one or more sub-generators or tasks to run. 57 | * 58 | * ```sh 59 | * $ gen project:choose 60 | * ``` 61 | * @name choose 62 | * @api public 63 | */ 64 | 65 | app.task('choose', function(cb) { 66 | var prompt = new Prompt({ 67 | message: 'Select the tasks or sub-generators to run:', 68 | choices: Object.keys(app.generators) 69 | }); 70 | 71 | prompt.run() 72 | .then(function(answer) { 73 | app.generate(answer, cb); 74 | }); 75 | }); 76 | 77 | /** 78 | * Generate starter files for a project. Runs the `default` task 79 | * on all micro-generators registered on `generate-project`. 80 | * See the list of [generated files](#files-1). 81 | * 82 | * ```sh 83 | * $ gen project:files 84 | * ``` 85 | * @name project:files 86 | * @api public 87 | */ 88 | 89 | app.task('files', ['rootfiles', 'dotfiles']); 90 | 91 | /** 92 | * Generate a basic `index.js` file. This task is used for composition 93 | * with other tasks. 94 | * 95 | * ```sh 96 | * $ gen project:index 97 | * ``` 98 | * @name project:index 99 | * @api public 100 | */ 101 | 102 | task(app, 'index', 'index.js'); 103 | 104 | /** 105 | * Generate the dotfiles from registered micro-generators. See 106 | * the [generated files](#dotfiles-1). 107 | * 108 | * ```sh 109 | * $ gen project:dotfiles 110 | * ``` 111 | * @name project:dotfiles 112 | * @api public 113 | */ 114 | 115 | app.task('dotfiles', function(cb) { 116 | app.generate([ 117 | 'gitattributes', 118 | 'gitignore:minimal', 119 | 'eslint:eslintrc', 120 | 'editorconfig', 121 | 'travis' 122 | ], cb); 123 | }); 124 | 125 | /** 126 | * Generate the main project files from registered micro-generators. 127 | * See the [generated files](#rootfiles-1). 128 | * 129 | * ```sh 130 | * $ gen project:rootfiles 131 | * ``` 132 | * @name project:rootfiles 133 | * @api public 134 | */ 135 | 136 | app.task('rootfiles', function(cb) { 137 | app.generate([ 138 | `license:${app.options.license || 'mit'}`, 139 | 'contributing', 140 | 'package', 141 | 'readme' 142 | ], cb); 143 | }); 144 | 145 | /** 146 | * Scaffold out basic project for a [gulp][] plugin. See 147 | * the [generated files](#gulp-1). 148 | * 149 | * ```sh 150 | * $ gen project:gulp 151 | * ``` 152 | * @name project:gulp 153 | * @api public 154 | */ 155 | 156 | app.task('gulp', ['prompt', 'rootfiles', 'dotfiles', 'gulp-plugin', 'gulp-file']); 157 | task(app, 'gulp-file', 'gulp/gulpfile.js'); 158 | task(app, 'gulp-plugin', 'gulp/plugin.js'); 159 | 160 | /** 161 | * Scaffold out a project for a [base][] plugin. See the 162 | * [generated files](#base-1). 163 | * 164 | * ```sh 165 | * $ gen project:base 166 | * ``` 167 | * @name project:base 168 | * @api public 169 | */ 170 | 171 | app.task('base', ['prompt', 'rootfiles', 'dotfiles', 'base-index']); 172 | task(app, 'base-index', 'base/plugin.js'); 173 | 174 | /** 175 | * Scaffold out a minimal code project. See the [generated files](#minimal-1). 176 | * 177 | * ```sh 178 | * $ gen project:min 179 | * $ gen project:minimal 180 | * ``` 181 | * @name project:minimal 182 | * @api public 183 | */ 184 | 185 | app.task('min', ['minimal']); 186 | app.task('minimal', function(cb) { 187 | app.generate([ 188 | 'is-empty', 189 | 'prompt', 190 | 'gitignore:node', 191 | `license:${app.options.license || 'mit'}`, 192 | 'package', 193 | 'readme' 194 | ], cb); 195 | }); 196 | 197 | /** 198 | * Scaffold out a basic code project. See the [generated files](#basic-1). 199 | * 200 | * ```sh 201 | * $ gen project:basic 202 | * ``` 203 | * @name project:basic 204 | * @api public 205 | */ 206 | 207 | app.task('basic', function(cb) { 208 | app.generate([ 209 | 'is-empty', 210 | 'prompt', 211 | 'gitignore:node', 212 | 'license:choose', 213 | 'package', 214 | 'readme' 215 | ], cb); 216 | }); 217 | 218 | /** 219 | * Scaffold out a basic code project. See the [generated files](#basic-1). 220 | * 221 | * ```sh 222 | * $ gen project:basic 223 | * ``` 224 | * @name project:basic 225 | * @api public 226 | */ 227 | 228 | task(app, 'update-configfile', 'update/_updaterc.json'); 229 | app.task('update-rc', [ 230 | 'is-empty', 231 | 'prompt', 232 | 'rootfiles', 233 | 'dotfiles', 234 | 'update-configfile' 235 | ]); 236 | 237 | /** 238 | * Scaffold out a basic [generate][] generator project. 239 | * 240 | * ```sh 241 | * $ gen project:generator 242 | * ``` 243 | * @name project:generator 244 | * @api public 245 | */ 246 | 247 | task(app, 'generator-files', 'generator/*.js'); 248 | app.task('gen', ['generator']); 249 | app.task('generator', [ 250 | 'is-empty', 251 | 'prompt', 252 | 'rootfiles', 253 | 'dotfiles', 254 | 'generator-files' 255 | ]); 256 | 257 | /** 258 | * Scaffold out a basic template helper project. 259 | * 260 | * ```sh 261 | * $ gen project:helper 262 | * ``` 263 | * @name project:helper 264 | * @api public 265 | */ 266 | 267 | task(app, 'helper', 'helper/*.js', ['is-empty', 'prompt', 'files']); 268 | 269 | /** 270 | * Scaffold out a basic JavaScript regex project. 271 | * 272 | * ```sh 273 | * $ gen project:regex 274 | * ``` 275 | * @name project:regex 276 | * @api public 277 | */ 278 | 279 | task(app, 'regex', 'regex/*.js', ['is-empty', 'prompt', 'files']); 280 | 281 | /** 282 | * Scaffold out an [assemble][] middleware project. 283 | * 284 | * ```sh 285 | * $ gen project:middleware 286 | * ``` 287 | * @name project:middleware 288 | * @api public 289 | */ 290 | 291 | task(app, 'middleware-index', 'middleware/index.js'); 292 | app.task('middleware', [ 293 | 'is-empty', 294 | 'prompt', 295 | 'rootfiles', 296 | 'dotfiles', 297 | 'middleware-index' 298 | ]); 299 | 300 | /** 301 | * Prompts for commonly used data. This task isn't necessary 302 | * needed, it's more of a convenience for asking questions up front, 303 | * instead of as files are generated. The actual messages for questions 304 | * can be found in the [common-questions][] library. 305 | * 306 | * ```sh 307 | * $ gen project:prompt 308 | * ``` 309 | * @name project:prompt 310 | * @api public 311 | */ 312 | 313 | app.task('prompt', function(cb) { 314 | if (app.options.prompt === false) return cb(); 315 | app.base.data(app.cache.data); 316 | 317 | app.base.set('cache.prompted', true); 318 | app.question('homepage', 'Project homepage?'); 319 | 320 | // common question names 321 | var keys = mapValues([ 322 | 'name', 323 | 'description', 324 | 'owner', 325 | 'homepage', 326 | 'license', 327 | 'author.name', 328 | 'author.username', 329 | 'author.url' 330 | ], app); 331 | 332 | if (keys.skip.length) { 333 | app.log(); 334 | app.log('', app.log.yellow(app.log.bold(app.log.underline('Heads up!')))); 335 | app.log(); 336 | app.log(' The following data from user environment and/or package.json'); 337 | app.log(' will be used to render templates (if applicable), and prompts'); 338 | app.log(' for these values will be skipped:'); 339 | app.log(); 340 | app.log(formatFields(app, keys.skip)); 341 | app.log(` Run with ${app.log.cyan('--noskip')} to disable this feature.`); 342 | app.log(); 343 | app.log(' ---'); 344 | app.log(); 345 | } 346 | 347 | app.ask(keys.ask, cb); 348 | }); 349 | 350 | /** 351 | * Verify that the current working directory is empty before generating any files. 352 | * This task is automatically run by the `default` task, but you'll need to call it 353 | * directly with any other task. This task is from [generate-defaults][]. 354 | * 355 | * ```sh 356 | * $ gen project:is-empty 357 | * ``` 358 | * @name project:is-empty 359 | * @api public 360 | */ 361 | 362 | app.task('is-empty', function(cb) { 363 | if (app.option('check-directory') !== false) { 364 | app.build('check-directory', cb); 365 | } else { 366 | cb(); 367 | } 368 | }); 369 | 370 | return generator; 371 | }; 372 | 373 | /** 374 | * Create a task with the given `name` and glob `pattern` 375 | */ 376 | 377 | function task(app, name, pattern, dependencies) { 378 | app.task(name, dependencies || [], function(cb) { 379 | return pattern ? file(app, pattern) : cb(); 380 | }); 381 | } 382 | 383 | /** 384 | * Generate files that match the given `pattern` 385 | */ 386 | 387 | function file(app, pattern) { 388 | var src = app.options.srcBase || path.join(__dirname, 'templates'); 389 | return app.src(pattern, {cwd: src}) 390 | .pipe(app.renderFile('*')).on('error', console.log) 391 | .pipe(app.conflicts(app.cwd)) 392 | .pipe(app.dest(app.cwd)); 393 | } 394 | 395 | /** 396 | * Map values and filter out keys for data that has already been defined, 397 | * to avoid asking unnecessary questions. This can be overridden 398 | * with `--noskip` 399 | */ 400 | 401 | function mapValues(keys, app) { 402 | if (app.option('hints') === false || app.option('skip') === false) { 403 | return {ask: keys, skip: []}; 404 | } 405 | 406 | var res = {ask: [], skip: []}; 407 | for (var i = 0; i < keys.length; i++) { 408 | var key = keys[i]; 409 | if (!app.has('cache.data', key)) { 410 | res.ask.push(key); 411 | } else { 412 | app.base.data(key, app.data(key)); 413 | res.skip.push([key, app.data(key)]); 414 | } 415 | } 416 | return res; 417 | } 418 | 419 | /** 420 | * Format skipped fields 421 | */ 422 | 423 | function formatFields(app, keys) { 424 | var list = ''; 425 | keys.forEach(function(key) { 426 | list += ' · ' + app.log.bold(key[0]); 427 | list += ': ' + app.log.green(key[1]) + '\n'; 428 | }); 429 | return list; 430 | } 431 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./generator'); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generate-project", 3 | "description": "Scaffold out complete code projects from the command line, or use this generator as a plugin in other generators to provide baseline functionality.", 4 | "version": "1.0.0", 5 | "homepage": "https://github.com/generate/generate-project", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "generate/generate-project", 8 | "bugs": { 9 | "url": "https://github.com/generate/generate-project/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "generator.js", 14 | "index.js", 15 | "templates" 16 | ], 17 | "main": "index.js", 18 | "engines": { 19 | "node": ">=4.0" 20 | }, 21 | "scripts": { 22 | "test": "mocha" 23 | }, 24 | "dependencies": { 25 | "data-store": "^1.0.0", 26 | "generate-contributing": "^0.3.0", 27 | "generate-defaults": "^0.6.6", 28 | "generate-editorconfig": "^0.2.1", 29 | "generate-eslint": "^1.0.0", 30 | "generate-gh-repo": "^1.1.0", 31 | "generate-git": "^0.2.0", 32 | "generate-gitattributes": "^0.1.2", 33 | "generate-gitignore": "^0.2.6", 34 | "generate-install": "^0.3.1", 35 | "generate-license": "^1.0.0", 36 | "generate-package": "^0.7.3", 37 | "generate-readme": "^0.3.1", 38 | "generate-travis": "^0.3.1", 39 | "is-valid-app": "^0.3.0", 40 | "prompt-checkbox": "^2.2.0" 41 | }, 42 | "devDependencies": { 43 | "mocha": "^4.0.1", 44 | "generate": "^0.14.0", 45 | "npm-install-global": "^1.0.0", 46 | "delete": "^1.1.0", 47 | "verb-repo-data": "^0.1.15", 48 | "gulp-format-md": "^1.0.0", 49 | "verb-trees": "^0.1.0", 50 | "verb-generate-readme": "^0.6.0" 51 | }, 52 | "keywords": [ 53 | "boilerplate", 54 | "build", 55 | "cli", 56 | "cli-app", 57 | "command-line", 58 | "create", 59 | "dev", 60 | "development", 61 | "framework", 62 | "front", 63 | "frontend", 64 | "generate", 65 | "generate-generator", 66 | "generate-plugin", 67 | "generategenerator", 68 | "generateplugin", 69 | "generator", 70 | "init", 71 | "initialize", 72 | "new", 73 | "plugin", 74 | "project", 75 | "projects", 76 | "scaffold", 77 | "scaffolder", 78 | "scaffolding", 79 | "template", 80 | "templates", 81 | "webapp", 82 | "yeoman", 83 | "yo" 84 | ], 85 | "lintDeps": { 86 | "ignore": [ 87 | "scaffolds", 88 | "templates" 89 | ] 90 | }, 91 | "verb": { 92 | "toc": { 93 | "collapsible": true, 94 | "method": "preWrite", 95 | "maxdepth": 3, 96 | "footer": "\n\n_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_", 97 | "render": true 98 | }, 99 | "layout": "generator", 100 | "tasks": [ 101 | "readme" 102 | ], 103 | "plugins": [ 104 | "gulp-format-md" 105 | ], 106 | "related": { 107 | "list": [ 108 | "generate-dest", 109 | "generate-install", 110 | "generate-package" 111 | ] 112 | }, 113 | "reflinks": [ 114 | "assemble", 115 | "base", 116 | "common-questions", 117 | "generate", 118 | "generate-defaults", 119 | "gulp" 120 | ], 121 | "lint": { 122 | "reflinks": true 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /templates/base/plugin.js: -------------------------------------------------------------------------------- 1 | --- 2 | rename: 3 | basename: 'index.js' 4 | install: 5 | devDependencies: ['is-valid-app'] 6 | --- 7 | 'use strict'; 8 | 9 | var isValid = require('is-valid-app'); 10 | 11 | module.exports = function(options) { 12 | return function(app) { 13 | if (!isValid(app, '<%= name %>')) return; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /templates/generator/generator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var isValid = require('is-valid-app'); 5 | 6 | module.exports = function(app) { 7 | // return if the generator is already registered 8 | if (!isValid(app, '<%= name %>')) return; 9 | 10 | /** 11 | * Generate a `index.js` file to the current working directory. Learn how to [customize 12 | * behavior(#customization) or override built-in templates. 13 | * 14 | * ```sh 15 | * $ gen <%= alias %>:<%= alias %> 16 | * ``` 17 | * @name <%= alias %>:<%= alias %> 18 | * @api public 19 | */ 20 | 21 | task(app, '<%= alias %>', 'index.js'); 22 | 23 | /** 24 | * Alias for running the [<%= alias %>](#<%= alias %>) task with the following command: 25 | * 26 | * ```sh 27 | * $ gen <%= alias %> 28 | * ``` 29 | * @name <%= alias %> 30 | * @api public 31 | */ 32 | 33 | app.task('default', ['<%= alias %>']); 34 | }; 35 | 36 | /** 37 | * Create a task with the given `name` and glob `pattern` 38 | */ 39 | 40 | function task(app, name, pattern) { 41 | app.task(name, function() { 42 | return app.src(pattern, {cwd: __dirname}) 43 | .pipe(app.renderFile('*')) 44 | .pipe(app.conflicts(app.cwd)) 45 | .pipe(app.dest(app.cwd)); 46 | }); 47 | } 48 | -------------------------------------------------------------------------------- /templates/gulp/gulpfile.js: -------------------------------------------------------------------------------- 1 | --- 2 | install: 3 | devDependencies: ['gulp'] 4 | --- 5 | 'use strict'; 6 | 7 | var gulp = require('gulp'); 8 | 9 | gulp.task('default', function() { 10 | return gulp.src('*.js') 11 | .pipe(gulp.dest('temp')); 12 | }); 13 | -------------------------------------------------------------------------------- /templates/gulp/plugin.js: -------------------------------------------------------------------------------- 1 | --- 2 | rename: 3 | basename: 'index.js' 4 | install: 5 | devDependencies: ['through2'] 6 | --- 7 | 'use strict'; 8 | 9 | var through = require('through2'); 10 | 11 | module.exports = function(options) { 12 | return through.obj(function(file, enc, next) { 13 | if (file.isNull()) { 14 | next(null, file); 15 | return; 16 | } 17 | 18 | var str = file.contents.toString(); 19 | file.contents = new Buffer(str); 20 | next(null, file); 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /templates/helper/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(str) { 4 | return str; 5 | }; 6 | -------------------------------------------------------------------------------- /templates/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function() { 4 | }; 5 | -------------------------------------------------------------------------------- /templates/middleware/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(file, next) { 4 | next(null, file); 5 | }; 6 | -------------------------------------------------------------------------------- /templates/regex/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * <%= name %> > 3 | * 4 | * Copyright (c) <%= year %> <%= ask('author.name') %>. 5 | * Licensed under the <%= ask('license', {default: 'MIT'}) %> license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function() { 11 | return /^.$/g; 12 | }; 13 | -------------------------------------------------------------------------------- /templates/update/_updaterc.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/plugins.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var assert = require('assert'); 7 | var generate = require('generate'); 8 | var npm = require('npm-install-global'); 9 | var del = require('delete'); 10 | var generator = require('..'); 11 | var app; 12 | 13 | var actual = path.resolve.bind(path, __dirname, 'actual'); 14 | 15 | function exists(name, cb) { 16 | return function(err) { 17 | if (err) return cb(err); 18 | var filepath = actual(name); 19 | fs.stat(filepath, function(err, stat) { 20 | if (err) return cb(err); 21 | assert(stat); 22 | del(actual(), cb); 23 | }); 24 | }; 25 | } 26 | 27 | describe('plugins', function() { 28 | this.slow(350); 29 | 30 | if (!process.env.CI && !process.env.TRAVIS) { 31 | before(function(cb) { 32 | npm.maybeInstall('generate', cb); 33 | }); 34 | } 35 | 36 | before(function(cb) { 37 | del(actual(), cb); 38 | }); 39 | 40 | beforeEach(function() { 41 | app = generate({silent: true}); 42 | app.cwd = actual(); 43 | app.option('dest', actual()); 44 | app.option('prompt', false); 45 | app.option('askWhen', 'not-answered'); 46 | app.option('check-directory', false); 47 | app.use(require('verb-repo-data')); 48 | app.use(generator); 49 | }); 50 | 51 | describe('editorconfig', function() { 52 | it('should run the `editorconfig` task with .build', function(cb) { 53 | app.generate('editorconfig', exists('.editorconfig', cb)); 54 | }); 55 | 56 | it('should run the `editorconfig` task with .generate', function(cb) { 57 | app.generate('editorconfig', exists('.editorconfig', cb)); 58 | }); 59 | }); 60 | 61 | describe('eslint', function() { 62 | it('should run the `eslint` task with .build', function(cb) { 63 | app.generate('eslint:eslintrc', exists('.eslintrc.json', cb)); 64 | }); 65 | 66 | it('should run the `eslint` task with .generate', function(cb) { 67 | app.generate('eslint', exists('.eslintrc.json', cb)); 68 | }); 69 | }); 70 | 71 | describe('license', function() { 72 | it('should run the `mit` task with .build', function(cb) { 73 | app.generate('license:mit', exists('LICENSE', cb)); 74 | }); 75 | 76 | it('should run the `mit` task with .generate', function(cb) { 77 | app.generate('license:mit', exists('LICENSE', cb)); 78 | }); 79 | }); 80 | 81 | describe('package', function() { 82 | it('should run the `package` task with .build', function(cb) { 83 | app.generate('package', exists('package.json', cb)); 84 | }); 85 | 86 | it('should run the `package` task with .generate', function(cb) { 87 | app.generate('package', exists('package.json', cb)); 88 | }); 89 | }); 90 | 91 | describe('travis', function() { 92 | it('should run the `travis` task with .build', function(cb) { 93 | app.generate('travis', exists('.travis.yml', cb)); 94 | }); 95 | 96 | it('should run the `travis` task with .generate', function(cb) { 97 | app.generate('travis', exists('.travis.yml', cb)); 98 | }); 99 | }); 100 | }); 101 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isTravis = process.env.CI || process.env.TRAVIS; 4 | require('mocha'); 5 | var fs = require('fs'); 6 | var path = require('path'); 7 | var assert = require('assert'); 8 | var generate = require('generate'); 9 | var isValid = require('is-valid-app'); 10 | var npm = require('npm-install-global'); 11 | var del = require('delete'); 12 | var pkg = require('../package'); 13 | var generator = require('..'); 14 | var app; 15 | 16 | var cwd = path.resolve.bind(path, process.cwd()); 17 | var tests = path.resolve.bind(path, __dirname); 18 | var actual = path.resolve.bind(path, __dirname, 'actual'); 19 | 20 | function exists(name, cb) { 21 | return function(err) { 22 | if (err) return cb(err); 23 | fs.stat(actual(name), function(err, stat) { 24 | if (err) return cb(err); 25 | del(actual(), cb); 26 | }); 27 | }; 28 | } 29 | 30 | describe('generate-project', function() { 31 | this.slow(350); 32 | 33 | if (!process.env.CI && !process.env.TRAVIS) { 34 | before(function(cb) { 35 | npm.maybeInstall('generate', cb); 36 | }); 37 | } 38 | 39 | before(function(cb) { 40 | del([tests('actual'), tests('trees')], cb); 41 | }); 42 | 43 | after(function(cb) { 44 | del([tests('actual'), tests('trees')], cb); 45 | }); 46 | 47 | beforeEach(function() { 48 | app = generate({silent: true}); 49 | app.cwd = actual(); 50 | 51 | app.use(require('verb-repo-data')); 52 | 53 | // pre-populate template data to avoid prompts from `ask` helper 54 | app.option('prompt', false); 55 | app.option('check-directory', false); 56 | app.option('askWhen', 'not-answered'); 57 | app.option('dest', actual()); 58 | app.option('trees', cwd('test/trees')); 59 | app.option('overwrite', function(file) { 60 | return /actual/.test(file.path); 61 | }); 62 | }); 63 | 64 | describe('tasks', function() { 65 | it('should extend tasks onto the instance', function() { 66 | app.use(generator); 67 | assert(app.tasks.hasOwnProperty('default')); 68 | }); 69 | 70 | it('should extend generators onto the instance', function() { 71 | app.use(generator); 72 | assert(app.generators.hasOwnProperty('package')); 73 | }); 74 | 75 | it('should run the `default` task with .build', function(cb) { 76 | app.use(generator); 77 | app.build(['default'], exists('package.json', cb)); 78 | }); 79 | 80 | it('should run the `default` task with .generate', function(cb) { 81 | app.use(generator); 82 | app.generate('default', exists('package.json', cb)); 83 | }); 84 | }); 85 | 86 | describe('files', function() { 87 | beforeEach(function() { 88 | app.cwd = actual(); 89 | }); 90 | 91 | it('should generate a LICENSE file', function(cb) { 92 | app.register('project', generator); 93 | app.generate('project.license:mit', exists('LICENSE', cb)); 94 | }); 95 | 96 | it('should generate an index.js file', function(cb) { 97 | app.register('project', generator); 98 | app.generate('project:index', exists('index.js', cb)); 99 | }); 100 | 101 | it('should generate a .eslintrc.json file', function(cb) { 102 | app.register('project', generator); 103 | app.generate('project.eslint:eslintrc', exists('.eslintrc.json', cb)); 104 | }); 105 | 106 | it('should generate a README.md file', function(cb) { 107 | app.register('project', generator); 108 | app.generate('project.readme', exists('README.md', cb)); 109 | }); 110 | 111 | it('should generate a package.json file', function(cb) { 112 | app.register('project', generator); 113 | app.generate('project.package', exists('package.json', cb)); 114 | }); 115 | 116 | it('should run the `gitignore-node` task', function(cb) { 117 | app.register('project', generator); 118 | app.generate('project.gitignore:node', exists('.gitignore', cb)); 119 | }); 120 | 121 | it('should generate a .gitattributes file', function(cb) { 122 | app.register('project', generator); 123 | app.generate('project.gitattributes', exists('.gitattributes', cb)); 124 | }); 125 | 126 | it('should generate a .editorconfig file', function(cb) { 127 | app.register('project', generator); 128 | app.generate('project.editorconfig', exists('.editorconfig', cb)); 129 | }); 130 | 131 | it('should generate dotfiles', function(cb) { 132 | app.register('project', generator); 133 | app.generate('project:dotfiles', exists('.editorconfig', cb)); 134 | }); 135 | }); 136 | 137 | describe('generator (CLI)', function() { 138 | it('should run the default task using the `generate-project` name', function(cb) { 139 | if (isTravis) { 140 | this.skip(); 141 | return; 142 | } 143 | app.generate('generate-project', exists('package.json', cb)); 144 | }); 145 | 146 | it('should run the default task using the `project` generator alias', function(cb) { 147 | if (isTravis) { 148 | this.skip(); 149 | return; 150 | } 151 | app.generate('project', exists('package.json', cb)); 152 | }); 153 | }); 154 | 155 | describe('generator (API)', function() { 156 | it('should run the default task on the generator', function(cb) { 157 | app.register('project', generator); 158 | app.generate('project', exists('package.json', cb)); 159 | }); 160 | 161 | it('should run the `package` task', function(cb) { 162 | app.register('project', generator); 163 | app.generate('project.package', exists('package.json', cb)); 164 | }); 165 | 166 | it('should run the `default` task when defined explicitly', function(cb) { 167 | app.register('project', generator); 168 | app.generate('project:default', exists('package.json', cb)); 169 | }); 170 | }); 171 | 172 | describe('project:minimal', function() { 173 | it('should run the minimal task on the generator', function(cb) { 174 | app.register('project', generator); 175 | app.generate('project:minimal', exists('package.json', cb)); 176 | }); 177 | 178 | it('should run the `min` alias task', function(cb) { 179 | app.register('project', generator); 180 | app.generate('project:min', exists('package.json', cb)); 181 | }); 182 | }); 183 | 184 | describe('project:gulp', function() { 185 | it('should run the gulp task on the generator', function(cb) { 186 | app.register('project', generator); 187 | app.generate('project:gulp', exists('gulpfile.js', cb)); 188 | }); 189 | }); 190 | 191 | describe('sub-generator', function() { 192 | it('should work as a sub-generator', function(cb) { 193 | app.register('foo', function(foo) { 194 | foo.register('project', generator); 195 | }); 196 | app.generate('foo.project', exists('package.json', cb)); 197 | }); 198 | 199 | it('should run the `default` task by default', function(cb) { 200 | app.register('foo', function(foo) { 201 | foo.register('project', generator); 202 | }); 203 | app.generate('foo.project', exists('package.json', cb)); 204 | }); 205 | 206 | it('should run the `project:default` task when defined explicitly', function(cb) { 207 | app.register('foo', function(foo) { 208 | foo.register('project', generator); 209 | }); 210 | app.generate('foo.project:default', exists('package.json', cb)); 211 | }); 212 | 213 | it('should run the `project:package` task', function(cb) { 214 | app.register('foo', function(foo) { 215 | foo.register('project', generator); 216 | }); 217 | app.generate('foo.project.package', exists('package.json', cb)); 218 | }); 219 | 220 | it('should work with nested sub-generators', function(cb) { 221 | app 222 | .register('foo', generator) 223 | .register('bar', generator) 224 | .register('baz', generator); 225 | app.generate('foo.bar.baz', exists('package.json', cb)); 226 | }); 227 | }); 228 | }); 229 | -------------------------------------------------------------------------------- /trees.md: -------------------------------------------------------------------------------- 1 | The following files trees are automatically generated by a task in [verbfile.js](verbfile.js). 2 | 3 | - [generated files](#generated-files): trees representing the actual generated "dest" files for each task 4 | - [source files](#source-files): trees representing the source files and templates used by each task 5 | 6 | _(See Generate's [customization docs ][docs]{customization.md} to learn how to override individual templates.)_ 7 | 8 | ### Generated files 9 | 10 | Files generated by each task (e.g. `dest` files). See the Generate [customization docs ][docs]{customization.md} to learn how to override individual templates. 11 | 12 | Note that diffs are base on comparisons against the files generated by the `default` task. Additionally, some tasks generate the same files, but with different contents (for example, the contents of `index.js` differs based on the task). 13 | 14 | #### default 15 | 16 | Files generated by the [default task](#default): 17 | 18 | ```diff 19 | . 20 | ├── .editorconfig 21 | ├── .eslintrc.json 22 | ├── .gitattributes 23 | ├── .gitignore 24 | ├── .travis.yml 25 | ├── index.js 26 | ├── contributing.md 27 | ├── LICENSE 28 | ├── package.json 29 | └── README.md 30 | ``` 31 | 32 | #### minimal 33 | 34 | Files generated by the [minimal task](#minimal): 35 | 36 | ```diff 37 | . 38 | -├── .editorconfig 39 | -├── .eslintrc.json 40 | -├── .gitattributes 41 | ├── .gitignore 42 | -├── .travis.yml 43 | -├── index.js 44 | -├── contributing.md 45 | ├── LICENSE 46 | ├── package.json 47 | └── README.md 48 | ``` 49 | 50 | #### gulp 51 | 52 | Files generated by the [gulp task](#gulp): 53 | 54 | ```diff 55 | . 56 | ├── .editorconfig 57 | ├── .eslintrc.json 58 | ├── .gitattributes 59 | ├── .gitignore 60 | ├── .travis.yml 61 | ├── index.js 62 | +├── gulpfile.js 63 | ├── contributing.md 64 | ├── LICENSE 65 | ├── package.json 66 | └── README.md 67 | ``` 68 | 69 | #### base 70 | 71 | Files generated by the [base task](#base): 72 | 73 | ```diff 74 | . 75 | ├── .editorconfig 76 | ├── .eslintrc.json 77 | ├── .gitattributes 78 | ├── .gitignore 79 | ├── .travis.yml 80 | ├── index.js 81 | ├── contributing.md 82 | ├── LICENSE 83 | ├── package.json 84 | └── README.md 85 | ``` 86 | 87 | #### generator 88 | 89 | Files generated by the [generator task](#generator): 90 | 91 | ```diff 92 | . 93 | ├── .editorconfig 94 | ├── .eslintrc.json 95 | ├── .gitattributes 96 | ├── .gitignore 97 | ├── .travis.yml 98 | -├── index.js 99 | +├── generator.js 100 | ├── contributing.md 101 | ├── LICENSE 102 | ├── package.json 103 | └── README.md 104 | ``` 105 | 106 | #### helper 107 | 108 | Files generated by the [helper task](#helper): 109 | 110 | ```diff 111 | . 112 | ├── .editorconfig 113 | ├── .eslintrc.json 114 | ├── .gitattributes 115 | ├── .gitignore 116 | ├── .travis.yml 117 | ├── contributing.md 118 | ├── LICENSE 119 | ├── package.json 120 | ├── README.md 121 | └── index.js 122 | ``` 123 | 124 | #### files 125 | 126 | Files generated by the [files task](#files): 127 | 128 | ```diff 129 | . 130 | ├── .editorconfig 131 | ├── .eslintrc.json 132 | ├── .gitattributes 133 | ├── .gitignore 134 | ├── .travis.yml 135 | -├── index.js 136 | ├── contributing.md 137 | ├── LICENSE 138 | ├── package.json 139 | └── README.md 140 | ``` 141 | 142 | #### rootfiles 143 | 144 | Files generated by the [rootfiles task](#rootfiles): 145 | 146 | ```diff 147 | . 148 | -├── .editorconfig 149 | -├── .eslintrc.json 150 | -├── .gitattributes 151 | -├── .gitignore 152 | -├── .travis.yml 153 | -├── index.js 154 | ├── contributing.md 155 | ├── LICENSE 156 | ├── package.json 157 | └── README.md 158 | ``` 159 | 160 | #### dotfiles 161 | 162 | Files generated by the [dotfiles task](#dotfiles): 163 | 164 | ```diff 165 | . 166 | ├── .editorconfig 167 | ├── .eslintrc.json 168 | ├── .gitattributes 169 | ├── .gitignore 170 | └── .travis.yml 171 | -├── index.js 172 | -├── contributing.md 173 | -├── LICENSE 174 | -├── package.json 175 | -└── README.md 176 | ``` 177 | 178 | #### index 179 | 180 | Files generated by the [index task](#index): 181 | 182 | ```diff 183 | . 184 | -├── .editorconfig 185 | -├── .eslintrc.json 186 | -├── .gitattributes 187 | -├── .gitignore 188 | -├── .travis.yml 189 | └── index.js 190 | -├── contributing.md 191 | -├── LICENSE 192 | -├── package.json 193 | -└── README.md 194 | ``` 195 | 196 | ### Source files 197 | 198 | The following trees represent the source files or templates that are used by each task. You'll see that most of the tasks use at least one "micro-generator" to generate a specific file. 199 | 200 | #### default 201 | 202 | Source files and/or libraries used by the [default task](#default): 203 | 204 | ```diff 205 | . 206 | ├─┬ node_modules 207 | │ ├─┬ generate-editorconfig 208 | │ │ └─┬ templates 209 | │ │ └── _editorconfig 210 | │ ├─┬ generate-eslint 211 | │ │ └─┬ templates 212 | │ │ └── _eslintrc.json 213 | │ ├─┬ generate-gitattributes 214 | │ │ └─┬ templates 215 | │ │ └── _gitattributes 216 | │ ├─┬ generate-gitignore 217 | │ │ └─┬ templates 218 | │ │ └── Minimal.gitignore 219 | │ ├─┬ generate-travis 220 | │ │ └─┬ templates 221 | │ │ └── _travis.yml 222 | │ ├─┬ generate-contributing 223 | │ │ └─┬ templates 224 | │ │ └── contributing.md 225 | │ ├─┬ generate-license 226 | │ │ └─┬ templates 227 | │ │ └── mit.tmpl 228 | │ ├─┬ generate-package 229 | │ │ └─┬ templates 230 | │ │ └── $package.json 231 | │ └─┬ generate-readme 232 | │ └─┬ templates 233 | │ └── node.md 234 | └─┬ templates 235 | └── index.js 236 | ``` 237 | 238 | #### minimal 239 | 240 | Source files and/or libraries used by the [minimal task](#minimal): 241 | 242 | ```diff 243 | . 244 | └─┬ node_modules 245 | ├─┬ generate-gitignore 246 | │ └─┬ templates 247 | │ └── Node.gitignore 248 | ├─┬ generate-license 249 | │ └─┬ templates 250 | │ └── mit.tmpl 251 | ├─┬ generate-package 252 | │ └─┬ templates 253 | │ └── $package.json 254 | └─┬ generate-readme 255 | └─┬ templates 256 | └── node.md 257 | ``` 258 | 259 | #### gulp 260 | 261 | Source files and/or libraries used by the [gulp task](#gulp): 262 | 263 | ```diff 264 | . 265 | ├─┬ node_modules 266 | │ ├─┬ generate-editorconfig 267 | │ │ └─┬ templates 268 | │ │ └── _editorconfig 269 | │ ├─┬ generate-eslint 270 | │ │ └─┬ templates 271 | │ │ └── _eslintrc.json 272 | │ ├─┬ generate-gitattributes 273 | │ │ └─┬ templates 274 | │ │ └── _gitattributes 275 | │ ├─┬ generate-gitignore 276 | │ │ └─┬ templates 277 | │ │ └── Minimal.gitignore 278 | │ ├─┬ generate-travis 279 | │ │ └─┬ templates 280 | │ │ └── _travis.yml 281 | │ ├─┬ generate-contributing 282 | │ │ └─┬ templates 283 | │ │ └── contributing.md 284 | │ ├─┬ generate-license 285 | │ │ └─┬ templates 286 | │ │ └── mit.tmpl 287 | │ ├─┬ generate-package 288 | │ │ └─┬ templates 289 | │ │ └── $package.json 290 | │ └─┬ generate-readme 291 | │ └─┬ templates 292 | │ └── node.md 293 | └─┬ templates 294 | └─┬ gulp 295 | ├── plugin.js 296 | └── gulpfile.js 297 | ``` 298 | 299 | #### base 300 | 301 | Source files and/or libraries used by the [base task](#base): 302 | 303 | ```diff 304 | . 305 | ├─┬ node_modules 306 | │ ├─┬ generate-editorconfig 307 | │ │ └─┬ templates 308 | │ │ └── _editorconfig 309 | │ ├─┬ generate-eslint 310 | │ │ └─┬ templates 311 | │ │ └── _eslintrc.json 312 | │ ├─┬ generate-gitattributes 313 | │ │ └─┬ templates 314 | │ │ └── _gitattributes 315 | │ ├─┬ generate-gitignore 316 | │ │ └─┬ templates 317 | │ │ └── Minimal.gitignore 318 | │ ├─┬ generate-travis 319 | │ │ └─┬ templates 320 | │ │ └── _travis.yml 321 | │ ├─┬ generate-contributing 322 | │ │ └─┬ templates 323 | │ │ └── contributing.md 324 | │ ├─┬ generate-license 325 | │ │ └─┬ templates 326 | │ │ └── mit.tmpl 327 | │ ├─┬ generate-package 328 | │ │ └─┬ templates 329 | │ │ └── $package.json 330 | │ └─┬ generate-readme 331 | │ └─┬ templates 332 | │ └── node.md 333 | └─┬ templates 334 | └─┬ base 335 | └── plugin.js 336 | ``` 337 | 338 | #### generator 339 | 340 | Source files and/or libraries used by the [generator task](#generator): 341 | 342 | ```diff 343 | . 344 | ├─┬ node_modules 345 | │ ├─┬ generate-editorconfig 346 | │ │ └─┬ templates 347 | │ │ └── _editorconfig 348 | │ ├─┬ generate-eslint 349 | │ │ └─┬ templates 350 | │ │ └── _eslintrc.json 351 | │ ├─┬ generate-gitattributes 352 | │ │ └─┬ templates 353 | │ │ └── _gitattributes 354 | │ ├─┬ generate-gitignore 355 | │ │ └─┬ templates 356 | │ │ └── Minimal.gitignore 357 | │ ├─┬ generate-travis 358 | │ │ └─┬ templates 359 | │ │ └── _travis.yml 360 | │ ├─┬ generate-contributing 361 | │ │ └─┬ templates 362 | │ │ └── contributing.md 363 | │ ├─┬ generate-license 364 | │ │ └─┬ templates 365 | │ │ └── mit.tmpl 366 | │ ├─┬ generate-package 367 | │ │ └─┬ templates 368 | │ │ └── $package.json 369 | │ └─┬ generate-readme 370 | │ └─┬ templates 371 | │ └── node.md 372 | └─┬ templates 373 | └─┬ generator 374 | └── generator.js 375 | ``` 376 | 377 | #### helper 378 | 379 | Source files and/or libraries used by the [helper task](#helper): 380 | 381 | ```diff 382 | . 383 | ├─┬ node_modules 384 | │ ├─┬ generate-editorconfig 385 | │ │ └─┬ templates 386 | │ │ └── _editorconfig 387 | │ ├─┬ generate-eslint 388 | │ │ └─┬ templates 389 | │ │ └── _eslintrc.json 390 | │ ├─┬ generate-gitattributes 391 | │ │ └─┬ templates 392 | │ │ └── _gitattributes 393 | │ ├─┬ generate-gitignore 394 | │ │ └─┬ templates 395 | │ │ └── Minimal.gitignore 396 | │ ├─┬ generate-travis 397 | │ │ └─┬ templates 398 | │ │ └── _travis.yml 399 | │ ├─┬ generate-contributing 400 | │ │ └─┬ templates 401 | │ │ └── contributing.md 402 | │ ├─┬ generate-license 403 | │ │ └─┬ templates 404 | │ │ └── mit.tmpl 405 | │ ├─┬ generate-package 406 | │ │ └─┬ templates 407 | │ │ └── $package.json 408 | │ └─┬ generate-readme 409 | │ └─┬ templates 410 | │ └── node.md 411 | └─┬ templates 412 | └─┬ helper 413 | └── index.js 414 | ``` 415 | 416 | #### files 417 | 418 | Source files and/or libraries used by the [files task](#files): 419 | 420 | ```diff 421 | . 422 | └─┬ node_modules 423 | ├─┬ generate-editorconfig 424 | │ └─┬ templates 425 | │ └── _editorconfig 426 | ├─┬ generate-eslint 427 | │ └─┬ templates 428 | │ └── _eslintrc.json 429 | ├─┬ generate-gitattributes 430 | │ └─┬ templates 431 | │ └── _gitattributes 432 | ├─┬ generate-gitignore 433 | │ └─┬ templates 434 | │ └── Minimal.gitignore 435 | ├─┬ generate-travis 436 | │ └─┬ templates 437 | │ └── _travis.yml 438 | ├─┬ generate-contributing 439 | │ └─┬ templates 440 | │ └── contributing.md 441 | ├─┬ generate-license 442 | │ └─┬ templates 443 | │ └── mit.tmpl 444 | ├─┬ generate-package 445 | │ └─┬ templates 446 | │ └── $package.json 447 | └─┬ generate-readme 448 | └─┬ templates 449 | └── node.md 450 | ``` 451 | 452 | #### rootfiles 453 | 454 | Source files and/or libraries used by the [rootfiles task](#rootfiles): 455 | 456 | ```diff 457 | . 458 | └─┬ node_modules 459 | ├─┬ generate-contributing 460 | │ └─┬ templates 461 | │ └── contributing.md 462 | ├─┬ generate-license 463 | │ └─┬ templates 464 | │ └── mit.tmpl 465 | ├─┬ generate-package 466 | │ └─┬ templates 467 | │ └── $package.json 468 | └─┬ generate-readme 469 | └─┬ templates 470 | └── node.md 471 | ``` 472 | 473 | #### dotfiles 474 | 475 | Source files and/or libraries used by the [dotfiles task](#dotfiles): 476 | 477 | ```diff 478 | . 479 | └─┬ node_modules 480 | ├─┬ generate-editorconfig 481 | │ └─┬ templates 482 | │ └── _editorconfig 483 | ├─┬ generate-eslint 484 | │ └─┬ templates 485 | │ └── _eslintrc.json 486 | ├─┬ generate-gitattributes 487 | │ └─┬ templates 488 | │ └── _gitattributes 489 | ├─┬ generate-gitignore 490 | │ └─┬ templates 491 | │ └── Minimal.gitignore 492 | └─┬ generate-travis 493 | └─┬ templates 494 | └── _travis.yml 495 | ``` 496 | 497 | #### index 498 | 499 | Source files and/or libraries used by the [index task](#index): 500 | 501 | ```diff 502 | . 503 | └─┬ templates 504 | └── index.js 505 | ``` 506 | 507 | [docs]: https://github.com/generate/generate/blob/master/docs/ 508 | 509 | -------------------------------------------------------------------------------- /verbfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var generator = require('./'); 4 | var trees = require('verb-trees'); 5 | var del = require('delete'); 6 | 7 | /** 8 | * Build docs: `$ verb` 9 | * 10 | * (verb takes ~2 sec to run, since it has to 11 | * run all of the tasks to create file trees) 12 | */ 13 | 14 | module.exports = function(app) { 15 | app.use(require('verb-generate-readme')); 16 | app.option('check-directory', false); 17 | app.option('overwrite', true); 18 | app.option('prompt', false); 19 | 20 | app.use(trees(generator, [ 21 | 'default', 22 | 'minimal', 23 | 'gulp', 24 | 'base', 25 | 'generator', 26 | 'helper', 27 | 'files', 28 | 'rootfiles', 29 | 'dotfiles', 30 | 'index' 31 | ])); 32 | 33 | app.task('docs', function(cb) { 34 | return app.src('docs/trees.md', {cwd: __dirname}) 35 | .pipe(app.renderFile('*')) 36 | .pipe(app.dest(app.cwd)); 37 | }); 38 | 39 | app.task('delete', function(cb) { 40 | del('.temp-trees', cb); 41 | }); 42 | 43 | app.task('default', ['trees', 'readme', 'docs', 'delete']); 44 | }; 45 | --------------------------------------------------------------------------------