From e8b4467609602799d51e5c45b36e4235f6fe7d4a Mon Sep 17 00:00:00 2001
From: jNullj <15849761+jNullj@users.noreply.github.com>
Date: Sun, 10 Sep 2023 15:18:16 +0300
Subject: [PATCH] Add [PythonVersionFromToml] shield (#9516)

* Add PythonVersionFromToml

Added new shield per issue #9410
The shield display required python versions for packages based on pyproject.toml

* Add tests for PythonVersionFromToml

* Improve docs for tests regex

* Improve title and description

Rename and updated description to bring into focus that only PEP 621 complaint pyproject.toml files are supported.

Solves review https://github.com/badges/shields/pull/9516#discussion_r1310648023

* replace complex regex with @renovate/pep440

solves review https://github.com/badges/shields/pull/9516#discussion_r1310648881
---
 .../python-version-from-toml.service.js       | 65 +++++++++++++++++++
 .../python/python-version-from-toml.tester.js | 27 ++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 services/python/python-version-from-toml.service.js
 create mode 100644 services/python/python-version-from-toml.tester.js

diff --git a/services/python/python-version-from-toml.service.js b/services/python/python-version-from-toml.service.js
new file mode 100644
index 0000000000..f05fe0d296
--- /dev/null
+++ b/services/python/python-version-from-toml.service.js
@@ -0,0 +1,65 @@
+import Joi from 'joi'
+import BaseTomlService from '../../core/base-service/base-toml.js'
+import { optionalUrl } from '../validators.js'
+
+const queryParamSchema = Joi.object({
+  tomlFilePath: optionalUrl.required(),
+}).required()
+
+const schema = Joi.object({
+  project: Joi.object({
+    'requires-python': Joi.string().required(),
+  }).required(),
+}).required()
+
+const documentation = `Shows the required python version for a package based on the values in the requires-python field in PEP 621 compliant pyproject.toml \n
+a URL of the toml is required, please note that when linking to files in github or similar sites, provide URL to raw file, for example:
+
+Use https://raw.githubusercontent.com/numpy/numpy/main/pyproject.toml \n
+And not https://github.com/numpy/numpy/blob/main/pyproject.toml
+`
+
+class PythonVersionFromToml extends BaseTomlService {
+  static category = 'platform-support'
+
+  static route = {
+    base: '',
+    pattern: 'python/required-version-toml',
+    queryParamSchema,
+  }
+
+  static examples = [
+    {
+      title: 'Python Version from PEP 621 TOML',
+      namedParams: {},
+      queryParams: {
+        tomlFilePath:
+          'https://raw.githubusercontent.com/numpy/numpy/main/pyproject.toml',
+      },
+      staticPreview: this.render({ requiresPythonString: '>=3.9' }),
+      documentation,
+    },
+  ]
+
+  static defaultBadgeData = { label: 'python' }
+
+  static render({ requiresPythonString }) {
+    // we only show requries-python as is
+    // for more info read the following issues:
+    // https://github.com/badges/shields/issues/9410
+    // https://github.com/badges/shields/issues/5551
+    return {
+      message: requiresPythonString,
+      color: 'blue',
+    }
+  }
+
+  async handle(namedParams, { tomlFilePath }) {
+    const tomlData = await this._requestToml({ url: tomlFilePath, schema })
+    const requiresPythonString = tomlData.project['requires-python']
+
+    return this.constructor.render({ requiresPythonString })
+  }
+}
+
+export { PythonVersionFromToml }
diff --git a/services/python/python-version-from-toml.tester.js b/services/python/python-version-from-toml.tester.js
new file mode 100644
index 0000000000..b1a0cdeaf1
--- /dev/null
+++ b/services/python/python-version-from-toml.tester.js
@@ -0,0 +1,27 @@
+import Joi from 'joi'
+import pep440 from '@renovate/pep440'
+import { createServiceTester } from '../tester.js'
+export const t = await createServiceTester()
+
+const validatePep440 = (value, helpers) => {
+  if (!pep440.validRange(value)) {
+    return helpers.error('any.invalid')
+  }
+  return value
+}
+
+const isCommaSeparatedPythonVersions = Joi.string().custom(validatePep440)
+
+t.create('python versions (valid)')
+  .get(
+    '/python/required-version-toml.json?tomlFilePath=https://raw.githubusercontent.com/numpy/numpy/main/pyproject.toml',
+  )
+  .expectBadge({ label: 'python', message: isCommaSeparatedPythonVersions })
+
+t.create(
+  'python versions - valid toml with missing python-requires field (invalid)',
+)
+  .get(
+    '/python/required-version-toml.json?tomlFilePath=https://raw.githubusercontent.com/django/django/main/pyproject.toml',
+  )
+  .expectBadge({ label: 'python', message: 'invalid response data' })
-- 
GitLab