Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
5 changes: 5 additions & 0 deletions cyclonedx_py/_internal/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("""\
Expand All @@ -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',
Expand Down
29 changes: 28 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -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
Expand All @@ -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
----------
Expand Down Expand Up @@ -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
---------

Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +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" # keep pinned to exact version, until a v1.0.0 is released



Expand Down
Empty file.
61 changes: 61 additions & 0 deletions tests/_data/infiles/environment/via-uv/init.py
Original file line number Diff line number Diff line change
@@ -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()
46 changes: 46 additions & 0 deletions tests/_data/infiles/environment/via-uv/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[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 <you@example.com>", "My Name"]
maintainers = [
"John Smith <johnsmith@example.org>",
"Jane Smith <janesmith@example.org>",
]

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/"


[tool.uv]
# https://docs.astral.sh/uv/reference/settings/
41 changes: 41 additions & 0 deletions tests/_data/infiles/environment/via-uv/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions tests/_data/snapshots/environment/plain_via-uv_1.0.xml.bin

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions tests/_data/snapshots/environment/plain_via-uv_1.1.xml.bin

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions tests/_data/snapshots/environment/plain_via-uv_1.2.json.bin

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading