CycloneDX / cyclonedx-python

CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments
https://cyclonedx.org
Apache License 2.0
257 stars 67 forks source link

[BUG] Crash on running `cyclonedx-py environment -h` on windows #804

Closed GadgetSteve closed 1 month ago

GadgetSteve commented 1 month ago

Describe the bug

On Windows running cyclonedx-py environment -h results in a crash that outputs:

  File "C:\Python311\Lib\argparse.py", line 511, in _format_text
    text = text % dict(prog=self._prog)
           ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
TypeError: not enough arguments for format string

To Reproduce

On a Windows machine run cyclonedx-py environment -h

Expected behavior

Expected to see the help text.

Screenshots or output-paste

cyclonedx-py environment -h

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Python311\Scripts\cyclonedx-py.exe\__main__.py", line 7, in <module>
  File "D:\ToolBuild\cyclonedx-python\cyclonedx_py\_internal\cli.py", line 270, in run
    args = vars(arg_parser.parse_args(argv))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\argparse.py", line 1874, in parse_args
    args, argv = self.parse_known_args(args, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 : 
 : 
  File "C:\Python311\Lib\argparse.py", line 217, in format_help
    item_help = join([func(*args) for func, args in self.items])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\argparse.py", line 217, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
                      ^^^^^^^^^^^
  File "C:\Python311\Lib\argparse.py", line 511, in _format_text
    text = text % dict(prog=self._prog)
           ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
TypeError: not enough arguments for format string

Environment

Additional context

Problem also occurs with other versions of python including 3.13.0rc2.

GadgetSteve commented 1 month ago

The problem results from the use of singe % characters in the Windows epilogue set from line 64 in _internal/environment.py which is then processed with % formatting by argparse. The following patch will resolve:

diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py
index abc13b0..b676db2 100644
--- a/cyclonedx_py/_internal/environment.py
+++ b/cyclonedx_py/_internal/environment.py
@@ -64,23 +64,23 @@ class EnvironmentBB(BomBuilder):
                        > %(prog)s "...\\some\\path\\bin\\python.exe"
                        > %(prog)s "...\\some\\path\\.venv"
                        > %(prog)s "$env:VIRTUAL_ENV"
-                       > %(prog)s %VIRTUAL_ENV%
+                       > %(prog)s %%VIRTUAL_ENV%%
                  • Build an SBOM from specific Python environment:
                        > where.exe python3.9.exe
-                       > %(prog)s "%path-to-specific-python%"
+                       > %(prog)s "%%path-to-specific-python%%"
                  • Build an SBOM from conda Python environment:
                        > conda.exe run where.exe python
-                       > %(prog)s "%path-to-conda-python%"
+                       > %(prog)s "%%path-to-conda-python%%"
                  • Build an SBOM from Pipenv environment:
                        > pipenv.exe --py
                        > pipenv.exe --venv
-                       > %(prog)s "%path-to-pipenv-python%"
+                       > %(prog)s "%%path-to-pipenv-python%%"
                  • Build an SBOM from Poetry environment:
                        > poetry.exe env info --executable
-                       > %(prog)s "%path-to-poetry-python%"
+                       > %(prog)s "%%path-to-poetry-python%%"
                  • Build an SBOM from PDM environment:
                        > pdm.exe info --python
-                       > %(prog)s "%path-to-pdm-python%"
+                       > %(prog)s "%%path-to-pdm-python%%"
                """)
         else:  # if os_name == 'posix':
             p.epilog = dedent("""\
jkowalleck commented 1 month ago

confirmed via https://github.com/CycloneDX/cyclonedx-python/pull/807

jkowalleck commented 1 month ago

thank you for the report and fix

jkowalleck commented 1 month ago

fix published via version 4.6.1