Add config parsing, and split into plenty of files

This commit is contained in:
Jeroen Engels 2016-02-29 11:45:19 +01:00
parent 46bc072166
commit 4066516ba4
7 changed files with 180 additions and 79 deletions

View file

@ -5,35 +5,49 @@ This is a tool to help automate adding contributor acknowledgements according to
## Usage ## Usage
``` ```
# Add new contributor <username>, who a contribution of type <contribution>
all-contributors <username> <contribution> all-contributors <username> <contribution>
``` ```
Where: Where:
- `username` is the user's GitHub username - `username` is the user's GitHub username
- `contribution` is a ';'-separated list of ways to contribute, from the following list ([see the specs](https://github.com/kentcdodds/all-contributors#emoji-key)): - `contribution` is a ','-separated list of ways to contribute, from the following list ([see the specs](https://github.com/kentcdodds/all-contributors#emoji-key)):
- code: 💻 - code: 💻
- plugin: 🔌 - plugin: 🔌
- tool: 🔧 - tool: 🔧
- doc: 📖 - doc: 📖
- question: ❓ - question: ❓
- test: ⚠️ - test: ⚠️
- bug: 🐛 - bug: 🐛
- example: 💡 - example: 💡
- blog: 📝 - blog: 📝
- tutorial: ✅ - tutorial: ✅
- video: 📹 - video: 📹
- talk: 📢 - talk: 📢
- design: 🎨 - design: 🎨
- review: 👀
## Configuration ## Configuration
You can configure the project by creating a `.all-contributors` JSON file. You can configure the project by creating a `.all-contributorsrc` JSON file.
```json ```json
{ {
"file": "README.md", "file": "README.md",
"owner": "jfmengels", "owner": "jfmengels",
"emoji": { "emoji": {
"thoughtleadering": "some emoji" "cheerful": ":smiley:"
}
}
```
or creating a `all-contributors` updating the `package.json` file:
```json
{
"name": "all-contributors-cli",
"...": "...",
"all-contributors": {
"file": "README.md",
"owner": "jfmengels"
} }
} }
``` ```

97
cli.js Normal file → Executable file
View file

@ -1,78 +1,51 @@
var options = { #!/usr/bin/env node
contributingFile: './fixture/some.md', 'use strict';
projectOwner: 'jfmengels',
projectName: 'all-contributors-cli',
imageSize: 130
};
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var request = require('request'); var assign = require('lodash.assign');
var findIndex = require('lodash.findindex');
function getUserInfo(username, cb) { var markdown = require('./lib/markdown');
request.get({ var getUserInfo = require('./lib/github');
url: 'https://api.github.com/users/' + username, var defaultEmojis = require('./lib/emoji');
headers: { var addContributor = require('./lib/addContributor');
'User-Agent': 'request'
var defaultRCFile = '.all-contributorsrc';
var argv = require('yargs')
.usage('Usage: $0 <username> <contribution>')
.demand(2)
.default('config', defaultRCFile)
.default('file', 'README.md')
.config('config', function(configPath) {
try {
return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
} catch (error) {
if (configPath !== path.join(__dirname, defaultRCFile)) {
console.error(error.message);
process.exit(1);
}
} }
}, function(error, res) { })
if (error) { .default('emoji', {})
return cb(error); .pkgConf('all-contributors')
} .argv;
return cb(null, JSON.parse(res.body));
});
}
function readMarkdown(filePath, cb) { argv.emoji = assign({}, defaultEmojis, argv.emoji);
fs.readFile(path.join(__dirname, filePath), 'utf8', cb); argv.username = argv._[0];
} argv.contributions = argv._[1].split(',');
argv.file = path.join(__dirname, argv.file);
function writeMarkdown(filePath, content, cb) { getUserInfo(argv.username, function(error, user) {
fs.writeFile(path.join(__dirname, filePath), content, cb);
}
function listAllContributors(start, lines) {
var i = 0;
while (start + i < lines.length && lines[start + i].indexOf('[![') === 0) {
i++;
}
return lines.slice(start, start + i);
}
function contributorEntry(options, user) {
return '[![' + user.name + '](' + user.avatar_url + '&s=' + options.imageSize + ')' +
'<br />' + user.name + '](' + user.html_url + ')' +
' | [📖](https://github.com/' + options.projectOwner + '/' + options.projectName + '/commits?author=' + user.login + ')';
}
function addContributor(contributor, fileContent) {
var lines = fileContent.split('\n');
var contributorListStart = findIndex(lines, function(line) {
return line.indexOf(':---: | :---:') !== -1;
});
var contributors = [].concat(
listAllContributors(contributorListStart + 1, lines),
contributor
);
return [].concat(
lines.slice(0, contributorListStart + 1),
contributors,
lines.slice(contributorListStart + contributors.length)
).join('\n')
}
getUserInfo('jfmengels', function(error, user) {
if (error) { if (error) {
return console.error(error); return console.error(error);
} }
readMarkdown(options.contributingFile, function(error, fileContent) { markdown.read(argv.file, function(error, fileContent) {
if (error) { if (error) {
return console.error(error); return console.error(error);
} }
var newFileContent = addContributor(contributorEntry(options, user), fileContent); var newFileContent = addContributor(argv, user, fileContent);
writeMarkdown(options.contributingFile, newFileContent, function(error, fileContent) { markdown.write(argv.file, newFileContent, function(error, fileContent) {
if (error) { if (error) {
return console.error(error); return console.error(error);
} }

51
lib/addContributor.js Normal file
View file

@ -0,0 +1,51 @@
'use strict';
var template = require('lodash.template');
var findIndex = require('lodash.findindex');
function listAllContributors(start, lines) {
var i = 0;
while (start + i < lines.length && lines[start + i].indexOf('[![') === 0) {
i++;
}
return lines.slice(start, start + i);
}
var contributionTemplate = template(
'[![<%= user.name %>](<%= user.avatar_url %>&s=<%= options.imageSize %>)' +
'<br /><%= user.name %>](<%= user.html_url %>)' +
' | [<%= contributions %>](https://github.com/<%= options.projectOwner %>/<%= options.projectName %>/commits?author=<%= user.login %>)'
);
function contributorEntry(options, user) {
var contributions = options.contributions
.map(function(contribution) {
return options.emoji[contribution];
})
.join('');
return contributionTemplate({
user: user,
contributions: contributions,
options: options
});
}
module.exports = function addContributor(options, user, fileContent) {
var contributor = contributorEntry(options, user);
var lines = fileContent.split('\n');
var contributorListStart = findIndex(lines, function(line) {
return line.indexOf(':---: | :---:') !== -1;
});
var contributors = [].concat(
listAllContributors(contributorListStart + 1, lines),
contributor
);
return [].concat(
lines.slice(0, contributorListStart + 1),
contributors,
lines.slice(contributorListStart + contributors.length)
).join('\n')
}

18
lib/emoji.js Normal file
View file

@ -0,0 +1,18 @@
'use strict';
module.exports = {
code: '💻',
plugin: '🔌',
tool: '🔧',
doc: '📖',
question: '❓',
test: '⚠️',
bug: '🐛',
example: '💡',
blog: '📝',
tutorial: '✅',
video: '📹',
talk: '📢',
design: '🎨',
review: '👀'
};

17
lib/github.js Normal file
View file

@ -0,0 +1,17 @@
'use strict';
var request = require('request');
module.exports = function getUserInfo(username, cb) {
request.get({
url: 'https://api.github.com/users/' + username,
headers: {
'User-Agent': 'request'
}
}, function(error, res) {
if (error) {
return cb(error);
}
return cb(null, JSON.parse(res.body));
});
}

16
lib/markdown.js Normal file
View file

@ -0,0 +1,16 @@
'use strict';
var fs = require('fs');
function read(filePath, cb) {
fs.readFile(filePath, 'utf8', cb);
}
function write(filePath, content, cb) {
fs.writeFile(filePath, content, cb);
}
module.exports = {
read: read,
write: write
}

View file

@ -19,7 +19,19 @@
}, },
"homepage": "https://github.com/jfmengels/all-contributors-cli#readme", "homepage": "https://github.com/jfmengels/all-contributors-cli#readme",
"dependencies": { "dependencies": {
"lodash.assign": "^4.0.4",
"lodash.findindex": "^4.2.0", "lodash.findindex": "^4.2.0",
"request": "^2.69.0" "lodash.template": "^4.2.1",
"request": "^2.69.0",
"yargs": "^4.2.0"
},
"all-contributors": {
"file": "./fixture/some.md",
"projectOwner": "jfmengels",
"projectName": "all-contributors-cli",
"imageSize": 100,
"emoji": {
"cheerful": ":smiley:"
}
} }
} }