Skip to content

Commit 1305a7c

Browse files
authored
fix: Bump inquirer to v3 and promisify everything (#34)
BREAKING CHANGE: Drop support for Node < v4. This uses native Promises available from Node v4. * fix: Bump inquirer to v3.0.1. Fixes #33 to improve Windows support. * refactor: Promisify everything as inquirer uses Promises from 1.0.0 onwards
1 parent 1e73194 commit 1305a7c

File tree

14 files changed

+164
-193
lines changed

14 files changed

+164
-193
lines changed

cli.js

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,31 @@ var argv = yargs
3939
})
4040
.argv;
4141

42-
function startGeneration(argv, cb) {
43-
argv.files
44-
.map(function (file) {
45-
return path.join(cwd, file);
46-
})
47-
.forEach(function (file) {
48-
util.markdown.read(file, function (error, fileContent) {
49-
if (error) {
50-
return cb(error);
51-
}
42+
function startGeneration(argv) {
43+
return Promise.all(
44+
argv.files.map(file => {
45+
const filePath = path.join(cwd, file);
46+
return util.markdown.read(filePath)
47+
.then(fileContent => {
5248
var newFileContent = generate(argv, argv.contributors, fileContent);
53-
util.markdown.write(file, newFileContent, cb);
49+
return util.markdown.write(filePath, newFileContent);
5450
});
55-
});
51+
})
52+
);
5653
}
5754

58-
function addContribution(argv, cb) {
55+
function addContribution(argv) {
5956
var username = argv._[1];
6057
var contributions = argv._[2];
6158
// Add or update contributor in the config file
62-
updateContributors(argv, username, contributions, function (error, data) {
63-
if (error) {
64-
return onError(error);
65-
}
59+
return updateContributors(argv, username, contributions)
60+
.then(data => {
6661
argv.contributors = data.contributors;
67-
startGeneration(argv, function (error) {
68-
if (error) {
69-
return cb(error);
70-
}
71-
if (!argv.commit) {
72-
return cb();
62+
return startGeneration(argv)
63+
.then(() => {
64+
if (argv.commit) {
65+
return util.git.commit(argv, data);
7366
}
74-
return util.git.commit(argv, data, cb);
7567
});
7668
});
7769
}
@@ -81,10 +73,10 @@ function onError(error) {
8173
console.error(error.message);
8274
process.exit(1);
8375
}
84-
process.exit();
76+
process.exit(0);
8577
}
8678

87-
function promptForCommand(argv, cb) {
79+
function promptForCommand(argv) {
8880
var questions = [{
8981
type: 'list',
9082
name: 'command',
@@ -99,17 +91,24 @@ function promptForCommand(argv, cb) {
9991
when: !argv._[0],
10092
default: 0
10193
}];
102-
inquirer.prompt(questions, function treatAnswers(answers) {
103-
return cb(answers.command || argv._[0]);
94+
95+
return inquirer.prompt(questions)
96+
.then(answers => {
97+
return answers.command || argv._[0];
10498
});
10599
}
106100

107-
promptForCommand(argv, function (command) {
108-
if (command === 'init') {
109-
init(onError);
110-
} else if (command === 'generate') {
111-
startGeneration(argv, onError);
112-
} else if (command === 'add') {
113-
addContribution(argv, onError);
114-
}
115-
});
101+
promptForCommand(argv)
102+
.then(command => {
103+
switch (command) {
104+
case 'init':
105+
return init();
106+
case 'generate':
107+
return startGeneration(argv);
108+
case 'add':
109+
return addContribution(argv);
110+
default:
111+
throw new Error(`Unknown command ${command}`);
112+
}
113+
})
114+
.catch(onError);

lib/contributors/add.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,19 @@ function updateExistingContributor(options, username, contributions) {
3030
});
3131
}
3232

33-
function addNewContributor(options, username, contributions, infoFetcher, cb) {
34-
infoFetcher(username, function (error, userData) {
35-
if (error) {
36-
return cb(error);
37-
}
33+
function addNewContributor(options, username, contributions, infoFetcher) {
34+
return infoFetcher(username)
35+
.then(userData => {
3836
var contributor = _.assign(userData, {
3937
contributions: formatContributions(options, [], contributions)
4038
});
41-
return cb(null, options.contributors.concat(contributor));
39+
return options.contributors.concat(contributor);
4240
});
4341
}
4442

45-
module.exports = function addContributor(options, username, contributions, infoFetcher, cb) {
43+
module.exports = function addContributor(options, username, contributions, infoFetcher) {
4644
if (_.find({login: username}, options.contributors)) {
47-
return cb(null, updateExistingContributor(options, username, contributions));
45+
return Promise.resolve(updateExistingContributor(options, username, contributions));
4846
}
49-
return addNewContributor(options, username, contributions, infoFetcher, cb);
47+
return addNewContributor(options, username, contributions, infoFetcher);
5048
};

lib/contributors/add.test.js

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import test from 'ava';
22
import addContributor from './add';
33

4-
function mockInfoFetcher(username, cb) {
5-
return cb(null, {
4+
function mockInfoFetcher(username) {
5+
return Promise.resolve({
66
login: username,
77
name: 'Some name',
88
avatar_url: 'www.avatar.url',
@@ -34,27 +34,27 @@ function fixtures() {
3434
return {options};
3535
}
3636

37-
test.cb('should callback with error if infoFetcher fails', t => {
37+
test('should callback with error if infoFetcher fails', t => {
3838
const {options} = fixtures();
3939
const username = 'login3';
4040
const contributions = ['doc'];
41-
function infoFetcher(username, cb) {
42-
return cb(new Error('infoFetcher error'));
41+
function infoFetcher() {
42+
return Promise.reject(new Error('infoFetcher error'));
4343
}
4444

45-
return addContributor(options, username, contributions, infoFetcher, function (error) {
46-
t.is(error.message, 'infoFetcher error');
47-
t.end();
48-
});
45+
return t.throws(
46+
addContributor(options, username, contributions, infoFetcher),
47+
'infoFetcher error'
48+
);
4949
});
5050

51-
test.cb('should add new contributor at the end of the list of contributors', t => {
51+
test('should add new contributor at the end of the list of contributors', t => {
5252
const {options} = fixtures();
5353
const username = 'login3';
5454
const contributions = ['doc'];
5555

56-
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) {
57-
t.falsy(error);
56+
return addContributor(options, username, contributions, mockInfoFetcher)
57+
.then(contributors => {
5858
t.is(contributors.length, 3);
5959
t.deepEqual(contributors[2], {
6060
login: 'login3',
@@ -65,18 +65,17 @@ test.cb('should add new contributor at the end of the list of contributors', t =
6565
'doc'
6666
]
6767
});
68-
t.end();
6968
});
7069
});
7170

72-
test.cb('should add new contributor at the end of the list of contributors with a url link', t => {
71+
test('should add new contributor at the end of the list of contributors with a url link', t => {
7372
const {options} = fixtures();
7473
const username = 'login3';
7574
const contributions = ['doc'];
7675
options.url = 'www.foo.bar';
7776

78-
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) {
79-
t.falsy(error);
77+
return addContributor(options, username, contributions, mockInfoFetcher)
78+
.then(contributors => {
8079
t.is(contributors.length, 3);
8180
t.deepEqual(contributors[2], {
8281
login: 'login3',
@@ -87,28 +86,26 @@ test.cb('should add new contributor at the end of the list of contributors with
8786
{type: 'doc', url: 'www.foo.bar'}
8887
]
8988
});
90-
t.end();
9189
});
9290
});
9391

94-
test.cb(`should not update an existing contributor's contributions where nothing has changed`, t => {
92+
test(`should not update an existing contributor's contributions where nothing has changed`, t => {
9593
const {options} = fixtures();
9694
const username = 'login2';
9795
const contributions = ['blog', 'code'];
9896

99-
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) {
100-
t.falsy(error);
97+
return addContributor(options, username, contributions, mockInfoFetcher)
98+
.then(contributors => {
10199
t.deepEqual(contributors, options.contributors);
102-
t.end();
103100
});
104101
});
105102

106-
test.cb(`should update an existing contributor's contributions if a new type is added`, t => {
103+
test(`should update an existing contributor's contributions if a new type is added`, t => {
107104
const {options} = fixtures();
108105
const username = 'login1';
109106
const contributions = ['bug'];
110-
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) {
111-
t.falsy(error);
107+
return addContributor(options, username, contributions, mockInfoFetcher)
108+
.then(contributors => {
112109
t.is(contributors.length, 2);
113110
t.deepEqual(contributors[0], {
114111
login: 'login1',
@@ -120,18 +117,17 @@ test.cb(`should update an existing contributor's contributions if a new type is
120117
'bug'
121118
]
122119
});
123-
t.end();
124120
});
125121
});
126122

127-
test.cb(`should update an existing contributor's contributions if a new type is added with a link`, t => {
123+
test(`should update an existing contributor's contributions if a new type is added with a link`, t => {
128124
const {options} = fixtures();
129125
const username = 'login1';
130126
const contributions = ['bug'];
131127
options.url = 'www.foo.bar';
132128

133-
return addContributor(options, username, contributions, mockInfoFetcher, function (error, contributors) {
134-
t.falsy(error);
129+
return addContributor(options, username, contributions, mockInfoFetcher)
130+
.then(contributors => {
135131
t.is(contributors.length, 2);
136132
t.deepEqual(contributors[0], {
137133
login: 'login1',
@@ -143,6 +139,5 @@ test.cb(`should update an existing contributor's contributions if a new type is
143139
{type: 'bug', url: 'www.foo.bar'}
144140
]
145141
});
146-
t.end();
147142
});
148143
});

lib/contributors/github.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
'use strict';
22

3-
var request = require('request');
3+
var pify = require('pify');
4+
var request = pify(require('request'));
45

5-
module.exports = function getUserInfo(username, cb) {
6-
request.get({
6+
module.exports = function getUserInfo(username) {
7+
return request.get({
78
url: 'https://api.github.com/users/' + username,
89
headers: {
910
'User-Agent': 'request'
1011
}
11-
}, function (error, res) {
12-
if (error) {
13-
return cb(error);
14-
}
12+
})
13+
.then(res => {
1514
var body = JSON.parse(res.body);
16-
var user = {
15+
return {
1716
login: body.login,
1817
name: body.name || username,
1918
avatar_url: body.avatar_url,
2019
profile: body.blog || body.html_url
2120
};
22-
return cb(null, user);
2321
});
2422
};

lib/contributors/github.test.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ import test from 'ava';
22
import nock from 'nock';
33
import getUserInfo from './github';
44

5-
test.cb('should handle errors', t => {
5+
test('should handle errors', t => {
66
nock('https://api.github.com')
77
.get('/users/nodisplayname')
88
.replyWithError(404);
99

10-
getUserInfo('nodisplayname', err => {
11-
t.truthy(err);
12-
t.end();
13-
});
10+
return t.throws(getUserInfo('nodisplayname'));
1411
});
1512

16-
test.cb('should fill in the name when null is returned', t => {
13+
test('should fill in the name when null is returned', t => {
1714
nock('https://api.github.com')
1815
.get('/users/nodisplayname')
1916
.reply(200, {
@@ -23,14 +20,13 @@ test.cb('should fill in the name when null is returned', t => {
2320
html_url: 'https://github.com/nodisplayname'
2421
});
2522

26-
getUserInfo('nodisplayname', (err, info) => {
27-
t.falsy(err);
23+
return getUserInfo('nodisplayname')
24+
.then(info => {
2825
t.is(info.name, 'nodisplayname');
29-
t.end();
3026
});
3127
});
3228

33-
test.cb('should fill in the name when an empty string is returned', t => {
29+
test('should fill in the name when an empty string is returned', t => {
3430
nock('https://api.github.com')
3531
.get('/users/nodisplayname')
3632
.reply(200, {
@@ -40,9 +36,8 @@ test.cb('should fill in the name when an empty string is returned', t => {
4036
html_url: 'https://github.com/nodisplayname'
4137
});
4238

43-
getUserInfo('nodisplayname', (err, info) => {
44-
t.falsy(err);
39+
return getUserInfo('nodisplayname')
40+
.then(info => {
4541
t.is(info.name, 'nodisplayname');
46-
t.end();
4742
});
4843
});

lib/contributors/index.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,24 @@ function isNewContributor(contributorList, username) {
1010
return !_.find({login: username}, contributorList);
1111
}
1212

13-
module.exports = function addContributor(options, username, contributions, cb) {
14-
prompt(options, username, contributions, function (answers) {
15-
add(options, answers.username, answers.contributions, github, function (error, contributors) {
16-
if (error) {
17-
return cb(error);
18-
}
19-
util.configFile.writeContributors(options.config, contributors, function (error) {
20-
return cb(error, {
21-
username: answers.username,
22-
contributions: answers.contributions,
23-
contributors: contributors,
24-
newContributor: isNewContributor(options.contributors, answers.username)
25-
});
26-
});
27-
});
13+
module.exports = function addContributor(options, username, contributions) {
14+
const answersP = prompt(options, username, contributions);
15+
const contributorsP = answersP
16+
.then(answers => add(options, answers.username, answers.contributions, github));
17+
18+
const writeContributorsP = contributorsP.then(
19+
contributors => util.configFile.writeContributors(options.config, contributors)
20+
);
21+
22+
return Promise.all([answersP, contributorsP, writeContributorsP])
23+
.then(res => {
24+
const answers = res[0];
25+
const contributors = res[1];
26+
return {
27+
username: answers.username,
28+
contributions: answers.contributions,
29+
contributors: contributors,
30+
newContributor: isNewContributor(options.contributors, answers.username)
31+
};
2832
});
2933
};

0 commit comments

Comments
 (0)