Skip to content

Commit

Permalink
feat: out-factor SPDX compund detection
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
  • Loading branch information
jkowalleck committed Sep 14, 2022
1 parent 26817c0 commit 2b69925
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 15 deletions.
11 changes: 4 additions & 7 deletions cyclonedx/factory/license.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from ..exception.factory import InvalidLicenseExpressionException, InvalidSpdxLicenseException
from ..model import AttachedText, License, LicenseChoice, XsUri
from ..spdx import fixup as spdx_fixup
from ..spdx import fixup_id as spdx_fixup, is_compound_expression as is_spdx_compound_expression


class LicenseFactory:
Expand Down Expand Up @@ -69,14 +69,11 @@ def make_from_string(self, expression_or_name_or_spdx: str) -> LicenseChoice:
def make_with_compound_expression(self, compound_expression: str) -> LicenseChoice:
"""Make a :class:`cyclonedx.model.LicenseChoice` with a compound expression.
:raises InvalidLicenseExpressionException: if `expression` is not known/supported license expression
.. note::
Uses a best-effort detection of SPDX compound expression according to `SPDX license expression spec`_.
Utilizes :func:`cyclonedx.spdx.is_compound_expression`.
.. _SPDX license expression spec: https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/
:raises InvalidLicenseExpressionException: if `expression` is not known/supported license expression
"""
if compound_expression.startswith('(') and compound_expression.endswith(')'):
if is_spdx_compound_expression(compound_expression):
return LicenseChoice(license_expression=compound_expression)
raise InvalidLicenseExpressionException(compound_expression)

Expand Down
17 changes: 14 additions & 3 deletions cyclonedx/spdx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#
# SPDX-License-Identifier: Apache-2.0

__all__ = ['is_supported', 'fixup']
__all__ = ['is_supported_id', 'fixup_id', 'is_compound_expression']

from json import load as json_load
from os.path import dirname, join as path_join
Expand All @@ -33,14 +33,25 @@

# endregion

def is_supported(value: str) -> bool:
def is_supported_id(value: str) -> bool:
"""Validate a SPDX-ID according to current spec."""
return value in __IDS


def fixup(value: str) -> Optional[str]:
def fixup_id(value: str) -> Optional[str]:
"""Fixup a SPDX-ID.
:returns: repaired value string, or `None` if fixup was unable to help.
"""
return __IDS_LOWER_MAP.get(value.lower())


def is_compound_expression(value: str) -> bool:
"""Validate compound expression.
.. note::
Uses a best-effort detection of SPDX compound expression according to `SPDX license expression spec`_.
.. _SPDX license expression spec: https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/
"""
return value.startswith('(') and value.endswith(')')
10 changes: 5 additions & 5 deletions tests/test_spdx.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from ddt import data, ddt, idata, unpack

from cyclonedx.spdx import fixup, is_supported
from cyclonedx.spdx import fixup_id, is_supported_id

with open(path_join(dirname(__file__), '..', 'cyclonedx', 'schema', 'spdx.schema.json')) as spdx_schema:
SPDX_IDS = json_load(spdx_schema)['enum']
Expand All @@ -40,12 +40,12 @@ class TestSpdx(TestCase):
'mit',
)
def test_not_supported(self, unsupported_value: str) -> None:
actual = is_supported(unsupported_value)
actual = is_supported_id(unsupported_value)
self.assertFalse(actual)

@idata(SPDX_IDS)
def test_is_supported(self, supported_value: str) -> None:
actual = is_supported(supported_value)
actual = is_supported_id(supported_value)
self.assertTrue(actual)

@idata(chain(
Expand All @@ -57,12 +57,12 @@ def test_is_supported(self, supported_value: str) -> None:
))
@unpack
def test_fixup(self, fixable: str, expected_fixed: str) -> None:
actual = fixup(fixable)
actual = fixup_id(fixable)
self.assertEqual(expected_fixed, actual)

@data(
'something unfixable',
)
def test_not_fixup(self, unfixable: str) -> None:
actual = fixup(unfixable)
actual = fixup_id(unfixable)
self.assertIsNone(actual)

0 comments on commit 2b69925

Please sign in to comment.