spl-core 4.0.0__py3-none-any.whl → 4.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spl_core/__init__.py +1 -1
- spl_core/common/command_line_executor.py +52 -0
- spl_core/project_creator/templates/project/{{cookiecutter.name}}/Pipfile +1 -4
- spl_core/test_utils/base_variant_test_runner.py +61 -0
- spl_core/test_utils/spl_build.py +77 -0
- {spl_core-4.0.0.dist-info → spl_core-4.1.0.dist-info}/METADATA +1 -1
- {spl_core-4.0.0.dist-info → spl_core-4.1.0.dist-info}/RECORD +9 -6
- {spl_core-4.0.0.dist-info → spl_core-4.1.0.dist-info}/LICENSE +0 -0
- {spl_core-4.0.0.dist-info → spl_core-4.1.0.dist-info}/WHEEL +0 -0
spl_core/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "4.
|
|
1
|
+
__version__ = "4.1.0"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CommandLineExecutor:
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
cwd: Optional[Path] = None,
|
|
10
|
+
env: Optional[Dict[str, str]] = None,
|
|
11
|
+
):
|
|
12
|
+
"""
|
|
13
|
+
A class for executing command line commands.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
- cmd: A string or list of strings representing the command to be executed.
|
|
17
|
+
- cwd: An optional Path object representing the current working directory.
|
|
18
|
+
- env: An optional dictionary of environment variables to be used in the command execution.
|
|
19
|
+
"""
|
|
20
|
+
self.current_working_directory = cwd
|
|
21
|
+
self.env = env
|
|
22
|
+
|
|
23
|
+
def execute(self, cmd: str | List[str]) -> subprocess.CompletedProcess[str]:
|
|
24
|
+
"""
|
|
25
|
+
Executes the command and returns a CompletedProcess object.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
- A subprocess.CompletedProcess object representing the result of the command execution.
|
|
29
|
+
"""
|
|
30
|
+
command = " ".join([cmd] if isinstance(cmd, str) else cmd)
|
|
31
|
+
output = ""
|
|
32
|
+
try:
|
|
33
|
+
print(f"Running command: {command}")
|
|
34
|
+
with subprocess.Popen(
|
|
35
|
+
command,
|
|
36
|
+
cwd=str(self.current_working_directory or Path.cwd()),
|
|
37
|
+
stdout=subprocess.PIPE,
|
|
38
|
+
stderr=subprocess.STDOUT,
|
|
39
|
+
bufsize=1,
|
|
40
|
+
text=True,
|
|
41
|
+
env=self.env,
|
|
42
|
+
universal_newlines=True,
|
|
43
|
+
) as process:
|
|
44
|
+
if process.stdout:
|
|
45
|
+
for line in process.stdout:
|
|
46
|
+
print(line, end="")
|
|
47
|
+
# We have to store the stdout content.
|
|
48
|
+
# This is necessary because the stdout object is closed after we printed its content
|
|
49
|
+
output += line
|
|
50
|
+
except Exception:
|
|
51
|
+
raise RuntimeError(f"Command '{command}' failed.") # noqa: B904
|
|
52
|
+
return subprocess.CompletedProcess(args=command, returncode=process.returncode, stdout=output, stderr=None)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from spl_core.test_utils.spl_build import SplBuild
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseVariantTestRunner(ABC):
|
|
10
|
+
@property
|
|
11
|
+
def variant(self) -> str:
|
|
12
|
+
return re.sub(r"^Test_", "", self.__class__.__name__).replace("__", "/")
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
@abstractmethod
|
|
16
|
+
def component_paths(self) -> List[Path]:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def expected_build_artifacts(self) -> List[Path]:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def expected_test_artifacts(self) -> List[Path]:
|
|
26
|
+
return [Path("reports/coverage/index.html")]
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def expected_variant_report_artifacts(self) -> List[Path]:
|
|
30
|
+
return [Path("reports/reports/index.html")]
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def expected_component_report_artifacts(self) -> List[Path]:
|
|
34
|
+
return [
|
|
35
|
+
Path("coverage.html"),
|
|
36
|
+
Path("unit_test_results.html"),
|
|
37
|
+
Path("unit_test_spec.html"),
|
|
38
|
+
Path("doxygen/html/index.html"),
|
|
39
|
+
Path("coverage/index.html"),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
def test_build(self) -> None:
|
|
43
|
+
spl_build: SplBuild = SplBuild(variant=self.variant, build_kit="prod")
|
|
44
|
+
assert 0 == spl_build.execute(target="all") # noqa: S101
|
|
45
|
+
for artifact in self.expected_build_artifacts:
|
|
46
|
+
assert artifact.exists() or Path.joinpath(spl_build.build_dir, artifact).exists() # noqa: S101
|
|
47
|
+
|
|
48
|
+
def test_unittest(self) -> None:
|
|
49
|
+
spl_build: SplBuild = SplBuild(variant=self.variant, build_kit="test")
|
|
50
|
+
assert 0 == spl_build.execute(target="unittests") # noqa: S101
|
|
51
|
+
for artifact in self.expected_test_artifacts:
|
|
52
|
+
assert artifact.exists() # noqa: S101
|
|
53
|
+
|
|
54
|
+
def test_reports(self) -> None:
|
|
55
|
+
spl_build: SplBuild = SplBuild(variant=self.variant, build_kit="test")
|
|
56
|
+
assert 0 == spl_build.execute(target="all") # noqa: S101
|
|
57
|
+
for artifact in self.expected_variant_report_artifacts:
|
|
58
|
+
assert Path.joinpath(spl_build.build_dir, artifact).exists() # noqa: S101
|
|
59
|
+
for component in self.component_paths:
|
|
60
|
+
for artifact in self.expected_component_report_artifacts:
|
|
61
|
+
assert Path.joinpath(spl_build.build_dir, component, artifact).exists() # noqa: S101
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from py_app_dev.core.logging import time_it
|
|
6
|
+
|
|
7
|
+
from spl_core.common.command_line_executor import CommandLineExecutor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SplBuild:
|
|
11
|
+
"""Class for building an SPL repository."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, variant: str, build_kit: str):
|
|
14
|
+
"""
|
|
15
|
+
Initialize a SplBuild instance.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
variant (str): The build variant.
|
|
19
|
+
build_kit (str): The build kit.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
self.variant = variant
|
|
23
|
+
self.build_kit = build_kit
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def build_dir(self) -> Path:
|
|
27
|
+
"""
|
|
28
|
+
Get the build directory.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Path: The build directory path.
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
return Path(f"build/{self.variant}/{self.build_kit}")
|
|
35
|
+
|
|
36
|
+
@time_it()
|
|
37
|
+
def execute(self, target: str, additional_args: Optional[List[str]] = None) -> int:
|
|
38
|
+
"""
|
|
39
|
+
Build the target
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
target (str): The build target.
|
|
43
|
+
additional_args (List[str], optional): Additional arguments for building. Defaults to ["-build"].
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
int: 0 in case of success.
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
if additional_args is None:
|
|
50
|
+
additional_args = ["-build"]
|
|
51
|
+
return_code = -1
|
|
52
|
+
while True:
|
|
53
|
+
cmd = [
|
|
54
|
+
"build.bat",
|
|
55
|
+
"-buildKit",
|
|
56
|
+
self.build_kit,
|
|
57
|
+
"-variants",
|
|
58
|
+
self.variant,
|
|
59
|
+
"-target",
|
|
60
|
+
target,
|
|
61
|
+
"-reconfigure",
|
|
62
|
+
]
|
|
63
|
+
cmd.extend(additional_args)
|
|
64
|
+
result = CommandLineExecutor().execute(cmd)
|
|
65
|
+
return_code = result.returncode
|
|
66
|
+
if result.returncode:
|
|
67
|
+
if result.stdout:
|
|
68
|
+
if any(error in str(result.stdout) for error in ["No valid floating license", "No valid license", "GHS_LMHOST = N/A"]):
|
|
69
|
+
print("Probably a license issue, retrying ...")
|
|
70
|
+
time.sleep(10)
|
|
71
|
+
else:
|
|
72
|
+
break
|
|
73
|
+
else:
|
|
74
|
+
break
|
|
75
|
+
else:
|
|
76
|
+
break
|
|
77
|
+
return return_code
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
spl_core/__init__.py,sha256=
|
|
1
|
+
spl_core/__init__.py,sha256=jegJMYuSW90VKiMotVdNAakBvYVPirm-A5oeyJVuhH8,22
|
|
2
2
|
spl_core/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
spl_core/common/cmake.py,sha256=qId_QIGqvG_qkJWOTJjiW723nev6p0vvP3O0Jlfppz4,2054
|
|
4
|
+
spl_core/common/command_line_executor.py,sha256=2ck2ndExyjfFORGMHhtOPTWA3gJGJ_GdZfopen2ISoY,2019
|
|
4
5
|
spl_core/common/path.py,sha256=sDujd3n4XP1XGjHc7ImXEdjihO6A8BOIDbKCf7HgQ0Y,462
|
|
5
6
|
spl_core/gcov_maid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
7
|
spl_core/gcov_maid/gcov_maid.py,sha256=5rPIeL9daQDm5ad9xzaIhlDf_0H5g6r2zHo8WN8T4-8,1455
|
|
@@ -20,7 +21,7 @@ spl_core/project_creator/templates/project/{{cookiecutter.name}}/.vscode/tasks.j
|
|
|
20
21
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/CMakeLists.txt,sha256=YHU4FBV3K4O3MUk289tLpC_t-rEAdbcXylWqNHRPVFY,1400
|
|
21
22
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/KConfig,sha256=gqH4r2MYLLDtfUDQo2nYyx-rgHjBI62ca5U9TTlLFpc,598
|
|
22
23
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/LICENSE,sha256=be3z6Wl8HeMABfG-fLSW2qst-PXlaByWyCbC6ztQT9A,1108
|
|
23
|
-
spl_core/project_creator/templates/project/{{cookiecutter.name}}/Pipfile,sha256=
|
|
24
|
+
spl_core/project_creator/templates/project/{{cookiecutter.name}}/Pipfile,sha256=Axw_VeFUvmaDzw2zKCbzv6ddzerOXy_eoVi-fFwm8Y8,513
|
|
24
25
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/README.md,sha256=3-uBrhvLWhjaaJxKVQXc3kajwS2o49_snrQxw6V8kWM,337
|
|
25
26
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/build.bat,sha256=HlOqePYRoHTrp7v6oQ551dXI-qCymGCG0gQ9Au6bpos,73
|
|
26
27
|
spl_core/project_creator/templates/project/{{cookiecutter.name}}/build.ps1,sha256=37Eui885PQC62nOD6l4dEgaeXBntiVxLBy_NYWvWDzU,10528
|
|
@@ -59,7 +60,9 @@ spl_core/project_creator/templates/variant/{{cookiecutter.flavor}}/{{cookiecutte
|
|
|
59
60
|
spl_core/project_creator/templates/variant/{{cookiecutter.flavor}}/{{cookiecutter.subsystem}}/parts.cmake,sha256=s-SMLPvajH4ZGupruSuh-SbL8jackverQpxGqdoD-Io,77
|
|
60
61
|
spl_core/project_creator/variant.py,sha256=juZWBvLT7i1ZtP1LlGBDalzTf0mhFvfoON43VoqjZOA,532
|
|
61
62
|
spl_core/project_creator/workspace_artifacts.py,sha256=E4oZjnFgC2-cz9jYIYUZzOC9R07LBJAbgGwHAuK0Arg,1279
|
|
62
|
-
spl_core
|
|
63
|
-
spl_core
|
|
64
|
-
spl_core-4.
|
|
65
|
-
spl_core-4.
|
|
63
|
+
spl_core/test_utils/base_variant_test_runner.py,sha256=xoMiNxCxXNyNdwAJ0xmzwqgMPrNJOSeanbttlDOxQSA,2256
|
|
64
|
+
spl_core/test_utils/spl_build.py,sha256=J7gj9Q979pivkYi6Bm2YUSCpjCXQ72rioCZbAgcCoLY,2172
|
|
65
|
+
spl_core-4.1.0.dist-info/LICENSE,sha256=UjjA0o8f5tT3wVm7qodTLAhPWLl6kgVyn9FPAd1VeYY,1099
|
|
66
|
+
spl_core-4.1.0.dist-info/METADATA,sha256=VHPQGIRfVlJq74E4--POmNp3_aC1Ir3_Qmh3SdV41g8,1997
|
|
67
|
+
spl_core-4.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
68
|
+
spl_core-4.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|