Skip to content

Commit fa437b4

Browse files
committed
wip
Signed-off-by: Jan Kowalleck <[email protected]>
1 parent ac18c40 commit fa437b4

File tree

4 files changed

+58
-11
lines changed

4 files changed

+58
-11
lines changed

cyclonedx/_internal/type.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# This file is part of CycloneDX Python Library
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
# Copyright (c) OWASP Foundation. All Rights Reserved.
17+
18+
19+
from typing import Optional, TypeGuard, TypeVar
20+
21+
_T = TypeVar('_T')
22+
23+
24+
def is_not_none(val: Optional[_T]) -> TypeGuard[_T]:
25+
return val is not None

cyclonedx/model/contact.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from .._internal.bom_ref import bom_ref_from_str as _bom_ref_from_str
2626
from .._internal.compare import ComparableTuple as _ComparableTuple
27-
from ..schema.schema import SchemaVersion1Dot6, SchemaVersion1Dot5
27+
from ..schema.schema import SchemaVersion1Dot5, SchemaVersion1Dot6
2828
from . import XsUri
2929
from .bom_ref import BomRef
3030

cyclonedx/model/license.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@
2929
import py_serializable as serializable
3030
from sortedcontainers import SortedSet
3131

32+
from .._internal.bom_ref import bom_ref_from_str as _bom_ref_from_str
3233
from .._internal.compare import ComparableTuple as _ComparableTuple
3334
from ..exception.model import MutuallyExclusivePropertiesException
3435
from ..exception.serialization import CycloneDxDeserializationException
35-
from ..schema.schema import SchemaVersion1Dot6, SchemaVersion1Dot5
36-
from . import AttachedText, XsUri, BomRef
37-
from .._internal.bom_ref import bom_ref_from_str as _bom_ref_from_str
36+
from ..schema.schema import SchemaVersion1Dot5, SchemaVersion1Dot6
37+
from . import AttachedText, XsUri
38+
from .bom_ref import BomRef
3839

3940

4041
@serializable.serializable_enum
@@ -112,7 +113,6 @@ def bom_ref(self) -> BomRef:
112113
"""
113114
return self._bom_ref
114115

115-
116116
@property
117117
@serializable.xml_sequence(1)
118118
def id(self) -> Optional[str]:
@@ -300,7 +300,6 @@ def bom_ref(self) -> BomRef:
300300
"""
301301
return self._bom_ref
302302

303-
304303
@property
305304
@serializable.xml_name('.')
306305
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)

cyclonedx/output/__init__.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@
2828
from random import random
2929
from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
3030

31+
from .._internal.type import is_not_none
3132
from ..schema import OutputFormat, SchemaVersion
3233

3334
if TYPE_CHECKING: # pragma: no cover
3435
from ..model.bom import Bom
3536
from ..model.bom_ref import BomRef
37+
from ..model.contact import OrganizationalEntity
38+
from ..model.license import License
3639
from .json import Json as JsonOutputter
3740
from .xml import Xml as XmlOutputter
3841

@@ -170,8 +173,28 @@ def _make_unique(self) -> str:
170173

171174
@classmethod
172175
def from_bom(cls, bom: 'Bom', prefix: str = 'BomRef') -> 'BomRefDiscriminator':
173-
return cls(chain(
174-
map(lambda c: c.bom_ref, bom._get_all_components()),
175-
map(lambda s: s.bom_ref, bom.services),
176-
map(lambda v: v.bom_ref, bom.vulnerabilities)
177-
), prefix)
176+
components = tuple(bom._get_all_components())
177+
services = tuple(bom.services)
178+
vulnerabilities = tuple(bom.vulnerabilities)
179+
orgs: tuple['OrganizationalEntity', ...] = tuple(filter(is_not_none, chain( # type:ignore[arg-type]
180+
(bom.metadata.manufacture, bom.metadata.manufacturer, bom.metadata.supplier),
181+
chain.from_iterable((c.manufacturer, c.supplier,) for c in components),
182+
(s.provider for s in services),
183+
chain.from_iterable(v.credits.organizations for v in vulnerabilities if v.credits),
184+
)))
185+
licenses: Iterable['License'] = chain(
186+
bom.metadata.licenses,
187+
chain.from_iterable(c.licenses for c in components),
188+
chain.from_iterable(c.evidence.licenses for c in components if c.evidence is not None),
189+
chain.from_iterable(s.licenses for s in services),
190+
)
191+
return cls(
192+
(i.bom_ref for i in chain( # type:ignore[attr-defined]
193+
components,
194+
services,
195+
vulnerabilities,
196+
orgs,
197+
(o.address for o in orgs if o.address is not None),
198+
licenses,
199+
)),
200+
prefix)

0 commit comments

Comments
 (0)