Rename template option to contributorTemplate. Rename tags to ALL-CONTRIBUTOR-*. Allow multiple files to be changed.

This commit is contained in:
Jeroen Engels 2016-03-06 16:49:46 +01:00
parent f9bb61d7a2
commit f7be0de327
9 changed files with 65 additions and 99 deletions

View file

@ -1,8 +1,8 @@
# all-contributors-cli
<!-- CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors)
<!-- CONTRIBUTORS-BADGE:END -->
<!-- ALL-CONTRIBUTORS-BADGE:END -->
This is a tool to help automate adding contributor acknowledgements according to the [all-contributors](https://github.com/kentcdodds/all-contributors) specification.
@ -21,7 +21,7 @@ You must create a `.all-contributorsrc` JSON file. The data used to generate the
```json
{
"file": "README.md",
"files": ["README.md"],
"owner": "jfmengels",
"types": {
"cheerful": {
@ -36,13 +36,13 @@ You must create a `.all-contributorsrc` JSON file. The data used to generate the
```
These are the keys you can specify:
- `file`: File to write the list of contributors in. Default: 'README.md'
- `files`: Array of files to update. Default: `['README.md']`
- `projectOwner`: Name of the user the project is hosted by. Example: `jfmengels/all-contributor-cli` --> `jfmengels`. Mandatory.
- `projectName`: Name of the project. Example: `jfmengels/all-contributor-cli` --> `all-contributor-cli`. Mandatory.
- `types`: Specify custom symbols or link templates for contribution types. Can override the documented types.
- `imageSize`: Size (in px) of the user's avatar. Default: 100.
- `contributorsPerLine`: Maximum number of columns for the contributors table. Default: 7.
- `template`: Define your own template to generate the contributor list.
- `imageSize`: Size (in px) of the user's avatar. Default: `100`.
- `contributorsPerLine`: Maximum number of columns for the contributors table. Default: `7`.
- `contributorTemplate`: Define your own template to generate the contributor list.
- `badgeTemplate`: Define your own template to generate the badge.
### Add contributors section
@ -52,8 +52,8 @@ If you don't already have a Contributors section in a Markdown file, create one.
```md
## Contributors
<!-- CONTRIBUTORS:START - Do not remove or modify this section -->
<!-- CONTRIBUTORS:END -->
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
```
If you wish to add a badge ( [![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors) ) indicating the number of collaborators, add the following tags (again, at the beginning of the line and each on their separate line):
@ -61,8 +61,8 @@ If you wish to add a badge ( [![All Contributors](https://img.shields.io/badge/a
```md
some-badge
<!-- CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<!-- CONTRIBUTORS-BADGE:END -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<!-- ALL-CONTRIBUTORS-BADGE:END -->
some-other-badge
```
@ -111,10 +111,10 @@ Where:
Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
<!-- CONTRIBUTORS:START - Do not remove or modify this section -->
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
| [![Jeroen Engels](https://avatars.githubusercontent.com/u/3869412?v=3&s=100)<br /><sub>Jeroen Engels</sub>](https://github.com/jfmengels)<br />[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=jfmengels) [📖](https://github.com/jfmengels/all-contributors-cli/commits?author=jfmengels) [⚠️](https://github.com/jfmengels/all-contributors-cli/commits?author=jfmengels) | [![Kent C. Dodds](https://avatars.githubusercontent.com/u/1500684?v=3&s=100)<br /><sub>Kent C. Dodds</sub>](http://kentcdodds.com/)<br />[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=kentcdodds) |
| :---: | :---: |
<!-- CONTRIBUTORS:END -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification.
Contributions of any kind welcome!

26
cli.js
View file

@ -19,7 +19,7 @@ var argv = require('yargs')
.command('add', 'add a new contributor')
.usage('Usage: $0 add <username> <contribution>')
.demand(2)
.default('file', 'README.md')
.default('files', ['README.md'])
.default('contributorsPerLine', 7)
.default('contributors', [])
.default('config', defaultRCFile)
@ -35,16 +35,20 @@ var argv = require('yargs')
})
.argv;
argv.file = path.join(cwd, argv.file);
function startGeneration(argv, cb) {
markdown.read(argv.file, function(error, fileContent) {
if (error) {
return cb(error);
}
var newFileContent = generate(argv, argv.contributors, fileContent);
markdown.write(argv.file, newFileContent, cb);
});
argv.files
.map(function(file) {
return path.join(cwd, file);
})
.forEach(function(file) {
markdown.read(file, function(error, fileContent) {
if (error) {
return cb(error);
}
var newFileContent = generate(argv, argv.contributors, fileContent);
markdown.write(file, newFileContent, cb);
});
});
}
function onError(error) {
@ -60,7 +64,7 @@ if (command === 'generate') {
} else if (command === 'add') {
var username = argv._[1];
var contributions = argv._[2];
// Add/update contributor and save him to the config file
// Add or update contributor in the config file
updateContributors(argv, username, contributions, function(error, contributors) {
if (error) {
return onError(error);

View file

@ -35,8 +35,6 @@ function fixtures() {
}
test.cb('should callback with error if infoFetcher fails', t => {
t.plan(1);
const {options} = fixtures();
const username = 'login3';
const contributions = ['doc'];
@ -51,8 +49,6 @@ test.cb('should callback with error if infoFetcher fails', t => {
});
test.cb('should add new contributor at the end of the list of contributors', t => {
t.plan(3);
const {options} = fixtures();
const username = 'login3';
const contributions = 'doc';
@ -74,8 +70,6 @@ test.cb('should add new contributor at the end of the list of contributors', t =
});
test.cb('should add new contributor at the end of the list of contributors with a url link', t => {
t.plan(3);
const {options} = fixtures();
const username = 'login3';
const contributions = 'doc';
@ -98,8 +92,6 @@ test.cb('should add new contributor at the end of the list of contributors with
});
test.cb(`should not update an existing contributor's contributions where nothing has changed`, t => {
t.plan(2);
const {options} = fixtures();
const username = 'login2';
const contributions = 'blog,code';
@ -112,8 +104,6 @@ test.cb(`should not update an existing contributor's contributions where nothing
});
test.cb(`should update an existing contributor's contributions if a new type is added`, t => {
t.plan(3);
const {options} = fixtures();
const username = 'login1';
const contributions = 'bug';
@ -136,8 +126,6 @@ test.cb(`should update an existing contributor's contributions if a new type is
});
test.cb(`should update an existing contributor's contributions if a new type is added with a link`, t => {
t.plan(3);
const {options} = fixtures();
const username = 'login1';
const contributions = 'bug';

View file

@ -4,7 +4,6 @@ var _ = require('lodash/fp');
var linkToCommits = 'https://github.com/<%= options.projectOwner %>/<%= options.projectName %>/commits?author=<%= contributor.login %>'
var linkToIssues = 'https://github.com/<%= options.projectOwner %>/<%= options.projectName %>/issues?q=author%3A<%= contributor.login %>';
var linkTemplate = _.template('[<%= symbol %>](<%= url %>)');
var defaultTypes = {
@ -37,23 +36,24 @@ var defaultTypes = {
video: { symbol: '📹' }
};
module.exports = function formatContribution(options, contributor, contribution) {
function getType(options, contribution) {
var types = _.assign(defaultTypes, options.types);
var type = types[contribution.type || contribution];
return types[contribution.type || contribution];
}
module.exports = function formatContribution(options, contributor, contribution) {
var type = getType(options, contribution);
var templateData = {
symbol: type.symbol,
contributor: contributor,
options: options
};
if (contribution.url) {
return linkTemplate(_.assign({url: contribution.url}, templateData));
}
if (type.link) {
var url = _.template(type.link)(templateData);
return linkTemplate(_.assign({url: url}, templateData));
}
return type.symbol;
};

View file

@ -12,8 +12,6 @@ const fixtures = () => {
}
test('should return corresponding symbol', t => {
t.plan(2);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
@ -22,8 +20,6 @@ test('should return corresponding symbol', t => {
});
test('should return link to commits', t => {
t.plan(3);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
const expectedLink = '(https://github.com/jfmengels/all-contributors-cli/commits?author=kentcdodds)';
@ -34,8 +30,6 @@ test('should return link to commits', t => {
});
test('should return link to issues', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
const expected = '[🐛](https://github.com/jfmengels/all-contributors-cli/issues?q=author%3Akentcdodds)';
@ -44,8 +38,6 @@ test('should return link to issues', t => {
});
test('should make any symbol into a link if contribution is an object', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
const contribution = {
@ -57,8 +49,6 @@ test('should make any symbol into a link if contribution is an object', t => {
});
test('should override url for given types', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
const contribution = {
@ -70,8 +60,6 @@ test('should override url for given types', t => {
});
test('should be able to add types to the symbol list', t => {
t.plan(2);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
options.types = {
@ -86,8 +74,6 @@ test('should be able to add types to the symbol list', t => {
});
test('should be able to add types with template to the symbol list', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
options.types = {
@ -101,8 +87,6 @@ test('should be able to add types with template to the symbol list', t => {
});
test('should be able to override existing types', t => {
t.plan(2);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
options.types = {
@ -117,8 +101,6 @@ test('should be able to override existing types', t => {
});
test('should be able to override existing templates', t => {
t.plan(2);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
options.types = {

View file

@ -24,16 +24,15 @@ function updateAvatarUrl(options, contributor) {
}
module.exports = function formatContributor(options, contributor) {
var contributions = contributor.contributions.map(
_.partial(formatContributionType, [options, contributor])
).join(' ');
var formatter = _.partial(formatContributionType, [options, contributor]);
var contributions = contributor.contributions
.map(formatter)
.join(' ');
var templateData = {
contributions: contributions,
contributor: updateAvatarUrl(options, contributor),
options: options
};
var customTemplate = options.template && _.template(options.template);
var customTemplate = options.contributorTemplate && _.template(options.contributorTemplate);
return (customTemplate || defaultTemplate)(templateData);
};

View file

@ -13,8 +13,6 @@ function fixtures() {
}
test('should format a simple contributor', t => {
t.plan(1);
const contributor = _.assign(contributors.kentcdodds, { contributions: ['review'] });
const {options} = fixtures();
@ -24,8 +22,6 @@ test('should format a simple contributor', t => {
});
test('should format contributor with complex contribution types', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
@ -35,11 +31,9 @@ test('should format contributor with complex contribution types', t => {
});
test('should format contributor using custom template', t => {
t.plan(1);
const contributor = contributors.kentcdodds;
const {options} = fixtures();
options.template = '<%= contributor.name %> is awesome!'
options.contributorTemplate = '<%= contributor.name %> is awesome!'
const expected = 'Kent C. Dodds is awesome!';
@ -47,11 +41,9 @@ test('should format contributor using custom template', t => {
});
test('should add image size to url', t => {
t.plan(2);
const {options} = fixtures();
const contributor = contributors.kentcdodds;
options.template = '<%= contributor.name %> at <%= contributor.avatar_url %>'
options.contributorTemplate = '<%= contributor.name %> at <%= contributor.avatar_url %>'
var contributionWithoutQuestionMarkUrl = _.assign(contributor, {
avatar_url: 'www.some-url-without-question-mark.com'

View file

@ -6,8 +6,8 @@ var formatContributor = require('./formatContributor');
var injectBetweenTags = _.curry(function(tag, newContent, previousContent) {
var lines = previousContent.split('\n');
var openingTagIndex = _.findIndex(_.startsWith('<!-- ' + tag + ':START '), lines);
var closingTagIndex = _.findIndex(_.startsWith('<!-- ' + tag + ':END '), lines);
var openingTagIndex = _.findIndex(_.startsWith('<!-- ALL-CONTRIBUTORS-' + tag + ':START '), lines);
var closingTagIndex = _.findIndex(_.startsWith('<!-- ALL-CONTRIBUTORS-' + tag + ':END '), lines);
if (openingTagIndex === -1 || closingTagIndex === -1) {
return previousContent;
}
@ -24,7 +24,7 @@ function formatLine(contributors) {
function generateContributorsList(options, contributors) {
return _.flow(
_.map(function(contributor) {
_.map(function formatEveryContributor(contributor) {
return formatContributor(options, contributor);
}),
_.chunk(options.contributorsPerLine),
@ -41,7 +41,7 @@ module.exports = function generate(options, contributors, fileContent) {
var contributorsList = generateContributorsList(options, contributors);
var badge = formatBadge(options, contributors);
return _.flow(
injectBetweenTags('CONTRIBUTORS', contributorsList),
injectBetweenTags('CONTRIBUTORS-BADGE', badge)
injectBetweenTags('LIST', contributorsList),
injectBetweenTags('BADGE', badge)
)(fileContent);
};

View file

@ -16,7 +16,7 @@ function fixtures() {
imageSize: 100,
contributorsPerLine: 5,
contributors: contributors,
template: '<%= contributor.name %> is awesome!'
contributorTemplate: '<%= contributor.name %> is awesome!'
};
const jfmengels = {
@ -34,9 +34,9 @@ function fixtures() {
'',
'## Contributors',
'These people contributed to the project:',
'<!-- CONTRIBUTORS:START -->',
'###Some content that will be replace###',
'<!-- CONTRIBUTORS:END -->',
'<!-- ALL-CONTRIBUTORS-LIST:START -->',
'###Some content that will be replaced###',
'<!-- ALL-CONTRIBUTORS-LIST:END -->',
'',
'Thanks a lot guys!'
].join('\n');
@ -44,7 +44,7 @@ function fixtures() {
return {options, jfmengels, content};
}
test('should replace the content between the CONTRIBUTORS tags by a table of contributors', t => {
test('should replace the content between the ALL-CONTRIBUTORS-LIST tags by a table of contributors', t => {
const {kentcdodds, bogas04} = contributors;
const {options, jfmengels, content} = fixtures();
const contributorList = [kentcdodds, bogas04, jfmengels];
@ -55,10 +55,10 @@ test('should replace the content between the CONTRIBUTORS tags by a table of co
'',
'## Contributors',
'These people contributed to the project:',
'<!-- CONTRIBUTORS:START -->',
'<!-- ALL-CONTRIBUTORS-LIST:START -->',
'| Kent C. Dodds is awesome! | Divjot Singh is awesome! | Jeroen Engels is awesome! |',
'| :---: | :---: | :---: |',
'<!-- CONTRIBUTORS:END -->',
'<!-- ALL-CONTRIBUTORS-LIST:END -->',
'',
'Thanks a lot guys!'
].join('\n');
@ -79,11 +79,11 @@ test('should split contributors into multiples lines when there are too many', t
'',
'## Contributors',
'These people contributed to the project:',
'<!-- CONTRIBUTORS:START -->',
'<!-- ALL-CONTRIBUTORS-LIST:START -->',
'| Kent C. Dodds is awesome! | Kent C. Dodds is awesome! | Kent C. Dodds is awesome! | Kent C. Dodds is awesome! | Kent C. Dodds is awesome! |',
'| Kent C. Dodds is awesome! | Kent C. Dodds is awesome! |',
'| :---: | :---: | :---: | :---: | :---: |',
'<!-- CONTRIBUTORS:END -->',
'<!-- ALL-CONTRIBUTORS-LIST:END -->',
'',
'Thanks a lot guys!'
].join('\n');
@ -117,8 +117,8 @@ test('should not inject anything if start tag is malformed', t => {
'# project',
'',
'Description',
'<!-- CONTRIBUTORS:SSSSSSSTART -->',
'<!-- CONTRIBUTORS:END -->',
'<!-- ALL-CONTRIBUTORS-LIST:SSSSSSSTART -->',
'<!-- ALL-CONTRIBUTORS-LIST:END -->',
'',
'License: MIT'
].join('\n');
@ -135,8 +135,8 @@ test('should not inject anything if end tag is malformed', t => {
'# project',
'',
'Description',
'<!-- CONTRIBUTORS:START -->',
'<!-- CONTRIBUTORS:EEEEEEEND -->',
'<!-- ALL-CONTRIBUTORS-LIST:START -->',
'<!-- ALL-CONTRIBUTORS-LIST:EEEEEEEND -->',
'',
'License: MIT'
].join('\n');
@ -145,7 +145,7 @@ test('should not inject anything if end tag is malformed', t => {
t.is(result, content);
});
test('should inject badge if badge tags are present', t => {
test('should inject badge if the ALL-CONTRIBUTORS-BADGE tag is present', t => {
const {kentcdodds} = contributors;
const {options} = fixtures();
const contributorList = [kentcdodds];
@ -153,8 +153,9 @@ test('should inject badge if badge tags are present', t => {
'# project',
'',
'Badges',
'<!-- CONTRIBUTORS-BADGE:START -->',
'<!-- CONTRIBUTORS-BADGE:END -->',
'<!-- ALL-CONTRIBUTORS-BADGE:START -->',
'###Some content that will be replaced###',
'<!-- ALL-CONTRIBUTORS-BADGE:END -->',
'',
'License: MIT'
].join('\n');
@ -162,9 +163,9 @@ test('should inject badge if badge tags are present', t => {
'# project',
'',
'Badges',
'<!-- CONTRIBUTORS-BADGE:START -->',
'<!-- ALL-CONTRIBUTORS-BADGE:START -->',
'[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)',
'<!-- CONTRIBUTORS-BADGE:END -->',
'<!-- ALL-CONTRIBUTORS-BADGE:END -->',
'',
'License: MIT'
].join('\n');