Rewrite [pypi]; affects [npm] (#1922)

This commit is contained in:
Paul Melnikow
2018-08-27 07:46:06 -04:00
committed by GitHub
parent 78bb890b52
commit 302c8606ff
25 changed files with 691 additions and 273 deletions

View File

@@ -614,21 +614,6 @@ const allBadgeExamples = [
title: 'PowerShell Gallery',
previewUri: '/powershellgallery/dt/ACMESharp.svg',
},
{
title: 'PyPI',
previewUri: '/pypi/dm/Django.svg',
keywords: ['python'],
},
{
title: 'PyPI',
previewUri: '/pypi/dw/Django.svg',
keywords: ['python'],
},
{
title: 'PyPI',
previewUri: '/pypi/dd/Django.svg',
keywords: ['python'],
},
{
title: 'Conda',
previewUri: '/conda/dn/conda-forge/python.svg',
@@ -1048,11 +1033,6 @@ const allBadgeExamples = [
title: 'Bower',
previewUri: '/bower/l/bootstrap.svg',
},
{
title: 'PyPI - License',
previewUri: '/pypi/l/Django.svg',
keywords: ['python', 'pypi'],
},
{
title: 'Hex.pm',
previewUri: '/hexpm/l/plug.svg',
@@ -1222,9 +1202,14 @@ const allBadgeExamples = [
},
examples: [
{
title: 'PyPI',
previewUri: '/pypi/v/nine.svg',
keywords: ['python'],
title: 'npm bundle size (minified)',
previewUri: '/bundlephobia/min/react.svg',
keywords: ['node'],
},
{
title: 'npm bundle size (minified + gzip)',
previewUri: '/bundlephobia/minzip/react.svg',
keywords: ['node'],
},
{
title: 'Conda',
@@ -1552,24 +1537,8 @@ const allBadgeExamples = [
},
examples: [
{
title: 'PyPI - Wheel',
previewUri: '/pypi/wheel/Django.svg',
keywords: ['python', 'pypi'],
},
{
title: 'PyPI - Format',
previewUri: '/pypi/format/Django.svg',
keywords: ['python', 'pypi'],
},
{
title: 'PyPI - Implementation',
previewUri: '/pypi/implementation/Django.svg',
keywords: ['python', 'pypi'],
},
{
title: 'PyPI - Status',
previewUri: '/pypi/status/Django.svg',
keywords: ['python', 'pypi'],
title: 'VersionEye',
previewUri: '/versioneye/d/ruby/rails.svg',
},
{
title: 'Wheelmap',

View File

@@ -2,6 +2,7 @@
const { makeBadgeData, setBadgeColor } = require('./badge-data')
const { deprecatedServices } = require('./deprecated-services')
const { Deprecated } = require('../services/errors')
const isDeprecated = function(
service,
@@ -21,7 +22,14 @@ const getDeprecatedBadge = function(label, data) {
return badgeData
}
function enforceDeprecation(effectiveDate) {
if (Date.now() >= effectiveDate.getTime()) {
throw new Deprecated()
}
}
module.exports = {
isDeprecated,
getDeprecatedBadge,
enforceDeprecation,
}

View File

@@ -1,4 +1,7 @@
'use strict'
const { toArray } = require('./badge-data')
const licenseTypes = {
// permissive licenses - not public domain and not copyleft
permissive: {
@@ -59,4 +62,21 @@ const defaultLicenseColor = 'lightgrey'
const licenseToColor = spdxId =>
licenseToColorMap[spdxId] || defaultLicenseColor
module.exports = { licenseToColor }
function renderLicenseBadge({ license, licenses }) {
if (licenses === undefined) {
licenses = toArray(license)
}
if (licenses.length === 0) {
return { message: 'missing', color: 'red' }
}
return {
message: licenses.join(', '),
// TODO This does not provide a color when more than one license is
// present. Probably that should be fixed.
color: licenseToColor(licenses),
}
}
module.exports = { licenseToColor, renderLicenseBadge }

View File

@@ -1,7 +1,7 @@
'use strict'
const { test, given } = require('sazerac')
const { licenseToColor } = require('./licenses')
const { test, given, forCases } = require('sazerac')
const { licenseToColor, renderLicenseBadge } = require('./licenses')
describe('license helpers', function() {
test(licenseToColor, () => {
@@ -11,4 +11,26 @@ describe('license helpers', function() {
given('unknown-license').expect('lightgrey')
given(null).expect('lightgrey')
})
test(renderLicenseBadge, () => {
forCases([
given({ license: undefined }),
given({ licenses: [] }),
given({}),
]).expect({
message: 'missing',
color: 'red',
})
forCases([
given({ license: 'WTFPL' }),
given({ licenses: ['WTFPL'] }),
]).expect({
message: 'WTFPL',
color: '7cd958',
})
given({ licenses: ['MPL-2.0', 'MIT'] }).expect({
message: 'MPL-2.0, MIT',
color: 'lightgrey',
})
})
})

View File

@@ -1,57 +0,0 @@
'use strict'
/*
Django versions will be specified in the form major.minor
trying to sort with `semver.compare` will throw e.g:
TypeError: Invalid Version: 1.11
because no patch release is specified, so we will define
our own functions to parse and sort django versions
*/
const parseDjangoVersionString = function(str) {
if (typeof str !== 'string') {
return false
}
const x = str.split('.')
const maj = parseInt(x[0]) || 0
const min = parseInt(x[1]) || 0
return {
major: maj,
minor: min,
}
}
// sort an array of django versions low to high
const sortDjangoVersions = function(versions) {
return versions.sort((a, b) => {
if (
parseDjangoVersionString(a).major === parseDjangoVersionString(b).major
) {
return (
parseDjangoVersionString(a).minor - parseDjangoVersionString(b).minor
)
} else {
return (
parseDjangoVersionString(a).major - parseDjangoVersionString(b).major
)
}
})
}
// extract classifiers from a pypi json response based on a regex
const parseClassifiers = function(parsedData, pattern) {
const results = []
for (let i = 0; i < parsedData.info.classifiers.length; i++) {
const matched = pattern.exec(parsedData.info.classifiers[i])
if (matched && matched[1]) {
results.push(matched[1].toLowerCase())
}
}
return results
}
module.exports = {
parseClassifiers,
parseDjangoVersionString,
sortDjangoVersions,
}

View File

@@ -1,100 +0,0 @@
'use strict'
const { test, given } = require('sazerac')
const {
parseClassifiers,
parseDjangoVersionString,
sortDjangoVersions,
} = require('./pypi-helpers.js')
const classifiersFixture = {
info: {
classifiers: [
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11',
'Intended Audience :: Developers',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Natural Language :: English',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Topic :: Internet :: WWW/HTTP',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
],
},
}
describe('PyPI helpers', function() {
test(parseClassifiers, function() {
given(
classifiersFixture,
/^Programming Language :: Python :: ([\d.]+)$/
).expect(['2', '2.7', '3', '3.4', '3.5', '3.6'])
given(classifiersFixture, /^Framework :: Django :: ([\d.]+)$/).expect([
'1.10',
'1.11',
])
given(
classifiersFixture,
/^Programming Language :: Python :: Implementation :: (\S+)$/
).expect(['cpython', 'pypy'])
// regex that matches everything
given(classifiersFixture, /^([\S\s+]+)$/).expect(
classifiersFixture.info.classifiers.map(e => e.toLowerCase())
)
// regex that matches nothing
given(classifiersFixture, /^(?!.*)*$/).expect([])
})
test(parseDjangoVersionString, function() {
given('1').expect({ major: 1, minor: 0 })
given('1.0').expect({ major: 1, minor: 0 })
given('7.2').expect({ major: 7, minor: 2 })
given('7.2derpderp').expect({ major: 7, minor: 2 })
given('7.2.9.5.8.3').expect({ major: 7, minor: 2 })
given('foo').expect({ major: 0, minor: 0 })
})
test(sortDjangoVersions, function() {
given(['2.0', '1.9', '10', '1.11', '2.1', '2.11']).expect([
'1.9',
'1.11',
'2.0',
'2.1',
'2.11',
'10',
])
given(['2', '1.9', '10', '1.11', '2.1', '2.11']).expect([
'1.9',
'1.11',
'2',
'2.1',
'2.11',
'10',
])
given(['2.0rc1', '10', '1.9', '1.11', '2.1', '2.11']).expect([
'1.9',
'1.11',
'2.0rc1',
'2.1',
'2.11',
'10',
])
})
})

View File

@@ -8,6 +8,8 @@
'use strict'
const semver = require('semver')
const { addv } = require('./text-formatters')
const { version: versionColor } = require('./color-formatters')
// Given a list of versions (as strings), return the latest version.
// Return undefined if no version could be found.
@@ -139,10 +141,19 @@ function rangeStart(v) {
return range.set[0][0].semver.version
}
function renderVersionBadge({ version, tag, defaultLabel }) {
return {
label: tag ? `${defaultLabel}@${tag}` : undefined,
message: addv(version),
color: versionColor(version),
}
}
module.exports = {
latest,
listCompare,
slice,
minor,
rangeStart,
renderVersionBadge,
}

View File

@@ -1,7 +1,7 @@
'use strict'
const { test, given } = require('sazerac')
const { latest, slice, rangeStart } = require('./version')
const { latest, slice, rangeStart, renderVersionBadge } = require('./version')
const includePre = true
describe('Version helpers', function() {
@@ -119,4 +119,17 @@ describe('Version helpers', function() {
test(rangeStart, () => {
given('^2.4.7').expect('2.4.7')
})
test(renderVersionBadge, () => {
given({ version: '1.2.3' }).expect({
label: undefined,
message: 'v1.2.3',
color: 'blue',
})
given({ version: '1.2.3', tag: 'next', defaultLabel: 'npm' }).expect({
label: 'npm@next',
message: 'v1.2.3',
color: 'blue',
})
})
})