From c2531910b60a15ea470e796a74e9476dca0b9a60 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 6 Mar 2025 12:14:15 +0100 Subject: [PATCH 1/5] docs: showcase usage with `uv` Signed-off-by: Jan Kowalleck --- README.md | 2 ++ cyclonedx_py/_internal/environment.py | 5 +++++ docs/usage.rst | 29 ++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c58e154..5cbbd552 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ Supported data sources are: * Pip's `requirements.txt` format * `PDM` manifest and lockfile are not explicitly supported. However, PDM's Python virtual environments are fully supported. See the docs for an example. +* `uv` manifest and lockfile are not explicitly supported. + However, uv's Python virtual environments are fully supported. See the docs for an example. * `Conda` as a package manager is no longer supported since version 4. However, conda's Python environments are fully supported via the methods listed above. See the docs for an example. diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index 0e412dd5..dfb2a288 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -81,6 +81,9 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': • Build an SBOM from PDM environment: > pdm.exe info --python > %(prog)s "%%path-to-pdm-python%%" + • Build an SBOM from uv environment: + > uv.exe python find + > %(prog)s "%%path-to-uv-python%%" """) else: # if os_name == 'posix': p.epilog = dedent("""\ @@ -102,6 +105,8 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': $ %(prog)s "$(poetry env info --executable)" • Build an SBOM from PDM environment: $ %(prog)s "$(pdm info --python)" + • Build an SBOM from uv environment: + $ %(prog)s "$(uv python find)" """) p.add_argument('--PEP-639', action='store_true', diff --git a/docs/usage.rst b/docs/usage.rst index 0c2b34b7..cf0d0083 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -145,6 +145,11 @@ Examples for macOS/Linux and alike $ cyclonedx-py environment "$(pdm info --python)" +.. code-block:: shell-session + :caption: Build an SBOM from uv environment + + $ cyclonedx-py environment "$(uv python find)" + Examples for Windows ^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +188,7 @@ Examples for Windows .. code-block:: doscon :caption: Build an SBOM from Poetry environment - > poetry.exe env info --executable + > poetry.exe env info --executable > cyclonedx-py environment "%path-to-poetry-python%" .. code-block:: doscon @@ -192,6 +197,12 @@ Examples for Windows > pdm.exe info --python > cyclonedx-py environment "%path-to-pdm-python%" +.. code-block:: doscon + :caption: Build an SBOM from uv environment + + > uv.exe python find + > cyclonedx-py environment "%path-to-uv-python%" + For Pipenv ---------- @@ -469,6 +480,22 @@ it is possible to use the functionality for Python (virtual) environments as des +For uv +------- + +Support for `uv`_ manifest and lockfile is not explicitly implemented, yet. + +However, since uv utilizes Python virtual environments under the hood, +it is possible to use the functionality for Python (virtual) environments as described above. + +.. _uv: https://docs.astral.sh/uv/ + + + +***** + + + For Conda --------- From 7306e79b87898944e334707e370c87dee1e90e3b Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 6 Mar 2025 12:51:59 +0100 Subject: [PATCH 2/5] tests: tetsbed for `uv` Signed-off-by: Jan Kowalleck --- pyproject.toml | 1 + .../infiles/environment/via-uv/.gitignore | 0 .../_data/infiles/environment/via-uv/init.py | 61 +++++++++++++++++++ .../infiles/environment/via-uv/pyproject.toml | 42 +++++++++++++ .../_data/infiles/environment/via-uv/uv.lock | 41 +++++++++++++ 5 files changed, 145 insertions(+) create mode 100644 tests/_data/infiles/environment/via-uv/.gitignore create mode 100644 tests/_data/infiles/environment/via-uv/init.py create mode 100644 tests/_data/infiles/environment/via-uv/pyproject.toml create mode 100644 tests/_data/infiles/environment/via-uv/uv.lock diff --git a/pyproject.toml b/pyproject.toml index d7aed922..2f36fdf3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,6 +103,7 @@ pip = ">=23.0" pipenv = ">=2023.11.5" poetry = "^1.7" pdm = "^2.11" +uv = "0.6.4" diff --git a/tests/_data/infiles/environment/via-uv/.gitignore b/tests/_data/infiles/environment/via-uv/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/tests/_data/infiles/environment/via-uv/init.py b/tests/_data/infiles/environment/via-uv/init.py new file mode 100644 index 00000000..67db2a55 --- /dev/null +++ b/tests/_data/infiles/environment/via-uv/init.py @@ -0,0 +1,61 @@ +# This file is part of CycloneDX Python +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + +""" +initialize this testbed. +""" + +from os import environ +from os.path import dirname, join +from shutil import rmtree +from subprocess import CompletedProcess, run # nosec:B404 +from sys import executable + +__all__ = ['main'] + +this_dir = dirname(__file__) +env_dir = join(this_dir, '.venv') + +uv_env = environ.copy() +uv_env['UV_NO_PROGRESS'] = '1' +uv_env['UV_PROJECT_ENVIRONMENT'] = env_dir + + +def uv_run(*args: str) -> CompletedProcess: + # uv is not API, but a CLI -- call it like that! + call = ( + executable, '-m', 'uv', + *args + ) + print('+ ', *call) + res = run(call, cwd=this_dir, env=uv_env, shell=False) # nosec:B603 + if res.returncode != 0: + raise RuntimeError('process failed') + return res + + +def main() -> None: + # needed to reinit partially stripped evn + rmtree(env_dir, ignore_errors=True) + + # the actual setup + uv_run('venv', env_dir) + uv_run('sync', '--no-dev', '--locked', '--no-active') + + +if __name__ == '__main__': + main() diff --git a/tests/_data/infiles/environment/via-uv/pyproject.toml b/tests/_data/infiles/environment/via-uv/pyproject.toml new file mode 100644 index 00000000..3d476838 --- /dev/null +++ b/tests/_data/infiles/environment/via-uv/pyproject.toml @@ -0,0 +1,42 @@ +[project] +# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata +name = "via-uv" +version = "0.1.0" +description = "environment via uv" +license = { text = "Apache-2.0 OR MIT" } +readme = "README.md" +requires-python = ">=3.8" + +# dynamic = [] # TODO + +authors = ["Your Name ", "My Name"] +maintainers = [ + "John Smith ", + "Jane Smith ", +] + +keywords = ["packaging", "pipenv", "test"] +classifiers = [ + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: MIT License", + "Classifier: Development Status :: 4 - Beta", + "Intended Audience :: Developers" +] + +dependencies = [ + 'toml' +] +optional-dependencies = { 'foo' = ['ddt'] } + +# entry-point = {} # TODO + +# gui-scripts = {} # TODO +# scripts = {} # TODO + +[project.urls] +homepage = "https://oss.acme.org/my-project/" +repository = "https://oss.acme.org/my-project.git" +documentation = "https://oss.acme.org/my-project/docs/" +"Bug Tracker" = "https://oss.acme.org/my-project/bugs/" +"Funding" = "https://oss.acme.org/my-project/funding/" +"Change log" = "https://oss.acme.org/my-project/changelog/" diff --git a/tests/_data/infiles/environment/via-uv/uv.lock b/tests/_data/infiles/environment/via-uv/uv.lock new file mode 100644 index 00000000..192664c2 --- /dev/null +++ b/tests/_data/infiles/environment/via-uv/uv.lock @@ -0,0 +1,41 @@ +version = 1 +revision = 1 +requires-python = ">=3.8" + +[[package]] +name = "ddt" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/d4/bdea45c5c1f1f0ae55844d841101b00905c9863ee1004da37d911253abb2/ddt-1.7.2.tar.gz", hash = "sha256:d215d6b083963013c4a19b1e4dcd6a96e80e43ab77519597a6acfcf2e9a3e04b", size = 13673 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/7c/38d1aec205833096eddefcbb3492fbb2c886e74174c72bc160da9522b2f0/ddt-1.7.2-py2.py3-none-any.whl", hash = "sha256:6adcfaf9785f0a36f9e73a89b91e412de9ef8649e289b750e3683bc79d5e2354", size = 7065 }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588 }, +] + +[[package]] +name = "via-uv" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "toml" }, +] + +[package.optional-dependencies] +foo = [ + { name = "ddt" }, +] + +[package.metadata] +requires-dist = [ + { name = "ddt", marker = "extra == 'foo'" }, + { name = "toml" }, +] +provides-extras = ["foo"] From 4ea7e4dad582ece890f89ef4daed067cd2410e15 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 6 Mar 2025 12:52:36 +0100 Subject: [PATCH 3/5] tests: tetstesults for `uv` Signed-off-by: Jan Kowalleck --- .../environment/plain_via-uv_1.0.xml.bin | 12 ++ .../environment/plain_via-uv_1.1.xml.bin | 22 +++ .../environment/plain_via-uv_1.2.json.bin | 99 +++++++++++ .../environment/plain_via-uv_1.2.xml.bin | 76 +++++++++ .../environment/plain_via-uv_1.3.json.bin | 105 ++++++++++++ .../environment/plain_via-uv_1.3.xml.bin | 79 +++++++++ .../environment/plain_via-uv_1.4.json.bin | 140 ++++++++++++++++ .../environment/plain_via-uv_1.4.xml.bin | 106 ++++++++++++ .../environment/plain_via-uv_1.5.json.bin | 154 +++++++++++++++++ .../environment/plain_via-uv_1.5.xml.bin | 116 +++++++++++++ .../environment/plain_via-uv_1.6.json.bin | 157 ++++++++++++++++++ .../environment/plain_via-uv_1.6.xml.bin | 116 +++++++++++++ 12 files changed, 1182 insertions(+) create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.0.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.1.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.2.json.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.2.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.3.json.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.3.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.4.json.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.4.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.5.json.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.5.xml.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.6.json.bin create mode 100644 tests/_data/snapshots/environment/plain_via-uv_1.6.xml.bin diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.0.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.0.xml.bin new file mode 100644 index 00000000..2316393a --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.0.xml.bin @@ -0,0 +1,12 @@ + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + pkg:pypi/toml@0.10.2 + false + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.1.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.1.xml.bin new file mode 100644 index 00000000..31bbeab3 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.1.xml.bin @@ -0,0 +1,22 @@ + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.2.json.bin b/tests/_data/snapshots/environment/plain_via-uv_1.2.json.bin new file mode 100644 index 00000000..b9056d29 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.2.json.bin @@ -0,0 +1,99 @@ +{ + "components": [ + { + "bom-ref": "toml==0.10.2", + "description": "Python Library for Tom's Obvious, Minimal Language", + "externalReferences": [ + { + "comment": "from packaging metadata: Home-page", + "type": "website", + "url": "https://github.com/uiri/toml" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "dependsOn": [ + "toml==0.10.2" + ], + "ref": "root-component" + }, + { + "ref": "toml==0.10.2" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "environment via uv", + "externalReferences": [ + { + "comment": "from pyproject urls: documentation", + "type": "documentation", + "url": "https://oss.acme.org/my-project/docs/" + }, + { + "comment": "from pyproject urls: Bug Tracker", + "type": "issue-tracker", + "url": "https://oss.acme.org/my-project/bugs/" + }, + { + "comment": "from pyproject urls: Funding", + "type": "other", + "url": "https://oss.acme.org/my-project/funding/" + }, + { + "comment": "from pyproject urls: Change log", + "type": "other", + "url": "https://oss.acme.org/my-project/changelog/" + }, + { + "comment": "from pyproject urls: repository", + "type": "vcs", + "url": "https://oss.acme.org/my-project.git" + }, + { + "comment": "from pyproject urls: homepage", + "type": "website", + "url": "https://oss.acme.org/my-project/" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "via-uv", + "type": "application", + "version": "0.1.0" + }, + "tools": [ + { + "name": "cyclonedx-py", + "vendor": "CycloneDX", + "version": "thisVersion-testing" + }, + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "libVersion-testing" + } + ] + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.2" +} \ No newline at end of file diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.2.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.2.xml.bin new file mode 100644 index 00000000..0c89f7a3 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.2.xml.bin @@ -0,0 +1,76 @@ + + + + + + CycloneDX + cyclonedx-py + thisVersion-testing + + + CycloneDX + cyclonedx-python-lib + libVersion-testing + + + + via-uv + 0.1.0 + environment via uv + + Apache-2.0 OR MIT + + + + https://oss.acme.org/my-project/docs/ + from pyproject urls: documentation + + + https://oss.acme.org/my-project/bugs/ + from pyproject urls: Bug Tracker + + + https://oss.acme.org/my-project/funding/ + from pyproject urls: Funding + + + https://oss.acme.org/my-project/changelog/ + from pyproject urls: Change log + + + https://oss.acme.org/my-project.git + from pyproject urls: repository + + + https://oss.acme.org/my-project/ + from pyproject urls: homepage + + + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + + + + + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.3.json.bin b/tests/_data/snapshots/environment/plain_via-uv_1.3.json.bin new file mode 100644 index 00000000..69b1c7c7 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.3.json.bin @@ -0,0 +1,105 @@ +{ + "components": [ + { + "bom-ref": "toml==0.10.2", + "description": "Python Library for Tom's Obvious, Minimal Language", + "externalReferences": [ + { + "comment": "from packaging metadata: Home-page", + "type": "website", + "url": "https://github.com/uiri/toml" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "dependsOn": [ + "toml==0.10.2" + ], + "ref": "root-component" + }, + { + "ref": "toml==0.10.2" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "environment via uv", + "externalReferences": [ + { + "comment": "from pyproject urls: documentation", + "type": "documentation", + "url": "https://oss.acme.org/my-project/docs/" + }, + { + "comment": "from pyproject urls: Bug Tracker", + "type": "issue-tracker", + "url": "https://oss.acme.org/my-project/bugs/" + }, + { + "comment": "from pyproject urls: Funding", + "type": "other", + "url": "https://oss.acme.org/my-project/funding/" + }, + { + "comment": "from pyproject urls: Change log", + "type": "other", + "url": "https://oss.acme.org/my-project/changelog/" + }, + { + "comment": "from pyproject urls: repository", + "type": "vcs", + "url": "https://oss.acme.org/my-project.git" + }, + { + "comment": "from pyproject urls: homepage", + "type": "website", + "url": "https://oss.acme.org/my-project/" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "via-uv", + "type": "application", + "version": "0.1.0" + }, + "properties": [ + { + "name": "cdx:reproducible", + "value": "true" + } + ], + "tools": [ + { + "name": "cyclonedx-py", + "vendor": "CycloneDX", + "version": "thisVersion-testing" + }, + { + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "libVersion-testing" + } + ] + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.3" +} \ No newline at end of file diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.3.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.3.xml.bin new file mode 100644 index 00000000..49e59fd6 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.3.xml.bin @@ -0,0 +1,79 @@ + + + + + + CycloneDX + cyclonedx-py + thisVersion-testing + + + CycloneDX + cyclonedx-python-lib + libVersion-testing + + + + via-uv + 0.1.0 + environment via uv + + Apache-2.0 OR MIT + + + + https://oss.acme.org/my-project/docs/ + from pyproject urls: documentation + + + https://oss.acme.org/my-project/bugs/ + from pyproject urls: Bug Tracker + + + https://oss.acme.org/my-project/funding/ + from pyproject urls: Funding + + + https://oss.acme.org/my-project/changelog/ + from pyproject urls: Change log + + + https://oss.acme.org/my-project.git + from pyproject urls: repository + + + https://oss.acme.org/my-project/ + from pyproject urls: homepage + + + + + true + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + + + + + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.4.json.bin b/tests/_data/snapshots/environment/plain_via-uv_1.4.json.bin new file mode 100644 index 00000000..013509a0 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.4.json.bin @@ -0,0 +1,140 @@ +{ + "components": [ + { + "bom-ref": "toml==0.10.2", + "description": "Python Library for Tom's Obvious, Minimal Language", + "externalReferences": [ + { + "comment": "from packaging metadata: Home-page", + "type": "website", + "url": "https://github.com/uiri/toml" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "dependsOn": [ + "toml==0.10.2" + ], + "ref": "root-component" + }, + { + "ref": "toml==0.10.2" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "environment via uv", + "externalReferences": [ + { + "comment": "from pyproject urls: documentation", + "type": "documentation", + "url": "https://oss.acme.org/my-project/docs/" + }, + { + "comment": "from pyproject urls: Bug Tracker", + "type": "issue-tracker", + "url": "https://oss.acme.org/my-project/bugs/" + }, + { + "comment": "from pyproject urls: Funding", + "type": "other", + "url": "https://oss.acme.org/my-project/funding/" + }, + { + "comment": "from pyproject urls: Change log", + "type": "release-notes", + "url": "https://oss.acme.org/my-project/changelog/" + }, + { + "comment": "from pyproject urls: repository", + "type": "vcs", + "url": "https://oss.acme.org/my-project.git" + }, + { + "comment": "from pyproject urls: homepage", + "type": "website", + "url": "https://oss.acme.org/my-project/" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "via-uv", + "type": "application", + "version": "0.1.0" + }, + "properties": [ + { + "name": "cdx:reproducible", + "value": "true" + } + ], + "tools": [ + { + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-bom/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-bom-tool.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python/" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python/#readme" + } + ], + "name": "cyclonedx-py", + "vendor": "CycloneDX", + "version": "thisVersion-testing" + }, + { + "externalReferences": [ ], + "name": "cyclonedx-python-lib", + "vendor": "CycloneDX", + "version": "libVersion-testing" + } + ] + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.4" +} \ No newline at end of file diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.4.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.4.xml.bin new file mode 100644 index 00000000..91bb7c4d --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.4.xml.bin @@ -0,0 +1,106 @@ + + + + + + CycloneDX + cyclonedx-py + thisVersion-testing + + + https://github.com/CycloneDX/cyclonedx-python/actions + + + https://pypi.org/project/cyclonedx-bom/ + + + https://cyclonedx-bom-tool.readthedocs.io/ + + + https://github.com/CycloneDX/cyclonedx-python/issues + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python/ + + + https://github.com/CycloneDX/cyclonedx-python/#readme + + + + + CycloneDX + cyclonedx-python-lib + libVersion-testing + + + + + via-uv + 0.1.0 + environment via uv + + Apache-2.0 OR MIT + + + + https://oss.acme.org/my-project/docs/ + from pyproject urls: documentation + + + https://oss.acme.org/my-project/bugs/ + from pyproject urls: Bug Tracker + + + https://oss.acme.org/my-project/funding/ + from pyproject urls: Funding + + + https://oss.acme.org/my-project/changelog/ + from pyproject urls: Change log + + + https://oss.acme.org/my-project.git + from pyproject urls: repository + + + https://oss.acme.org/my-project/ + from pyproject urls: homepage + + + + + true + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + + + + + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.5.json.bin b/tests/_data/snapshots/environment/plain_via-uv_1.5.json.bin new file mode 100644 index 00000000..ff2632a5 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.5.json.bin @@ -0,0 +1,154 @@ +{ + "components": [ + { + "bom-ref": "toml==0.10.2", + "description": "Python Library for Tom's Obvious, Minimal Language", + "externalReferences": [ + { + "comment": "from packaging metadata: Home-page", + "type": "website", + "url": "https://github.com/uiri/toml" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "dependsOn": [ + "toml==0.10.2" + ], + "ref": "root-component" + }, + { + "ref": "toml==0.10.2" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "environment via uv", + "externalReferences": [ + { + "comment": "from pyproject urls: documentation", + "type": "documentation", + "url": "https://oss.acme.org/my-project/docs/" + }, + { + "comment": "from pyproject urls: Bug Tracker", + "type": "issue-tracker", + "url": "https://oss.acme.org/my-project/bugs/" + }, + { + "comment": "from pyproject urls: Funding", + "type": "other", + "url": "https://oss.acme.org/my-project/funding/" + }, + { + "comment": "from pyproject urls: Change log", + "type": "release-notes", + "url": "https://oss.acme.org/my-project/changelog/" + }, + { + "comment": "from pyproject urls: repository", + "type": "vcs", + "url": "https://oss.acme.org/my-project.git" + }, + { + "comment": "from pyproject urls: homepage", + "type": "website", + "url": "https://oss.acme.org/my-project/" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "via-uv", + "type": "application", + "version": "0.1.0" + }, + "properties": [ + { + "name": "cdx:reproducible", + "value": "true" + } + ], + "tools": { + "components": [ + { + "description": "CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments", + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-bom/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-bom-tool.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python/" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python/#readme" + } + ], + "group": "CycloneDX", + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "cyclonedx-py", + "type": "application", + "version": "thisVersion-testing" + }, + { + "description": "stripped", + "externalReferences": [ ], + "group": "CycloneDX", + "licenses": [ ], + "name": "cyclonedx-python-lib", + "type": "library", + "version": "libVersion-testing" + } + ] + } + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5" +} \ No newline at end of file diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.5.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.5.xml.bin new file mode 100644 index 00000000..5c5a342f --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.5.xml.bin @@ -0,0 +1,116 @@ + + + + + + + CycloneDX + cyclonedx-py + thisVersion-testing + CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments + + + Apache-2.0 + + + + + https://github.com/CycloneDX/cyclonedx-python/actions + + + https://pypi.org/project/cyclonedx-bom/ + + + https://cyclonedx-bom-tool.readthedocs.io/ + + + https://github.com/CycloneDX/cyclonedx-python/issues + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python/ + + + https://github.com/CycloneDX/cyclonedx-python/#readme + + + + + CycloneDX + cyclonedx-python-lib + libVersion-testing + + + + + + + + via-uv + 0.1.0 + environment via uv + + Apache-2.0 OR MIT + + + + https://oss.acme.org/my-project/docs/ + from pyproject urls: documentation + + + https://oss.acme.org/my-project/bugs/ + from pyproject urls: Bug Tracker + + + https://oss.acme.org/my-project/funding/ + from pyproject urls: Funding + + + https://oss.acme.org/my-project/changelog/ + from pyproject urls: Change log + + + https://oss.acme.org/my-project.git + from pyproject urls: repository + + + https://oss.acme.org/my-project/ + from pyproject urls: homepage + + + + + true + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + + + + + + + diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.6.json.bin b/tests/_data/snapshots/environment/plain_via-uv_1.6.json.bin new file mode 100644 index 00000000..76c94e9e --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.6.json.bin @@ -0,0 +1,157 @@ +{ + "components": [ + { + "bom-ref": "toml==0.10.2", + "description": "Python Library for Tom's Obvious, Minimal Language", + "externalReferences": [ + { + "comment": "from packaging metadata: Home-page", + "type": "website", + "url": "https://github.com/uiri/toml" + } + ], + "licenses": [ + { + "license": { + "acknowledgement": "declared", + "id": "MIT" + } + } + ], + "name": "toml", + "purl": "pkg:pypi/toml@0.10.2", + "type": "library", + "version": "0.10.2" + } + ], + "dependencies": [ + { + "dependsOn": [ + "toml==0.10.2" + ], + "ref": "root-component" + }, + { + "ref": "toml==0.10.2" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "environment via uv", + "externalReferences": [ + { + "comment": "from pyproject urls: documentation", + "type": "documentation", + "url": "https://oss.acme.org/my-project/docs/" + }, + { + "comment": "from pyproject urls: Bug Tracker", + "type": "issue-tracker", + "url": "https://oss.acme.org/my-project/bugs/" + }, + { + "comment": "from pyproject urls: Funding", + "type": "other", + "url": "https://oss.acme.org/my-project/funding/" + }, + { + "comment": "from pyproject urls: Change log", + "type": "release-notes", + "url": "https://oss.acme.org/my-project/changelog/" + }, + { + "comment": "from pyproject urls: repository", + "type": "vcs", + "url": "https://oss.acme.org/my-project.git" + }, + { + "comment": "from pyproject urls: homepage", + "type": "website", + "url": "https://oss.acme.org/my-project/" + } + ], + "licenses": [ + { + "acknowledgement": "declared", + "expression": "Apache-2.0 OR MIT" + } + ], + "name": "via-uv", + "type": "application", + "version": "0.1.0" + }, + "properties": [ + { + "name": "cdx:reproducible", + "value": "true" + } + ], + "tools": { + "components": [ + { + "description": "CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments", + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-bom/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-bom-tool.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python/" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python/#readme" + } + ], + "group": "CycloneDX", + "licenses": [ + { + "license": { + "acknowledgement": "declared", + "id": "Apache-2.0" + } + } + ], + "name": "cyclonedx-py", + "type": "application", + "version": "thisVersion-testing" + }, + { + "description": "stripped", + "externalReferences": [ ], + "group": "CycloneDX", + "licenses": [ ], + "name": "cyclonedx-python-lib", + "type": "library", + "version": "libVersion-testing" + } + ] + } + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6" +} \ No newline at end of file diff --git a/tests/_data/snapshots/environment/plain_via-uv_1.6.xml.bin b/tests/_data/snapshots/environment/plain_via-uv_1.6.xml.bin new file mode 100644 index 00000000..f89b2f64 --- /dev/null +++ b/tests/_data/snapshots/environment/plain_via-uv_1.6.xml.bin @@ -0,0 +1,116 @@ + + + + + + + CycloneDX + cyclonedx-py + thisVersion-testing + CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments + + + Apache-2.0 + + + + + https://github.com/CycloneDX/cyclonedx-python/actions + + + https://pypi.org/project/cyclonedx-bom/ + + + https://cyclonedx-bom-tool.readthedocs.io/ + + + https://github.com/CycloneDX/cyclonedx-python/issues + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE + + + https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md + + + https://github.com/CycloneDX/cyclonedx-python/ + + + https://github.com/CycloneDX/cyclonedx-python/#readme + + + + + CycloneDX + cyclonedx-python-lib + libVersion-testing + + + + + + + + via-uv + 0.1.0 + environment via uv + + Apache-2.0 OR MIT + + + + https://oss.acme.org/my-project/docs/ + from pyproject urls: documentation + + + https://oss.acme.org/my-project/bugs/ + from pyproject urls: Bug Tracker + + + https://oss.acme.org/my-project/funding/ + from pyproject urls: Funding + + + https://oss.acme.org/my-project/changelog/ + from pyproject urls: Change log + + + https://oss.acme.org/my-project.git + from pyproject urls: repository + + + https://oss.acme.org/my-project/ + from pyproject urls: homepage + + + + + true + + + + + toml + 0.10.2 + Python Library for Tom's Obvious, Minimal Language + + + MIT + + + pkg:pypi/toml@0.10.2 + + + https://github.com/uiri/toml + from packaging metadata: Home-page + + + + + + + + + + + From 98f127b2388daf00c5904badf82b172191765546 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 6 Mar 2025 13:01:52 +0100 Subject: [PATCH 4/5] docs Signed-off-by: Jan Kowalleck --- tests/_data/infiles/environment/via-uv/pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/_data/infiles/environment/via-uv/pyproject.toml b/tests/_data/infiles/environment/via-uv/pyproject.toml index 3d476838..c3135950 100644 --- a/tests/_data/infiles/environment/via-uv/pyproject.toml +++ b/tests/_data/infiles/environment/via-uv/pyproject.toml @@ -40,3 +40,7 @@ documentation = "https://oss.acme.org/my-project/docs/" "Bug Tracker" = "https://oss.acme.org/my-project/bugs/" "Funding" = "https://oss.acme.org/my-project/funding/" "Change log" = "https://oss.acme.org/my-project/changelog/" + + +[tool.uv] +# https://docs.astral.sh/uv/reference/settings/ From 982f16e10890e324dc4fae62e97e3349c5d4c4a4 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 6 Mar 2025 16:10:42 +0100 Subject: [PATCH 5/5] docs Signed-off-by: Jan Kowalleck --- pyproject.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2f36fdf3..60756e3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,15 +95,18 @@ mypy = "1.14.1" bandit = "1.7.10" tomli = { version = "^2.0.1", python = "<3.11" } tox = "4.24.1" + # min version required to be able to install some dependencies # see https://github.com/MichaelKim0407/flake8-use-fstring/issues/33 setuptools = ">= 47.0.0" -# install` needed for setup/init of testbeds for `environment` purpose + +# some package managers needed for setup/init of testbeds for `environment` purpose. +# we do not relaly care for exact versions, as long as they have a stable CLI and craft usable virtual-environments pip = ">=23.0" pipenv = ">=2023.11.5" poetry = "^1.7" pdm = "^2.11" -uv = "0.6.4" +uv = "0.6.4" # keep pinned to exact version, until a v1.0.0 is released