diff --git a/services/gitlab/gitlab-license.service.js b/services/gitlab/gitlab-license.service.js new file mode 100644 index 0000000000000..ae847804302b3 --- /dev/null +++ b/services/gitlab/gitlab-license.service.js @@ -0,0 +1,89 @@ +import Joi from 'joi' +import { optionalUrl } from '../validators.js' +import { renderLicenseBadge } from '../licenses.js' +import GitLabBase from './gitlab-base.js' + +const schema = Joi.object({ + license: Joi.object({ + name: Joi.string().required(), + }).allow(null), +}).required() + +const queryParamSchema = Joi.object({ + gitlab_url: optionalUrl, +}).required() + +const documentation = ` +

+ You may use your GitLab Project Id (e.g. 13083) or your Project Path (e.g. gitlab-org/gitlab-foss ) +

+` +const commonProps = { + namedParams: { + project: 'gitlab-org/gitlab-foss', + }, + documentation, +} + +export default class GitlabLicense extends GitLabBase { + static category = 'license' + + static route = { + base: 'gitlab/v/license', + pattern: ':project+', + queryParamSchema, + } + + static examples = [ + { + title: 'GitLab', + ...commonProps, + staticPreview: { + label: 'license', + message: 'MIT License', + color: 'green', + }, + }, + { + title: 'GitLab (custom server)', + ...commonProps, + queryParams: { gitlab_url: 'https://jihulab.com' }, + staticPreview: { + label: 'license', + message: 'MIT License', + color: 'green', + }, + }, + ] + + static defaultBadgeData = { label: 'license' } + + static render({ license }) { + if (license) { + return renderLicenseBadge({ license }) + } else { + return { message: 'not specified' } + } + } + + async fetch({ project, baseUrl }) { + // https://docs.gitlab.com/ee/api/projects.html#get-single-project + return super.fetch({ + schema, + url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`, + options: { searchParams: { license: '1' } }, + errorMessages: { + 404: 'repo not found', + }, + }) + } + + async handle({ project }, { gitlab_url: baseUrl = 'https://gitlab.com' }) { + const { license: licenseObject } = await this.fetch({ + project, + baseUrl, + }) + const license = licenseObject ? licenseObject.name : undefined + return this.constructor.render({ license }) + } +} diff --git a/services/gitlab/gitlab-license.tester.js b/services/gitlab/gitlab-license.tester.js new file mode 100644 index 0000000000000..7d848cc40be8e --- /dev/null +++ b/services/gitlab/gitlab-license.tester.js @@ -0,0 +1,57 @@ +import { licenseToColor } from '../licenses.js' +import { createServiceTester } from '../tester.js' +export const t = await createServiceTester() + +const publicDomainLicenseColor = licenseToColor('MIT License') +const unknownLicenseColor = licenseToColor() + +t.create('License') + .get('/guoxudong.io/shields-test/licenced-test.json') + .expectBadge({ + label: 'license', + message: 'MIT License', + color: `${publicDomainLicenseColor}`, + }) + +t.create('License for repo without a license') + .get('/guoxudong.io/shields-test/no-license-test.json') + .expectBadge({ + label: 'license', + message: 'not specified', + color: 'lightgrey', + }) + +t.create('Other license').get('/gitlab-org/gitlab-foss.json').expectBadge({ + label: 'license', + message: 'Other', + color: unknownLicenseColor, +}) + +t.create('License for unknown repo') + .get('/user1/gitlab-does-not-have-this-repo.json') + .expectBadge({ + label: 'license', + message: 'repo not found', + color: 'red', + }) + +t.create('Mocking License') + .get('/group/project.json') + .intercept(nock => + nock('https://gitlab.com') + .get('/api/v4/projects/group%2Fproject?license=1') + .reply(200, { + license: { + key: 'apache-2.0', + name: 'Apache License 2.0', + nickname: '', + html_url: 'http://choosealicense.com/licenses/apache-2.0/', + source_url: '', + }, + }) + ) + .expectBadge({ + label: 'license', + message: 'Apache License 2.0', + color: unknownLicenseColor, + })