all-contributors-cli
Advanced tools
Comparing version 3.1.1 to 4.0.0
73
cli.js
@@ -42,35 +42,27 @@ #!/usr/bin/env node | ||
function startGeneration(argv, cb) { | ||
argv.files | ||
.map(function (file) { | ||
return path.join(cwd, file); | ||
}) | ||
.forEach(function (file) { | ||
util.markdown.read(file, function (error, fileContent) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
function startGeneration(argv) { | ||
return Promise.all( | ||
argv.files.map(file => { | ||
const filePath = path.join(cwd, file); | ||
return util.markdown.read(filePath) | ||
.then(fileContent => { | ||
var newFileContent = generate(argv, argv.contributors, fileContent); | ||
util.markdown.write(file, newFileContent, cb); | ||
return util.markdown.write(filePath, newFileContent); | ||
}); | ||
}); | ||
}) | ||
); | ||
} | ||
function addContribution(argv, cb) { | ||
function addContribution(argv) { | ||
var username = argv._[1]; | ||
var contributions = argv._[2]; | ||
// Add or update contributor in the config file | ||
updateContributors(argv, username, contributions, function (error, data) { | ||
if (error) { | ||
return onError(error); | ||
} | ||
return updateContributors(argv, username, contributions) | ||
.then(data => { | ||
argv.contributors = data.contributors; | ||
startGeneration(argv, function (error) { | ||
if (error) { | ||
return cb(error); | ||
return startGeneration(argv) | ||
.then(() => { | ||
if (argv.commit) { | ||
return util.git.commit(argv, data); | ||
} | ||
if (!argv.commit) { | ||
return cb(); | ||
} | ||
return util.git.commit(argv, data, cb); | ||
}); | ||
@@ -85,6 +77,6 @@ }); | ||
} | ||
process.exit(); | ||
process.exit(0); | ||
} | ||
function promptForCommand(argv, cb) { | ||
function promptForCommand(argv) { | ||
var questions = [{ | ||
@@ -104,15 +96,22 @@ type: 'list', | ||
}]; | ||
inquirer.prompt(questions, function treatAnswers(answers) { | ||
return cb(answers.command || argv._[0]); | ||
return inquirer.prompt(questions) | ||
.then(answers => { | ||
return answers.command || argv._[0]; | ||
}); | ||
} | ||
promptForCommand(argv, function (command) { | ||
if (command === 'init') { | ||
init(onError); | ||
} else if (command === 'generate') { | ||
startGeneration(argv, onError); | ||
} else if (command === 'add') { | ||
addContribution(argv, onError); | ||
} | ||
}); | ||
promptForCommand(argv) | ||
.then(command => { | ||
switch (command) { | ||
case 'init': | ||
return init(); | ||
case 'generate': | ||
return startGeneration(argv); | ||
case 'add': | ||
return addContribution(argv); | ||
default: | ||
throw new Error(`Unknown command ${command}`); | ||
} | ||
}) | ||
.catch(onError); |
@@ -33,19 +33,17 @@ 'use strict'; | ||
function addNewContributor(options, username, contributions, infoFetcher, cb) { | ||
infoFetcher(username, function (error, userData) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
function addNewContributor(options, username, contributions, infoFetcher) { | ||
return infoFetcher(username) | ||
.then(userData => { | ||
var contributor = _.assign(userData, { | ||
contributions: formatContributions(options, [], contributions) | ||
}); | ||
return cb(null, options.contributors.concat(contributor)); | ||
return options.contributors.concat(contributor); | ||
}); | ||
} | ||
module.exports = function addContributor(options, username, contributions, infoFetcher, cb) { | ||
module.exports = function addContributor(options, username, contributions, infoFetcher) { | ||
if (_.find({login: username}, options.contributors)) { | ||
return cb(null, updateExistingContributor(options, username, contributions)); | ||
return Promise.resolve(updateExistingContributor(options, username, contributions)); | ||
} | ||
return addNewContributor(options, username, contributions, infoFetcher, cb); | ||
return addNewContributor(options, username, contributions, infoFetcher); | ||
}; |
import test from 'ava'; | ||
import addContributor from './add'; | ||
function mockInfoFetcher(username, cb) { | ||
return cb(null, { | ||
function mockInfoFetcher(username) { | ||
return Promise.resolve({ | ||
login: username, | ||
@@ -37,17 +37,17 @@ name: 'Some name', | ||
test.cb('should callback with error if infoFetcher fails', t => { | ||
test('should callback with error if infoFetcher fails', t => { | ||
const {options} = fixtures(); | ||
const username = 'login3'; | ||
const contributions = ['doc']; | ||
function infoFetcher(username, cb) { | ||
return cb(new Error('infoFetcher error')); | ||
function infoFetcher() { | ||
return Promise.reject(new Error('infoFetcher error')); | ||
} | ||
return addContributor(options, username, contributions, infoFetcher, function (error) { | ||
t.is(error.message, 'infoFetcher error'); | ||
t.end(); | ||
}); | ||
return t.throws( | ||
addContributor(options, username, contributions, infoFetcher), | ||
'infoFetcher error' | ||
); | ||
}); | ||
test.cb('should add new contributor at the end of the list of contributors', t => { | ||
test('should add new contributor at the end of the list of contributors', t => { | ||
const {options} = fixtures(); | ||
@@ -57,4 +57,4 @@ const username = 'login3'; | ||
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) { | ||
t.falsy(error); | ||
return addContributor(options, username, contributions, mockInfoFetcher) | ||
.then(contributors => { | ||
t.is(contributors.length, 3); | ||
@@ -70,7 +70,6 @@ t.deepEqual(contributors[2], { | ||
}); | ||
t.end(); | ||
}); | ||
}); | ||
test.cb('should add new contributor at the end of the list of contributors with a url link', t => { | ||
test('should add new contributor at the end of the list of contributors with a url link', t => { | ||
const {options} = fixtures(); | ||
@@ -81,4 +80,4 @@ const username = 'login3'; | ||
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) { | ||
t.falsy(error); | ||
return addContributor(options, username, contributions, mockInfoFetcher) | ||
.then(contributors => { | ||
t.is(contributors.length, 3); | ||
@@ -94,7 +93,6 @@ t.deepEqual(contributors[2], { | ||
}); | ||
t.end(); | ||
}); | ||
}); | ||
test.cb(`should not update an existing contributor's contributions where nothing has changed`, t => { | ||
test(`should not update an existing contributor's contributions where nothing has changed`, t => { | ||
const {options} = fixtures(); | ||
@@ -104,15 +102,14 @@ const username = 'login2'; | ||
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) { | ||
t.falsy(error); | ||
return addContributor(options, username, contributions, mockInfoFetcher) | ||
.then(contributors => { | ||
t.deepEqual(contributors, options.contributors); | ||
t.end(); | ||
}); | ||
}); | ||
test.cb(`should update an existing contributor's contributions if a new type is added`, t => { | ||
test(`should update an existing contributor's contributions if a new type is added`, t => { | ||
const {options} = fixtures(); | ||
const username = 'login1'; | ||
const contributions = ['bug']; | ||
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) { | ||
t.falsy(error); | ||
return addContributor(options, username, contributions, mockInfoFetcher) | ||
.then(contributors => { | ||
t.is(contributors.length, 2); | ||
@@ -129,7 +126,6 @@ t.deepEqual(contributors[0], { | ||
}); | ||
t.end(); | ||
}); | ||
}); | ||
test.cb(`should update an existing contributor's contributions if a new type is added with a link`, t => { | ||
test(`should update an existing contributor's contributions if a new type is added with a link`, t => { | ||
const {options} = fixtures(); | ||
@@ -140,4 +136,4 @@ const username = 'login1'; | ||
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) { | ||
t.falsy(error); | ||
return addContributor(options, username, contributions, mockInfoFetcher) | ||
.then(contributors => { | ||
t.is(contributors.length, 2); | ||
@@ -154,4 +150,3 @@ t.deepEqual(contributors[0], { | ||
}); | ||
t.end(); | ||
}); | ||
}); |
'use strict'; | ||
var request = require('request'); | ||
var pify = require('pify'); | ||
var request = pify(require('request')); | ||
module.exports = function getUserInfo(username, cb) { | ||
request.get({ | ||
module.exports = function getUserInfo(username) { | ||
return request.get({ | ||
url: 'https://api.github.com/users/' + username, | ||
@@ -11,8 +12,6 @@ headers: { | ||
} | ||
}, function (error, res) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
}) | ||
.then(res => { | ||
var body = JSON.parse(res.body); | ||
var user = { | ||
return { | ||
login: body.login, | ||
@@ -23,4 +22,3 @@ name: body.name || username, | ||
}; | ||
return cb(null, user); | ||
}); | ||
}; |
@@ -5,3 +5,3 @@ import test from 'ava'; | ||
test.cb('should handle errors', t => { | ||
test('should handle errors', t => { | ||
nock('https://api.github.com') | ||
@@ -11,9 +11,6 @@ .get('/users/nodisplayname') | ||
getUserInfo('nodisplayname', err => { | ||
t.truthy(err); | ||
t.end(); | ||
}); | ||
return t.throws(getUserInfo('nodisplayname')); | ||
}); | ||
test.cb('should fill in the name when null is returned', t => { | ||
test('should fill in the name when null is returned', t => { | ||
nock('https://api.github.com') | ||
@@ -28,10 +25,9 @@ .get('/users/nodisplayname') | ||
getUserInfo('nodisplayname', (err, info) => { | ||
t.falsy(err); | ||
return getUserInfo('nodisplayname') | ||
.then(info => { | ||
t.is(info.name, 'nodisplayname'); | ||
t.end(); | ||
}); | ||
}); | ||
test.cb('should fill in the name when an empty string is returned', t => { | ||
test('should fill in the name when an empty string is returned', t => { | ||
nock('https://api.github.com') | ||
@@ -46,7 +42,6 @@ .get('/users/nodisplayname') | ||
getUserInfo('nodisplayname', (err, info) => { | ||
t.falsy(err); | ||
return getUserInfo('nodisplayname') | ||
.then(info => { | ||
t.is(info.name, 'nodisplayname'); | ||
t.end(); | ||
}); | ||
}); |
@@ -13,18 +13,22 @@ 'use strict'; | ||
module.exports = function addContributor(options, username, contributions, cb) { | ||
prompt(options, username, contributions, function (answers) { | ||
add(options, answers.username, answers.contributions, github, function (error, contributors) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
util.configFile.writeContributors(options.config, contributors, function (error) { | ||
return cb(error, { | ||
username: answers.username, | ||
contributions: answers.contributions, | ||
contributors: contributors, | ||
newContributor: isNewContributor(options.contributors, answers.username) | ||
}); | ||
}); | ||
}); | ||
module.exports = function addContributor(options, username, contributions) { | ||
const answersP = prompt(options, username, contributions); | ||
const contributorsP = answersP | ||
.then(answers => add(options, answers.username, answers.contributions, github)); | ||
const writeContributorsP = contributorsP.then( | ||
contributors => util.configFile.writeContributors(options.config, contributors) | ||
); | ||
return Promise.all([answersP, contributorsP, writeContributorsP]) | ||
.then(res => { | ||
const answers = res[0]; | ||
const contributors = res[1]; | ||
return { | ||
username: answers.username, | ||
contributions: answers.contributions, | ||
contributors: contributors, | ||
newContributor: isNewContributor(options.contributors, answers.username) | ||
}; | ||
}); | ||
}; |
@@ -36,3 +36,3 @@ 'use strict'; | ||
module.exports = function prompt(options, username, contributions, cb) { | ||
module.exports = function prompt(options, username, contributions) { | ||
var defaults = { | ||
@@ -43,6 +43,4 @@ username: username, | ||
var questions = getQuestions(options, username, contributions); | ||
inquirer.prompt(questions, _.flow( | ||
_.assign(defaults), | ||
cb | ||
)); | ||
return inquirer.prompt(questions) | ||
.then(_.assign(defaults)); | ||
}; |
'use strict'; | ||
var _ = require('lodash/fp'); | ||
var series = require('async/series'); | ||
var util = require('../util'); | ||
@@ -11,26 +9,18 @@ var prompt = require('./prompt'); | ||
function injectInFile(file, fn, cb) { | ||
markdown.read(file, function (error, content) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
markdown.write(file, fn(content), cb); | ||
}); | ||
function injectInFile(file, fn) { | ||
return markdown.read(file) | ||
.then(content => markdown.write(file, fn(content))); | ||
} | ||
module.exports = function init(callback) { | ||
prompt(function postPrompt(result) { | ||
var tasks = [ | ||
function writeConfig(cb) { | ||
configFile.writeConfig('.all-contributorsrc', result.config, cb); | ||
}, | ||
function addContributorsList(cb) { | ||
injectInFile(result.contributorFile, initContent.addContributorsList, cb); | ||
}, | ||
result.badgeFile && function addBadge(cb) { | ||
injectInFile(result.badgeFile, initContent.addBadge, cb); | ||
} | ||
]; | ||
series(_.compact(tasks), callback); | ||
}); | ||
module.exports = function init() { | ||
return prompt() | ||
.then(result => { | ||
return configFile.writeConfig('.all-contributorsrc', result.config) | ||
.then(() => injectInFile(result.contributorFile, initContent.addContributorsList)) | ||
.then(() => { | ||
if (result.badgeFile) { | ||
return injectInFile(result.badgeFile, initContent.addBadge); | ||
} | ||
}); | ||
}); | ||
}; |
@@ -52,7 +52,5 @@ 'use strict'; | ||
module.exports = function prompt(cb) { | ||
git.getRepoInfo(function (error, repoInfo) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
module.exports = function prompt() { | ||
return git.getRepoInfo() | ||
.then(repoInfo => { | ||
if (repoInfo) { | ||
@@ -62,4 +60,7 @@ questions[0].default = repoInfo.projectName; | ||
} | ||
inquirer.prompt(questions, function treatAnswers(answers) { | ||
var config = { | ||
return inquirer.prompt(questions); | ||
}) | ||
.then(answers => { | ||
return { | ||
config: { | ||
projectName: answers.projectName, | ||
@@ -71,10 +72,7 @@ projectOwner: answers.projectOwner, | ||
contributors: [] | ||
}; | ||
return cb({ | ||
config: config, | ||
contributorFile: answers.contributorFile, | ||
badgeFile: answers.badgeFile | ||
}); | ||
}); | ||
}, | ||
contributorFile: answers.contributorFile, | ||
badgeFile: answers.badgeFile | ||
}; | ||
}); | ||
}; |
'use strict'; | ||
var fs = require('fs'); | ||
var pify = require('pify'); | ||
var _ = require('lodash/fp'); | ||
@@ -17,7 +18,7 @@ | ||
function writeConfig(configPath, content, cb) { | ||
return fs.writeFile(configPath, JSON.stringify(content, null, 2) + '\n', cb); | ||
function writeConfig(configPath, content) { | ||
return pify(fs.writeFile)(configPath, JSON.stringify(content, null, 2) + '\n'); | ||
} | ||
function writeContributors(configPath, contributors, cb) { | ||
function writeContributors(configPath, contributors) { | ||
var config; | ||
@@ -27,6 +28,6 @@ try { | ||
} catch (error) { | ||
return cb(error); | ||
return Promise.reject(error); | ||
} | ||
var content = _.assign(config, {contributors: contributors}); | ||
return writeConfig(configPath, content, cb); | ||
return writeConfig(configPath, content); | ||
} | ||
@@ -33,0 +34,0 @@ |
@@ -8,12 +8,7 @@ import test from 'ava'; | ||
test('Reading an absent configuration file throws a helpful error', t => { | ||
t.throws(() => { | ||
configFile.readConfig(absentFile); | ||
}, expected); | ||
t.throws(() => configFile.readConfig(absentFile), expected); | ||
}); | ||
test.cb('Writing contributors in an absent configuration file throws a helpful error', t => { | ||
configFile.writeContributors(absentFile, [], error => { | ||
t.is(error.message, expected); | ||
t.end(); | ||
}); | ||
test('Writing contributors in an absent configuration file throws a helpful error', t => { | ||
t.throws(configFile.writeContributors(absentFile, []), expected); | ||
}); |
@@ -6,6 +6,7 @@ 'use strict'; | ||
var _ = require('lodash/fp'); | ||
var pify = require('pify'); | ||
var commitTemplate = '<%= (newContributor ? "Add" : "Update") %> @<%= username %> as a contributor'; | ||
function getRemoteOriginData(cb) { | ||
var getRemoteOriginData = pify(cb => { | ||
var output = ''; | ||
@@ -21,3 +22,3 @@ var git = spawn('git', 'config --get remote.origin.url'.split(' ')); | ||
}); | ||
} | ||
}); | ||
@@ -36,29 +37,23 @@ function parse(originUrl) { | ||
function getRepoInfo(cb) { | ||
getRemoteOriginData(function (error, originUrl) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
return cb(null, parse(originUrl)); | ||
}); | ||
function getRepoInfo() { | ||
return getRemoteOriginData() | ||
.then(parse); | ||
} | ||
function spawnGitCommand(args, cb) { | ||
var spawnGitCommand = pify((args, cb) => { | ||
var git = spawn('git', args); | ||
git.stderr.on('data', cb); | ||
git.on('close', cb); | ||
} | ||
}); | ||
function commit(options, data, cb) { | ||
function commit(options, data) { | ||
var files = options.files.concat(options.config); | ||
var absolutePathFiles = files.map(function (file) { | ||
var absolutePathFiles = files.map(file => { | ||
return path.resolve(process.cwd(), file); | ||
}); | ||
spawnGitCommand(['add'].concat(absolutePathFiles), function (error) { | ||
if (error) { | ||
return cb(error); | ||
} | ||
var commitMessage = _.template(options.commitTemplate || commitTemplate)(data); | ||
spawnGitCommand(['commit', '-m', commitMessage], cb); | ||
}); | ||
return spawnGitCommand(['add'].concat(absolutePathFiles)) | ||
.then(() => { | ||
var commitMessage = _.template(options.commitTemplate || commitTemplate)(data); | ||
return spawnGitCommand(['commit', '-m', commitMessage]); | ||
}); | ||
} | ||
@@ -65,0 +60,0 @@ |
'use strict'; | ||
var fs = require('fs'); | ||
var pify = require('pify'); | ||
function read(filePath, cb) { | ||
fs.readFile(filePath, 'utf8', cb); | ||
function read(filePath) { | ||
return pify(fs.readFile)(filePath, 'utf8'); | ||
} | ||
function write(filePath, content, cb) { | ||
fs.writeFile(filePath, content, cb); | ||
function write(filePath, content) { | ||
return pify(fs.writeFile)(filePath, content); | ||
} | ||
@@ -12,0 +13,0 @@ |
{ | ||
"name": "all-contributors-cli", | ||
"version": "3.1.1", | ||
"version": "4.0.0", | ||
"description": "Tool to easily add recognition for new contributors", | ||
@@ -8,2 +8,5 @@ "bin": { | ||
}, | ||
"engines": { | ||
"node": ">=4" | ||
}, | ||
"scripts": { | ||
@@ -29,4 +32,5 @@ "test": "xo && nyc ava", | ||
"async": "^2.0.0-rc.1", | ||
"inquirer": "^0.12.0", | ||
"inquirer": "^3.0.1", | ||
"lodash": "^4.11.2", | ||
"pify": "^2.3.0", | ||
"request": "^2.72.0", | ||
@@ -33,0 +37,0 @@ "yargs": "^4.7.0" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
47920
6
1279
+ Addedpify@^2.3.0
+ Addedansi-escapes@3.2.0(transitive)
+ Addedansi-regex@3.0.1(transitive)
+ Addedansi-styles@3.2.1(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedchardet@0.4.2(transitive)
+ Addedcli-cursor@2.1.0(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addedexternal-editor@2.2.0(transitive)
+ Addedfigures@2.0.0(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addediconv-lite@0.4.24(transitive)
+ Addedinquirer@3.3.0(transitive)
+ Addedis-fullwidth-code-point@2.0.0(transitive)
+ Addedmimic-fn@1.2.0(transitive)
+ Addedmute-stream@0.0.7(transitive)
+ Addedonetime@2.0.1(transitive)
+ Addedos-tmpdir@1.0.2(transitive)
+ Addedrestore-cursor@2.0.0(transitive)
+ Addedrun-async@2.4.1(transitive)
+ Addedrx-lite@4.0.8(transitive)
+ Addedrx-lite-aggregates@4.0.8(transitive)
+ Addedsignal-exit@3.0.7(transitive)
+ Addedstring-width@2.1.1(transitive)
+ Addedstrip-ansi@4.0.0(transitive)
+ Addedsupports-color@5.5.0(transitive)
+ Addedtmp@0.0.33(transitive)
- Removedansi-escapes@1.4.0(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedchalk@1.1.3(transitive)
- Removedcli-cursor@1.0.2(transitive)
- Removedexit-hook@1.1.1(transitive)
- Removedfigures@1.7.0(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedinquirer@0.12.0(transitive)
- Removedmute-stream@0.0.5(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedonce@1.4.0(transitive)
- Removedonetime@1.1.0(transitive)
- Removedreadline2@1.0.1(transitive)
- Removedrestore-cursor@1.0.1(transitive)
- Removedrun-async@0.1.0(transitive)
- Removedrx-lite@3.1.2(transitive)
- Removedsupports-color@2.0.0(transitive)
- Removedwrappy@1.0.2(transitive)
Updatedinquirer@^3.0.1