Add badge indicating the number of collaborators (fixes #5)

This commit is contained in:
Jeroen Engels 2016-03-06 10:40:19 +01:00
parent 5949ac389b
commit f9bb61d7a2
7 changed files with 166 additions and 32 deletions

View file

@ -1,5 +1,9 @@
# all-contributors-cli
<!-- 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 -->
This is a tool to help automate adding contributor acknowledgements according to the [all-contributors](https://github.com/kentcdodds/all-contributors) specification.
## Installation
@ -11,17 +15,6 @@ npm install all-contributors-cli
## Configuration
### Add contributing section
If you don't already have a Contributing section in a Markdown file, create one. Then add the following comment tags section to it. Don't worry, they're visible only to those that read the raw file. The tags **must** be at the beginning of the line.
```md
## Contributing
<!-- CONTRIBUTORS:START - Do not remove or modify this section -->
<!-- CONTRIBUTORS:END -->
```
### Create a `.all-contributorsrc` file
You must create a `.all-contributorsrc` JSON file. The data used to generate the contributors list will be stored in here, and you can configure how you want `all-contributors-cli` to generate the list.
@ -50,6 +43,28 @@ These are the keys you can specify:
- `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.
- `badgeTemplate`: Define your own template to generate the badge.
### Add contributors section
If you don't already have a Contributors section in a Markdown file, create one. Then add the comment tags section below to it. Don't worry, they're visible only to those that read the raw file. The tags **must** be at the beginning of the line, and each on their separate line.
```md
## Contributors
<!-- CONTRIBUTORS:START - Do not remove or modify this section -->
<!-- CONTRIBUTORS: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):
```md
some-badge
<!-- CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<!-- CONTRIBUTORS-BADGE:END -->
some-other-badge
```
## Usage

1
cli.js
View file

@ -3,7 +3,6 @@
var fs = require('fs');
var path = require('path');
var assign = require('lodash.assign');
var generate = require('./lib/generate');
var markdown = require('./lib/markdown');

View file

@ -0,0 +1,11 @@
'use strict';
var _ = require('lodash/fp');
var defaultTemplate = '[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg?style=flat-square)](#contributors)';
module.exports = function formatBadge(options, contributors) {
return _.template(options.badgeTemplate || defaultTemplate)({
contributors: contributors
});
};

View file

@ -0,0 +1,32 @@
import test from 'ava';
import _ from 'lodash/fp';
import formatBadge from './formatBadge';
const fixtures = () => {
const options = {
projectOwner: 'jfmengels',
projectName: 'all-contributors-cli',
imageSize: 100
};
return {options};
}
test('should return badge with the number of contributors', t => {
const options = {};
const expected8 =
'[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors)';
const expected16 =
'[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors)';
t.is(formatBadge(options, _.times(_.constant({}), 8)), expected8);
t.is(formatBadge(options, _.times(_.constant({}), 16)), expected16);
});
test('should be able to specify custom badge template', t => {
const options = {
badgeTemplate: 'We have <%= contributors.length %> contributors'
};
t.is(formatBadge(options, _.times(_.constant({}), 8)), 'We have 8 contributors');
t.is(formatBadge(options, _.times(_.constant({}), 16)), 'We have 16 contributors');
});

View file

@ -1,18 +1,22 @@
'use strict';
var _ = require('lodash/fp');
var formatBadge = require('./formatBadge');
var formatContributor = require('./formatContributor');
function injectBetweenTags(fileContent, newContent) {
var lines = fileContent.split('\n');
var openingTagIndex = _.findIndex(_.startsWith('<!-- CONTRIBUTORS:START'), lines);
var closingTagIndex = _.findIndex(_.startsWith('<!-- CONTRIBUTORS:END'), lines);
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);
if (openingTagIndex === -1 || closingTagIndex === -1) {
return previousContent;
}
return [].concat(
lines.slice(0, openingTagIndex + 1),
newContent,
lines.slice(closingTagIndex)
).join('\n');
}
});
function formatLine(contributors) {
return '| ' + contributors.join(' | ') + ' |';
@ -34,8 +38,10 @@ function generateContributorsList(options, contributors) {
}
module.exports = function generate(options, contributors, fileContent) {
var contributorsList = generateContributorsList(options, contributors);
var badge = formatBadge(options, contributors);
return _.flow(
generateContributorsList,
_.partial(injectBetweenTags, [fileContent])
)(options, contributors);
injectBetweenTags('CONTRIBUTORS', contributorsList),
injectBetweenTags('CONTRIBUTORS-BADGE', badge)
)(fileContent);
};

View file

@ -45,8 +45,6 @@ function fixtures() {
}
test('should replace the content between the CONTRIBUTORS tags by a table of contributors', t => {
t.plan(1);
const {kentcdodds, bogas04} = contributors;
const {options, jfmengels, content} = fixtures();
const contributorList = [kentcdodds, bogas04, jfmengels];
@ -71,10 +69,8 @@ test('should replace the content between the CONTRIBUTORS tags by a table of co
});
test('should split contributors into multiples lines when there are too many', t => {
t.plan(1);
const {kentcdodds, bogas04} = contributors;
const {options, jfmengels, content} = fixtures();
const {kentcdodds} = contributors;
const {options, content} = fixtures();
const contributorList = [kentcdodds, kentcdodds, kentcdodds, kentcdodds, kentcdodds, kentcdodds, kentcdodds];
const expected = [
'# project',
@ -96,3 +92,83 @@ test('should split contributors into multiples lines when there are too many', t
t.is(result, expected);
});
test('should not inject anything if there is no tags to inject content in', t => {
const {kentcdodds} = contributors;
const {options} = fixtures();
const contributorList = [kentcdodds];
const content = [
'# project',
'',
'Description',
'',
'License: MIT'
].join('\n');
const result = generate(options, contributorList, content);
t.is(result, content);
});
test('should not inject anything if start tag is malformed', t => {
const {kentcdodds} = contributors;
const {options} = fixtures();
const contributorList = [kentcdodds];
const content = [
'# project',
'',
'Description',
'<!-- CONTRIBUTORS:SSSSSSSTART -->',
'<!-- CONTRIBUTORS:END -->',
'',
'License: MIT'
].join('\n');
const result = generate(options, contributorList, content);
t.is(result, content);
});
test('should not inject anything if end tag is malformed', t => {
const {kentcdodds} = contributors;
const {options} = fixtures();
const contributorList = [kentcdodds];
const content = [
'# project',
'',
'Description',
'<!-- CONTRIBUTORS:START -->',
'<!-- CONTRIBUTORS:EEEEEEEND -->',
'',
'License: MIT'
].join('\n');
const result = generate(options, contributorList, content);
t.is(result, content);
});
test('should inject badge if badge tags are present', t => {
const {kentcdodds} = contributors;
const {options} = fixtures();
const contributorList = [kentcdodds];
const content = [
'# project',
'',
'Badges',
'<!-- CONTRIBUTORS-BADGE:START -->',
'<!-- CONTRIBUTORS-BADGE:END -->',
'',
'License: MIT'
].join('\n');
const expected = [
'# project',
'',
'Badges',
'<!-- CONTRIBUTORS-BADGE:START -->',
'[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors)',
'<!-- CONTRIBUTORS-BADGE:END -->',
'',
'License: MIT'
].join('\n');
const result = generate(options, contributorList, content);
t.is(result, expected);
});

View file

@ -6,7 +6,7 @@
"all-contributors": "cli.js"
},
"scripts": {
"test": "ava lib/**/*.test.js",
"test": "ava 'lib/**/*.test.js'",
"test:w": "npm test -- --watch"
},
"repository": {
@ -25,11 +25,6 @@
"homepage": "https://github.com/jfmengels/all-contributors-cli#readme",
"dependencies": {
"lodash": "^4.6.1",
"lodash.assign": "^4.0.4",
"lodash.findindex": "^4.2.0",
"lodash.template": "^4.2.1",
"lodash.uniq": "^4.2.0",
"lodash.values": "^4.1.0",
"request": "^2.69.0",
"yargs": "^4.2.0"
},