[pypi]: Fix broken badges (#2023)
- When license is empty, get license from trove classifiers - Allow empty classifiers array
This commit is contained in:
@@ -6,9 +6,10 @@ const BaseJsonService = require('../base-json')
|
||||
const schema = Joi.object({
|
||||
info: Joi.object({
|
||||
version: Joi.string().required(),
|
||||
license: Joi.string().required(),
|
||||
// https://github.com/badges/shields/issues/2022
|
||||
license: Joi.string().allow(''),
|
||||
classifiers: Joi.array()
|
||||
.items(Joi.string().required())
|
||||
.items(Joi.string())
|
||||
.required(),
|
||||
}).required(),
|
||||
releases: Joi.object()
|
||||
|
||||
@@ -50,6 +50,27 @@ const parseClassifiers = function(parsedData, pattern) {
|
||||
return results
|
||||
}
|
||||
|
||||
function getLicenses(packageData) {
|
||||
const {
|
||||
info: { license },
|
||||
} = packageData
|
||||
if (license) {
|
||||
return [license]
|
||||
} else {
|
||||
const acronymRegex = /\(([^)]+)\)/
|
||||
let licenses = parseClassifiers(packageData, /^License :: (.+)$/)
|
||||
.map(classifier => classifier.split(' :: ').pop())
|
||||
.map(license => {
|
||||
const match = license.match(acronymRegex)
|
||||
return match ? match[1].toUpperCase() : license
|
||||
})
|
||||
if (licenses.length > 1) {
|
||||
licenses = licenses.filter(l => l !== 'dfsg approved')
|
||||
}
|
||||
return licenses
|
||||
}
|
||||
}
|
||||
|
||||
function getPackageFormats(packageData) {
|
||||
const {
|
||||
info: { version },
|
||||
@@ -70,5 +91,6 @@ module.exports = {
|
||||
parseClassifiers,
|
||||
parseDjangoVersionString,
|
||||
sortDjangoVersions,
|
||||
getLicenses,
|
||||
getPackageFormats,
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
const { test, given } = require('sazerac')
|
||||
const { test, given, forCases } = require('sazerac')
|
||||
const {
|
||||
parseClassifiers,
|
||||
parseDjangoVersionString,
|
||||
sortDjangoVersions,
|
||||
getLicenses,
|
||||
getPackageFormats,
|
||||
} = require('./pypi-helpers.js')
|
||||
|
||||
@@ -100,6 +101,29 @@ describe('PyPI helpers', function() {
|
||||
])
|
||||
})
|
||||
|
||||
test(getLicenses, () => {
|
||||
forCases([given({ info: { license: 'MIT', classifiers: [] } })]).expect([
|
||||
'MIT',
|
||||
])
|
||||
forCases([
|
||||
given({
|
||||
info: {
|
||||
license: '',
|
||||
classifiers: ['License :: OSI Approved :: MIT License'],
|
||||
},
|
||||
}),
|
||||
given({
|
||||
info: {
|
||||
license: '',
|
||||
classifiers: [
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'License :: DFSG approved',
|
||||
],
|
||||
},
|
||||
}),
|
||||
]).expect(['mit license'])
|
||||
})
|
||||
|
||||
test(getPackageFormats, () => {
|
||||
given({
|
||||
info: { version: '2.19.1' },
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
const { renderLicenseBadge } = require('../../lib/licenses')
|
||||
const PypiBase = require('./pypi-base')
|
||||
const { getLicenses } = require('./pypi-helpers')
|
||||
|
||||
module.exports = class PypiLicense extends PypiBase {
|
||||
static get category() {
|
||||
@@ -22,14 +23,13 @@ module.exports = class PypiLicense extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static render({ license }) {
|
||||
return renderLicenseBadge({ license })
|
||||
static render({ licenses }) {
|
||||
return renderLicenseBadge({ licenses })
|
||||
}
|
||||
|
||||
async handle({ egg }) {
|
||||
const {
|
||||
info: { license },
|
||||
} = await this.fetch({ egg })
|
||||
return this.constructor.render({ license })
|
||||
const packageData = await this.fetch({ egg })
|
||||
const licenses = getLicenses(packageData)
|
||||
return this.constructor.render({ licenses })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,25 @@ t.create('version (invalid)')
|
||||
.get('/v/not-a-package.json')
|
||||
.expectJSON({ name: 'pypi', value: 'package or version not found' })
|
||||
|
||||
t.create('no trove classifiers')
|
||||
.get('/v/mapi.json')
|
||||
.intercept(nock =>
|
||||
nock('https://pypi.org')
|
||||
.get('/pypi/mapi/json')
|
||||
.reply(200, {
|
||||
info: {
|
||||
version: '1.2.3',
|
||||
license: 'foo',
|
||||
classifiers: [],
|
||||
},
|
||||
releases: {},
|
||||
})
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'pypi',
|
||||
value: 'v1.2.3',
|
||||
})
|
||||
|
||||
// tests for license endpoint
|
||||
|
||||
t.create('license (valid, package version in request)')
|
||||
@@ -98,6 +117,46 @@ t.create('license (invalid)')
|
||||
.get('/l/not-a-package.json')
|
||||
.expectJSON({ name: 'license', value: 'package or version not found' })
|
||||
|
||||
t.create('license (from trove classifier)')
|
||||
.get('/l/mapi.json')
|
||||
.intercept(nock =>
|
||||
nock('https://pypi.org')
|
||||
.get('/pypi/mapi/json')
|
||||
.reply(200, {
|
||||
info: {
|
||||
version: '1.2.3',
|
||||
license: '',
|
||||
classifiers: ['License :: OSI Approved :: MIT License'],
|
||||
},
|
||||
releases: {},
|
||||
})
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'license',
|
||||
value: 'mit license',
|
||||
})
|
||||
|
||||
t.create('license (as acronym from trove classifier)')
|
||||
.get('/l/magma.json')
|
||||
.intercept(nock =>
|
||||
nock('https://pypi.org')
|
||||
.get('/pypi/magma/json')
|
||||
.reply(200, {
|
||||
info: {
|
||||
version: '1.2.3',
|
||||
license: '',
|
||||
classifiers: [
|
||||
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||
],
|
||||
},
|
||||
releases: {},
|
||||
})
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'license',
|
||||
value: 'GPL',
|
||||
})
|
||||
|
||||
// tests for wheel endpoint
|
||||
|
||||
t.create('wheel (has wheel, package version in request)')
|
||||
|
||||
Reference in New Issue
Block a user