├── .gitignore ├── .npmignore ├── test ├── some-module │ ├── default.json │ ├── expected.json │ └── package.json ├── tape-test.json ├── no-test.json ├── empty-scripts.json ├── node-test.json ├── default-test.json └── index.js ├── bin └── cmd.js ├── LICENSE.md ├── package.json ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | *.log 4 | .DS_Store 5 | bundle.js 6 | test 7 | test.js 8 | demo/ 9 | .npmignore 10 | LICENSE.md -------------------------------------------------------------------------------- /test/some-module/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "some-module", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Matt DesLauriers ", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /test/some-module/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "some-module", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "standard" 8 | }, 9 | "author": "Matt DesLauriers ", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "standard": "^5.4.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/some-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "some-module", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "standard" 8 | }, 9 | "author": "Matt DesLauriers ", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "standard": "^5.4.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /bin/cmd.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var argv = require('minimist')(process.argv.slice(2), { 3 | boolean: [ 'silent', 'snazzy', 'semi' ] 4 | }) 5 | var color = require('term-color') 6 | 7 | require('../')({ 8 | verbose: !argv.silent, 9 | snazzy: argv.snazzy, 10 | semi: argv.semi 11 | }, function (err) { 12 | if (err) { 13 | console.error(color.red('ERROR:'), err.message) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /test/tape-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "tape test.js" 8 | }, 9 | "devDependencies": { 10 | "faucet": "0.0.1", 11 | "snazzy": "^1.0.3", 12 | "standard": "^4.5.4", 13 | "tape": "^4.0.1" 14 | }, 15 | "author": "Matt DesLauriers ", 16 | "license": "ISC" 17 | } -------------------------------------------------------------------------------- /test/no-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "hello world", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "faucet": "0.0.1", 8 | "snazzy": "^1.0.3", 9 | "standard": "^4.5.4", 10 | "tape": "^4.0.1" 11 | }, 12 | "keywords": [ 13 | "foo", 14 | "bar", 15 | "baz" 16 | ], 17 | "author": "Matt DesLauriers ", 18 | "license": "ISC" 19 | } 20 | -------------------------------------------------------------------------------- /test/empty-scripts.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "hello world", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "" 8 | }, 9 | "devDependencies": { 10 | "faucet": "0.0.1", 11 | "snazzy": "^1.0.3", 12 | "standard": "^4.5.4", 13 | "tape": "^4.0.1" 14 | }, 15 | "keywords": [ 16 | "foo", 17 | "bar", 18 | "baz" 19 | ], 20 | "author": "Matt DesLauriers ", 21 | "license": "ISC" 22 | } 23 | -------------------------------------------------------------------------------- /test/node-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "hello world", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js" 8 | }, 9 | "devDependencies": { 10 | "faucet": "0.0.1", 11 | "snazzy": "^1.0.3", 12 | "standard": "^4.5.4", 13 | "tape": "^4.0.1" 14 | }, 15 | "keywords": [ 16 | "foo", 17 | "bar", 18 | "baz" 19 | ], 20 | "author": "Matt DesLauriers ", 21 | "license": "ISC" 22 | } 23 | -------------------------------------------------------------------------------- /test/default-test.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "hello world", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "devDependencies": { 10 | "faucet": "0.0.1", 11 | "snazzy": "^1.0.3", 12 | "standard": "^4.5.4", 13 | "tape": "^4.0.1" 14 | }, 15 | "keywords": [ 16 | "foo", 17 | "bar", 18 | "baz" 19 | ], 20 | "author": "Matt DesLauriers ", 21 | "license": "ISC" 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2015 Matt DesLauriers 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "standardize", 3 | "version": "1.2.2", 4 | "description": "sets up standard on a new module", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Matt DesLauriers", 9 | "email": "dave.des@gmail.com", 10 | "url": "https://github.com/mattdesl" 11 | }, 12 | "dependencies": { 13 | "install-if-needed": "^1.0.2", 14 | "minimist": "^1.1.2", 15 | "read-json": "^1.0.0", 16 | "term-color": "^1.0.1" 17 | }, 18 | "devDependencies": { 19 | "faucet": "0.0.1", 20 | "object-assign": "^3.0.0", 21 | "proxyquire": "^1.6.0", 22 | "snazzy": "^1.0.3", 23 | "tape": "^4.0.1" 24 | }, 25 | "scripts": { 26 | "test": "snazzy && node test/index.js | faucet" 27 | }, 28 | "keywords": [ 29 | "standard", 30 | "module", 31 | "package", 32 | "json", 33 | "package.json", 34 | "install", 35 | "auto", 36 | "stub", 37 | "script", 38 | "bin", 39 | "quick", 40 | "test", 41 | "style", 42 | "styling", 43 | "lint", 44 | "linting", 45 | "lints" 46 | ], 47 | "repository": { 48 | "type": "git", 49 | "url": "git://github.com/mattdesl/standardize.git" 50 | }, 51 | "homepage": "https://github.com/mattdesl/standardize", 52 | "bugs": { 53 | "url": "https://github.com/mattdesl/standardize/issues" 54 | }, 55 | "bin": { 56 | "standardize": "./bin/cmd.js" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var path = require('path') 3 | var proxyquire = require('proxyquire') 4 | var assign = require('object-assign') 5 | var fs = require('fs') 6 | var defaultJson = require('./some-module/default.json') 7 | var expectedJson = require('./some-module/expected.json') 8 | var readJson = require('read-json') 9 | 10 | var fsStub = { 11 | } 12 | 13 | var standardize = proxyquire('../', { 14 | fs: fsStub 15 | }) 16 | 17 | test('applies standard to existing test', run('tape-test.json', 'standard && tape test.js')) 18 | test('applies standard to existing test', run('node-test.json', 'standard && node test.js')) 19 | test('applies standard style to a module', run('no-test.json', 'standard')) 20 | test('applies standard style to a module', run('empty-scripts.json', 'standard')) 21 | test('applies standard style to a module', run('default-test.json', 'standard')) 22 | test('applies standard style to a module', run('default-test.json', 'snazzy', { snazzy: true })) 23 | 24 | test('should apply to module not in cwd', function (t) { 25 | t.plan(1) 26 | 27 | fsStub.writeFile = fs.writeFile.bind(fs) 28 | var pkgJson = path.resolve(__dirname, 'some-module', 'package.json') 29 | // reset json to default 30 | fs.writeFile(pkgJson, JSON.stringify(defaultJson), function (err) { 31 | if (err) t.fail(err) 32 | // run installation etc 33 | standardize({ 34 | cwd: path.resolve(__dirname, 'some-module') 35 | }, function (err) { 36 | if (err) return t.fail(err) 37 | readJson(pkgJson, function (err, data) { 38 | if (err) return t.fail(err) 39 | t.deepEqual(data, expectedJson, 'matches result') 40 | }) 41 | }) 42 | }) 43 | 44 | }) 45 | 46 | function run (file, expectedScript, opt) { 47 | return function (t) { 48 | file = path.resolve(__dirname, file) 49 | t.plan(1) 50 | fsStub.writeFile = function (file, data, cb) { 51 | t.equal(JSON.parse(data).scripts.test, expectedScript) 52 | process.nextTick(cb) 53 | } 54 | standardize(assign({ 55 | package: file 56 | }, opt), function (err) { 57 | if (err) t.fail(err) 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # standardize 2 | 3 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 4 | 5 | Scaffolds [standard](https://github.com/feross/standard) style for a new module. 6 | 7 | - runs `npm install --save-dev standard` 8 | - adds `standard` to your `"scripts"` test 9 | 10 | PRs/suggestions welcome. 11 | 12 | 13 | 14 | ## Install 15 | 16 | ```sh 17 | npm install standardize -g 18 | ``` 19 | 20 | ## Example 21 | 22 | Just run `standardize` on your module directory 23 | 24 | ```sh 25 | standardize 26 | ``` 27 | 28 | It will auto-install `standard` (if it isn't already installed), then add a new script field that looks like: 29 | 30 | ```js 31 | "scripts": { 32 | "test": "standard" 33 | } 34 | ``` 35 | 36 | If the existing script starts with `node` or `tape`, then `standard` will be prefixed like so: 37 | 38 | ```js 39 | "scripts": { 40 | "test": "standard && node test.js" 41 | } 42 | ``` 43 | 44 | You can specify `standardize --snazzy` if you would rather install and use [snazzy](http://npmjs.com/package/snazzy) in your module, for better error reporting. 45 | 46 | ## semistandard 47 | 48 | You can use `standardize --semi` to install `semistandard` instead of `standard`. 49 | 50 | ## Usage 51 | 52 | [![NPM](https://nodei.co/npm/standardize.png)](https://www.npmjs.com/package/standardize) 53 | 54 | ### CLI 55 | 56 | ```sh 57 | Usage: 58 | standardize [opts] 59 | 60 | Options: 61 | --snazzy use a pretty-printer for standard 62 | --silent does not log anything to terminal 63 | 64 | Example: 65 | standardize --snazzy --silent 66 | ``` 67 | 68 | ### API 69 | 70 | #### `standardize([opt], cb)` 71 | 72 | Standardizes the module at `process.cwd()` and calls `cb(err)` when finished. Options: 73 | 74 | - `cwd` the base directory to install from 75 | - `package` the `package.json` path, defaults to `path.join(cwd, 'package.json')` 76 | - `verbose` whether to print install and update information to `stderr` (default false) 77 | 78 | Example: 79 | 80 | ```js 81 | var standardize = require('standardize') 82 | var path = require('path') 83 | 84 | standardize({ 85 | cwd: process.cwd(), 86 | package: path.join(process.cwd(), 'package.json') 87 | }, function (err) { 88 | if (err) throw err 89 | console.log("updated!") 90 | }) 91 | ``` 92 | 93 | ## License 94 | 95 | MIT, see [LICENSE.md](http://github.com/mattdesl/standardize/blob/master/LICENSE.md) for details. 96 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var install = require('install-if-needed') 2 | var path = require('path') 3 | var fs = require('fs') 4 | var readJson = require('read-json') 5 | var color = require('term-color') 6 | var check = '\u2714' 7 | 8 | module.exports = standardize 9 | 10 | function standardize (opt, cb) { 11 | if (typeof opt === 'function') { 12 | cb = opt 13 | opt = {} 14 | } 15 | 16 | var file = opt.package 17 | if (!file) { 18 | var cwd = opt.cwd || process.cwd() 19 | file = path.resolve(cwd, 'package.json') 20 | } 21 | standardizePackage(file, opt, cb) 22 | } 23 | 24 | function standardizePackage (file, opt, cb) { 25 | opt = opt || {} 26 | var verbose = opt.verbose 27 | 28 | var tool = opt.snazzy ? 'snazzy' : 'standard' 29 | if (opt.semi) tool = 'semistandard' 30 | readJson(file, function (err, data) { 31 | if (err) return cb(new Error('could not read JSON at ' + file)) 32 | if (verbose) { 33 | console.error(check, 'updating', color.bold(file)) 34 | } 35 | 36 | rewritePackage(data, file, function (err) { 37 | if (err) return cb(new Error('could not write package at ' + file)) 38 | if (verbose) console.error(check, 'installing', color.bold(tool)) 39 | install({ 40 | cwd: opt.cwd, 41 | devDependencies: [ tool ], 42 | package: data, 43 | save: true, 44 | stdio: verbose ? 'inherit' : undefined 45 | }, function (err) { 46 | if (err) return cb(new Error('error installing ' + tool)) 47 | cb(null) 48 | }) 49 | }) 50 | }) 51 | 52 | function rewritePackage (data, file, cb) { 53 | // only write to file if we changed data 54 | var changed = transform(data) 55 | if (changed) { 56 | var json = JSON.stringify(data, undefined, 2) + '\n' 57 | fs.writeFile(file, json, cb) 58 | } else { 59 | process.nextTick(cb) 60 | } 61 | } 62 | 63 | function transform (pkg) { 64 | var oldTest = pkg.scripts && pkg.scripts.test 65 | 66 | if (!pkg.scripts) { 67 | pkg.scripts = { 68 | test: tool 69 | } 70 | } else if (pkg.scripts.test) { 71 | // handle default npm init 72 | if (pkg.scripts.test === 'echo "Error: no test specified" && exit 1') { 73 | pkg.scripts.test = tool 74 | } else if (/^(node|tape)/.test(pkg.scripts.test)) { 75 | pkg.scripts.test = tool + ' && ' + pkg.scripts.test 76 | } 77 | } else { 78 | pkg.scripts.test = tool 79 | } 80 | var changed = oldTest !== pkg.scripts.test 81 | if (verbose && changed) { 82 | console.error(check, 'updating script:', color.bold(JSON.stringify(pkg.scripts.test))) 83 | } 84 | return changed 85 | } 86 | } 87 | --------------------------------------------------------------------------------