├── .npmignore ├── .travis.yml ├── .gitignore ├── welcome.jpg ├── pseudo_test.js ├── replaced_test.js ├── empty.json ├── package.json ├── cmd.js ├── index.js ├── README.md └── test.js /.npmignore: -------------------------------------------------------------------------------- 1 | www 2 | welcome.jpg 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .DS_Store 3 | /www/bundle.js 4 | npm-debug.log -------------------------------------------------------------------------------- /welcome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coleww/npm-add-script/HEAD/welcome.jpg -------------------------------------------------------------------------------- /pseudo_test.js: -------------------------------------------------------------------------------- 1 | var tap = require('tap') 2 | 3 | tap.test('pseudo test', function (t) { 4 | t.ok(true) 5 | t.end() 6 | }) 7 | -------------------------------------------------------------------------------- /replaced_test.js: -------------------------------------------------------------------------------- 1 | var tap = require('tap') 2 | 3 | tap.test('replaced test', function (t) { 4 | t.ok(true) 5 | t.end() 6 | }) 7 | -------------------------------------------------------------------------------- /empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-add-script", 3 | "description": "Programmatically add entries to yr package.json scripts", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "tap": "^1.3.2", 8 | "standard": "4.5.4" 9 | }, 10 | "license": "MIT", 11 | "keywords": [ 12 | "npm", 13 | "add", 14 | "script" 15 | ], 16 | "author": "Cole Willsea (http://colewillsea.com/)" 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "npm-add-script", 3 | "description": "Programmatically add entries to yr package.json scripts!", 4 | "version": "1.0.4", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "standard && node test.js" 8 | }, 9 | "devDependencies": { 10 | "tap": "^1.3.2", 11 | "standard": "4.5.4" 12 | }, 13 | "license": "MIT", 14 | "keywords": [ 15 | "npm", 16 | "add", 17 | "script" 18 | ], 19 | "bin": { 20 | "npmAddScript": "cmd.js" 21 | }, 22 | "author": "Cole Willsea (http://colewillsea.com/)", 23 | "dependencies": { 24 | "jsonfile": "^2.2.1", 25 | "yargs": "^3.19.0" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/coleww/npm-add-script.git" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/coleww/npm-add-script/issues" 33 | }, 34 | "homepage": "https://github.com/coleww/npm-add-script" 35 | } 36 | -------------------------------------------------------------------------------- /cmd.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var npmAddScript = require('./') 4 | 5 | var argv = require('yargs') 6 | .alias('h', 'help') 7 | .help('help') 8 | .usage('--~~===////|||||NPM-ADD-SCRIPT|||||\\\\\\\\\\===~~--\n - add scripts to yr package.json\'s!') 9 | .example('npmAddScript -k test -v "node test.js"') 10 | .alias('k', 'key') 11 | .alias('v', 'value') 12 | .boolean('f') 13 | .alias('f', 'force') 14 | .describe('k', 'the name of your script') 15 | .describe('v', 'your script') 16 | .describe('f', 'force overwrite if script key already exists') 17 | .demand('k') 18 | .demand('v') 19 | .argv 20 | 21 | try { 22 | npmAddScript({key: argv.k, value: argv.v, force: argv.f}) 23 | process.stdout.write('ADDED ' + argv.k + ' TO YOUR PACKAGE dot JASON') 24 | process.stdout.write('\n') 25 | process.exit() 26 | } catch (e) { 27 | process.stdout.write('Encounted a wild ' + e.name + '!!!\nThis error is carrying a note that reads as follows:\n------------\n' + e.message) 28 | process.stdout.write('\n') 29 | process.exit(1) 30 | } 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var jsonfile = require('jsonfile') 2 | 3 | function ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError (name) { 4 | this.name = 'ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError' 5 | this.message = 'My friend:\n it seems as though the script entry you have specified,\n "' + name + '"\n is already present in the package.json file,\n of your current working directory.\n Please try again,\n or amend this egregious error.\nThank You.' 6 | } 7 | 8 | ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError.prototype = new Error() 9 | ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError.prototype.constructor = ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError 10 | 11 | function YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error (name) { 12 | this.name = 'YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error' 13 | this.message = 'My friend:\n it seems as though your current working directory\n does not contain a package.json file,\n and is therefore not a Node.js project.\n Please run npm init,\n in order to amend this tremendous violation.\nThank You.' 14 | } 15 | 16 | YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error.prototype = new Error() 17 | YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error.prototype.constructor = YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error 18 | 19 | module.exports = function (script) { 20 | try { 21 | var packaged = jsonfile.readFileSync('package.json') 22 | if (!packaged.scripts) packaged.scripts = {} 23 | if (!script.force && packaged.scripts[script.key]) { 24 | throw new ThatScriptsEntryAlreadyExistsThereInThePackageDotJsonMyFriendError(script.key) 25 | } 26 | packaged.scripts[script.key] = script.value 27 | jsonfile.writeFileSync('package.json', packaged, {spaces: 2}) 28 | } catch (e) { 29 | if (e.message === 'ENOENT, no such file or directory \'package.json\'') { 30 | throw new YouDoNotAppearToBeInANodeProjectPerhapsUShouldRun_npm_init_error() 31 | } else { 32 | throw e 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | npm-add-script 2 | ---------------- 3 | 4 | programmatically add `scripts` entries to yr package.json file. 5 | 6 | [![NPM](https://nodei.co/npm/npm-add-script.png)](https://nodei.co/npm/npm-add-script/) 7 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) 8 | [![Build Status](https://secure.travis-ci.org/coleww/npm-add-script.png)](http://travis-ci.org/coleww/npm-add-script) 9 | 10 | OK SO you can use `--save` or `--save-dev` to download modules and save them to yr package.json. But what if you are building a tool that generates stuff for projects and you need to be able to insert a brand new script into an existing thing? Or what if you want to just add a script entry at the command line because you've already been running and re-running the same convoluted test command for hours?!?! 11 | 12 | NPM-ADD-SCRIPT IS HERE. 13 | 14 | ![hello](welcome.jpg) 15 | 16 | ### CLI 17 | 18 | To use as a cli tool, just install it globally! This is most probably what you want if you just want command line manipulation of scripts entries. 19 | 20 | `npm install -g npm-add-script` 21 | 22 | ``` 23 | --~~===////|||||NPM-ADD-SCRIPT|||||\\\\\===~~-- 24 | - add scripts to yr package.json's! 25 | 26 | Options: 27 | -k, --key the name of your script [required] 28 | -v, --value your script [required] 29 | -h, --help Show help [boolean] 30 | -f, --force Override existing script entry [boolean] 31 | 32 | Examples: 33 | npmAddScript -k test -v "node test.js" 34 | npmAddScript -k test -v "node test2.js" -f 35 | ``` 36 | 37 | 38 | ### API 39 | 40 | If you're making some sort of project scaffolding tool or test library or i don't know what you can also call this from node. For example, maybe your library requires a convoluted series of manuevers to work properly, you could automagically add those commands as a scripts entry! 41 | 42 | ```javascript 43 | var npmAddScript = require('npm-add-script') 44 | // do some stuff related to yr special snowflake of a node module 45 | npmAddScript({key: "specialSnowFlake" , value: "node special_snowflake.js"}) 46 | npmAddScript({key: "specialSnowFlake" , value: "node specialer_snowflake.js" , force: true}) 47 | ``` 48 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var tap = require('tap') 2 | var fs = require('fs') 3 | var exec = require('child_process').exec 4 | 5 | var npmAddScript = require('./') 6 | 7 | // THESE //T/W/O// THREE TESTS DO NOT LIKE EACH OTHER, NOT ONE BIT I TELL YOOOOOOO 8 | 9 | var funkies = [testWithExistingScriptsEntry, testWithNoScriptsEntry, testWithAScriptsClash, testWithAScriptsClashUsingForce, testWithnoPackage] // this is officially convoluted 10 | 11 | function testIt () { 12 | if (funkies.length) funkies.pop()(testIt, function () {}) 13 | } 14 | 15 | testIt() 16 | 17 | function testWithExistingScriptsEntry (cb, err) { 18 | tap.test('does the thing with existing script', function (t) { 19 | t.plan(2) 20 | 21 | fs.writeFileSync('SAFEpackage.json', fs.readFileSync('package.json')) 22 | 23 | try { 24 | npmAddScript({key: 'testy', value: 'node pseudo_test.js'}) 25 | t.ok(fs.readFileSync('package.json').toString().match('"testy": "node pseudo_test.js"'), 'adds the stuff') 26 | exec('npm run testy', function (error, stdout, stderr) { 27 | t.ok(!error, 'runs the added script') 28 | fs.unlinkSync('package.json') 29 | fs.renameSync('SAFEpackage.json', 'package.json') 30 | cb() 31 | }) 32 | } catch (e) { 33 | fs.unlinkSync('package.json') 34 | fs.renameSync('SAFEpackage.json', 'package.json') 35 | err() 36 | } 37 | }) 38 | } 39 | 40 | function testWithNoScriptsEntry (cb, err) { 41 | tap.test('does the thing with no scripts', function (t) { 42 | t.plan(2) 43 | 44 | fs.writeFileSync('superSAFEpackage.json', fs.readFileSync('package.json')) 45 | fs.unlinkSync('package.json') 46 | fs.writeFileSync('package.json', fs.readFileSync('empty.json')) 47 | 48 | try { 49 | npmAddScript({key: 'testy', value: 'node pseudo_test.js'}) 50 | 51 | t.ok(fs.readFileSync('package.json').toString().match('"testy": "node pseudo_test.js"'), 'adds the stuff') 52 | 53 | exec('npm run testy', function (error, stdout, stderr) { 54 | t.ok(!error, 'runs the added script') 55 | fs.unlinkSync('package.json') 56 | fs.renameSync('superSAFEpackage.json', 'package.json') 57 | cb() 58 | }) 59 | } catch (e) { 60 | 61 | fs.unlinkSync('package.json') 62 | fs.renameSync('superSAFEpackage.json', 'package.json') 63 | err() 64 | } 65 | }) 66 | } 67 | 68 | function testWithAScriptsClash (cb, err) { 69 | tap.test('does the thing with duplicate scripts', function (t) { 70 | t.plan(1) 71 | 72 | fs.writeFileSync('superDuperSAFEpackage.json', fs.readFileSync('package.json')) 73 | try { 74 | npmAddScript({key: 'test', value: 'node pseudo_test.js'}) 75 | err() 76 | } catch (e) { 77 | t.ok(fs.readFileSync('package.json').toString().match('"test": "standard && node test.js"'), 'does not override the old stuff, instead it throws an error') 78 | fs.unlinkSync('package.json') 79 | fs.renameSync('superDuperSAFEpackage.json', 'package.json') 80 | cb() 81 | } 82 | }) 83 | } 84 | 85 | function testWithAScriptsClashUsingForce (cb, err) { 86 | tap.test('using --force, replaces an existing script', function (t) { 87 | t.plan(2) 88 | 89 | fs.writeFileSync('SAFEpackage.json', fs.readFileSync('package.json')) 90 | 91 | try { 92 | npmAddScript({key: 'test', value: 'node replaced_test.js', force: true}) 93 | t.ok(fs.readFileSync('package.json').toString().match('"test": "node replaced_test.js"'), 'adds the stuff') 94 | exec('npm run test', function (error, stdout, stderr) { 95 | t.ok(!error, 'runs the added script') 96 | fs.unlinkSync('package.json') 97 | fs.renameSync('SAFEpackage.json', 'package.json') 98 | cb() 99 | }) 100 | } catch (e) { 101 | fs.unlinkSync('package.json') 102 | fs.renameSync('SAFEpackage.json', 'package.json') 103 | err() 104 | } 105 | }) 106 | } 107 | 108 | function testWithnoPackage (cb, err) { 109 | tap.test('does the thing with no package', function (t) { 110 | t.plan(1) 111 | 112 | fs.writeFileSync('superDuperSAFEpackage.json', fs.readFileSync('package.json')) 113 | fs.unlinkSync('package.json') 114 | try { 115 | npmAddScript({key: 'test', value: 'node pseudo_test.js'}) 116 | err() 117 | } catch (e) { 118 | t.ok(true, 'throws a helpful error if no package.json exists') 119 | fs.renameSync('superDuperSAFEpackage.json', 'package.json') 120 | cb() 121 | } 122 | }) 123 | } 124 | --------------------------------------------------------------------------------