Compare commits
2 Commits
master
...
requires-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
332a496e84 | ||
|
|
5f28ac34cc |
15
package-lock.json
generated
15
package-lock.json
generated
@@ -6460,6 +6460,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@renovate/pep440": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@renovate/pep440/-/pep440-0.4.1.tgz",
|
||||
"integrity": "sha512-UJR4qqM5l1b84iXd9SS8nPOFfxCWDgL3uOhhYwb15DgC1j8wf5ZLoyTcVUhnCLXG770c999PNLJEUl4wRscvhQ==",
|
||||
"requires": {
|
||||
"xregexp": "4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"xregexp": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.0.tgz",
|
||||
"integrity": "sha512-IyMa7SVe9FyT4WbQVW3b95mTLVceHhLEezQ02+QMvmIqDnKTxk0MLWIQPSW2MXAr1zQb+9yvwYhcyQULneh3wA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@samverschueren/stream-to-observable": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz",
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^17.1.1",
|
||||
"@renovate/pep440": "^0.4.1",
|
||||
"@sentry/node": "^5.24.2",
|
||||
"@shields_io/camp": "^18.0.0",
|
||||
"badge-maker": "file:badge-maker",
|
||||
"bytes": "^3.1.0",
|
||||
"camelcase": "^5.3.1",
|
||||
"@shields_io/camp": "^18.0.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chalk": "^4.1.0",
|
||||
"check-node-version": "^4.0.3",
|
||||
@@ -39,7 +41,6 @@
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"fast-xml-parser": "^3.17.4",
|
||||
"fsos": "^1.1.6",
|
||||
"badge-maker": "file:badge-maker",
|
||||
"glob": "^7.1.6",
|
||||
"graphql": "^14.7.0",
|
||||
"graphql-tag": "^2.11.0",
|
||||
|
||||
@@ -9,6 +9,7 @@ const schema = Joi.object({
|
||||
// https://github.com/badges/shields/issues/2022
|
||||
license: Joi.string().allow(''),
|
||||
classifiers: Joi.array().items(Joi.string()).required(),
|
||||
requires_python: Joi.alternatives().try(Joi.string(), Joi.allow(null)),
|
||||
}).required(),
|
||||
releases: Joi.object()
|
||||
.pattern(
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const { satisfies } = require('@renovate/pep440')
|
||||
|
||||
// This list tracks "Active Python Releases" at
|
||||
// https://www.python.org/downloads/ which means it needs to be manually updated
|
||||
// every two years or so. It would be good to find a machine-readable version of
|
||||
// this listing (like we do with PHP) so it does not need to be updated manually.
|
||||
const ACTIVE_PYTHON_VERSIONS = ['2.7', '3.5', '3.6', '3.7', '3.8']
|
||||
|
||||
/*
|
||||
Django versions will be specified in the form major.minor
|
||||
trying to sort with `semver.compare` will throw e.g:
|
||||
@@ -93,10 +101,52 @@ function getPackageFormats(packageData) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPythonVersionsFromClassifiers(packageData) {
|
||||
let versions = parseClassifiers(
|
||||
packageData,
|
||||
/^Programming Language :: Python :: ([\d.]+)$/
|
||||
)
|
||||
|
||||
// If no versions are found yet, check "X :: Only" as a fallback.
|
||||
if (versions.length === 0) {
|
||||
versions.push(
|
||||
...parseClassifiers(
|
||||
packageData,
|
||||
/^Programming Language :: Python :: (\d+) :: Only$/
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// We only show v2 if eg. v2.4 does not appear.
|
||||
// See https://github.com/badges/shields/pull/489 for more.
|
||||
;['2', '3'].forEach(majorVersion => {
|
||||
if (versions.some(v => v.startsWith(`${majorVersion}.`))) {
|
||||
versions = versions.filter(v => v !== majorVersion)
|
||||
}
|
||||
})
|
||||
|
||||
return versions.sort()
|
||||
}
|
||||
|
||||
function getPythonVersionsFromPythonRequires(packageData) {
|
||||
const {
|
||||
info: { requires_python: pythonRequires },
|
||||
} = packageData
|
||||
if (pythonRequires) {
|
||||
return ACTIVE_PYTHON_VERSIONS.filter(activeVersion =>
|
||||
satisfies(activeVersion, pythonRequires)
|
||||
)
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseClassifiers,
|
||||
parseDjangoVersionString,
|
||||
sortDjangoVersions,
|
||||
getLicenses,
|
||||
getPackageFormats,
|
||||
getPythonVersionsFromClassifiers,
|
||||
getPythonVersionsFromPythonRequires,
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ const {
|
||||
sortDjangoVersions,
|
||||
getLicenses,
|
||||
getPackageFormats,
|
||||
getPythonVersionsFromPythonRequires,
|
||||
} = require('./pypi-helpers')
|
||||
|
||||
const classifiersFixture = {
|
||||
@@ -168,4 +169,13 @@ describe('PyPI helpers', function () {
|
||||
},
|
||||
}).expect({ hasWheel: false, hasEgg: true })
|
||||
})
|
||||
|
||||
test(getPythonVersionsFromPythonRequires, () => {
|
||||
given({ info: { requires_python: null } }).expect(undefined)
|
||||
given({
|
||||
info: {
|
||||
requires_python: '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
},
|
||||
}).expect(['2.7', '3.5', '3.6', '3.7', '3.8'])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
const PypiBase = require('./pypi-base')
|
||||
const { parseClassifiers } = require('./pypi-helpers')
|
||||
const {
|
||||
getPythonVersionsFromClassifiers,
|
||||
getPythonVersionsFromPythonRequires,
|
||||
} = require('./pypi-helpers')
|
||||
|
||||
module.exports = class PypiPythonVersions extends PypiBase {
|
||||
static get category() {
|
||||
@@ -18,7 +21,7 @@ module.exports = class PypiPythonVersions extends PypiBase {
|
||||
title: 'PyPI - Python Version',
|
||||
pattern: ':packageName',
|
||||
namedParams: { packageName: 'Django' },
|
||||
staticPreview: this.render({ versions: ['3.5', '3.6', '3.7'] }),
|
||||
staticPreview: this.render({ versions: ['3.5', '3.6', '3.7', '3.8'] }),
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -28,17 +31,9 @@ module.exports = class PypiPythonVersions extends PypiBase {
|
||||
}
|
||||
|
||||
static render({ versions }) {
|
||||
const versionSet = new Set(versions)
|
||||
// We only show v2 if eg. v2.4 does not appear.
|
||||
// See https://github.com/badges/shields/pull/489 for more.
|
||||
;['2', '3'].forEach(majorVersion => {
|
||||
if (Array.from(versions).some(v => v.startsWith(`${majorVersion}.`))) {
|
||||
versionSet.delete(majorVersion)
|
||||
}
|
||||
})
|
||||
if (versionSet.size) {
|
||||
if (versions.length) {
|
||||
return {
|
||||
message: Array.from(versionSet).sort().join(' | '),
|
||||
message: versions.join(' | '),
|
||||
color: 'blue',
|
||||
}
|
||||
} else {
|
||||
@@ -52,19 +47,10 @@ module.exports = class PypiPythonVersions extends PypiBase {
|
||||
async handle({ egg }) {
|
||||
const packageData = await this.fetch({ egg })
|
||||
|
||||
const versions = parseClassifiers(
|
||||
packageData,
|
||||
/^Programming Language :: Python :: ([\d.]+)$/
|
||||
)
|
||||
// If no versions are found yet, check "X :: Only" as a fallback.
|
||||
if (versions.length === 0) {
|
||||
versions.push(
|
||||
...parseClassifiers(
|
||||
packageData,
|
||||
/^Programming Language :: Python :: (\d+) :: Only$/
|
||||
)
|
||||
)
|
||||
}
|
||||
const versions =
|
||||
getPythonVersionsFromClassifiers(packageData) ||
|
||||
getPythonVersionsFromPythonRequires(packageData) ||
|
||||
[]
|
||||
|
||||
return this.constructor.render({ versions })
|
||||
}
|
||||
|
||||
@@ -21,11 +21,29 @@ t.create('python versions (valid, no package version specified)')
|
||||
message: isPipeSeparatedPythonVersions,
|
||||
})
|
||||
|
||||
t.create('python versions ("Only" and others)')
|
||||
t.create(
|
||||
'python versions (valid, package version in request, experimental flag)'
|
||||
)
|
||||
.get('/requests/2.18.4.json?experimental')
|
||||
.expectBadge({
|
||||
label: 'python',
|
||||
message: isPipeSeparatedPythonVersions,
|
||||
})
|
||||
|
||||
t.create(
|
||||
'python versions (valid, no package version specified, experimental flag)'
|
||||
)
|
||||
.get('/requests.json?experimental')
|
||||
.expectBadge({
|
||||
label: 'python',
|
||||
message: isPipeSeparatedPythonVersions,
|
||||
})
|
||||
|
||||
t.create('python versions ("Only" classifier and others)')
|
||||
.get('/uvloop/0.12.1.json')
|
||||
.expectBadge({ label: 'python', message: '3.5 | 3.6 | 3.7' })
|
||||
|
||||
t.create('python versions ("Only" only)')
|
||||
t.create('python versions ("Only" classifier only)')
|
||||
.get('/hashpipe/0.9.1.json')
|
||||
.expectBadge({ label: 'python', message: '3' })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user