Skip to content

Commit

Permalink
feat: Support self-hosted GitLab instance (all-contributors#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-dura committed Jul 30, 2018
1 parent d2ce3be commit c4c9d7b
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 22 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -165,6 +165,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`.
* `privateToken`: The personal access token to authenticate with the GitLab API. Offer it if you use a self hosted repository. Default: `''`. *WARNING: this will keep your private token in the config file, and may commit to git*
* `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`.
Expand Down
15 changes: 12 additions & 3 deletions package.json
Expand Up @@ -5,7 +5,9 @@
"bin": {
"all-contributors": "dist/cli.js"
},
"files": ["dist"],
"files": [
"dist"
],
"engines": {
"node": ">=4"
},
Expand All @@ -21,7 +23,10 @@
"type": "git",
"url": "https://github.com/jfmengels/all-contributors-cli.git"
},
"keywords": ["all-contributors", "contributors"],
"keywords": [
"all-contributors",
"contributors"
],
"author": "Jeroen Engels <jfm.engels@gmail.com>",
"license": "MIT",
"bugs": {
Expand All @@ -41,7 +46,11 @@
"kcd-scripts": "^0.29.0",
"nock": "^9.1.0"
},
"eslintIgnore": ["node_modules", "coverage", "dist"],
"eslintIgnore": [
"node_modules",
"coverage",
"dist"
],
"eslintConfig": {
"extends": "./node_modules/kcd-scripts/eslint.js",
"rules": {
Expand Down
1 change: 1 addition & 0 deletions src/cli.js
Expand Up @@ -81,6 +81,7 @@ function checkContributors(argv) {
configData.projectName,
configData.repoType,
configData.repoHost,
configData.privateToken,
)
.then(repoContributors => {
const checkKey = repo.getCheckKey(configData.repoType)
Expand Down
19 changes: 11 additions & 8 deletions src/contributors/add.js
Expand Up @@ -46,14 +46,17 @@ function updateExistingContributor(options, username, contributions) {
}

function addNewContributor(options, username, contributions, infoFetcher) {
return infoFetcher(username, options.repoType, options.repoHost).then(
userData => {
const contributor = _.assign(userData, {
contributions: formatContributions(options, [], contributions),
})
return options.contributors.concat(contributor)
},
)
return infoFetcher(
username,
options.repoType,
options.repoHost,
options.privateToken,
).then(userData => {
const contributor = _.assign(userData, {
contributions: formatContributions(options, [], contributions),
})
return options.contributors.concat(contributor)
})
}

module.exports = function addContributor(
Expand Down
16 changes: 14 additions & 2 deletions src/init/prompt.js
Expand Up @@ -32,7 +32,8 @@ const questions = [
{
type: 'input',
name: 'repoHost',
message: 'Where is the repository hosted? Hit Enter if it\'s on GitHub or GitLab',
message:
"Where is the repository hosted? Hit Enter if it's on GitHub or GitLab",
default: function(answers) {
if (answers.repoType === 'github') {
return 'https://github.com'
Expand All @@ -41,6 +42,13 @@ const questions = [
}
},
},
{
type: 'input',
name: 'privateToken',
message:
'What is the personal access token? (If you use a self hosted repository)',
default: '',
},
{
type: 'input',
name: 'contributorFile',
Expand Down Expand Up @@ -79,7 +87,10 @@ const questions = [
},
]

const uniqueFiles = _.flow(_.compact, _.uniq)
const uniqueFiles = _.flow(
_.compact,
_.uniq,
)

module.exports = function prompt() {
return git
Expand All @@ -98,6 +109,7 @@ module.exports = function prompt() {
projectOwner: answers.projectOwner,
repoType: answers.repoType,
repoHost: answers.repoHost,
privateToken: answers.privateToken,
files: uniqueFiles([answers.contributorFile, answers.badgeFile]),
imageSize: answers.imageSize,
commit: answers.commit,
Expand Down
29 changes: 29 additions & 0 deletions src/repo/__tests__/gitlab.js
Expand Up @@ -103,3 +103,32 @@ test('retrieve user from a different gitlab registry', async () => {
)
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', ''),
)
})
28 changes: 21 additions & 7 deletions src/repo/gitlab.js
@@ -1,15 +1,25 @@
const pify = require('pify')
const request = pify(require('request'))

const getUserInfo = function(username, hostname) {
const addPrivateToken = (url, privateToken = '') => {
if (privateToken === '') return url
return `${url}&private_token=${privateToken}`
.replace(/\?/g, '&')
.replace('&', '?')
}

const getUserInfo = function(username, hostname, privateToken = '') {
/* eslint-disable complexity */
if (!hostname) {
hostname = 'https://gitlab.com'
}

return request
.get({
url: `${hostname}/api/v4/users?username=${username}`,
url: addPrivateToken(
`${hostname}/api/v4/users?username=${username}`,
privateToken,
),
headers: {
'User-Agent': 'request',
},
Expand All @@ -35,14 +45,17 @@ const getUserInfo = function(username, hostname) {
})
}

const getContributors = function(owner, name, hostname) {
const getContributors = function(owner, name, hostname, privateToken = '') {
if (!hostname) {
hostname = 'https://gitlab.com'
}

return request
.get({
url: `${hostname}/api/v4/projects?search=${name}`,
url: addPrivateToken(
`${hostname}/api/v4/projects?search=${name}`,
privateToken,
),
headers: {
'User-Agent': 'request',
},
Expand All @@ -69,9 +82,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`,
privateToken,
),
headers: {
'User-Agent': 'request',
},
Expand Down
12 changes: 10 additions & 2 deletions src/repo/index.js
Expand Up @@ -76,22 +76,30 @@ const getLinkToIssues = function(repoType) {
return null
}

const getUserInfo = function(username, repoType, repoHost) {
const getUserInfo = function(username, repoType, repoHost, privateToken = '') {
if (repoType in SUPPORTED_REPO_TYPES) {
return SUPPORTED_REPO_TYPES[repoType].getUserInfo(
username,
getHostname(repoType, repoHost),
privateToken,
)
}
return null
}

const getContributors = function(owner, name, repoType, repoHost) {
const getContributors = function(
owner,
name,
repoType,
repoHost,
privateToken = '',
) {
if (repoType in SUPPORTED_REPO_TYPES) {
return SUPPORTED_REPO_TYPES[repoType].getContributors(
owner,
name,
getHostname(repoType, repoHost),
privateToken,
)
}
return null
Expand Down

0 comments on commit c4c9d7b

Please sign in to comment.