Skip to content

Commit ee72779

Browse files
authored
Merge pull request #207 from opossum-tool/finalize_switch_flow
Finalize switch flow
2 parents e872ed9 + 15d9a59 commit ee72779

File tree

96 files changed

+1903
-2278
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1903
-2278
lines changed

.github/workflows/lint_and_run_tests.yml

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ jobs:
4848
- name: Run mypy
4949
run: uv run python -m mypy src/ tests/
5050

51+
- name: Run import linter
52+
run: uv run lint-imports
53+
5154
test:
5255
runs-on: ${{ matrix.os }}
5356
if: |

.importlinter

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
[importlinter]
6+
root_package = opossum_lib
7+
# Optional:
8+
include_external_packages = True
9+
exclude_type_checking_imports = True
10+
11+
[importlinter:contract:file-formats-independent]
12+
name = The different file formats should be independent
13+
type = independence
14+
modules =
15+
opossum_lib.input_formats.*
16+
17+
18+
[importlinter:contract:core-should-not-depend -on-input-files]
19+
name = Core should not depend on input files
20+
type = forbidden
21+
source_modules =
22+
opossum_lib.core
23+
forbidden_modules =
24+
opossum_lib.input_formats
25+
26+
[importlinter:contract:shared_objects_not_depend_on_input_formats]
27+
name = Shared package not depend on input formats
28+
type = forbidden
29+
source_modules =
30+
opossum_lib.shared
31+
forbidden_modules =
32+
opossum_lib.input_formats

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ Options:
6464
that you would like to include in the final output.
6565
Option can be repeated.
6666
-o, --outfile TEXT The file path to write the generated opossum document
67-
to. If appropriate, the extension ".opossum" will be
68-
appended. [default: output.opossum]
67+
to. If appropriate, the extension ".opossum" is
68+
appended. If the output file already exists, it is
69+
overwritten. [default: output.opossum]
6970
--help Show this message and exit.
7071

7172

@@ -80,6 +81,7 @@ uv run ruff check
8081
uv run ruff format --check
8182
uv run python -m mypy src/ tests/
8283
uv run pytest
84+
uv run lint-imports
8385
```
8486

8587
# Build

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ dependencies = [
1212
"click>=8.1.8,<9",
1313
"pydantic>=2.10.6",
1414
"pyinstaller>=6.11.1",
15-
"faker>=35.0.0",
1615
]
1716

1817
[project.urls]
@@ -22,11 +21,12 @@ Repository = "https://github.com/opossum-tool/opossum-file"
2221
opossum-file = "opossum_lib.cli:opossum_file"
2322

2423
[dependency-groups]
25-
test = ["pytest>=8.3.4,<9"]
24+
test = ["pytest>=8.3.4,<9", "faker>=35.0.0",]
2625
dev = [
2726
"mypy>=1.14.1,<2",
2827
"pre-commit>=4.1.0,<5",
2928
"ruff>=0.9.3",
29+
"import-linter>=2.1",
3030
]
3131

3232
[tool.uv]

src/opossum_lib/cli.py

+18-37
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
44
#
55
# SPDX-License-Identifier: Apache-2.0
6-
7-
86
import logging
97
import sys
108
from pathlib import Path
119

1210
import click
1311

14-
from opossum_lib.opossum.file_generation import OpossumFileWriter
15-
from opossum_lib.opossum.opossum_file_content import OpossumFileContent
16-
from opossum_lib.opossum.read_opossum_file import read_opossum_file
17-
from opossum_lib.scancode.convert_scancode_to_opossum import (
18-
convert_scancode_file_to_opossum,
12+
from opossum_lib.core.services.generate_impl import (
13+
generate_impl,
14+
)
15+
from opossum_lib.core.services.input_reader import InputReader
16+
from opossum_lib.input_formats.opossum.services.opossum_file_reader import (
17+
OpossumFileReader,
18+
)
19+
from opossum_lib.input_formats.scancode.services.scancode_file_reader import (
20+
ScancodeFileReader,
1921
)
2022

2123

@@ -47,12 +49,13 @@ def opossum_file() -> None:
4749
default="output.opossum",
4850
show_default=True,
4951
help="The file path to write the generated opossum document to. "
50-
'If appropriate, the extension ".opossum" will be appended.',
52+
'If appropriate, the extension ".opossum" is appended. '
53+
"If the output file already exists, it is overwritten.",
5154
)
5255
def generate(
53-
scancode_json_files: list[str],
54-
opossum_files: list[str],
55-
outfile: str,
56+
scancode_json_files: list[Path],
57+
opossum_files: list[Path],
58+
outfile: Path,
5659
) -> None:
5760
"""
5861
Generate an Opossum file from various other file formats.
@@ -62,41 +65,19 @@ def generate(
6265
- ScanCode
6366
- Opossum
6467
"""
65-
validate_input_and_exit_on_error(scancode_json_files, opossum_files)
66-
opossum_file_content = convert_after_valid_input(scancode_json_files, opossum_files)
67-
68-
if not outfile.endswith(".opossum"):
69-
outfile += ".opossum"
7068

71-
if Path.is_file(Path(outfile)):
72-
logging.warning(f"{outfile} already exists and will be overwritten.")
73-
74-
OpossumFileWriter.write_opossum_information_to_file(
75-
opossum_file_content, Path(outfile)
76-
)
77-
78-
79-
def validate_input_and_exit_on_error(
80-
scancode_json_files: list[str], opossum_files: list[str]
81-
) -> None:
8269
total_number_of_files = len(scancode_json_files) + len(opossum_files)
8370
if total_number_of_files == 0:
8471
logging.warning("No input provided. Exiting.")
8572
sys.exit(1)
8673
if total_number_of_files > 1:
8774
logging.error("Merging of multiple files not yet supported!")
8875
sys.exit(1)
76+
input_readers: list[InputReader] = []
77+
input_readers += [ScancodeFileReader(path=path) for path in scancode_json_files]
78+
input_readers += [OpossumFileReader(path=path) for path in opossum_files]
8979

90-
91-
def convert_after_valid_input(
92-
scancode_json_files: list[str], opossum_files: list[str]
93-
) -> OpossumFileContent:
94-
if len(scancode_json_files) == 1:
95-
scancode_json_input_file = scancode_json_files[0]
96-
return convert_scancode_file_to_opossum(scancode_json_input_file)
97-
else:
98-
opossum_input_file = opossum_files[0]
99-
return read_opossum_file(opossum_input_file)
80+
generate_impl(input_readers=input_readers, output_file=Path(outfile))
10081

10182

10283
if __name__ == "__main__":
File renamed without changes.
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
# #
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel, ConfigDict
8+
9+
from opossum_lib.shared.entities.opossum_input_file_model import BaseUrlsForSourcesModel
10+
11+
12+
class BaseUrlsForSources(BaseModel):
13+
model_config = ConfigDict(frozen=True, extra="allow")
14+
15+
def to_opossum_file_model(self) -> BaseUrlsForSourcesModel:
16+
return BaseUrlsForSourcesModel(**self.model_dump())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
# #
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel, ConfigDict
8+
9+
from opossum_lib.shared.entities.opossum_input_file_model import (
10+
ExternalAttributionSourceModel,
11+
)
12+
13+
14+
class ExternalAttributionSource(BaseModel):
15+
model_config = ConfigDict(frozen=True, extra="forbid")
16+
name: str
17+
priority: int
18+
is_relevant_for_preferred: bool | None = None
19+
20+
def to_opossum_file_model(self) -> ExternalAttributionSourceModel:
21+
return ExternalAttributionSourceModel(
22+
name=self.name,
23+
priority=self.priority,
24+
is_relevant_for_preferred=self.is_relevant_for_preferred,
25+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
# #
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel, ConfigDict
8+
9+
from opossum_lib.shared.entities.opossum_input_file_model import FrequentLicenseModel
10+
11+
12+
class FrequentLicense(BaseModel):
13+
model_config = ConfigDict(frozen=True, extra="forbid")
14+
full_name: str
15+
short_name: str
16+
default_text: str
17+
18+
def to_opossum_file_model(self) -> FrequentLicenseModel:
19+
return FrequentLicenseModel(
20+
full_name=self.full_name,
21+
short_name=self.short_name,
22+
default_text=self.default_text,
23+
)
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
# #
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel, ConfigDict
8+
9+
from opossum_lib.shared.entities.opossum_input_file_model import MetadataModel
10+
11+
12+
class Metadata(BaseModel):
13+
model_config = ConfigDict(frozen=True, extra="allow")
14+
project_id: str
15+
file_creation_date: str
16+
project_title: str
17+
project_version: str | None = None
18+
expected_release_date: str | None = None
19+
build_date: str | None = None
20+
21+
def to_opossum_file_model(self) -> MetadataModel:
22+
return MetadataModel(**self.model_dump())
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from pydantic import BaseModel, ConfigDict
8+
9+
from opossum_lib.core.entities.scan_results import ScanResults
10+
from opossum_lib.shared.entities.opossum_file_model import OpossumFileModel
11+
from opossum_lib.shared.entities.opossum_output_file_model import OpossumOutputFileModel
12+
13+
type OpossumPackageIdentifier = str
14+
type ResourcePath = str
15+
16+
17+
class Opossum(BaseModel):
18+
model_config = ConfigDict(frozen=True, extra="forbid")
19+
scan_results: ScanResults
20+
review_results: OpossumOutputFileModel | None = None
21+
22+
def to_opossum_file_model(self) -> OpossumFileModel:
23+
return OpossumFileModel(
24+
input_file=self.scan_results.to_opossum_file_model(),
25+
output_file=self.review_results,
26+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# SPDX-FileCopyrightText: TNG Technology Consulting GmbH <https://www.tngtech.com>
2+
# #
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
from __future__ import annotations
6+
7+
from typing import Literal
8+
9+
from pydantic import BaseModel, ConfigDict
10+
11+
from opossum_lib.core.entities.source_info import SourceInfo
12+
from opossum_lib.shared.entities.opossum_input_file_model import OpossumPackageModel
13+
14+
15+
class OpossumPackage(BaseModel):
16+
model_config = ConfigDict(frozen=True, extra="forbid")
17+
source: SourceInfo
18+
attribution_confidence: int | None = None
19+
comment: str | None = None
20+
package_name: str | None = None
21+
package_version: str | None = None
22+
package_namespace: str | None = None
23+
package_type: str | None = None
24+
package_purl_appendix: str | None = None
25+
copyright: str | None = None
26+
license_name: str | None = None
27+
license_text: str | None = None
28+
url: str | None = None
29+
first_party: bool | None = None
30+
exclude_from_notice: bool | None = None
31+
pre_selected: bool | None = None
32+
follow_up: Literal["FOLLOW_UP"] | None = None
33+
origin_id: str | None = None
34+
origin_ids: tuple[str, ...] | None = None
35+
criticality: Literal["high"] | Literal["medium"] | None = None
36+
was_preferred: bool | None = None
37+
38+
def to_opossum_file_model(self) -> OpossumPackageModel:
39+
return OpossumPackageModel(
40+
source=self.source.to_opossum_file_model(),
41+
attribution_confidence=self.attribution_confidence,
42+
comment=self.comment,
43+
package_name=self.package_name,
44+
package_version=self.package_version,
45+
package_namespace=self.package_namespace,
46+
package_type=self.package_type,
47+
package_p_u_r_l_appendix=self.package_purl_appendix,
48+
copyright=self.copyright,
49+
license_name=self.license_name,
50+
license_text=self.license_text,
51+
url=self.url,
52+
first_party=self.first_party,
53+
exclude_from_notice=self.exclude_from_notice,
54+
pre_selected=self.pre_selected,
55+
follow_up=self.follow_up,
56+
origin_id=self.origin_id,
57+
origin_ids=self.origin_ids,
58+
criticality=self.criticality,
59+
was_preferred=self.was_preferred,
60+
)

0 commit comments

Comments
 (0)