├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── bin └── cli.js ├── docs └── layout.html ├── index.js ├── package.json ├── templates ├── .gitignore.mustache ├── .travis.yml.mustache ├── CHANGELOG.md.mustache ├── CONTRIBUTING.md.mustache ├── LICENSE.md │ ├── Apache-2.0.mustache │ ├── BSD-3-Clause.mustache │ ├── CC0-1.0.mustache │ ├── ISC.mustache │ ├── MIT.mustache │ └── UNLICENSED.mustache ├── README.md.mustache ├── index.js ├── package.json.mustache └── test │ └── index.js │ ├── semistandard.mustache │ └── standard.mustache └── test └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | site 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4' 4 | - '6' 5 | cache: 6 | directories: 7 | - node_modules 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # module-init change log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [1.5.0](https://github.com/ungoldman/module-init/releases/v1.5.0) - 2016-09-17 9 | 10 | [view diff](https://github.com/ungoldman/module-init/compare/v1.4.0...v1.5.0) 11 | 12 | - templates: `.travis.yml`: drop `0.10`, `0.12`, `5` 13 | - templates: `CHANGELOG.md`: update header language 14 | - templates: `README.md`: move project description up 15 | - site: add scripts for generating a gh-pages site 16 | 17 | ## [1.4.0] - 2016-03-18 18 | - add BSD-3-Clause, CC0-1.0, MIT, and UNLICENSED options (resolves #34) 19 | - go back to using `.md` extension for licenses for better readability on github (reverts e971059) 20 | - add `private` CLI option 21 | - update CONTRIBUTING.md 22 | - move linting back to front of test chain (reverts #31) 23 | 24 | ## [1.3.6] - 2015-11-19 25 | * make npm install & git init optional ([#33](https://github.com/ungoldman/module-init/issues/33)) 26 | * add `--force` option to skip prompt and init with defaults 27 | * fix package name default when `--dir` cli option is a nested path 28 | 29 | ## [1.3.5] - 2015-11-15 30 | * add codes style badges to READMEs ([#30](https://github.com/ungoldman/module-init/pull/30)) 31 | * move linting to the end of the test chain ([#31](https://github.com/ungoldman/module-init/pull/31)) 32 | * Include example test in test/index.js ([#14](https://github.com/ungoldman/module-init/issues/14)) 33 | 34 | ## [1.3.4] - 2015-10-20 35 | * fix --version flag ([#28](https://github.com/ungoldman/module-init/pull/28)) 36 | * fix keywords being escaped ([#29](https://github.com/ungoldman/module-init/pull/29)) 37 | 38 | ## [1.3.3] - 2015-09-30 39 | * add 0.10 and 0.12 back to travis 40 | * remove redundant `script` section of travis (default is already `npm test`) 41 | 42 | ## [1.3.2] - 2015-09-22 43 | * remove can-haz-package from dependencies (oops) 44 | * fix bad reference to `package.json` 45 | 46 | ## [1.3.1] - 2015-09-22 47 | * hide contributing section if no pkgContributing ([#24](https://github.com/ungoldman/module-init/pull/24)) 48 | * default to stable node for `.travis.yml` 49 | * remove can-haz-package validation due to issue ([#23](https://github.com/ungoldman/module-init/issues/23)) 50 | * no errant newlines in readme if description omitted 51 | 52 | ## 1.3.0 - 2015-08-10 53 | * Remove errant newline in ISC template ([#22](https://github.com/ungoldman/module-init/pull/22)) 54 | * Add `dir` option to specify directory 55 | * Fix missing `pkgVersion` default 56 | 57 | ## 1.2.1 - 2015-08-05 58 | * Change `LICENSE.md` to `LICENSE` in all the places 59 | 60 | ## 1.2.0 - 2015-08-04 61 | * Validate package name with [can-haz-package](https://github.com/flet/can-haz-package) 62 | 63 | ## 1.1.1 - 2015-07-18 64 | * Fix typo in CONTRIBUTING.md & CONTRIBUTING.md.mustache 65 | 66 | ## 1.1.0 - 2015-07-05 67 | 68 | ### Added 69 | * CLI now has `--version` and `--help` arguments 70 | 71 | ## 1.0.1 - 2015-07-01 72 | 73 | ### Changed 74 | * Updated contributing guidelines & template based on changes in [ngoldman/contributing@b1f54df](https://github.com/ungoldman/contributing/commit/b1f54df669d02e1db87598bc07540d823b423d4d). 75 | 76 | ### Fixed 77 | * Use `tap-spec` 4.x to fix rendering issues ([#16](https://github.com/ungoldman/module-init/issues/16)) 78 | 79 | ## 1.0.0 - 2015-06-15 80 | 81 | ### Changed 82 | * Refactored object returned by `templates/index.js` to deal with fix for ([#13](https://github.com/ungoldman/module-init/issues/13)) 83 | 84 | ### Fixed 85 | * remove `pkgContributing` from required list, default to true 86 | * fix error when selecting 'No' for contributing ([#13](https://github.com/ungoldman/module-init/issues/13)) 87 | 88 | ## 0.3.2 89 | * use github's [node `.gitignore`](https://github.com/github/gitignore/edit/master/Node.gitignore) 90 | * improve `CONTRIBUTING.md` to be useful for contributors as well as collaborators 91 | * switch from `faucet` to `tap-spec` for tap output ([#12](https://github.com/ungoldman/module-init/issues/12)) 92 | 93 | ## 0.3.1 94 | * change `standard` devDep to always use latest ([#7](https://github.com/ungoldman/module-init/issues/7)) 95 | * add linter options ([#8](https://github.com/ungoldman/module-init/issues/8)) 96 | 97 | ## 0.3.0 98 | 99 | ### Added 100 | * add `Apache-2.0` license option 101 | * add validation for license options 102 | * add test for invalid option error 103 | * add and expose `moduleInit.OPTIONS` constant 104 | * add default license (ISC) 105 | 106 | ### Removed 107 | * remove license from required list 108 | 109 | ### Changed 110 | * public method `moduleInit.validate()` returns `{ missing, invalid }` object instead of `missing` array 111 | * improve CLI feedback 112 | * update dependencies 113 | 114 | ## 0.2.0 115 | * switch Node API to EventEmitter pattern 116 | * remove io.js dependency ([#6](https://github.com/ungoldman/module-init/issues/6)) 117 | * add node 0.10 & 0.12 to travis tests 118 | * add stability index badge as fair warning 119 | 120 | ## 0.1.5 121 | * fix keywords again 122 | * add [`fixpack`](https://github.com/HenrikJoreteg/fixpack/) step 123 | * add `npm install` step 124 | * add implementation table to readme 125 | 126 | ## 0.1.4 127 | * move `.gitconfig` checks before prompt ([#2](https://github.com/ungoldman/module-init/issues/2)) 128 | 129 | ## 0.1.3 130 | * fix missing module 131 | * skip unimplemented test 132 | 133 | ## 0.1.2 134 | * add colors to creation process 135 | * slight improvement to tests 136 | * always exit process in bin 137 | * catch git config errors 138 | * nix repo creation 139 | * desc no longer has default 140 | * fixed keywords & added back 141 | * removed unused npmUsr variable 142 | 143 | ## 0.1.1 144 | * add newline to blank `index.js` & `test/index.js` 145 | * remove fake github repo confirmation & creation 146 | * removed unused dependency (mkdirp) 147 | * disable keywords for now 148 | 149 | ## 0.1.0 150 | * working draft 151 | 152 | [1.4.0]: https://github.com/ungoldman/module-init/compare/v1.3.6...v1.4.0 153 | [1.3.6]: https://github.com/ungoldman/module-init/compare/v1.3.5...v1.3.6 154 | [1.3.5]: https://github.com/ungoldman/module-init/compare/v1.3.4...v1.3.5 155 | [1.3.4]: https://github.com/ungoldman/module-init/compare/v1.3.3...v1.3.4 156 | [1.3.3]: https://github.com/ungoldman/module-init/compare/v1.3.2...v1.3.3 157 | [1.3.2]: https://github.com/ungoldman/module-init/compare/v1.3.1...v1.3.2 158 | [1.3.1]: https://github.com/ungoldman/module-init/compare/v1.3.0...v1.3.1 159 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Contributions welcome! 4 | 5 | **Before spending lots of time on something, ask for feedback on your idea first!** 6 | 7 | Please search issues and pull requests before adding something new to avoid duplicating efforts and conversations. 8 | 9 | This project welcomes non-code contributions, too! The following types of contributions are welcome: 10 | 11 | - **Ideas**: participate in an issue thread or start your own to have your voice heard. 12 | - **Writing**: contribute your expertise in an area by helping expand the included content. 13 | - **Copy editing**: fix typos, clarify language, and generally improve the quality of the content. 14 | - **Formatting**: help keep content easy to read with consistent formatting. 15 | 16 | # Project Governance 17 | 18 | **This is an [OPEN Open Source Project](http://openopensource.org/).** 19 | 20 | Individuals making significant and valuable contributions are given commit access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project. 21 | 22 | ## Rules 23 | 24 | There are a few basic ground rules for collaborators: 25 | 26 | 1. **No `--force` pushes** or modifying the Git history in any way. 27 | 1. **Non-master branches** ought to be used for ongoing work. 28 | 1. **External API changes and significant modifications** ought to be subject to an **internal pull request** to solicit feedback from other contributors. 29 | 1. Internal pull requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor. 30 | 1. Contributors should attempt to adhere to the prevailing code style. 31 | 32 | ## Releases 33 | 34 | Declaring formal releases remains the prerogative of the project maintainer. 35 | 36 | ## Changes to this arrangement 37 | 38 | This is an experiment and feedback is welcome! This document may also be subject to pull requests or changes by contributors where you believe you have something valuable to add or change. 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # [ISC License](https://spdx.org/licenses/ISC) 2 | 3 | Copyright (c) 2016, Nate Goldman 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # module-init 2 | 3 | Create a new node module with all the right stuff. 4 | 5 | [![npm][npm-image]][npm-url] 6 | [![travis][travis-image]][travis-url] 7 | [![standard][standard-image]][standard-url] 8 | [![downloads][downloads-image]][npm-url] 9 | 10 | [npm-image]: https://img.shields.io/npm/v/module-init.svg?style=flat-square 11 | [npm-url]: https://www.npmjs.com/package/module-init 12 | [travis-image]: https://img.shields.io/travis/ungoldman/module-init.svg?style=flat-square 13 | [travis-url]: https://travis-ci.org/ungoldman/module-init 14 | [standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square 15 | [standard-url]: http://standardjs.com/ 16 | [downloads-image]: https://img.shields.io/npm/dm/module-init.svg?style=flat-square 17 | 18 | ## Overview 19 | 20 | `module-init` is a command-line tool for generating a new node module. 21 | 22 | The following list of files are created based on user input: 23 | 24 | - **README.md** 25 | - Automatically generates title, description, and some tasteful badges (version, build status, code style). 26 | - Auto-populates install, usage, contributing, and license sections with relevant info. 27 | - **LICENSE.md** 28 | - Options: `Apache-2.0`, `BSD-3-Clause`, `CC0-1.0`, `ISC`, `MIT`, `UNLICENSED`. 29 | - **CHANGELOG.md** 30 | - Uses [Keep a Changelog](http://keepachangelog.com/) style. 31 | - **CONTRIBUTING.md** 32 | - Optionally generates contributing guidelines based on [CONTRIBUTING.md](https://github.com/ungoldman/CONTRIBUTING.md) boilerplate. 33 | - **package.json** 34 | - Fills out all standard fields. 35 | - Adds code style linter ([`standard`](https://github.com/feross/standard) or [`semistandard`](https://github.com/Flet/semistandard)) to `devDependencies`. 36 | - Adds [`tape`](https://github.com/substack/tape) & [`tap-spec`](https://github.com/scottcorgan/tap-spec) to `devDependencies`. 37 | - Sets up `npm test` script. 38 | - Runs [`fixpack`](https://github.com/HenrikJoreteg/fixpack). 39 | - **.travis.yml** 40 | - Covers Node.js `4` and `6`. 41 | - **.gitignore** 42 | - Ignores `node_modules` directory. 43 | - **index.js** 44 | - A blank module entry point file. 45 | - **test/index.js** 46 | - A boilerplate test file using [`tape`](https://github.com/substack/tape). 47 | 48 | Optionally runs `git init` and `npm install` in the new module directory. 49 | 50 | ## Install 51 | 52 | ``` 53 | npm install module-init -g 54 | ``` 55 | 56 | ## Usage 57 | 58 | ### CLI 59 | 60 | ``` 61 | $ module-init --help 62 | Usage: module-init [options] 63 | --dir, -d specify module directory (default: cwd) 64 | --version, -v show version information 65 | --force, -f skip prompt and init with defaults 66 | --help, -h show help 67 | ``` 68 | 69 | #### Example 70 | 71 | ``` 72 | ~ $ module-init -d new-project 73 | ? name: new-project 74 | ? version: 1.0.0 75 | ? description: 76 | ? keywords: 77 | ? license: ISC 78 | ? private: No 79 | ? CONTRIBUTING.md: Yes 80 | ? linter: standard 81 | ? git init: Yes 82 | ? npm install: Yes 83 | Initialized empty Git repository in /Users/yourname/new-project/.git/ 84 | ✓ .gitignore created 85 | ✓ .travis.yml created 86 | ✓ CHANGELOG.md created 87 | ✓ CONTRIBUTING.md created 88 | ✓ LICENSE created 89 | ✓ README.md created 90 | ✓ package.json created 91 | ✓ index.js created 92 | ✓ test/index.js created 93 | tape@4.0.3 node_modules/tape 94 | ... 95 | tap-spec@4.0.2 node_modules/tap-spec 96 | ... 97 | standard@5.0.2 node_modules/standard 98 | ... 99 | ✓ new-project initialized 100 | ``` 101 | 102 | ### Node API 103 | 104 | `module-init` can also be required as a regular node module. 105 | 106 | Configuration properties from other sources (`.gitconfig`, current working directory) will not be automatically used as defaults in this mode. All required properties need to be passed in explicitly. 107 | 108 | ```js 109 | var moduleInit = require('module-init') 110 | 111 | var options = { 112 | pkgName: 'cool-package', // required 113 | pkgVersion: '1.0.0', // required 114 | usrName: 'Your Name', // required 115 | usrEmail: 'your@email.com', // required 116 | usrGithub: 'githubUsername' // required 117 | pkgDescription: 'description', // optional 118 | pkgKeywords: 'one, two, three', // optional 119 | pkgContributing: true, // optional, default: true 120 | pkgLinter: 'standard', // optional, default: standard 121 | pkgLicense: 'ISC', // optional, default: ISC 122 | private: true, // optional, default: false (omitted if false) 123 | dir: 'project-directory' // optional: default: cwd 124 | } 125 | 126 | moduleInit(options) 127 | .on('create', function (filename) { 128 | console.log(`${filename} created`) 129 | // file created 130 | }) 131 | .on('warn', function (message) { 132 | console.log(`warning: ${message}`) 133 | // something weird but non-critical happened 134 | }) 135 | .on('err', function (err) { 136 | console.error(err) 137 | process.exit(1) 138 | // something went horribly wrong! stop everything! 139 | }) 140 | .on('done', function (result) { 141 | console.log(result) // object containing module metadata 142 | // done! 143 | }) 144 | .run() // run the thing 145 | ``` 146 | 147 | `moduleInit` returns an event emitter that emits `create`, `warn`, `err`, and `done`. 148 | 149 | `moduleInit.on(string, function)` works as demonstrated in the example above. 150 | 151 | `moduleInit.run()` runs the initialization process. It also calls `moduleInit.validate()` internally before proceeding and will emit an `err` event if required options are missing. Event listeners need to be set before `moduleInit.run()` is called. 152 | 153 | `moduleInit.validate()` returns an array of missing required options. It returns an empty array if everything's fine. This method is really just for internal use, but is exposed for testing and convenience. 154 | 155 | Take a look at [bin/cli.js](bin/cli.js) to see how the API is being used by the CLI. 156 | 157 | ## Contributing 158 | 159 | Contributions welcome! Please read the [contributing guidelines](CONTRIBUTING.md) before getting started. 160 | 161 | ## Collaborators 162 | 163 | `module-init` is only possible due to the excellent work of the following collaborators: 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 |
bcomnesGitHub/bcomnes
FletGitHub/Flet
paulcpedersonGitHub/paulcpederson
ungoldmanGitHub/ungoldman
172 | 173 | ## See Also 174 | 175 | - [Open Source Maintenance Guidelines](http://ungoldman.com/articles/open-source-maintenance-guidelines/) 176 | - [init-module](https://github.com/ungoldman/init-module) 177 | 178 | ## License 179 | 180 | [ISC](LICENSE.md) 181 | -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var moduleInit = require('../') 4 | var path = require('path') 5 | var chalk = require('chalk') 6 | var config = require('git-config').sync() 7 | var inquirer = require('inquirer') 8 | var clopts = require('cliclopts')([ 9 | { 10 | name: 'dir', 11 | abbr: 'd', 12 | help: 'specify module directory (default: cwd)' 13 | }, 14 | { 15 | name: 'version', 16 | abbr: 'v', 17 | boolean: true, 18 | help: 'show version information' 19 | }, 20 | { 21 | name: 'force', 22 | abbr: 'f', 23 | help: 'skip prompt and init with defaults', 24 | boolean: true 25 | }, 26 | { 27 | name: 'help', 28 | abbr: 'h', 29 | help: 'show help', 30 | boolean: true 31 | } 32 | ]) 33 | var argv = require('minimist')(process.argv.slice(2), { 34 | alias: clopts.alias(), 35 | boolean: clopts.boolean(), 36 | default: clopts.default() 37 | }) 38 | 39 | catchInputErrors() 40 | 41 | var questions = [ 42 | { 43 | type: 'input', 44 | name: 'pkgName', 45 | message: 'name', 46 | default: path.basename(argv.dir || process.cwd()) 47 | }, 48 | { 49 | type: 'input', 50 | name: 'pkgVersion', 51 | message: 'version', 52 | default: '1.0.0' 53 | }, 54 | { 55 | type: 'input', 56 | name: 'pkgDescription', 57 | message: 'description' 58 | }, 59 | { 60 | type: 'input', 61 | name: 'pkgKeywords', 62 | message: 'keywords' 63 | }, 64 | { 65 | type: 'list', 66 | name: 'pkgLicense', 67 | message: 'license', 68 | choices: ['Apache-2.0', 'BSD-3-Clause', 'CC0-1.0', 'ISC', 'MIT', 'UNLICENSED'], 69 | default: 'ISC' 70 | }, 71 | { 72 | type: 'confirm', 73 | name: 'private', 74 | message: 'private', 75 | default: false 76 | }, 77 | { 78 | type: 'confirm', 79 | name: 'pkgContributing', 80 | message: 'CONTRIBUTING.md', 81 | default: true 82 | }, 83 | { 84 | type: 'list', 85 | name: 'pkgLinter', 86 | message: 'linter', 87 | choices: ['standard', 'semistandard'], 88 | default: 'standard' 89 | }, 90 | { 91 | type: 'confirm', 92 | name: 'gitInit', 93 | message: 'git init', 94 | default: true 95 | }, 96 | { 97 | type: 'confirm', 98 | name: 'npmInstall', 99 | message: 'npm install', 100 | default: true 101 | } 102 | ] 103 | 104 | if (argv.force) { 105 | force() 106 | } else { 107 | prompt() 108 | } 109 | 110 | function catchInputErrors () { 111 | var errs = 0 112 | 113 | if (argv.version) { 114 | console.log(require(path.resolve(__dirname, '..', 'package.json')).version) 115 | process.exit(0) 116 | } 117 | 118 | if (argv.help) { 119 | console.log('Usage: module-init [options]') 120 | clopts.print() 121 | process.exit(0) 122 | } 123 | 124 | if (!config.user || 125 | !config.user.name) { 126 | console.log(chalk.red('Missing user name in .gitconfig')) 127 | console.log(' Please make sure your name is set, e.g.') 128 | console.log(' git config --global user.name "YOUR NAME"') 129 | errs++ 130 | } 131 | 132 | if (!config.user || 133 | !config.user.email) { 134 | console.log(chalk.red('Missing user email in .gitconfig')) 135 | console.log(' Please make sure your email is set, e.g.') 136 | console.log(' git config --global user.email "YOUR EMAIL"') 137 | errs++ 138 | } 139 | 140 | if (!config.github || !config.github.user) { 141 | console.log(chalk.red('Missing github user in .gitconfig')) 142 | console.log(' Please make sure your github username is set, e.g.') 143 | console.log(' git config --global github.user "YOUR USERNAME"') 144 | errs++ 145 | } 146 | 147 | if (errs) process.exit(1) 148 | } 149 | 150 | function force () { 151 | var data = {} 152 | 153 | for (var i = 0; i < questions.length; i++) { 154 | if (typeof questions[i].default !== 'undefined') { 155 | data[questions[i].name] = questions[i].default 156 | } 157 | } 158 | 159 | data = prepData(data) 160 | init(data) 161 | } 162 | 163 | function prompt () { 164 | inquirer.prompt(questions, function (data) { 165 | data = prepData(data) 166 | init(data) 167 | }) 168 | } 169 | 170 | function prepData (data) { 171 | data.usrName = config.user.name 172 | data.usrEmail = config.user.email 173 | data.usrGithub = config.github.user 174 | 175 | if (argv.dir) data.dir = argv.dir 176 | if (!data.pkgDescription) data.pkgDescription = '' 177 | if (!data.pkgKeywords) data.pkgKeywords = '' 178 | if (data.pkgKeywords !== '') { 179 | data.pkgKeywords = data.pkgKeywords 180 | .split(/[\s,]+/) 181 | .filter(function (value, index, self) { 182 | return !!value && self.indexOf(value) === index 183 | }) 184 | .map(function (value) { 185 | return '"' + value + '"' 186 | }) 187 | .join(', ') 188 | } 189 | 190 | return data 191 | } 192 | 193 | function init (data) { 194 | moduleInit(data) 195 | .on('create', function (file) { 196 | // file created 197 | console.log(chalk.green('✓ ') + chalk.bold(file) + ' created') 198 | }) 199 | .on('warn', function (msg) { 200 | // something weird happened 201 | console.log(chalk.yellow('✗ ' + msg)) 202 | }) 203 | .on('err', function (err) { 204 | // something went horribly wrong! 205 | console.error(err) 206 | process.exit(1) 207 | }) 208 | .on('done', function (res) { 209 | // we did it! 210 | console.log(chalk.green('✓ ') + chalk.bold(res.pkgName) + ' initialized') 211 | process.exit(0) 212 | }) 213 | .run() // run the thing 214 | } 215 | -------------------------------------------------------------------------------- /docs/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | module-init 6 | 7 | 8 | 9 | 10 | 11 | 18 |
19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | var util = require('util') 4 | var extend = util._extend 5 | var EventEmitter = require('events').EventEmitter 6 | var camelCase = require('camel-case') 7 | var cd = require('shelljs').cd 8 | var exec = require('shelljs').exec 9 | var fixpack = require('fixpack') 10 | var mkdirp = require('mkdirp') 11 | var templates = require('./templates') 12 | 13 | var OPTIONS = { 14 | required: [ 15 | 'pkgName', 16 | 'usrName', 17 | 'usrEmail', 18 | 'usrGithub' 19 | ], 20 | valid: { 21 | pkgLicense: ['Apache-2.0', 'BSD-3-Clause', 'CC0-1.0', 'ISC', 'MIT', 'UNLICENSED'], 22 | pkgLinter: ['standard', 'semistandard'] 23 | }, 24 | defaults: { 25 | 'dir': process.cwd(), 26 | 'gitInit': true, 27 | 'pkgContributing': true, 28 | 'pkgLicense': 'ISC', 29 | 'pkgLinter': 'standard', 30 | 'pkgVersion': '1.0.0', 31 | 'npmInstall': true 32 | } 33 | } 34 | 35 | function ModuleInit (data, cb) { 36 | if (!(this instanceof ModuleInit)) return new ModuleInit(data, cb) 37 | this.set(data) 38 | this.cb = cb || function noop () {} 39 | } 40 | 41 | util.inherits(ModuleInit, EventEmitter) 42 | 43 | ModuleInit.OPTIONS = OPTIONS 44 | 45 | ModuleInit.prototype.set = function set (data) { 46 | var defaults = extend({}, OPTIONS.defaults) 47 | if (this.data) extend(this.data, data || {}) 48 | else this.data = extend(defaults, data || {}) 49 | } 50 | 51 | ModuleInit.prototype.validate = function validate () { 52 | var data = this.data 53 | var missing = [] 54 | var invalid = [] 55 | 56 | function checkMissing (opt) { 57 | if (!data[opt]) missing.push(opt) 58 | } 59 | 60 | function validateInput (opt) { 61 | if (OPTIONS.valid[opt].indexOf(data[opt]) === -1) { 62 | invalid.push(opt) 63 | } 64 | } 65 | 66 | OPTIONS.required.forEach(checkMissing) 67 | Object.keys(OPTIONS.valid).forEach(validateInput) 68 | 69 | return { 70 | invalid: invalid, 71 | missing: missing 72 | } 73 | } 74 | 75 | ModuleInit.prototype.run = function run () { 76 | var cwd = process.cwd() 77 | var differentDir = this.data.dir !== cwd 78 | var errors = this.validate() 79 | var err 80 | 81 | if (errors.missing.length) { 82 | err = new Error('missing required options: ' + errors.missing.join(', ')) 83 | this.emit('err', err) 84 | return this.cb(err) 85 | } 86 | 87 | if (errors.invalid.length) { 88 | err = new Error('invalid options: ' + errors.invalid.join(', ')) 89 | this.emit('err', err) 90 | return this.cb(err) 91 | } 92 | 93 | this.data.nodeName = this.data.nodeName || camelCase(this.data.pkgName) 94 | this.data.year = this.data.year || new Date().getFullYear() 95 | 96 | if (differentDir) { 97 | mkdirp.sync(this.data.dir) 98 | cd(this.data.dir) 99 | } 100 | 101 | if (this.data.gitInit) exec('git init') 102 | 103 | createIndex.apply(this) 104 | createTestDir.apply(this) 105 | templates.forEach(createFileFromTemplate.bind(this)) 106 | fixpack(path.resolve('package.json'), { quiet: true }) 107 | 108 | if (this.data.npmInstall) exec('npm install') 109 | 110 | if (differentDir) cd(cwd) 111 | 112 | this.emit('done', this.data) 113 | return this.cb(null, this.data) 114 | } 115 | 116 | function createFileFromTemplate (tpl) { 117 | if (this.data[tpl.name] === false) return 118 | 119 | var filePath = path.resolve(tpl.file) 120 | 121 | if (fs.existsSync(filePath)) { 122 | return this.emit('warn', tpl.file + ' already exists') 123 | } 124 | 125 | fs.writeFileSync(filePath, tpl.template(this.data)) 126 | 127 | this.emit('create', tpl.file) 128 | } 129 | 130 | function createIndex () { 131 | var filePath = path.resolve('index.js') 132 | 133 | if (fs.existsSync(filePath)) { 134 | return this.emit('warn', 'index.js already exists') 135 | } 136 | 137 | fs.writeFileSync(filePath, '\n') 138 | this.emit('create', 'index.js') 139 | } 140 | 141 | function createTestDir () { 142 | var dirPath = path.resolve('test') 143 | 144 | if (fs.existsSync(dirPath)) { 145 | return this.emit('warn', 'test directory already exists') 146 | } 147 | 148 | fs.mkdirSync(dirPath) 149 | this.emit('create', 'test/') 150 | } 151 | 152 | module.exports = ModuleInit 153 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "module-init", 3 | "description": "Create a new node module with all the right stuff.", 4 | "version": "1.5.0", 5 | "author": "Nate Goldman ", 6 | "bin": { 7 | "module-init": "./bin/cli.js" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/ungoldman/module-init/issues" 11 | }, 12 | "dependencies": { 13 | "async": "^0.9.0", 14 | "camel-case": "^1.1.1", 15 | "chalk": "^1.0.0", 16 | "cliclopts": "^1.1.0", 17 | "fixpack": "^2.2.0", 18 | "git-config": "0.0.6", 19 | "inquirer": "^0.8.2", 20 | "minimist": "^1.1.1", 21 | "mkdirp": "^0.5.1", 22 | "mustache": "^2.1.3", 23 | "shelljs": "^0.4.0" 24 | }, 25 | "devDependencies": { 26 | "gh-pages": "^0.11.0", 27 | "live-server": "^1.1.0", 28 | "npm-run-all": "^3.1.0", 29 | "rimraf": "^2.4.2", 30 | "sitedown": "^3.1.0", 31 | "snazzy": "^5.0.0", 32 | "standard": "^6.0.0", 33 | "tap-spec": "^4.0.2", 34 | "tape": "^4.0.0", 35 | "win-spawn": "^2.0.0" 36 | }, 37 | "homepage": "https://github.com/ungoldman/module-init", 38 | "keywords": [ 39 | "automate", 40 | "automation", 41 | "create", 42 | "creation", 43 | "init", 44 | "module", 45 | "package" 46 | ], 47 | "license": "ISC", 48 | "main": "index.js", 49 | "repository": { 50 | "type": "git", 51 | "url": "git+https://github.com/ungoldman/module-init.git" 52 | }, 53 | "scripts": { 54 | "gh-pages": "npm run site && gh-pages -d site", 55 | "pretest": "standard | snazzy", 56 | "serve:site": "live-server site", 57 | "serve:watch": "npm run site:html -- -w", 58 | "site": "run-s site:*", 59 | "site:clean": "rm -rf site", 60 | "site:html": "sitedown -b site -l docs/layout.html", 61 | "start": "npm-run-all site --parallel serve:*", 62 | "test": "tape test/*.js | tap-spec" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /templates/.gitignore.mustache: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /templates/.travis.yml.mustache: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4' 4 | - '6' 5 | cache: 6 | directories: 7 | - node_modules 8 | -------------------------------------------------------------------------------- /templates/CHANGELOG.md.mustache: -------------------------------------------------------------------------------- 1 | # {{pkgName}} change log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## Unreleased 9 | 10 | * engage 11 | -------------------------------------------------------------------------------- /templates/CONTRIBUTING.md.mustache: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Contributions welcome! 4 | 5 | **Before spending lots of time on something, ask for feedback on your idea first!** 6 | 7 | Please search issues and pull requests before adding something new to avoid duplicating efforts and conversations. 8 | 9 | This project welcomes non-code contributions, too! The following types of contributions are welcome: 10 | 11 | - **Ideas**: participate in an issue thread or start your own to have your voice heard. 12 | - **Writing**: contribute your expertise in an area by helping expand the included content. 13 | - **Copy editing**: fix typos, clarify language, and generally improve the quality of the content. 14 | - **Formatting**: help keep content easy to read with consistent formatting. 15 | 16 | ## Code Style 17 | 18 | [![{{pkgLinter}}][{{pkgLinter}}-image]][{{pkgLinter}}-url] 19 | 20 | This repository uses [`{{pkgLinter}}`][{{pkgLinter}}-url] to maintain code style and consistency and avoid style arguments. `npm test` runs `{{pkgLinter}}` so you don't have to! 21 | 22 | [standard-image]: https://cdn.rawgit.com/feross/standard/master/badge.svg 23 | [standard-url]: https://github.com/feross/standard 24 | [semistandard-image]: https://cdn.rawgit.com/flet/semistandard/master/badge.svg 25 | [semistandard-url]: https://github.com/Flet/semistandard 26 | 27 | # Project Governance 28 | 29 | **This is an [OPEN Open Source Project](http://openopensource.org/).** 30 | 31 | Individuals making significant and valuable contributions are given commit access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project. 32 | 33 | ## Rules 34 | 35 | There are a few basic ground rules for collaborators: 36 | 37 | 1. **No `--force` pushes** or modifying the Git history in any way. 38 | 1. **Non-master branches** ought to be used for ongoing work. 39 | 1. **External API changes and significant modifications** ought to be subject to an **internal pull request** to solicit feedback from other contributors. 40 | 1. Internal pull requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor. 41 | 1. Contributors should attempt to adhere to the prevailing code style. 42 | 43 | ## Releases 44 | 45 | Declaring formal releases remains the prerogative of the project maintainer. 46 | 47 | ## Changes to this arrangement 48 | 49 | This is an experiment and feedback is welcome! This document may also be subject to pull requests or changes by contributors where you believe you have something valuable to add or change. 50 | -------------------------------------------------------------------------------- /templates/LICENSE.md/Apache-2.0.mustache: -------------------------------------------------------------------------------- 1 | # [Apache License 2.0](https://spdx.org/licenses/Apache-2.0) 2 | 3 | Copyright {{year}} {{usrName}} <{{usrEmail}}> 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | > http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /templates/LICENSE.md/BSD-3-Clause.mustache: -------------------------------------------------------------------------------- 1 | # [BSD 3-clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause) 2 | 3 | Copyright (c) {{year}}, {{usrName}} <{{usrEmail}}>. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 10 | 11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /templates/LICENSE.md/CC0-1.0.mustache: -------------------------------------------------------------------------------- 1 | # [Creative Commons Zero v1.0 Universal](https://spdx.org/licenses/CC0-1.0) 2 | 3 | ## Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). 6 | 7 | Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. 8 | 9 | For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 10 | 11 | ## 1. Copyright and Related Rights. 12 | 13 | A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: 14 | 15 | - i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; 16 | - ii. moral rights retained by the original author(s) and/or performer(s); 17 | - iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; 18 | - iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; 19 | - v. rights protecting the extraction, dissemination, use and reuse of data in a Work; 20 | - vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and 21 | - vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 22 | 23 | ## 2. Waiver. 24 | 25 | To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 26 | 27 | ## 3. Public License Fallback. 28 | 29 | Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 30 | 31 | ## 4. Limitations and Disclaimers. 32 | 33 | - a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. 34 | - b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. 35 | - c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. 36 | - d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. 37 | -------------------------------------------------------------------------------- /templates/LICENSE.md/ISC.mustache: -------------------------------------------------------------------------------- 1 | # [ISC License](https://spdx.org/licenses/ISC) 2 | 3 | Copyright (c) {{year}}, {{usrName}} <{{usrEmail}}> 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 8 | -------------------------------------------------------------------------------- /templates/LICENSE.md/MIT.mustache: -------------------------------------------------------------------------------- 1 | # [MIT License](https://spdx.org/licenses/MIT) 2 | 3 | Copyright (c) {{year}} {{usrName}} <{{usrEmail}}> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /templates/LICENSE.md/UNLICENSED.mustache: -------------------------------------------------------------------------------- 1 | # UNLICENSED 2 | 3 | No licensing terms. This is a private module. 4 | -------------------------------------------------------------------------------- /templates/README.md.mustache: -------------------------------------------------------------------------------- 1 | # {{pkgName}} 2 | 3 | {{#pkgDescription}} 4 | {{pkgDescription}} 5 | 6 | {{/pkgDescription}} 7 | [![npm][npm-image]][npm-url] 8 | [![travis][travis-image]][travis-url] 9 | [![standard][standard-image]][standard-url] 10 | 11 | [npm-image]: https://img.shields.io/npm/v/{{pkgName}}.svg?style=flat-square 12 | [npm-url]: https://www.npmjs.com/package/{{pkgName}} 13 | [travis-image]: https://img.shields.io/travis/{{usrGithub}}/{{pkgName}}.svg?style=flat-square 14 | [travis-url]: https://travis-ci.org/{{usrGithub}}/{{pkgName}} 15 | [standard-image]: https://img.shields.io/badge/code%20style-{{pkgLinter}}-brightgreen.svg?style=flat-square 16 | [standard-url]: http://npm.im/{{pkgLinter}} 17 | 18 | ## Install 19 | 20 | ``` 21 | npm install {{pkgName}} 22 | ``` 23 | 24 | ## Usage 25 | 26 | ```js 27 | var {{nodeName}} = require('{{pkgName}}') 28 | ``` 29 | 30 | {{#pkgContributing}} 31 | ## Contributing 32 | 33 | Contributions welcome! Please read the [contributing guidelines](CONTRIBUTING.md) first. 34 | 35 | {{/pkgContributing}} 36 | ## License 37 | 38 | [{{pkgLicense}}](LICENSE.md) 39 | -------------------------------------------------------------------------------- /templates/index.js: -------------------------------------------------------------------------------- 1 | var mustache = require('mustache') 2 | var path = require('path') 3 | var fs = require('fs') 4 | 5 | function getTemplate (tpl) { 6 | var template = function (data) { 7 | var filename = tpl.file 8 | var filePath 9 | 10 | switch (filename) { 11 | case 'LICENSE.md': 12 | filePath = path.join(__dirname, filename, data.pkgLicense + '.mustache') 13 | break 14 | case 'test/index.js': 15 | filePath = path.join(__dirname, filename, data.pkgLinter + '.mustache') 16 | break 17 | default: 18 | filePath = path.join(__dirname, filename + '.mustache') 19 | } 20 | 21 | var fileContent = fs.readFileSync(filePath, 'utf8') 22 | return mustache.render(fileContent, data) 23 | } 24 | 25 | tpl.template = template 26 | return tpl 27 | } 28 | 29 | module.exports = [ 30 | { 31 | file: '.gitignore', 32 | name: 'pkgGitignore' 33 | }, 34 | { 35 | file: '.travis.yml', 36 | name: 'pkgTravis' 37 | }, 38 | { 39 | file: 'CHANGELOG.md', 40 | name: 'pkgChangelog' 41 | }, 42 | { 43 | file: 'CONTRIBUTING.md', 44 | name: 'pkgContributing' 45 | }, 46 | { 47 | file: 'LICENSE.md', 48 | name: 'pkgLicense' 49 | }, 50 | { 51 | file: 'README.md', 52 | name: 'pkgReadme' 53 | }, 54 | { 55 | file: 'package.json', 56 | name: 'pkgJson' 57 | }, 58 | { 59 | file: 'test/index.js', 60 | name: 'pkgLinter' 61 | } 62 | ].map(getTemplate) 63 | -------------------------------------------------------------------------------- /templates/package.json.mustache: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{pkgName}}", 3 | "description": "{{pkgDescription}}", 4 | "version": "{{pkgVersion}}", 5 | "author": "{{usrName}} <{{usrEmail}}>", 6 | "bugs": { 7 | "url": "https://github.com/{{usrGithub}}/{{pkgName}}/issues" 8 | }, 9 | "devDependencies": { 10 | "{{pkgLinter}}": "*", 11 | "tap-spec": "^4.0.2", 12 | "tape": "^4.0.0" 13 | }, 14 | "homepage": "https://github.com/{{usrGithub}}/{{pkgName}}", 15 | "license": "{{pkgLicense}}", 16 | "keywords": [{{{pkgKeywords}}}], 17 | "main": "index.js", 18 | {{#private}}"private": true,{{/private}} 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/{{usrGithub}}/{{pkgName}}.git" 22 | }, 23 | "scripts": { 24 | "test": "{{pkgLinter}} && tape test/*.js | tap-spec" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /templates/test/index.js/semistandard.mustache: -------------------------------------------------------------------------------- 1 | var test = require('tape'); 2 | 3 | test('Example Test', function (t) { 4 | t.plan(1); 5 | t.error('No tests defined.'); 6 | }); 7 | -------------------------------------------------------------------------------- /templates/test/index.js/standard.mustache: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | 3 | test('Example Test', function (t) { 4 | t.plan(1) 5 | t.error('No tests defined.') 6 | }) 7 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var moduleInit = require('..') 2 | var test = require('tape') 3 | var rimraf = require('rimraf') 4 | var spawn = require('win-spawn') 5 | var fs = require('fs') 6 | var path = require('path') 7 | var util = require('util') 8 | 9 | var d = Date.now() 10 | var testData = { 11 | pkgName: util.format('tmp-%s', d), 12 | pkgDescription: 'desc', 13 | pkgLicense: 'ISC', 14 | pkgContributing: true, 15 | pkgKeywords: '"hello", "world"', 16 | pkgLinter: 'standard', 17 | usrName: 'BOB', 18 | usrEmail: 'BOB@hotmail.com', 19 | usrGithub: 'BOB', 20 | usrNpm: 'BOB', 21 | dir: 'test/' + util.format('tmp-%s', d), 22 | gitInit: false, 23 | npmInstall: false 24 | } 25 | var badData = { 26 | pkgName: util.format('tmp-%s', d), 27 | pkgDescription: 'desc', 28 | pkgLicense: 'klaatu', 29 | pkgContributing: 'niktu', 30 | pkgLinter: 'barada', 31 | usrName: 'BOB', 32 | usrEmail: 'BOB@hotmail.com', 33 | usrGithub: 'BOB', 34 | usrNpm: 'BOB', 35 | dir: 'test/dummy-module' 36 | } 37 | 38 | test('emit err on missing option', function (t) { 39 | t.plan(1) 40 | 41 | var required = moduleInit.OPTIONS.required.join(', ') 42 | 43 | moduleInit() 44 | .on('err', function (err) { 45 | var match = err.message.match('missing required options: ' + required) 46 | t.ok(match, 'returned missing required options: ' + required) 47 | t.end() 48 | }) 49 | .run() 50 | }) 51 | 52 | test('emit err on invalid option', function (t) { 53 | t.plan(1) 54 | 55 | var invalid = Object.keys(moduleInit.OPTIONS.valid).join(', ') 56 | 57 | moduleInit(badData) 58 | .on('err', function (err) { 59 | var match = err.message.match('invalid options: ' + invalid) 60 | t.ok(match, 'returned invalid options: ' + invalid) 61 | t.end() 62 | }) 63 | .run() 64 | }) 65 | 66 | test('create things as expected', function (t) { 67 | moduleInit(testData) 68 | .on('create', function (file) { 69 | // file created 70 | console.log(file + ' created') 71 | }) 72 | .on('warn', function (msg) { 73 | console.log(msg) 74 | }) 75 | .on('err', function (err) { 76 | t.error(err, 'did not error') 77 | }) 78 | .on('done', function (res) { 79 | var file = path.resolve(testData.dir, 'package.json') 80 | var exists = fs.existsSync(file) 81 | var pkgJson = require(file) 82 | 83 | t.ok(exists, 'package.json exists') 84 | t.deepEquals(pkgJson.keywords, ['hello', 'world'], 'keywords in package.json are correct') 85 | t.ok(res, 'got response') 86 | t.ok(exists, 'directory exists') 87 | rimraf.sync(testData.dir) 88 | t.end() 89 | }) 90 | .run() 91 | }) 92 | 93 | // CLI tests work fine locally but cause issues with travis since they require a .gitconfig. 94 | // disabling them for now. 95 | 96 | test.skip('CLI --version flag works correctly', function (t) { 97 | var version = spawn(path.join(__dirname, '../bin/cli.js'), ['--version'], {stdio: 'inherit'}) 98 | 99 | version.on('close', function (code) { 100 | t.equals(code, 0, 'should return error code 0 (success)') 101 | t.end() 102 | }) 103 | }) 104 | 105 | test.skip('CLI --dir flag works correctly', function (t) { 106 | var testDir = 'test/' + util.format('tmp-%s/abc/xyz', d) 107 | var dir = spawn(path.join(__dirname, '../bin/cli.js'), ['-d', testDir, '-f'], {stdio: 'inherit'}) 108 | 109 | dir.on('close', function (code) { 110 | t.equals(code, 0, 'should return error code 0 (success)') 111 | var file = path.resolve(testDir, 'package.json') 112 | var exists = fs.existsSync(file) 113 | t.ok(exists, 'directory exists') 114 | rimraf.sync(testData.dir) 115 | t.end() 116 | }) 117 | }) 118 | --------------------------------------------------------------------------------