diff --git a/README.md b/README.md index b5913b7..a378548 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # all-contributors-cli - + [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors) - + 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 - - + + ``` 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 - - + + some-other-badge ``` @@ -111,10 +111,10 @@ Where: Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): - + | [![Jeroen Engels](https://avatars.githubusercontent.com/u/3869412?v=3&s=100)
Jeroen Engels](https://github.com/jfmengels)
[💻](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)
Kent C. Dodds](http://kentcdodds.com/)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=kentcdodds) | | :---: | :---: | - + This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! diff --git a/cli.js b/cli.js index 49e5388..16172e1 100755 --- a/cli.js +++ b/cli.js @@ -19,7 +19,7 @@ var argv = require('yargs') .command('add', 'add a new contributor') .usage('Usage: $0 add ') .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); diff --git a/lib/contributors/add.test.js b/lib/contributors/add.test.js index cc301d9..5dfa883 100644 --- a/lib/contributors/add.test.js +++ b/lib/contributors/add.test.js @@ -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'; diff --git a/lib/generate/formatContributionType.js b/lib/generate/formatContributionType.js index f1d1dda..322c997 100644 --- a/lib/generate/formatContributionType.js +++ b/lib/generate/formatContributionType.js @@ -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; }; diff --git a/lib/generate/formatContributionType.test.js b/lib/generate/formatContributionType.test.js index 929a055..1afa401 100644 --- a/lib/generate/formatContributionType.test.js +++ b/lib/generate/formatContributionType.test.js @@ -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 = { diff --git a/lib/generate/formatContributor.js b/lib/generate/formatContributor.js index ad3fb78..e0b667f 100644 --- a/lib/generate/formatContributor.js +++ b/lib/generate/formatContributor.js @@ -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); }; diff --git a/lib/generate/formatContributor.test.js b/lib/generate/formatContributor.test.js index 6285ae7..025df8b 100644 --- a/lib/generate/formatContributor.test.js +++ b/lib/generate/formatContributor.test.js @@ -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' diff --git a/lib/generate/index.js b/lib/generate/index.js index f5d5426..0b0311d 100644 --- a/lib/generate/index.js +++ b/lib/generate/index.js @@ -6,8 +6,8 @@ var formatContributor = require('./formatContributor'); var injectBetweenTags = _.curry(function(tag, newContent, previousContent) { var lines = previousContent.split('\n'); - var openingTagIndex = _.findIndex(_.startsWith('', - '###Some content that will be replace###', - '', + '', + '###Some content that will be replaced###', + '', '', '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:', - '', + '', '| Kent C. Dodds is awesome! | Divjot Singh is awesome! | Jeroen Engels is awesome! |', '| :---: | :---: | :---: |', - '', + '', '', '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:', - '', + '', '| 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! |', '| :---: | :---: | :---: | :---: | :---: |', - '', + '', '', 'Thanks a lot guys!' ].join('\n'); @@ -117,8 +117,8 @@ test('should not inject anything if start tag is malformed', t => { '# project', '', 'Description', - '', - '', + '', + '', '', 'License: MIT' ].join('\n'); @@ -135,8 +135,8 @@ test('should not inject anything if end tag is malformed', t => { '# project', '', 'Description', - '', - '', + '', + '', '', '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', - '', - '', + '', + '###Some content that will be replaced###', + '', '', 'License: MIT' ].join('\n'); @@ -162,9 +163,9 @@ test('should inject badge if badge tags are present', t => { '# project', '', 'Badges', - '', + '', '[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)', - '', + '', '', 'License: MIT' ].join('\n');