This commit is contained in:
Iliyan Angelov
2025-12-01 06:50:10 +02:00
parent 91f51bc6fe
commit 62c1fe5951
4682 changed files with 544807 additions and 31208 deletions

View File

@@ -0,0 +1,25 @@
# This file is part of CycloneDX Python Library
#
# 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.
"""
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
Everything might change without any notice.
"""
# THIS FILE IS INTENDED TO BE EMPTY.
# Put symbols in own modules/packages, not in this file!

View File

@@ -0,0 +1,51 @@
# This file is part of CycloneDX Python Library
#
# 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.
"""
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
Everything might change without any notice.
"""
from typing import Literal, Optional, Union, overload
from ..model.bom_ref import BomRef
@overload
def bom_ref_from_str(bom_ref: BomRef, optional: bool = ...) -> BomRef:
... # pragma: no cover
@overload
def bom_ref_from_str(bom_ref: Optional[str], optional: Literal[False] = False) -> BomRef:
... # pragma: no cover
@overload
def bom_ref_from_str(bom_ref: Optional[str], optional: Literal[True] = ...) -> Optional[BomRef]:
... # pragma: no cover
def bom_ref_from_str(bom_ref: Optional[Union[str, BomRef]], optional: bool = False) -> Optional[BomRef]:
if isinstance(bom_ref, BomRef):
return bom_ref
if bom_ref:
return BomRef(value=str(bom_ref))
return None \
if optional \
else BomRef()

View File

@@ -0,0 +1,82 @@
# This file is part of CycloneDX Python Library
#
# 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.
"""
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
Everything might change without any notice.
"""
from itertools import zip_longest
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple
if TYPE_CHECKING: # pragma: no cover
from packageurl import PackageURL
class ComparableTuple(Tuple[Optional[Any], ...]):
"""
Allows comparison of tuples, allowing for None values.
"""
def __lt__(self, other: Any) -> bool:
for s, o in zip_longest(self, other):
if s == o:
continue
# the idea is to have any consistent order, not necessarily "natural" order.
if s is None:
return False
if o is None:
return True
return bool(s < o)
return False
def __gt__(self, other: Any) -> bool:
for s, o in zip_longest(self, other):
if s == o:
continue
# the idea is to have any consistent order, not necessarily "natural" order.
if s is None:
return True
if o is None:
return False
return bool(s > o)
return False
class ComparableDict(ComparableTuple):
"""
Allows comparison of dictionaries, allowing for missing/None values.
"""
def __new__(cls, d: Dict[Any, Any]) -> 'ComparableDict':
return super(ComparableDict, cls).__new__(cls, sorted(d.items()))
class ComparablePackageURL(ComparableTuple):
"""
Allows comparison of PackageURL, allowing for qualifiers.
"""
def __new__(cls, p: 'PackageURL') -> 'ComparablePackageURL':
return super(ComparablePackageURL, cls).__new__(cls, (
p.type,
p.namespace,
p.version,
ComparableDict(p.qualifiers) if isinstance(p.qualifiers, dict) else p.qualifiers,
p.subpath
))

View File

@@ -0,0 +1,43 @@
# This file is part of CycloneDX Python Library
#
# 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.
"""
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
Everything might change without any notice.
"""
from hashlib import sha1
def file_sha1sum(filename: str) -> str:
"""
Generate a SHA1 hash of the provided file.
Args:
filename:
Absolute path to file to hash as `str`
Returns:
SHA-1 hash
"""
h = sha1() # nosec B303, B324
with open(filename, 'rb') as f:
for byte_block in iter(lambda: f.read(4096), b''):
h.update(byte_block)
return h.hexdigest()

View File

@@ -0,0 +1,29 @@
# This file is part of CycloneDX Python Library
#
# 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.
"""
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
Everything might change without any notice.
"""
from datetime import datetime, timezone
def get_now_utc() -> datetime:
return datetime.now(tz=timezone.utc)