Skip to content

Commit 5f07cb3

Browse files
committed
feat: subcommand environment got alias env/venv
Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 12cc59b commit 5f07cb3

File tree

5 files changed

+31
-18
lines changed

5 files changed

+31
-18
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,12 @@ usage: cyclonedx-py [-h] [--version] command ...
7676
Creates CycloneDX Software Bill of Materials (SBOM) from Python projects and environments.
7777

7878
positional arguments:
79-
command
80-
environment Build an SBOM from Python (virtual) environment
81-
requirements Build an SBOM from Pip requirements
82-
pipenv Build an SBOM from Pipenv manifest
83-
poetry Build an SBOM from Poetry project
79+
<command>
80+
environment (env, venv)
81+
Build an SBOM from Python (virtual) environment
82+
requirements Build an SBOM from Pip requirements
83+
pipenv Build an SBOM from Pipenv manifest
84+
poetry Build an SBOM from Poetry project
8485

8586
options:
8687
-h, --help show this help message and exit

cyclonedx_py/_internal/cli.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import sys
2020
from argparse import ArgumentParser, FileType, RawDescriptionHelpFormatter
2121
from itertools import chain
22-
from typing import TYPE_CHECKING, Any, Dict, NoReturn, Optional, Sequence, TextIO, Type, Union
22+
from typing import TYPE_CHECKING, Any, Dict, List, NoReturn, Optional, Sequence, TextIO, Type, Union
2323

2424
from cyclonedx.model import Property
2525
from cyclonedx.output import make_outputter
@@ -53,6 +53,7 @@
5353
class Command:
5454
@classmethod
5555
def make_argument_parser(cls, sco: ArgumentParser, **kwargs: Any) -> ArgumentParser:
56+
# region Command
5657
p = ArgumentParser(
5758
description='Creates CycloneDX Software Bill of Materials (SBOM) from Python projects and environments.',
5859
formatter_class=RawDescriptionHelpFormatter,
@@ -62,7 +63,9 @@ def make_argument_parser(cls, sco: ArgumentParser, **kwargs: Any) -> ArgumentPar
6263
sp = p.add_subparsers(metavar='<command>', dest='command',
6364
# not required. if omitted: show help and exit
6465
required=False)
66+
# region Command
6567

68+
# region SubCOmmand
6669
op = ArgumentParser(add_help=False)
6770
op.add_argument('--short-PURLs',
6871
help='Omit all qualifiers from PackageURLs.\n'
@@ -124,21 +127,24 @@ def make_argument_parser(cls, sco: ArgumentParser, **kwargs: Any) -> ArgumentPar
124127
action='store_false')
125128

126129
scbbc: Type['BomBuilder']
127-
for sct, scbbc in (
128-
('environment', EnvironmentBB),
129-
('requirements', RequirementsBB),
130-
('pipenv', PipenvBB),
131-
('poetry', PoetryBB),
130+
sct: str
131+
scta: List[str]
132+
for scbbc, sct, *scta in (
133+
(EnvironmentBB, 'environment', 'env', 'venv'),
134+
(RequirementsBB, 'requirements'),
135+
(PipenvBB, 'pipenv'),
136+
(PoetryBB, 'poetry'),
132137
):
133138
spp = scbbc.make_argument_parser(add_help=False)
134-
sp.add_parser(sct,
139+
sp.add_parser(sct, aliases=scta,
135140
help=(spp.description or '').split('\n')[0].strip('. '),
136141
description=spp.description,
137142
epilog=spp.epilog,
138143
parents=[spp, op, sco],
139144
formatter_class=p.formatter_class,
140145
allow_abbrev=p.allow_abbrev,
141146
).set_defaults(_bbc=scbbc)
147+
# endregion SubCommand
142148

143149
return p
144150

cyclonedx_py/_internal/poetry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def __purl_qualifiers4lock(self, package: 'T_NameDict') -> 'T_NameDict':
444444
# > For version-controlled files, the VCS location syntax is similar to a URL and has the:
445445
# > `<vcs_tool>+<transport>://<host_name>[/<path_to_repository>][@<revision_tag_or_branch>][#<sub_path>]`
446446
qs['vcs_url'] = f'{source_type}+{redact_auth_from_url(source["url"])}@' + \
447-
source.get('resolved_reference', source.get('reference', ''))
447+
source.get('resolved_reference', source.get('reference', ''))
448448
elif source_type == 'url':
449449
if '://files.pythonhosted.org/' not in source['url']:
450450
# skip PURL bloat, do not add implicit information

docs/usage.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ For Python (virtual) environment
4141

4242
**subcommand:** ``environment``
4343

44+
**aliases:** ``env``, ``venv``
45+
4446
.. TODO: describe what an environment is...
4547
46-
This will produce the most accurate and complete CycloneDX BOM as it analyses the actually installed packages.
47-
It will include metadata, licenses, dependency graph, and more in the generated CycloneDX SBOM.
48+
By analyzing the actually installed packages, this will produce the most accurate and complete CycloneDX BOM.
49+
The generated CycloneDX SBOM will include metadata, licenses, dependency graph, and more.
4850

4951
The full documentation can be issued by running with ``environment --help``:
5052

tests/integration/test_cli_environment.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from unittest import TestCase, skipIf
2626

2727
from cyclonedx.schema import OutputFormat, SchemaVersion
28-
from ddt import ddt, named_data
28+
from ddt import data, ddt, named_data
2929

3030
from tests import INFILES_DIRECTORY, INIT_TESTBEDS, SUPPORTED_OF_SV, SnapshotMixin, make_comparable
3131
from tests.integration import run_cli
@@ -45,8 +45,12 @@ def test_data_file_filter(s: str) -> Generator[Any, None, None]:
4545
@ddt
4646
class TestCliEnvironment(TestCase, SnapshotMixin):
4747

48-
def test_help(self) -> None:
49-
res, out, err = run_cli('environment', '--help')
48+
@data(
49+
'environment',
50+
'env', 'venv' # aliases
51+
)
52+
def test_help(self, subcommand: str) -> None:
53+
res, out, err = run_cli(subcommand, '--help')
5054
self.assertEqual(0, res, '\n'.join((out, err)))
5155

5256
@classmethod

0 commit comments

Comments
 (0)