diff --git a/.all-contributorsrc b/.all-contributorsrc
index 7459677b..5de1c6d4 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -204,6 +204,16 @@
"doc",
"ideas"
]
+ },
+ {
+ "login": "xuchaoying",
+ "name": "C.Y.Xu",
+ "avatar_url": "https://avatars2.githubusercontent.com/u/8073251?v=4",
+ "profile": "https://github.com/xuchaoying",
+ "contributions": [
+ "code"
+ ]
}
- ]
+ ],
+ "repoType": "github"
}
diff --git a/README.md b/README.md
index a0357fcc..b0a72a29 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
[![version][version-badge]][package] [![downloads][downloads-badge]][downloads]
[![MIT License][license-badge]][license]
-[](#contributors)
+[](#contributors)
[![PRs Welcome][prs-badge]][prs] [![Code of Conduct][coc-badge]][coc]
[![Watch on GitHub][github-watch-badge]][github-watch]
[![Star on GitHub][github-star-badge]][github-star]
@@ -158,6 +158,7 @@ These are the keys you can specify:
--> `all-contributors-cli`. Mandatory.
* `repoType`: Type of repository. Must be either `github` or `gitlab`. Default: `github`.
* `repoHost`: Points to the repository hostname. Change it if you use a self hosted repository. Default: `https://github.com` if `repoType` is `github`, and `https://gitlab.com` if `repoType` is `gitlab`.
+* `private_token`: The personal access token to to authenticate with the GitLab API. Offer it if you use a self hosted repository. Default: `''`.
* `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`.
@@ -178,7 +179,7 @@ Thanks goes to these wonderful people
| :---: | :---: | :---: | :---: | :---: | :---: |
| [
Jerod Santo](https://jerodsanto.net)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=jerodsanto "Code") | [
Kevin Jalbert](https://github.com/kevinjalbert)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=kevinjalbert "Code") | [
tunnckoCore](https://i.am.charlike.online)
[🔧](#tool-charlike "Tools") | [
Mehdi Achour](https://machour.idk.tn/)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=machour "Code") | [
Roy Revelt](https://codsen.com)
[🐛](https://github.com/jfmengels/all-contributors-cli/issues?q=author%3Arevelt "Bug reports") | [
Chris Vickery](https://github.com/chrisinajar)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=chrisinajar "Code") |
| [
Bryce Reynolds](https://github.com/brycereynolds)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=brycereynolds "Code") | [
James, please](http://www.jmeas.com)
[🤔](#ideas-jmeas "Ideas, Planning, & Feedback") [💻](https://github.com/jfmengels/all-contributors-cli/commits?author=jmeas "Code") | [
Spyros Ioakeimidis](http://www.spyros.io)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=spirosikmd "Code") | [
Fernando Costa](https://github.com/fadc80)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=fadc80 "Code") | [
snipe](https://snipe.net)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=snipe "Documentation") | [
Gant Laborde](http://gantlaborde.com/)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=GantMan "Code") |
-| [
Md Zubair Ahmed](https://in.linkedin.com/in/mzubairahmed)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=M-ZubairAhmed "Documentation") [🐛](https://github.com/jfmengels/all-contributors-cli/issues?q=author%3AM-ZubairAhmed "Bug reports") | [
Divjot Singh](http://bogas04.github.io)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=bogas04 "Documentation") | [
João Marques](https://github.com/tigermarques)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=tigermarques "Code") [📖](https://github.com/jfmengels/all-contributors-cli/commits?author=tigermarques "Documentation") [🤔](#ideas-tigermarques "Ideas, Planning, & Feedback") |
+| [
Md Zubair Ahmed](https://in.linkedin.com/in/mzubairahmed)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=M-ZubairAhmed "Documentation") [🐛](https://github.com/jfmengels/all-contributors-cli/issues?q=author%3AM-ZubairAhmed "Bug reports") [💻](https://github.com/jfmengels/all-contributors-cli/commits?author=M-ZubairAhmed "Code") [⚠️](https://github.com/jfmengels/all-contributors-cli/commits?author=M-ZubairAhmed "Tests") | [
Divjot Singh](http://bogas04.github.io)
[📖](https://github.com/jfmengels/all-contributors-cli/commits?author=bogas04 "Documentation") | [
João Marques](https://github.com/tigermarques)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=tigermarques "Code") [📖](https://github.com/jfmengels/all-contributors-cli/commits?author=tigermarques "Documentation") [🤔](#ideas-tigermarques "Ideas, Planning, & Feedback") | [
C.Y.Xu](https://github.com/xuchaoying)
[💻](https://github.com/jfmengels/all-contributors-cli/commits?author=xuchaoying "Code") |
This project follows the
diff --git a/src/cli.js b/src/cli.js
index 636881dc..367e7c4f 100755
--- a/src/cli.js
+++ b/src/cli.js
@@ -76,7 +76,13 @@ function checkContributors(argv) {
const configData = util.configFile.readConfig(argv.config)
return repo
- .getContributors(configData.projectOwner, configData.projectName, configData.repoType, configData.repoHost)
+ .getContributors(
+ configData.projectOwner,
+ configData.projectName,
+ configData.repoType,
+ configData.repoHost,
+ configData.private_token,
+ )
.then(repoContributors => {
const checkKey = repo.getCheckKey(configData.repoType)
const knownContributions = configData.contributors.reduce((obj, item) => {
@@ -138,7 +144,8 @@ function promptForCommand(argv) {
value: 'generate',
},
{
- name: 'Compare contributors from the repository with the credited ones',
+ name:
+ 'Compare contributors from the repository with the credited ones',
value: 'check',
},
],
@@ -155,16 +162,16 @@ function promptForCommand(argv) {
promptForCommand(yargv)
.then(command => {
switch (command) {
- case 'init':
- return init()
- case 'generate':
- return startGeneration(yargv)
- case 'add':
- return addContribution(yargv)
- case 'check':
- return checkContributors(yargv)
- default:
- throw new Error(`Unknown command ${command}`)
+ case 'init':
+ return init()
+ case 'generate':
+ return startGeneration(yargv)
+ case 'add':
+ return addContribution(yargv)
+ case 'check':
+ return checkContributors(yargv)
+ default:
+ throw new Error(`Unknown command ${command}`)
}
})
.catch(onError)
diff --git a/src/contributors/add.js b/src/contributors/add.js
index a23a2ddf..df53d343 100644
--- a/src/contributors/add.js
+++ b/src/contributors/add.js
@@ -38,7 +38,12 @@ function updateExistingContributor(options, username, contributions) {
}
function addNewContributor(options, username, contributions, infoFetcher) {
- return infoFetcher(username, options.repoType, options.repoHost).then(userData => {
+ return infoFetcher(
+ username,
+ options.repoType,
+ options.repoHost,
+ options.private_token,
+ ).then(userData => {
const contributor = _.assign(userData, {
contributions: formatContributions(options, [], contributions),
})
diff --git a/src/init/prompt.js b/src/init/prompt.js
index 81dcdd19..bded98f6 100644
--- a/src/init/prompt.js
+++ b/src/init/prompt.js
@@ -41,6 +41,13 @@ const questions = [
}
},
},
+ {
+ type: 'input',
+ name: 'private_token',
+ message:
+ 'What is the personal access token? (If you use a self hosted repository)',
+ default: '',
+ },
{
type: 'input',
name: 'contributorFile',
@@ -79,7 +86,10 @@ const questions = [
},
]
-const uniqueFiles = _.flow(_.compact, _.uniq)
+const uniqueFiles = _.flow(
+ _.compact,
+ _.uniq,
+)
module.exports = function prompt() {
return git
@@ -98,6 +108,7 @@ module.exports = function prompt() {
projectOwner: answers.projectOwner,
repoType: answers.repoType,
repoHost: answers.repoHost,
+ private_token: answers.private_token,
files: uniqueFiles([answers.contributorFile, answers.badgeFile]),
imageSize: answers.imageSize,
commit: answers.commit,
diff --git a/src/repo/__tests__/gitlab.js b/src/repo/__tests__/gitlab.js
index c13cbff0..c00f708e 100644
--- a/src/repo/__tests__/gitlab.js
+++ b/src/repo/__tests__/gitlab.js
@@ -19,12 +19,15 @@ test('handle errors', async () => {
test('fill in the name when it is returned', async () => {
nock('https://gitlab.com')
.get('/api/v4/users?username=nodisplayname')
- .reply(200, [{
- username: 'nodisplayname',
- name: 'No Display Name',
- avatar_url: 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/nodisplayname',
- }])
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: 'No Display Name',
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'https://gitlab.com/nodisplayname',
+ },
+ ])
const info = await getUserInfo('nodisplayname')
expect(info.name).toBe('No Display Name')
@@ -33,12 +36,15 @@ test('fill in the name when it is returned', async () => {
test('fill in the name when null is returned', async () => {
nock('https://gitlab.com')
.get('/api/v4/users?username=nodisplayname')
- .reply(200, [{
- username: 'nodisplayname',
- name: null,
- avatar_url: 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/nodisplayname',
- }])
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: null,
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'https://gitlab.com/nodisplayname',
+ },
+ ])
const info = await getUserInfo('nodisplayname')
expect(info.name).toBe('nodisplayname')
@@ -47,12 +53,15 @@ test('fill in the name when null is returned', async () => {
test('fill in the name when an empty string is returned', async () => {
nock('https://gitlab.com')
.get('/api/v4/users?username=nodisplayname')
- .reply(200, [{
- username: 'nodisplayname',
- name: '',
- avatar_url: 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/nodisplayname',
- }])
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: '',
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'https://gitlab.com/nodisplayname',
+ },
+ ])
const info = await getUserInfo('nodisplayname')
expect(info.name).toBe('nodisplayname')
@@ -61,12 +70,15 @@ test('fill in the name when an empty string is returned', async () => {
test('append http when no absolute link is provided', async () => {
nock('https://gitlab.com')
.get('/api/v4/users?username=nodisplayname')
- .reply(200, [{
- username: 'nodisplayname',
- name: 'No Display Name',
- avatar_url: 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
- web_url: 'www.gitlab.com/nodisplayname',
- }])
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: 'No Display Name',
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'www.gitlab.com/nodisplayname',
+ },
+ ])
const info = await getUserInfo('nodisplayname')
expect(info.profile).toBe('http://www.gitlab.com/nodisplayname')
@@ -75,13 +87,50 @@ test('append http when no absolute link is provided', async () => {
test('retrieve user from a different gitlab registry', async () => {
nock('http://gitlab.myhost.com:3000')
.get('/api/v4/users?username=nodisplayname')
- .reply(200, [{
- username: 'nodisplayname',
- name: 'No Display Name',
- avatar_url: 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/nodisplayname',
- }])
-
- const info = await getUserInfo('nodisplayname', 'http://gitlab.myhost.com:3000')
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: 'No Display Name',
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'https://gitlab.com/nodisplayname',
+ },
+ ])
+
+ const info = await getUserInfo(
+ 'nodisplayname',
+ 'http://gitlab.myhost.com:3000',
+ )
+ expect(info.name).toBe('No Display Name')
+})
+
+test('retrieve user from a gitlab registry that needs a token', async () => {
+ nock('http://gitlab.needtoken.com:3000')
+ .get('/api/v4/users?username=nodisplayname&private_token=faketoken')
+ .reply(200, [
+ {
+ username: 'nodisplayname',
+ name: 'No Display Name',
+ avatar_url:
+ 'http://www.gravatar.com/avatar/3186450a99d1641bf75a44baa23f0826?s=80\u0026d=identicon',
+ web_url: 'https://gitlab.com/nodisplayname',
+ },
+ ])
+
+ const info = await getUserInfo(
+ 'nodisplayname',
+ 'http://gitlab.needtoken.com:3000',
+ 'faketoken',
+ )
expect(info.name).toBe('No Display Name')
})
+
+test('handle error when no token is offered', async () => {
+ nock('http://gitlab.needtoken.com:3000')
+ .get('/api/v4/users?username=nodisplayname')
+ .reply(200, [])
+
+ await rejects(
+ getUserInfo('nodisplayname', 'http://gitlab.needtoken.com:3000', ''),
+ )
+})
diff --git a/src/repo/gitlab.js b/src/repo/gitlab.js
index 5d7a69bc..6c139ce3 100644
--- a/src/repo/gitlab.js
+++ b/src/repo/gitlab.js
@@ -1,15 +1,26 @@
const pify = require('pify')
const request = pify(require('request'))
-const getUserInfo = function(username, hostname) {
+const addPrivateToken = (url, private_token = '') => {
+ if (private_token === '') return url
+
+ return `${url}&private_token=${private_token}`
+ .replace(/\?/g, '&')
+ .replace('&', '?')
+}
+
+const getUserInfo = function(username, hostname, private_token = '') {
/* eslint-disable complexity */
if (!hostname) {
- hostname = 'https://gitlab.com';
+ hostname = 'https://gitlab.com'
}
return request
.get({
- url: `${hostname}/api/v4/users?username=${username}`,
+ url: addPrivateToken(
+ `${hostname}/api/v4/users?username=${username}`,
+ private_token,
+ ),
headers: {
'User-Agent': 'request',
},
@@ -28,19 +39,24 @@ const getUserInfo = function(username, hostname) {
login: user.username,
name: user.name || username,
avatar_url: user.avatar_url,
- profile: user.web_url.startsWith('http') ? user.web_url : `http://${user.web_url}`,
+ profile: user.web_url.startsWith('http')
+ ? user.web_url
+ : `http://${user.web_url}`,
}
})
}
-const getContributors = function(owner, name, hostname) {
+const getContributors = function(owner, name, hostname, private_token = '') {
if (!hostname) {
- hostname = 'https://gitlab.com';
+ hostname = 'https://gitlab.com'
}
return request
.get({
- url: `${hostname}/api/v4/projects?search=${name}`,
+ url: addPrivateToken(
+ `${hostname}/api/v4/projects?search=${name}`,
+ private_token,
+ ),
headers: {
'User-Agent': 'request',
},
@@ -57,7 +73,7 @@ const getContributors = function(owner, name, hostname) {
for (let i = 0; i < projects.length; i++) {
if (projects[i].path_with_namespace === `${owner}/${name}`) {
project = projects[i]
- break;
+ break
}
}
@@ -67,7 +83,10 @@ const getContributors = function(owner, name, hostname) {
return request
.get({
- url: `${hostname}/api/v4/projects/${project.id}/repository/contributors`,
+ url: addPrivateToken(
+ `${hostname}/api/v4/projects/${project.id}/repository/contributors`,
+ private_token,
+ ),
headers: {
'User-Agent': 'request',
},
@@ -87,5 +106,5 @@ const getContributors = function(owner, name, hostname) {
module.exports = {
getUserInfo,
- getContributors
+ getContributors,
}
diff --git a/src/repo/index.js b/src/repo/index.js
index 1810c7fc..26361109 100644
--- a/src/repo/index.js
+++ b/src/repo/index.js
@@ -7,30 +7,36 @@ const SUPPORTED_REPO_TYPES = {
name: 'GitHub',
checkKey: 'login',
defaultHost: 'https://github.com',
- linkToCommits: '<%= options.repoHost || "https://github.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/commits?author=<%= contributor.login %>',
- linkToIssues: '<%= options.repoHost || "https://github.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/issues?q=author%3A<%= contributor.login %>',
+ linkToCommits:
+ '<%= options.repoHost || "https://github.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/commits?author=<%= contributor.login %>',
+ linkToIssues:
+ '<%= options.repoHost || "https://github.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/issues?q=author%3A<%= contributor.login %>',
getUserInfo: githubAPI.getUserInfo,
- getContributors: githubAPI.getContributors
+ getContributors: githubAPI.getContributors,
},
gitlab: {
value: 'gitlab',
name: 'GitLab',
checkKey: 'name',
defaultHost: 'https://gitlab.com',
- linkToCommits: '<%= options.repoHost || "https://gitlab.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/commits/master',
- linkToIssues: '<%= options.repoHost || "https://gitlab.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/issues?author_username=<%= contributor.login %>',
+ linkToCommits:
+ '<%= options.repoHost || "https://gitlab.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/commits/master',
+ linkToIssues:
+ '<%= options.repoHost || "https://gitlab.com" %>/<%= options.projectOwner %>/<%= options.projectName %>/issues?author_username=<%= contributor.login %>',
getUserInfo: gitlabAPI.getUserInfo,
- getContributors: gitlabAPI.getContributors
- }
+ getContributors: gitlabAPI.getContributors,
+ },
}
const getChoices = function() {
- return Object.keys(SUPPORTED_REPO_TYPES).map(key => SUPPORTED_REPO_TYPES[key]).map(item => {
- return {
- value: item.value,
- name: item.name
- }
- })
+ return Object.keys(SUPPORTED_REPO_TYPES)
+ .map(key => SUPPORTED_REPO_TYPES[key])
+ .map(item => {
+ return {
+ value: item.value,
+ name: item.name,
+ }
+ })
}
const getHostname = function(repoType, repoHost) {
@@ -70,16 +76,31 @@ const getLinkToIssues = function(repoType) {
return null
}
-const getUserInfo = function(username, repoType, repoHost) {
+const getUserInfo = function(username, repoType, repoHost, private_token = '') {
if (repoType in SUPPORTED_REPO_TYPES) {
- return SUPPORTED_REPO_TYPES[repoType].getUserInfo(username, getHostname(repoType, repoHost))
+ return SUPPORTED_REPO_TYPES[repoType].getUserInfo(
+ username,
+ getHostname(repoType, repoHost),
+ private_token,
+ )
}
return null
}
-const getContributors = function(owner, name, repoType, repoHost) {
+const getContributors = function(
+ owner,
+ name,
+ repoType,
+ repoHost,
+ private_token = '',
+) {
if (repoType in SUPPORTED_REPO_TYPES) {
- return SUPPORTED_REPO_TYPES[repoType].getContributors(owner, name, getHostname(repoType, repoHost))
+ return SUPPORTED_REPO_TYPES[repoType].getContributors(
+ owner,
+ name,
+ getHostname(repoType, repoHost),
+ private_token,
+ )
}
return null
}
@@ -92,5 +113,5 @@ module.exports = {
getLinkToCommits,
getLinkToIssues,
getUserInfo,
- getContributors
+ getContributors,
}