ScriptCollection 4.0.11__py3-none-any.whl → 4.0.13__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.
- ScriptCollection/AnionBuildPlatform.py +2 -0
- ScriptCollection/ScriptCollectionCore.py +1 -1
- ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +88 -0
- ScriptCollection/TFCPS/Docker/__init__.py +0 -0
- ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationBase.py +8 -0
- ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationGenerate.py +6 -0
- ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationNoGenerate.py +7 -0
- ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py +479 -0
- ScriptCollection/TFCPS/DotNet/__init__.py +0 -0
- ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +43 -0
- ScriptCollection/TFCPS/Flutter/__init__.py +0 -0
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +123 -0
- ScriptCollection/TFCPS/NodeJS/__init__.py +0 -0
- ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py +114 -0
- ScriptCollection/TFCPS/Python/__init__.py +0 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +417 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py +120 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +80 -0
- ScriptCollection/TFCPS/TFCPS_CreateRelease.py +97 -0
- ScriptCollection/TFCPS/TFCPS_Generic.py +43 -0
- ScriptCollection/TFCPS/TFCPS_MergeToMain.py +125 -0
- ScriptCollection/TFCPS/TFCPS_MergeToStable.py +361 -0
- ScriptCollection/TFCPS/TFCPS_Tools_Dependencies.py +16 -0
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +1076 -0
- ScriptCollection/TFCPS/__init__.py +0 -0
- {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/METADATA +1 -1
- scriptcollection-4.0.13.dist-info/RECORD +41 -0
- scriptcollection-4.0.11.dist-info/RECORD +0 -17
- {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/WHEEL +0 -0
- {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/entry_points.txt +0 -0
- {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
import os
|
2
|
+
from ...GeneralUtilities import GeneralUtilities
|
3
|
+
from ...SCLog import LogLevel
|
4
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
5
|
+
|
6
|
+
class TFCPS_CodeUnitSpecific_Docker_Functions(TFCPS_CodeUnitSpecific_Base):
|
7
|
+
|
8
|
+
def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool):
|
9
|
+
super().__init__(current_file, verbosity,targetenvironmenttype,use_cache)
|
10
|
+
|
11
|
+
|
12
|
+
@GeneralUtilities.check_arguments
|
13
|
+
def build(self=None) -> None:
|
14
|
+
use_cache: bool = False
|
15
|
+
|
16
|
+
codeunitname: str =self.get_codeunit_name()
|
17
|
+
codeunit_folder =self.get_codeunit_folder()
|
18
|
+
codeunitname_lower = codeunitname.lower()
|
19
|
+
codeunit_file =self.get_codeunit_file()
|
20
|
+
codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(codeunit_file)
|
21
|
+
args = ["image", "build", "--pull", "--force-rm", "--progress=plain", "--build-arg", f"TargetEnvironmentType={self.get_target_environment_type()}", "--build-arg", f"CodeUnitName={codeunitname}", "--build-arg", f"CodeUnitVersion={codeunitversion}", "--build-arg", f"CodeUnitOwnerName={self.tfcps_Tools_General.get_codeunit_owner_name(self.get_codeunit_file())}", "--build-arg", f"CodeUnitOwnerEMailAddress={self.tfcps_Tools_General.get_codeunit_owner_emailaddress(self.get_codeunit_file())}"]
|
22
|
+
custom_arguments:dict[str,str]={}#TODO must be setable from outside
|
23
|
+
if custom_arguments is not None:
|
24
|
+
for custom_argument_key, custom_argument_value in custom_arguments.items():
|
25
|
+
args.append("--build-arg")
|
26
|
+
args.append(f"{custom_argument_key}={custom_argument_value}")
|
27
|
+
args = args+["--tag", f"{codeunitname_lower}:latest", "--tag", f"{codeunitname_lower}:{codeunitversion}", "--file", f"{codeunitname}/Dockerfile"]
|
28
|
+
if not use_cache:
|
29
|
+
args.append("--no-cache")
|
30
|
+
args.append(".")
|
31
|
+
codeunit_content_folder = os.path.join(codeunit_folder)
|
32
|
+
self._protected_sc.run_program_argsasarray("docker", args, codeunit_content_folder, print_errors_as_information=True)
|
33
|
+
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
34
|
+
app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
|
35
|
+
GeneralUtilities.ensure_directory_does_not_exist(app_artifacts_folder)
|
36
|
+
GeneralUtilities.ensure_directory_exists(app_artifacts_folder)
|
37
|
+
self._protected_sc.run_program_argsasarray("docker", ["save", "--output", f"{codeunitname}_v{codeunitversion}.tar", f"{codeunitname_lower}:{codeunitversion}"], app_artifacts_folder, print_errors_as_information=True)
|
38
|
+
self.copy_source_files_to_output_directory()
|
39
|
+
self.__generate_sbom_for_docker_image()
|
40
|
+
|
41
|
+
|
42
|
+
@GeneralUtilities.check_arguments
|
43
|
+
def __generate_sbom_for_docker_image(self) -> None:
|
44
|
+
|
45
|
+
codeunitname=self.get_codeunit_name()
|
46
|
+
codeunit_folder =self.get_codeunit_folder()
|
47
|
+
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
48
|
+
codeunitname_lower = codeunitname.lower()
|
49
|
+
sbom_folder = os.path.join(artifacts_folder, "BOM")
|
50
|
+
codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(self.get_codeunit_file())
|
51
|
+
GeneralUtilities.ensure_directory_exists(sbom_folder)
|
52
|
+
self._protected_sc.run_program_argsasarray("docker", ["sbom", "--format", "cyclonedx", f"{codeunitname_lower}:{codeunitversion}", "--output", f"{codeunitname}.{codeunitversion}.sbom.xml"], sbom_folder, print_errors_as_information=True)
|
53
|
+
self._protected_sc.format_xml_file(sbom_folder+f"/{codeunitname}.{codeunitversion}.sbom.xml")
|
54
|
+
|
55
|
+
@GeneralUtilities.check_arguments
|
56
|
+
def linting(self=None) -> None:
|
57
|
+
pass#TODO
|
58
|
+
|
59
|
+
@GeneralUtilities.check_arguments
|
60
|
+
def do_common_tasks(self,current_codeunit_version:str )-> None:
|
61
|
+
codeunitname =self.get_codeunit_name()
|
62
|
+
codeunit_folder = self.get_codeunit_folder()
|
63
|
+
codeunit_version = current_codeunit_version
|
64
|
+
self._protected_sc.replace_version_in_dockerfile_file(GeneralUtilities.resolve_relative_path(f"./{codeunitname}/Dockerfile", codeunit_folder), codeunit_version)
|
65
|
+
self.do_common_tasks_base(current_codeunit_version)
|
66
|
+
self.tfcps_Tools_General.standardized_tasks_update_version_in_docker_examples(codeunit_folder,codeunit_version)
|
67
|
+
|
68
|
+
@GeneralUtilities.check_arguments
|
69
|
+
def generate_reference(self=None) -> None:
|
70
|
+
self.generate_reference_using_docfx()
|
71
|
+
|
72
|
+
@GeneralUtilities.check_arguments
|
73
|
+
def update_dependencies(self=None) -> None:
|
74
|
+
pass#TODO
|
75
|
+
|
76
|
+
@GeneralUtilities.check_arguments
|
77
|
+
def run_testcases(self=None) -> None:
|
78
|
+
pass#TODO
|
79
|
+
|
80
|
+
class TFCPS_CodeUnitSpecific_Docker_CLI:
|
81
|
+
|
82
|
+
@staticmethod
|
83
|
+
def parse(file:str)->TFCPS_CodeUnitSpecific_Docker_Functions:
|
84
|
+
parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
85
|
+
#add custom parameter if desired
|
86
|
+
args=parser.parse_args()
|
87
|
+
result:TFCPS_CodeUnitSpecific_Docker_Functions=TFCPS_CodeUnitSpecific_Docker_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache)
|
88
|
+
return result
|
File without changes
|
@@ -0,0 +1,479 @@
|
|
1
|
+
import os
|
2
|
+
import re
|
3
|
+
import shutil
|
4
|
+
import tempfile
|
5
|
+
import uuid
|
6
|
+
import json
|
7
|
+
from lxml import etree
|
8
|
+
import yaml
|
9
|
+
|
10
|
+
from .CertificateGeneratorInformationBase import CertificateGeneratorInformationBase
|
11
|
+
from ...GeneralUtilities import GeneralUtilities
|
12
|
+
from ...SCLog import LogLevel
|
13
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
14
|
+
|
15
|
+
class TFCPS_CodeUnitSpecific_DotNet_Functions(TFCPS_CodeUnitSpecific_Base):
|
16
|
+
|
17
|
+
is_library:bool
|
18
|
+
csproj_file:bool
|
19
|
+
|
20
|
+
def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool):
|
21
|
+
super().__init__(current_file, verbosity,targetenvironmenttype,use_cache)
|
22
|
+
self.csproj_file=os.path.join(self.get_codeunit_folder(), self.get_codeunit_name(), self.get_codeunit_name() + ".csproj")
|
23
|
+
self.is_library="<OutputType>Library</OutputType>" in GeneralUtilities.read_text_from_file(self.csproj_file)#TODO do a real check
|
24
|
+
|
25
|
+
@GeneralUtilities.check_arguments
|
26
|
+
def build(self,runtimes:list[str],generate_open_api_spec:bool) -> None:
|
27
|
+
if self.is_library:
|
28
|
+
self.standardized_tasks_build_for_dotnet_library_project(runtimes)
|
29
|
+
GeneralUtilities.assert_condition(not generate_open_api_spec,"OpenAPI-Specification can not be generated for a library.")
|
30
|
+
else:
|
31
|
+
self.standardized_tasks_build_for_dotnet_project(runtimes)
|
32
|
+
if generate_open_api_spec:
|
33
|
+
self.generate_openapi_file(runtimes[0])
|
34
|
+
|
35
|
+
@GeneralUtilities.check_arguments
|
36
|
+
def generate_openapi_file(self, runtime: str) -> None:
|
37
|
+
swagger_document_name: str = "APISpecification"
|
38
|
+
self._protected_sc.log.log("Generate OpenAPI-specification-file...")
|
39
|
+
codeunitname =self.get_codeunit_name()
|
40
|
+
repository_folder =self.get_repository_folder()
|
41
|
+
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
42
|
+
artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts")
|
43
|
+
GeneralUtilities.ensure_directory_exists(os.path.join(artifacts_folder, "APISpecification"))
|
44
|
+
codeunit_version = self.tfcps_Tools_General.get_version_of_codeunit(os.path.join(codeunit_folder,f"{codeunitname}.codeunit.xml"))
|
45
|
+
|
46
|
+
versioned_api_spec_file = f"APISpecification/{codeunitname}.v{codeunit_version}.api.json"
|
47
|
+
self._protected_sc.run_program("swagger", f"tofile --output {versioned_api_spec_file} BuildResult_DotNet_{runtime}/{codeunitname}.dll {swagger_document_name}", artifacts_folder)
|
48
|
+
api_file: str = os.path.join(artifacts_folder, versioned_api_spec_file)
|
49
|
+
shutil.copyfile(api_file, os.path.join(artifacts_folder, f"APISpecification/{codeunitname}.latest.api.json"))
|
50
|
+
|
51
|
+
resources_folder = os.path.join(codeunit_folder, "Other", "Resources")
|
52
|
+
GeneralUtilities.ensure_directory_exists(resources_folder)
|
53
|
+
resources_apispec_folder = os.path.join(resources_folder, "APISpecification")
|
54
|
+
GeneralUtilities.ensure_directory_exists(resources_apispec_folder)
|
55
|
+
resource_target_file = os.path.join(resources_apispec_folder, f"{codeunitname}.api.json")
|
56
|
+
GeneralUtilities.ensure_file_does_not_exist(resource_target_file)
|
57
|
+
shutil.copyfile(api_file, resource_target_file)
|
58
|
+
|
59
|
+
with open(api_file, encoding="utf-8") as api_file_content:
|
60
|
+
reloaded_json = json.load(api_file_content)
|
61
|
+
|
62
|
+
yamlfile1: str = str(os.path.join(artifacts_folder, f"APISpecification/{codeunitname}.v{codeunit_version}.api.yaml"))
|
63
|
+
GeneralUtilities.ensure_file_does_not_exist(yamlfile1)
|
64
|
+
GeneralUtilities.ensure_file_exists(yamlfile1)
|
65
|
+
with open(yamlfile1, "w+", encoding="utf-8") as yamlfile:
|
66
|
+
yaml.dump(reloaded_json, yamlfile, allow_unicode=True)
|
67
|
+
|
68
|
+
yamlfile2: str = str(os.path.join(artifacts_folder, f"APISpecification/{codeunitname}.latest.api.yaml"))
|
69
|
+
GeneralUtilities.ensure_file_does_not_exist(yamlfile2)
|
70
|
+
shutil.copyfile(yamlfile1, yamlfile2)
|
71
|
+
|
72
|
+
yamlfile3: str = str(os.path.join(resources_apispec_folder, f"{codeunitname}.api.yaml"))
|
73
|
+
GeneralUtilities.ensure_file_does_not_exist(yamlfile3)
|
74
|
+
shutil.copyfile(yamlfile1, yamlfile3)
|
75
|
+
|
76
|
+
@GeneralUtilities.check_arguments
|
77
|
+
def __standardized_tasks_build_for_dotnet_build(self, csproj_file: str, originaloutputfolder: str, files_to_sign: dict[str, str], commitid: str, runtimes: list[str], target_environmenttype_mapping: dict[str, str], copy_license_file_to_target_folder: bool, repository_folder: str, codeunit_name: str) -> None:
|
78
|
+
self._protected_sc.assert_is_git_repository(repository_folder)
|
79
|
+
csproj_filename = os.path.basename(csproj_file)
|
80
|
+
self._protected_sc.log.log(f"Build {csproj_filename}...")
|
81
|
+
dotnet_build_configuration: str = self.get_target_environment_type()
|
82
|
+
codeunit_folder = os.path.join(repository_folder, codeunit_name)
|
83
|
+
csproj_file_folder = os.path.dirname(csproj_file)
|
84
|
+
csproj_file_name = os.path.basename(csproj_file)
|
85
|
+
csproj_file_name_without_extension = csproj_file_name.split(".")[0]
|
86
|
+
sarif_folder = os.path.join(codeunit_folder, "Other", "Resources", "CodeAnalysisResult")
|
87
|
+
GeneralUtilities.ensure_directory_exists(sarif_folder)
|
88
|
+
gitkeep_file = os.path.join(sarif_folder, ".gitkeep")
|
89
|
+
GeneralUtilities.ensure_file_exists(gitkeep_file)
|
90
|
+
for runtime in runtimes:
|
91
|
+
outputfolder = originaloutputfolder+runtime
|
92
|
+
GeneralUtilities.ensure_directory_does_not_exist(os.path.join(csproj_file_folder, "obj"))
|
93
|
+
GeneralUtilities.ensure_directory_does_not_exist(outputfolder)
|
94
|
+
self._protected_sc.run_program("dotnet", "clean", csproj_file_folder)
|
95
|
+
GeneralUtilities.ensure_directory_exists(outputfolder)
|
96
|
+
self._protected_sc.run_program("dotnet", "restore", codeunit_folder)
|
97
|
+
self._protected_sc.run_program_argsasarray("dotnet", ["build", csproj_file_name, "-c", dotnet_build_configuration, "-o", outputfolder, "--runtime", runtime], csproj_file_folder)
|
98
|
+
if copy_license_file_to_target_folder:
|
99
|
+
license_file = os.path.join(repository_folder, "License.txt")
|
100
|
+
target = os.path.join(outputfolder, f"{codeunit_name}.License.txt")
|
101
|
+
shutil.copyfile(license_file, target)
|
102
|
+
if 0 < len(files_to_sign):
|
103
|
+
for key, value in files_to_sign.items():
|
104
|
+
dll_file = key
|
105
|
+
snk_file = value
|
106
|
+
dll_file_full = os.path.join(outputfolder, dll_file)
|
107
|
+
if os.path.isfile(dll_file_full):
|
108
|
+
GeneralUtilities.assert_condition(self._protected_sc.run_program("sn", f"-vf {dll_file}", outputfolder, throw_exception_if_exitcode_is_not_zero=False)[0] == 1, f"Pre-verifying of {dll_file} failed.")
|
109
|
+
self._protected_sc.run_program_argsasarray("sn", ["-R", dll_file, snk_file], outputfolder)
|
110
|
+
GeneralUtilities.assert_condition(self._protected_sc.run_program("sn", f"-vf {dll_file}", outputfolder, throw_exception_if_exitcode_is_not_zero=False)[0] == 0, f"Verifying of {dll_file} failed.")
|
111
|
+
sarif_filename = f"{csproj_file_name_without_extension}.sarif"
|
112
|
+
sarif_source_file = os.path.join(sarif_folder, sarif_filename)
|
113
|
+
if os.path.exists(sarif_source_file):
|
114
|
+
sarif_folder_target = os.path.join(codeunit_folder, "Other", "Artifacts", "CodeAnalysisResult")
|
115
|
+
GeneralUtilities.ensure_directory_exists(sarif_folder_target)
|
116
|
+
sarif_target_file = os.path.join(sarif_folder_target, sarif_filename)
|
117
|
+
GeneralUtilities.ensure_file_does_not_exist(sarif_target_file)
|
118
|
+
shutil.copyfile(sarif_source_file, sarif_target_file)
|
119
|
+
#TODO check for updateable dependencies (in a unified way)
|
120
|
+
|
121
|
+
@GeneralUtilities.check_arguments
|
122
|
+
def standardized_tasks_build_for_dotnet_project(self,runtimes:list[str]) -> None:
|
123
|
+
self.__standardized_tasks_build_for_dotnet_project(runtimes)
|
124
|
+
|
125
|
+
@GeneralUtilities.check_arguments
|
126
|
+
def standardized_tasks_build_for_dotnet_library_project(self,runtimes:list[str]) -> None:
|
127
|
+
self.__standardized_tasks_build_for_dotnet_project( runtimes)
|
128
|
+
self.__standardized_tasks_build_nupkg_for_dotnet_create_package(runtimes)
|
129
|
+
|
130
|
+
|
131
|
+
@staticmethod
|
132
|
+
@GeneralUtilities.check_arguments
|
133
|
+
def get_filestosign_from_commandline_arguments( default_value: dict[str, str]) -> dict[str, str]:
|
134
|
+
result_plain =None# TODO TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, "sign")
|
135
|
+
if result_plain is None:
|
136
|
+
return default_value
|
137
|
+
else:
|
138
|
+
result: dict[str, str] = dict[str, str]()
|
139
|
+
files_tuples = GeneralUtilities.to_list(result_plain, ";")
|
140
|
+
for files_tuple in files_tuples:
|
141
|
+
splitted = files_tuple.split("=")
|
142
|
+
result[splitted[0]] = splitted[1]
|
143
|
+
return result
|
144
|
+
|
145
|
+
@GeneralUtilities.check_arguments
|
146
|
+
def __standardized_tasks_build_for_dotnet_project(self,runtimes:list[str]) -> None:
|
147
|
+
|
148
|
+
target_environment_type: str=self.get_target_environment_type()
|
149
|
+
copy_license_file_to_target_folder: bool=True
|
150
|
+
codeunitname: str = self.get_codeunit_name()
|
151
|
+
|
152
|
+
files_to_sign: dict[str, str] = self.get_filestosign_from_commandline_arguments( dict())
|
153
|
+
repository_folder: str = self.get_repository_folder()
|
154
|
+
commitid = self._protected_sc.git_get_commit_id(repository_folder)
|
155
|
+
outputfolder = GeneralUtilities.resolve_relative_path("./Other/Artifacts", self.get_codeunit_folder())
|
156
|
+
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
157
|
+
csproj_file = os.path.join(codeunit_folder, codeunitname, codeunitname + ".csproj")
|
158
|
+
csproj_test_file = os.path.join(codeunit_folder, codeunitname+"Tests", codeunitname+"Tests.csproj")
|
159
|
+
self.__standardized_tasks_build_for_dotnet_build(csproj_file, os.path.join(outputfolder, "BuildResult_DotNet_"), files_to_sign, commitid, runtimes, target_environment_type, copy_license_file_to_target_folder, repository_folder, codeunitname)
|
160
|
+
self.__standardized_tasks_build_for_dotnet_build(csproj_test_file, os.path.join(outputfolder, "BuildResultTests_DotNet_"), files_to_sign, commitid, runtimes, target_environment_type, copy_license_file_to_target_folder, repository_folder, codeunitname)
|
161
|
+
self.generate_sbom_for_dotnet_project(codeunit_folder)
|
162
|
+
self.copy_source_files_to_output_directory()
|
163
|
+
|
164
|
+
@GeneralUtilities.check_arguments
|
165
|
+
def __standardized_tasks_build_nupkg_for_dotnet_create_package(self,runtimes:list[str]) -> None:
|
166
|
+
codeunitname: str = self.get_codeunit_name()
|
167
|
+
repository_folder: str =self.get_repository_folder()
|
168
|
+
build_folder = os.path.join(repository_folder, codeunitname, "Other", "Build")
|
169
|
+
outputfolder = GeneralUtilities.resolve_relative_path("./Other/Artifacts/BuildResult_NuGet",self.get_codeunit_folder())
|
170
|
+
root: etree._ElementTree = etree.parse(os.path.join(build_folder, f"{codeunitname}.nuspec"))
|
171
|
+
current_version = root.xpath("//*[name() = 'package']/*[name() = 'metadata']/*[name() = 'version']/text()")[0]
|
172
|
+
nupkg_filename = f"{codeunitname}.{current_version}.nupkg"
|
173
|
+
nupkg_file = f"{build_folder}/{nupkg_filename}"
|
174
|
+
GeneralUtilities.ensure_file_does_not_exist(nupkg_file)
|
175
|
+
commit_id = self._protected_sc.git_get_commit_id(repository_folder)
|
176
|
+
self._protected_sc.run_program("nuget", f"pack {codeunitname}.nuspec -Properties \"commitid={commit_id}\"", build_folder)
|
177
|
+
GeneralUtilities.ensure_directory_does_not_exist(outputfolder)
|
178
|
+
GeneralUtilities.ensure_directory_exists(outputfolder)
|
179
|
+
os.rename(nupkg_file, f"{outputfolder}/{nupkg_filename}")
|
180
|
+
|
181
|
+
@GeneralUtilities.check_arguments
|
182
|
+
def generate_sbom_for_dotnet_project(self, codeunit_folder: str) -> None:
|
183
|
+
self._protected_sc.log.log("Generate SBOM...")
|
184
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
185
|
+
bomfile_folder = "Other\\Artifacts\\BOM"
|
186
|
+
self._protected_sc.run_program_argsasarray("dotnet", ["CycloneDX", f"{codeunit_name}\\{codeunit_name}.csproj", "-o", bomfile_folder, "--disable-github-licenses"], codeunit_folder)
|
187
|
+
codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunit_name}.codeunit.xml"))
|
188
|
+
target = f"{codeunit_folder}\\{bomfile_folder}\\{codeunit_name}.{codeunitversion}.sbom.xml"
|
189
|
+
GeneralUtilities.ensure_file_does_not_exist(target)
|
190
|
+
os.rename(f"{codeunit_folder}\\{bomfile_folder}\\bom.xml", target)
|
191
|
+
self._protected_sc.format_xml_file(target)
|
192
|
+
|
193
|
+
@GeneralUtilities.check_arguments
|
194
|
+
def linting(self=None) -> None:
|
195
|
+
pass#TODO
|
196
|
+
|
197
|
+
@GeneralUtilities.check_arguments
|
198
|
+
def do_common_tasks(self,current_codeunit_version:str,certificateGeneratorInformation:CertificateGeneratorInformationBase,run_t4:bool)-> None:
|
199
|
+
self.do_common_tasks_base(current_codeunit_version)
|
200
|
+
codeunit_name =self.get_codeunit_name()
|
201
|
+
codeunit_version = self.tfcps_Tools_General.get_version_of_project(self.get_repository_folder()) # Should always be the same as the project-version #TODO make this configurable from outside
|
202
|
+
folder_of_current_file =os.path.join(self.get_codeunit_folder(),"Other")
|
203
|
+
self._protected_sc.replace_version_in_csproj_file(GeneralUtilities.resolve_relative_path(f"../{codeunit_name}/{codeunit_name}.csproj", folder_of_current_file), codeunit_version)
|
204
|
+
self._protected_sc.replace_version_in_csproj_file(GeneralUtilities.resolve_relative_path(f"../{codeunit_name}Tests/{codeunit_name}Tests.csproj", folder_of_current_file), codeunit_version)
|
205
|
+
if self.is_library:
|
206
|
+
self._protected_sc.replace_version_in_nuspec_file(GeneralUtilities.resolve_relative_path(f"./Build/{codeunit_name}.nuspec", folder_of_current_file), codeunit_version)
|
207
|
+
if certificateGeneratorInformation.generate_certificate():
|
208
|
+
self.tfcps_Tools_General.set_constants_for_certificate_private_information(self.get_codeunit_folder())
|
209
|
+
if run_t4:
|
210
|
+
self.tfcps_Tools_General.t4_transform(self.get_codeunit_folder(),True,self.use_cache())
|
211
|
+
self.standardized_task_verify_standard_format_csproj_files()
|
212
|
+
|
213
|
+
@GeneralUtilities.check_arguments
|
214
|
+
def standardized_task_verify_standard_format_csproj_files(self) -> bool:
|
215
|
+
codeunit_folder=self.get_codeunit_folder()
|
216
|
+
repository_folder = os.path.dirname(codeunit_folder)
|
217
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
218
|
+
codeunit_folder = os.path.join(repository_folder, codeunit_name)
|
219
|
+
codeunit_version = self.tfcps_Tools_General.get_version_of_codeunit(self.get_codeunit_file())
|
220
|
+
|
221
|
+
csproj_project_name = codeunit_name
|
222
|
+
csproj_file = os.path.join(codeunit_folder, csproj_project_name, csproj_project_name+".csproj")
|
223
|
+
result1: tuple[bool, str, list[str]] = self.__standardized_task_verify_standard_format_for_project_csproj_file(csproj_file, codeunit_folder, codeunit_name, codeunit_version)
|
224
|
+
if not result1[0]:
|
225
|
+
hints: str = "\n".join(result1[2])
|
226
|
+
raise ValueError(f"'{csproj_file}' with content '{GeneralUtilities.read_text_from_file(csproj_file)}' does not match the standardized .csproj-file-format which is defined by the regex '{result1[1]}'.\n{hints}")
|
227
|
+
|
228
|
+
test_csproj_project_name = csproj_project_name+"Tests"
|
229
|
+
test_csproj_file = os.path.join(codeunit_folder, test_csproj_project_name, test_csproj_project_name+".csproj")
|
230
|
+
result2: tuple[bool, str, list[str]] = self.__standardized_task_verify_standard_format_for_test_csproj_file(test_csproj_file, codeunit_name, codeunit_version)
|
231
|
+
if not result2[0]:
|
232
|
+
hints: str = "\n".join(result2[2])
|
233
|
+
raise ValueError(f"'{test_csproj_file}' with content '{GeneralUtilities.read_text_from_file(test_csproj_file)}' does not match the standardized .csproj-file-format which is defined by the regex '{result2[1]}'.\n{hints}")
|
234
|
+
|
235
|
+
def __standardized_task_verify_standard_format_for_project_csproj_file(self, csproj_file: str, codeunit_folder: str, codeunit_name: str, codeunit_version: str) -> tuple[bool, str, str]:
|
236
|
+
codeunit_name_regex = re.escape(codeunit_name)
|
237
|
+
codeunit_description = self.tfcps_Tools_General.get_codeunit_description(self.get_codeunit_file())
|
238
|
+
codeunit_version_regex = re.escape(codeunit_version)
|
239
|
+
codeunit_description_regex = re.escape(codeunit_description)
|
240
|
+
regex = f"""^<Project Sdk=\\"Microsoft\\.NET\\.Sdk\\">
|
241
|
+
<PropertyGroup>
|
242
|
+
<TargetFramework>([^<]+)<\\/TargetFramework>
|
243
|
+
<Authors>([^<]+)<\\/Authors>
|
244
|
+
<Version>{codeunit_version_regex}<\\/Version>
|
245
|
+
<AssemblyVersion>{codeunit_version_regex}<\\/AssemblyVersion>
|
246
|
+
<FileVersion>{codeunit_version_regex}<\\/FileVersion>
|
247
|
+
<SelfContained>false<\\/SelfContained>
|
248
|
+
<IsPackable>false<\\/IsPackable>
|
249
|
+
<PreserveCompilationContext>false<\\/PreserveCompilationContext>
|
250
|
+
<GenerateRuntimeConfigurationFiles>true<\\/GenerateRuntimeConfigurationFiles>
|
251
|
+
<Copyright>([^<]+)<\\/Copyright>
|
252
|
+
<Description>{codeunit_description_regex}<\\/Description>
|
253
|
+
<PackageProjectUrl>https:\\/\\/([^<]+)<\\/PackageProjectUrl>
|
254
|
+
<RepositoryUrl>https:\\/\\/([^<]+)\\.git<\\/RepositoryUrl>
|
255
|
+
<RootNamespace>([^<]+)\\.Core<\\/RootNamespace>
|
256
|
+
<ProduceReferenceAssembly>false<\\/ProduceReferenceAssembly>
|
257
|
+
<Nullable>(disable|enable|warnings|annotations)<\\/Nullable>
|
258
|
+
<Configurations>Development;QualityCheck;Productive<\\/Configurations>
|
259
|
+
<IsTestProject>false<\\/IsTestProject>
|
260
|
+
<LangVersion>([^<]+)<\\/LangVersion>
|
261
|
+
<PackageRequireLicenseAcceptance>true<\\/PackageRequireLicenseAcceptance>
|
262
|
+
<GenerateSerializationAssemblies>Off<\\/GenerateSerializationAssemblies>
|
263
|
+
<AppendTargetFrameworkToOutputPath>false<\\/AppendTargetFrameworkToOutputPath>
|
264
|
+
<OutputPath>\\.\\.\\\\Other\\\\Artifacts\\\\BuildResult_DotNet_win\\-x64<\\/OutputPath>
|
265
|
+
<PlatformTarget>([^<]+)<\\/PlatformTarget>
|
266
|
+
<WarningLevel>\\d<\\/WarningLevel>
|
267
|
+
<Prefer32Bit>false<\\/Prefer32Bit>
|
268
|
+
<SignAssembly>true<\\/SignAssembly>
|
269
|
+
<AssemblyOriginatorKeyFile>\\.\\.\\\\\\.\\.\\\\Other\\\\Resources\\\\PublicKeys\\\\StronglyNamedKey\\\\([^<]+)PublicKey\\.snk<\\/AssemblyOriginatorKeyFile>
|
270
|
+
<DelaySign>true<\\/DelaySign>
|
271
|
+
<NoWarn>([^<]+)<\\/NoWarn>
|
272
|
+
<WarningsAsErrors>([^<]+)<\\/WarningsAsErrors>
|
273
|
+
<ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\CodeAnalysisResult\\\\{codeunit_name_regex}\\.sarif<\\/ErrorLog>
|
274
|
+
<OutputType>([^<]+)<\\/OutputType>
|
275
|
+
<DocumentationFile>\\.\\.\\\\Other\\\\Artifacts\\\\MetaInformation\\\\{codeunit_name_regex}\\.xml<\\/DocumentationFile>(\\n|.)*
|
276
|
+
<\\/PropertyGroup>
|
277
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='Development'\\\">
|
278
|
+
<DebugType>full<\\/DebugType>
|
279
|
+
<DebugSymbols>true<\\/DebugSymbols>
|
280
|
+
<Optimize>false<\\/Optimize>
|
281
|
+
<DefineConstants>TRACE;DEBUG;Development<\\/DefineConstants>
|
282
|
+
<ErrorReport>prompt<\\/ErrorReport>
|
283
|
+
<\\/PropertyGroup>
|
284
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='QualityCheck'\\\">
|
285
|
+
<DebugType>portable<\\/DebugType>
|
286
|
+
<DebugSymbols>true<\\/DebugSymbols>
|
287
|
+
<Optimize>false<\\/Optimize>
|
288
|
+
<DefineConstants>TRACE;QualityCheck<\\/DefineConstants>
|
289
|
+
<ErrorReport>none<\\/ErrorReport>
|
290
|
+
<\\/PropertyGroup>
|
291
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='Productive'\\\">
|
292
|
+
<DebugType>none<\\/DebugType>
|
293
|
+
<DebugSymbols>false<\\/DebugSymbols>
|
294
|
+
<Optimize>true<\\/Optimize>
|
295
|
+
<DefineConstants>Productive<\\/DefineConstants>
|
296
|
+
<ErrorReport>none<\\/ErrorReport>
|
297
|
+
<\\/PropertyGroup>(\\n|.)*
|
298
|
+
<\\/Project>$"""
|
299
|
+
result = self.__standardized_task_verify_standard_format_for_csproj_files(regex, csproj_file)
|
300
|
+
return (result[0], regex, result[1])
|
301
|
+
|
302
|
+
def __standardized_task_verify_standard_format_for_test_csproj_file(self, csproj_file: str, codeunit_name: str, codeunit_version: str) -> tuple[bool, str, str]:
|
303
|
+
codeunit_name_regex = re.escape(codeunit_name)
|
304
|
+
codeunit_version_regex = re.escape(codeunit_version)
|
305
|
+
regex = f"""^<Project Sdk=\\"Microsoft\\.NET\\.Sdk\\">
|
306
|
+
<PropertyGroup>
|
307
|
+
<TargetFramework>([^<]+)<\\/TargetFramework>
|
308
|
+
<Authors>([^<]+)<\\/Authors>
|
309
|
+
<Version>{codeunit_version_regex}<\\/Version>
|
310
|
+
<AssemblyVersion>{codeunit_version_regex}<\\/AssemblyVersion>
|
311
|
+
<FileVersion>{codeunit_version_regex}<\\/FileVersion>
|
312
|
+
<SelfContained>false<\\/SelfContained>
|
313
|
+
<IsPackable>false<\\/IsPackable>
|
314
|
+
<PreserveCompilationContext>false<\\/PreserveCompilationContext>
|
315
|
+
<GenerateRuntimeConfigurationFiles>true<\\/GenerateRuntimeConfigurationFiles>
|
316
|
+
<Copyright>([^<]+)<\\/Copyright>
|
317
|
+
<Description>{codeunit_name_regex}Tests is the test-project for {codeunit_name_regex}\\.<\\/Description>
|
318
|
+
<PackageProjectUrl>https:\\/\\/([^<]+)<\\/PackageProjectUrl>
|
319
|
+
<RepositoryUrl>https:\\/\\/([^<]+)\\.git</RepositoryUrl>
|
320
|
+
<RootNamespace>([^<]+)\\.Tests<\\/RootNamespace>
|
321
|
+
<ProduceReferenceAssembly>false<\\/ProduceReferenceAssembly>
|
322
|
+
<Nullable>(disable|enable|warnings|annotations)<\\/Nullable>
|
323
|
+
<Configurations>Development;QualityCheck;Productive<\\/Configurations>
|
324
|
+
<IsTestProject>true<\\/IsTestProject>
|
325
|
+
<LangVersion>([^<]+)<\\/LangVersion>
|
326
|
+
<PackageRequireLicenseAcceptance>true<\\/PackageRequireLicenseAcceptance>
|
327
|
+
<GenerateSerializationAssemblies>Off<\\/GenerateSerializationAssemblies>
|
328
|
+
<AppendTargetFrameworkToOutputPath>false<\\/AppendTargetFrameworkToOutputPath>
|
329
|
+
<OutputPath>\\.\\.\\\\Other\\\\Artifacts\\\\BuildResultTests_DotNet_win\\-x64<\\/OutputPath>
|
330
|
+
<PlatformTarget>([^<]+)<\\/PlatformTarget>
|
331
|
+
<WarningLevel>\\d<\\/WarningLevel>
|
332
|
+
<Prefer32Bit>false<\\/Prefer32Bit>
|
333
|
+
<SignAssembly>true<\\/SignAssembly>
|
334
|
+
<AssemblyOriginatorKeyFile>\\.\\.\\\\\\.\\.\\\\Other\\\\Resources\\\\PublicKeys\\\\StronglyNamedKey\\\\([^<]+)PublicKey\\.snk<\\/AssemblyOriginatorKeyFile>
|
335
|
+
<DelaySign>true<\\/DelaySign>
|
336
|
+
<NoWarn>([^<]+)<\\/NoWarn>
|
337
|
+
<WarningsAsErrors>([^<]+)<\\/WarningsAsErrors>
|
338
|
+
<ErrorLog>\\.\\.\\\\Other\\\\Resources\\\\CodeAnalysisResult\\\\{codeunit_name_regex}Tests\\.sarif<\\/ErrorLog>
|
339
|
+
<OutputType>Library<\\/OutputType>(\\n|.)*
|
340
|
+
<\\/PropertyGroup>
|
341
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='Development'\\\">
|
342
|
+
<DebugType>full<\\/DebugType>
|
343
|
+
<DebugSymbols>true<\\/DebugSymbols>
|
344
|
+
<Optimize>false<\\/Optimize>
|
345
|
+
<DefineConstants>TRACE;DEBUG;Development<\\/DefineConstants>
|
346
|
+
<ErrorReport>prompt<\\/ErrorReport>
|
347
|
+
<\\/PropertyGroup>
|
348
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='QualityCheck'\\\">
|
349
|
+
<DebugType>portable<\\/DebugType>
|
350
|
+
<DebugSymbols>true<\\/DebugSymbols>
|
351
|
+
<Optimize>false<\\/Optimize>
|
352
|
+
<DefineConstants>TRACE;QualityCheck<\\/DefineConstants>
|
353
|
+
<ErrorReport>none<\\/ErrorReport>
|
354
|
+
<\\/PropertyGroup>
|
355
|
+
<PropertyGroup Condition=\\\"'\\$\\(Configuration\\)'=='Productive'\\\">
|
356
|
+
<DebugType>none<\\/DebugType>
|
357
|
+
<DebugSymbols>false<\\/DebugSymbols>
|
358
|
+
<Optimize>true<\\/Optimize>
|
359
|
+
<DefineConstants>Productive<\\/DefineConstants>
|
360
|
+
<ErrorReport>none<\\/ErrorReport>
|
361
|
+
<\\/PropertyGroup>(\\n|.)*
|
362
|
+
<\\/Project>$"""
|
363
|
+
result = self.__standardized_task_verify_standard_format_for_csproj_files(regex, csproj_file)
|
364
|
+
return (result[0], regex, result[1])
|
365
|
+
|
366
|
+
def __standardized_task_verify_standard_format_for_csproj_files(self, regex: str, csproj_file: str) -> tuple[bool, list[str]]:
|
367
|
+
filename = os.path.basename(csproj_file)
|
368
|
+
self._protected_sc.log.log(f"Check {filename}...",LogLevel.Debug)
|
369
|
+
file_content = GeneralUtilities.read_text_from_file(csproj_file)
|
370
|
+
regex_for_check = regex.replace("\r", GeneralUtilities.empty_string).replace("\n", "\\n")
|
371
|
+
file_content = file_content.replace("\r", GeneralUtilities.empty_string)
|
372
|
+
match = re.match(regex_for_check, file_content)
|
373
|
+
result = match is not None
|
374
|
+
hints = None
|
375
|
+
if not result:
|
376
|
+
hints = self.get_hints_for_csproj(regex, file_content)
|
377
|
+
return (result, hints)
|
378
|
+
|
379
|
+
@GeneralUtilities.check_arguments
|
380
|
+
def get_hints_for_csproj(self, regex: str, file_content: str) -> list[str]:
|
381
|
+
result: list[str] = []
|
382
|
+
regex_lines = GeneralUtilities.string_to_lines(regex)
|
383
|
+
file_content_lines = GeneralUtilities.string_to_lines(file_content)
|
384
|
+
#amount_of_regexes = len(regex_lines)
|
385
|
+
amount_of_lines = len(file_content_lines)
|
386
|
+
if amount_of_lines< len(regex_lines):
|
387
|
+
result.append("csproj-file has less lines than the regex requires.")
|
388
|
+
return result
|
389
|
+
for i in range(35):
|
390
|
+
s = file_content_lines[i]
|
391
|
+
r = regex_lines[i]
|
392
|
+
if not re.match(r, s):
|
393
|
+
result.append(f"Line {i+1} does not match: Regex='{r}' String='{s}'")
|
394
|
+
return result
|
395
|
+
|
396
|
+
@GeneralUtilities.check_arguments
|
397
|
+
def generate_reference(self) -> None:
|
398
|
+
self.generate_reference_using_docfx()
|
399
|
+
|
400
|
+
@GeneralUtilities.check_arguments
|
401
|
+
def update_dependencies(self) -> None:
|
402
|
+
self.update_year_for_dotnet_codeunit()
|
403
|
+
#TODO
|
404
|
+
|
405
|
+
@GeneralUtilities.check_arguments
|
406
|
+
def update_year_for_dotnet_codeunit(self) -> None:
|
407
|
+
codeunit_folder:str=self.get_codeunit_folder()
|
408
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
409
|
+
csproj_file = os.path.join(codeunit_folder, codeunit_name, f"{codeunit_name}.csproj")
|
410
|
+
self._protected_sc.update_year_in_copyright_tags(csproj_file)
|
411
|
+
csprojtests_file = os.path.join(codeunit_folder, f"{codeunit_name}Tests", f"{codeunit_name}Tests.csproj")
|
412
|
+
self._protected_sc.update_year_in_copyright_tags(csprojtests_file)
|
413
|
+
nuspec_file = os.path.join(codeunit_folder, "Other", "Build", f"{codeunit_name}.nuspec")
|
414
|
+
if os.path.isfile(nuspec_file):
|
415
|
+
self._protected_sc.update_year_in_copyright_tags(nuspec_file)
|
416
|
+
|
417
|
+
@GeneralUtilities.check_arguments
|
418
|
+
def run_testcases(self) -> None:
|
419
|
+
self._protected_sc.log.log("Run testcases...")
|
420
|
+
dotnet_build_configuration: str = self.get_target_environment_type()
|
421
|
+
codeunit_name: str = self.get_codeunit_name()
|
422
|
+
|
423
|
+
repository_folder: str = self.get_repository_folder().replace("\\", "/")
|
424
|
+
coverage_file_folder = os.path.join(repository_folder, codeunit_name, "Other/Artifacts/TestCoverage")
|
425
|
+
temp_folder = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
|
426
|
+
GeneralUtilities.ensure_directory_exists(temp_folder)
|
427
|
+
runsettings_file = "runsettings.xml"
|
428
|
+
codeunit_folder = f"{repository_folder}/{codeunit_name}"
|
429
|
+
arg = f"test . -c {dotnet_build_configuration} -o {temp_folder}"
|
430
|
+
if os.path.isfile(os.path.join(codeunit_folder, runsettings_file)):
|
431
|
+
arg = f"{arg} --settings {runsettings_file}"
|
432
|
+
arg = f"{arg} /p:CollectCoverage=true /p:CoverletOutput=../Other/Artifacts/TestCoverage/Testcoverage /p:CoverletOutputFormat=cobertura"
|
433
|
+
self._protected_sc.run_program("dotnet", arg, codeunit_folder, print_live_output=True)
|
434
|
+
target_file = os.path.join(coverage_file_folder, "TestCoverage.xml")
|
435
|
+
GeneralUtilities.ensure_file_does_not_exist(target_file)
|
436
|
+
os.rename(os.path.join(coverage_file_folder, "Testcoverage.cobertura.xml"), target_file)
|
437
|
+
self.__remove_unrelated_package_from_testcoverage_file(target_file, codeunit_name)
|
438
|
+
root: etree._ElementTree = etree.parse(target_file)
|
439
|
+
source_base_path_in_coverage_file: str = root.xpath("//coverage/sources/source/text()")[0].replace("\\", "/")
|
440
|
+
content = GeneralUtilities.read_text_from_file(target_file)
|
441
|
+
GeneralUtilities.assert_condition(source_base_path_in_coverage_file.startswith(repository_folder) or repository_folder.startswith(source_base_path_in_coverage_file), f"Unexpected path for coverage. Sourcepath: \"{source_base_path_in_coverage_file}\"; repository: \"{repository_folder}\"")
|
442
|
+
content = re.sub('\\\\', '/', content)
|
443
|
+
content = re.sub("filename=\"([^\"]+)\"", lambda match: self.__standardized_tasks_run_testcases_for_dotnet_project_helper(source_base_path_in_coverage_file, codeunit_folder, match), content)
|
444
|
+
GeneralUtilities.write_text_to_file(target_file, content)
|
445
|
+
self.run_testcases_common_post_task(repository_folder, codeunit_name, True, self.get_target_environment_type())
|
446
|
+
artifacts_folder = os.path.join(repository_folder, codeunit_name, "Other", "Artifacts")
|
447
|
+
for subfolder in GeneralUtilities.get_direct_folders_of_folder(artifacts_folder):
|
448
|
+
if os.path.basename(subfolder).startswith("BuildResultTests_DotNet_"):
|
449
|
+
GeneralUtilities.ensure_directory_does_not_exist(subfolder)
|
450
|
+
|
451
|
+
|
452
|
+
@GeneralUtilities.check_arguments
|
453
|
+
def __remove_unrelated_package_from_testcoverage_file(self, file: str, codeunit_name: str) -> None:
|
454
|
+
root: etree._ElementTree = etree.parse(file)
|
455
|
+
packages = root.xpath('//coverage/packages/package')
|
456
|
+
for package in packages:
|
457
|
+
if package.attrib['name'] != codeunit_name:
|
458
|
+
package.getparent().remove(package)
|
459
|
+
result = etree.tostring(root).decode("utf-8")
|
460
|
+
GeneralUtilities.write_text_to_file(file, result)
|
461
|
+
|
462
|
+
@GeneralUtilities.check_arguments
|
463
|
+
def __standardized_tasks_run_testcases_for_dotnet_project_helper(self, source: str, codeunit_folder: str, match: re.Match) -> str:
|
464
|
+
filename = match.group(1)
|
465
|
+
file = os.path.join(source, filename)
|
466
|
+
GeneralUtilities.assert_condition(file.startswith(codeunit_folder), f"Unexpected path for coverage-file. File: \"{file}\"; codeunitfolder: \"{codeunit_folder}\"")
|
467
|
+
filename_relative = f".{file[len(codeunit_folder):]}"
|
468
|
+
return f'filename="{filename_relative}"'
|
469
|
+
|
470
|
+
|
471
|
+
class TFCPS_CodeUnitSpecific_DotNet_CLI:
|
472
|
+
|
473
|
+
@staticmethod
|
474
|
+
def parse(file:str)->TFCPS_CodeUnitSpecific_DotNet_Functions:
|
475
|
+
parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
476
|
+
#add custom parameter if desired
|
477
|
+
args=parser.parse_args()
|
478
|
+
result:TFCPS_CodeUnitSpecific_DotNet_Functions=TFCPS_CodeUnitSpecific_DotNet_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache)
|
479
|
+
return result
|
File without changes
|