ScriptCollection 3.3.23__py3-none-any.whl → 4.0.78__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 +206 -0
- ScriptCollection/{UpdateCertificates.py → CertificateUpdater.py} +149 -128
- ScriptCollection/Executables.py +868 -292
- ScriptCollection/GeneralUtilities.py +609 -107
- ScriptCollection/ImageUpdater.py +648 -0
- ScriptCollection/ProcessesRunner.py +41 -0
- ScriptCollection/ProgramRunnerBase.py +47 -42
- ScriptCollection/ProgramRunnerMock.py +2 -0
- ScriptCollection/ProgramRunnerPopen.py +57 -50
- ScriptCollection/ProgramRunnerSudo.py +108 -0
- ScriptCollection/SCLog.py +115 -0
- ScriptCollection/ScriptCollectionCore.py +2541 -1383
- ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +95 -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 +485 -0
- ScriptCollection/TFCPS/DotNet/__init__.py +0 -0
- ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +130 -0
- ScriptCollection/TFCPS/Flutter/__init__.py +0 -0
- ScriptCollection/TFCPS/Go/TFCPS_CodeUnitSpecific_Go.py +74 -0
- ScriptCollection/TFCPS/Go/__init__.py +0 -0
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +131 -0
- ScriptCollection/TFCPS/NodeJS/__init__.py +0 -0
- ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py +227 -0
- ScriptCollection/TFCPS/Python/__init__.py +0 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +418 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py +128 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +136 -0
- ScriptCollection/TFCPS/TFCPS_CreateRelease.py +95 -0
- ScriptCollection/TFCPS/TFCPS_Generic.py +43 -0
- ScriptCollection/TFCPS/TFCPS_MergeToMain.py +122 -0
- ScriptCollection/TFCPS/TFCPS_MergeToStable.py +350 -0
- ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py +47 -0
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +1356 -0
- ScriptCollection/TFCPS/__init__.py +0 -0
- {ScriptCollection-3.3.23.dist-info → scriptcollection-4.0.78.dist-info}/METADATA +26 -21
- scriptcollection-4.0.78.dist-info/RECORD +43 -0
- {ScriptCollection-3.3.23.dist-info → scriptcollection-4.0.78.dist-info}/WHEEL +1 -1
- scriptcollection-4.0.78.dist-info/entry_points.txt +64 -0
- ScriptCollection/Hardening.py +0 -59
- ScriptCollection/ProgramRunnerEpew.py +0 -122
- ScriptCollection/TasksForCommonProjectStructure.py +0 -1170
- ScriptCollection-3.3.23.dist-info/RECORD +0 -15
- ScriptCollection-3.3.23.dist-info/entry_points.txt +0 -24
- {ScriptCollection-3.3.23.dist-info → scriptcollection-4.0.78.dist-info}/top_level.txt +0 -0
|
@@ -1,1170 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
import os
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
import shutil
|
|
5
|
-
import re
|
|
6
|
-
import tempfile
|
|
7
|
-
import json
|
|
8
|
-
import configparser
|
|
9
|
-
import xmlschema
|
|
10
|
-
from lxml import etree
|
|
11
|
-
from .GeneralUtilities import GeneralUtilities
|
|
12
|
-
from .ScriptCollectionCore import ScriptCollectionCore
|
|
13
|
-
from .ProgramRunnerEpew import ProgramRunnerEpew
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class CodeUnitConfiguration():
|
|
17
|
-
name: str
|
|
18
|
-
push_to_registry_script: str
|
|
19
|
-
additional_arguments_file: str
|
|
20
|
-
|
|
21
|
-
def __init__(self, name: str, push_to_registry_script: str, additional_arguments_file: str):
|
|
22
|
-
|
|
23
|
-
self.name = name
|
|
24
|
-
self.push_to_registry_script = push_to_registry_script
|
|
25
|
-
self.additional_arguments_file = additional_arguments_file
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class CreateReleaseConfiguration():
|
|
29
|
-
projectname: str
|
|
30
|
-
remotename: str
|
|
31
|
-
artifacts_folder: str
|
|
32
|
-
codeunits: dict[str, CodeUnitConfiguration]
|
|
33
|
-
verbosity: int
|
|
34
|
-
reference_repository_remote_name: str = None
|
|
35
|
-
reference_repository_branch_name: str = "main"
|
|
36
|
-
build_repository_branch: str = "main"
|
|
37
|
-
public_repository_url: str
|
|
38
|
-
|
|
39
|
-
def __init__(self, projectname: str, remotename: str, build_artifacts_target_folder: str, codeunits: dict[str, CodeUnitConfiguration],
|
|
40
|
-
verbosity: int, public_repository_url: str):
|
|
41
|
-
|
|
42
|
-
self.projectname = projectname
|
|
43
|
-
self.remotename = remotename
|
|
44
|
-
self.artifacts_folder = build_artifacts_target_folder
|
|
45
|
-
self.codeunits = codeunits
|
|
46
|
-
self.verbosity = verbosity
|
|
47
|
-
self.public_repository_url = public_repository_url
|
|
48
|
-
self.reference_repository_remote_name = self.remotename
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class CreateReleaseInformationForProjectInCommonProjectFormat:
|
|
52
|
-
projectname: str
|
|
53
|
-
repository: str
|
|
54
|
-
artifacts_folder: str
|
|
55
|
-
verbosity: int = 1
|
|
56
|
-
reference_repository: str = None
|
|
57
|
-
public_repository_url: str = None
|
|
58
|
-
target_branch_name: str = None
|
|
59
|
-
codeunits: dict[str, CodeUnitConfiguration]
|
|
60
|
-
target_environmenttype_for_qualitycheck: str = "QualityCheck"
|
|
61
|
-
target_environmenttype_for_productive: str = "Productive"
|
|
62
|
-
|
|
63
|
-
def __init__(self, repository: str, artifacts_folder: str, projectname: str, public_repository_url: str, target_branch_name: str):
|
|
64
|
-
self.repository = repository
|
|
65
|
-
self.public_repository_url = public_repository_url
|
|
66
|
-
self.target_branch_name = target_branch_name
|
|
67
|
-
self.artifacts_folder = artifacts_folder
|
|
68
|
-
if projectname is None:
|
|
69
|
-
projectname = os.path.basename(self.repository)
|
|
70
|
-
else:
|
|
71
|
-
self.projectname = projectname
|
|
72
|
-
self.reference_repository = GeneralUtilities.resolve_relative_path(f"../{projectname}Reference", repository)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class MergeToStableBranchInformationForProjectInCommonProjectFormat:
|
|
76
|
-
repository: str
|
|
77
|
-
sourcebranch: str = "main"
|
|
78
|
-
targetbranch: str = "stable"
|
|
79
|
-
sign_git_tags: bool = True
|
|
80
|
-
codeunits: dict[str, CodeUnitConfiguration]
|
|
81
|
-
target_environmenttype_for_qualitycheck: str = "QualityCheck"
|
|
82
|
-
target_environmenttype_for_productive: str = "Productive"
|
|
83
|
-
|
|
84
|
-
push_source_branch: bool = False
|
|
85
|
-
push_source_branch_remote_name: str = None
|
|
86
|
-
push_target_branch: bool = False
|
|
87
|
-
push_target_branch_remote_name: str = None
|
|
88
|
-
|
|
89
|
-
verbosity: int = 1
|
|
90
|
-
|
|
91
|
-
def __init__(self, repository: str):
|
|
92
|
-
self.repository = repository
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class TasksForCommonProjectStructure:
|
|
96
|
-
__sc: ScriptCollectionCore = None
|
|
97
|
-
reference_latest_version_of_xsd_when_generating_xml: bool = True
|
|
98
|
-
|
|
99
|
-
def __init__(self, sc: ScriptCollectionCore = None):
|
|
100
|
-
if sc is None:
|
|
101
|
-
sc = ScriptCollectionCore()
|
|
102
|
-
self.__sc = sc
|
|
103
|
-
|
|
104
|
-
@GeneralUtilities.check_arguments
|
|
105
|
-
def get_build_folder_in_repository_in_common_repository_format(self, repository_folder: str, codeunit_name: str) -> str:
|
|
106
|
-
return os.path.join(repository_folder, codeunit_name, "Other", "Build")
|
|
107
|
-
|
|
108
|
-
@GeneralUtilities.check_arguments
|
|
109
|
-
def get_artifacts_folder_in_repository_in_common_repository_format(self, repository_folder: str, codeunit_name: str) -> str:
|
|
110
|
-
return os.path.join(repository_folder, codeunit_name, "Other", "Artifacts")
|
|
111
|
-
|
|
112
|
-
@GeneralUtilities.check_arguments
|
|
113
|
-
def get_wheel_file_in_repository_in_common_repository_format(self, repository_folder: str, codeunit_name: str) -> str:
|
|
114
|
-
return self.__sc.find_file_by_extension(os.path.join(self.get_artifacts_folder_in_repository_in_common_repository_format(repository_folder, codeunit_name),
|
|
115
|
-
"BuildResult_Wheel"), "whl")
|
|
116
|
-
|
|
117
|
-
@GeneralUtilities.check_arguments
|
|
118
|
-
def __get_testcoverage_threshold_from_codeunit_file(self, codeunit_file):
|
|
119
|
-
root: etree._ElementTree = etree.parse(codeunit_file)
|
|
120
|
-
return float(str(root.xpath('//cps:minimalcodecoverageinpercent/text()', namespaces={
|
|
121
|
-
'cps': 'https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure'
|
|
122
|
-
})[0]))
|
|
123
|
-
|
|
124
|
-
@GeneralUtilities.check_arguments
|
|
125
|
-
def check_testcoverage_for_project_in_common_project_structure(self, testcoverage_file_in_cobertura_format: str, repository_folder: str, codeunitname: str):
|
|
126
|
-
root: etree._ElementTree = etree.parse(testcoverage_file_in_cobertura_format)
|
|
127
|
-
coverage_in_percent = round(float(str(root.xpath('//coverage/@line-rate')[0]))*100, 2)
|
|
128
|
-
codeunit_file = os.path.join(repository_folder, codeunitname, f"{codeunitname}.codeunit.xml")
|
|
129
|
-
threshold_in_percent = self.__get_testcoverage_threshold_from_codeunit_file(codeunit_file)
|
|
130
|
-
minimalrequiredtestcoverageinpercent = threshold_in_percent
|
|
131
|
-
if (coverage_in_percent < minimalrequiredtestcoverageinpercent):
|
|
132
|
-
raise ValueError(f"The testcoverage must be {minimalrequiredtestcoverageinpercent}% or more but is {coverage_in_percent}%.")
|
|
133
|
-
|
|
134
|
-
@GeneralUtilities.check_arguments
|
|
135
|
-
def replace_version_in_python_file(self, file: str, new_version_value: str):
|
|
136
|
-
GeneralUtilities.write_text_to_file(file, re.sub("version = \"\\d+\\.\\d+\\.\\d+\"", f"version = \"{new_version_value}\"",
|
|
137
|
-
GeneralUtilities.read_text_from_file(file)))
|
|
138
|
-
|
|
139
|
-
@GeneralUtilities.check_arguments
|
|
140
|
-
def __standardized_tasks_run_testcases_for_python_codeunit(self, repository_folder: str, codeunitname: str, verbosity: int):
|
|
141
|
-
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
|
142
|
-
self.__sc.run_program("coverage", "run -m pytest", codeunit_folder, verbosity=verbosity)
|
|
143
|
-
self.__sc.run_program("coverage", "xml", codeunit_folder, verbosity=verbosity)
|
|
144
|
-
coveragefolder = os.path.join(repository_folder, codeunitname, "Other/Artifacts/TestCoverage")
|
|
145
|
-
GeneralUtilities.ensure_directory_exists(coveragefolder)
|
|
146
|
-
coveragefile = os.path.join(coveragefolder, "TestCoverage.xml")
|
|
147
|
-
GeneralUtilities.ensure_file_does_not_exist(coveragefile)
|
|
148
|
-
os.rename(os.path.join(repository_folder, codeunitname, "coverage.xml"), coveragefile)
|
|
149
|
-
self.check_testcoverage_for_project_in_common_project_structure(coveragefile, repository_folder, codeunitname)
|
|
150
|
-
|
|
151
|
-
@staticmethod
|
|
152
|
-
@GeneralUtilities.check_arguments
|
|
153
|
-
def __adjust_source_in_testcoverage_file(testcoverage_file: str, codeunitname: str) -> None:
|
|
154
|
-
GeneralUtilities.write_text_to_file(testcoverage_file, re.sub("<source>.+<\\/source>", f"<source>{codeunitname}</source>",
|
|
155
|
-
GeneralUtilities.read_text_from_file(testcoverage_file)))
|
|
156
|
-
|
|
157
|
-
@staticmethod
|
|
158
|
-
@GeneralUtilities.check_arguments
|
|
159
|
-
def update_path_of_source(repository_folder: str, codeunitname: str) -> None:
|
|
160
|
-
folder = f"{repository_folder}/{codeunitname}/Other/Artifacts/TestCoverage"
|
|
161
|
-
filename = "TestCoverage.xml"
|
|
162
|
-
full_file = os.path.join(folder, filename)
|
|
163
|
-
TasksForCommonProjectStructure.__adjust_source_in_testcoverage_file(full_file, codeunitname)
|
|
164
|
-
|
|
165
|
-
@GeneralUtilities.check_arguments
|
|
166
|
-
def standardized_tasks_run_testcases_for_python_codeunit_in_common_project_structure(self, run_testcases_file: str, generate_badges: bool, verbosity: int, targetenvironmenttype: str,
|
|
167
|
-
commandline_arguments: list[str]):
|
|
168
|
-
codeunitname: str = Path(os.path.dirname(run_testcases_file)).parent.parent.name
|
|
169
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
170
|
-
repository_folder: str = str(Path(os.path.dirname(run_testcases_file)).parent.parent.parent.absolute())
|
|
171
|
-
self.__standardized_tasks_run_testcases_for_python_codeunit(repository_folder, codeunitname, verbosity)
|
|
172
|
-
self.standardized_tasks_generate_coverage_report(repository_folder, codeunitname, verbosity, generate_badges, targetenvironmenttype, commandline_arguments)
|
|
173
|
-
self.update_path_of_source(repository_folder, codeunitname)
|
|
174
|
-
|
|
175
|
-
@GeneralUtilities.check_arguments
|
|
176
|
-
def standardized_tasks_build_for_python_codeunit_in_common_project_structure(self, buildscript_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]):
|
|
177
|
-
codeunitname: str = Path(os.path.dirname(buildscript_file)).parent.parent.name
|
|
178
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
179
|
-
codeunit_folder = str(Path(os.path.dirname(buildscript_file)).parent.parent.absolute())
|
|
180
|
-
repository_folder: str = str(Path(os.path.dirname(buildscript_file)).parent.parent.parent.absolute())
|
|
181
|
-
target_directory = GeneralUtilities.resolve_relative_path(
|
|
182
|
-
"../Artifacts/BuildResult_Wheel", os.path.join(self.get_artifacts_folder_in_repository_in_common_repository_format(repository_folder, codeunitname)))
|
|
183
|
-
GeneralUtilities.ensure_directory_exists(target_directory)
|
|
184
|
-
self.__sc.run_program("python", f"-m build --wheel --outdir {target_directory}", codeunit_folder, verbosity=verbosity)
|
|
185
|
-
|
|
186
|
-
@GeneralUtilities.check_arguments
|
|
187
|
-
def standardized_tasks_push_wheel_file_to_registry(self, wheel_file: str, api_key: str, repository: str, gpg_identity: str, verbosity: int) -> None:
|
|
188
|
-
# repository-value when PyPi should be used: "pypi"
|
|
189
|
-
# gpg_identity-value when wheel-file should not be signed: None
|
|
190
|
-
folder = os.path.dirname(wheel_file)
|
|
191
|
-
filename = os.path.basename(wheel_file)
|
|
192
|
-
|
|
193
|
-
if gpg_identity is None:
|
|
194
|
-
gpg_identity_argument = ""
|
|
195
|
-
else:
|
|
196
|
-
gpg_identity_argument = f" --sign --identity {gpg_identity}"
|
|
197
|
-
|
|
198
|
-
if verbosity > 2:
|
|
199
|
-
verbose_argument = " --verbose"
|
|
200
|
-
else:
|
|
201
|
-
verbose_argument = ""
|
|
202
|
-
|
|
203
|
-
twine_argument = f"upload{gpg_identity_argument} --repository {repository} --non-interactive {filename} --disable-progress-bar"
|
|
204
|
-
twine_argument = f"{twine_argument} --username __token__ --password {api_key}{verbose_argument}"
|
|
205
|
-
self.__sc.run_program("twine", twine_argument, folder, verbosity=verbosity, throw_exception_if_exitcode_is_not_zero=True)
|
|
206
|
-
|
|
207
|
-
@GeneralUtilities.check_arguments
|
|
208
|
-
def push_wheel_build_artifact_of_repository_in_common_file_structure(self, push_build_artifacts_file, product_name, codeunitname, repository: str,
|
|
209
|
-
apikey: str, gpg_identity: str, verbosity: int, commandline_arguments: list[str]) -> None:
|
|
210
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
211
|
-
folder_of_this_file = os.path.dirname(push_build_artifacts_file)
|
|
212
|
-
repository_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}../Submodules{os.path.sep}{product_name}", folder_of_this_file)
|
|
213
|
-
wheel_file = self.get_wheel_file_in_repository_in_common_repository_format(repository_folder, codeunitname)
|
|
214
|
-
self.standardized_tasks_push_wheel_file_to_registry(wheel_file, apikey, repository, gpg_identity, verbosity)
|
|
215
|
-
|
|
216
|
-
@GeneralUtilities.check_arguments
|
|
217
|
-
def get_version_of_codeunit(self, codeunit_file: str) -> None:
|
|
218
|
-
root: etree._ElementTree = etree.parse(codeunit_file)
|
|
219
|
-
result = str(root.xpath('//cps:version/text()',
|
|
220
|
-
namespaces={'cps': 'https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure'})[0])
|
|
221
|
-
return result
|
|
222
|
-
|
|
223
|
-
@GeneralUtilities.check_arguments
|
|
224
|
-
def get_version_of_codeunit_folder(self, codeunit_folder: str) -> None:
|
|
225
|
-
codeunit_file = os.path.join(codeunit_folder, f"{os.path.basename(codeunit_folder)}.codeunit.xml")
|
|
226
|
-
return self.get_version_of_codeunit(codeunit_file)
|
|
227
|
-
|
|
228
|
-
@staticmethod
|
|
229
|
-
@GeneralUtilities.check_arguments
|
|
230
|
-
def get_buildconfigurationdevelopment_from_commandline_arguments(commandline_arguments: list[str], default_value: str) -> str:
|
|
231
|
-
return TasksForCommonProjectStructure.get_string_value_from_commandline_arguments(commandline_arguments, "buildconfigurationdevelopment", default_value)
|
|
232
|
-
|
|
233
|
-
@staticmethod
|
|
234
|
-
@GeneralUtilities.check_arguments
|
|
235
|
-
def get_buildconfigurationqualitycheck_from_commandline_arguments(commandline_arguments: list[str], default_value: str) -> str:
|
|
236
|
-
return TasksForCommonProjectStructure.get_string_value_from_commandline_arguments(commandline_arguments, "buildconfigurationqualitycheck", default_value)
|
|
237
|
-
|
|
238
|
-
@staticmethod
|
|
239
|
-
@GeneralUtilities.check_arguments
|
|
240
|
-
def get_buildconfigurationproductive_from_commandline_arguments(commandline_arguments: list[str], default_value: str) -> str:
|
|
241
|
-
return TasksForCommonProjectStructure.get_string_value_from_commandline_arguments(commandline_arguments, "buildconfigurationproductive", default_value)
|
|
242
|
-
|
|
243
|
-
@staticmethod
|
|
244
|
-
@GeneralUtilities.check_arguments
|
|
245
|
-
def get_string_value_from_commandline_arguments(commandline_arguments: list[str], property_name: str, default_value: str) -> str:
|
|
246
|
-
result = TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, property_name)
|
|
247
|
-
if result is None:
|
|
248
|
-
return default_value
|
|
249
|
-
else:
|
|
250
|
-
return result
|
|
251
|
-
|
|
252
|
-
@staticmethod
|
|
253
|
-
@GeneralUtilities.check_arguments
|
|
254
|
-
def get_verbosity_from_commandline_arguments(commandline_arguments: list[str], default_value: int) -> int:
|
|
255
|
-
result = TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, "verbosity")
|
|
256
|
-
if result is None:
|
|
257
|
-
return default_value
|
|
258
|
-
else:
|
|
259
|
-
return int(result)
|
|
260
|
-
|
|
261
|
-
@staticmethod
|
|
262
|
-
@GeneralUtilities.check_arguments
|
|
263
|
-
def get_targetenvironmenttype_from_commandline_arguments(commandline_arguments: list[str], default_value: str) -> str:
|
|
264
|
-
result = TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, "targetenvironmenttype")
|
|
265
|
-
if result is None:
|
|
266
|
-
return default_value
|
|
267
|
-
else:
|
|
268
|
-
return result
|
|
269
|
-
|
|
270
|
-
@staticmethod
|
|
271
|
-
@GeneralUtilities.check_arguments
|
|
272
|
-
def get_additionalargumentsfile_from_commandline_arguments(commandline_arguments: list[str], default_value: str) -> str:
|
|
273
|
-
result = TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, "additionalargumentsfile")
|
|
274
|
-
if result is None:
|
|
275
|
-
return default_value
|
|
276
|
-
else:
|
|
277
|
-
return result
|
|
278
|
-
|
|
279
|
-
@staticmethod
|
|
280
|
-
@GeneralUtilities.check_arguments
|
|
281
|
-
def get_filestosign_from_commandline_arguments(commandline_arguments: list[str], default_value: dict[str, str]) -> dict[str, str]():
|
|
282
|
-
result_plain = TasksForCommonProjectStructure.get_property_from_commandline_arguments(commandline_arguments, "sign")
|
|
283
|
-
if result_plain is None:
|
|
284
|
-
return default_value
|
|
285
|
-
else:
|
|
286
|
-
result: dict[str, str] = dict[str, str]()
|
|
287
|
-
files_tuples = GeneralUtilities.to_list(result_plain, ";")
|
|
288
|
-
for files_tuple in files_tuples:
|
|
289
|
-
splitted = files_tuple.split("=")
|
|
290
|
-
result[splitted[0]] = splitted[1]
|
|
291
|
-
return result
|
|
292
|
-
|
|
293
|
-
@staticmethod
|
|
294
|
-
@GeneralUtilities.check_arguments
|
|
295
|
-
def get_property_from_commandline_arguments(commandline_arguments: list[str], property_name: str) -> str:
|
|
296
|
-
result: str = None
|
|
297
|
-
for commandline_argument in commandline_arguments[1:]:
|
|
298
|
-
prefix = f"--overwrite_{property_name}"
|
|
299
|
-
if commandline_argument.startswith(prefix):
|
|
300
|
-
if m := re.match(f"^{re.escape(prefix)}=(.+)$", commandline_argument):
|
|
301
|
-
result = m.group(1)
|
|
302
|
-
return result
|
|
303
|
-
|
|
304
|
-
@GeneralUtilities.check_arguments
|
|
305
|
-
def update_version_of_codeunit_to_project_version(self, common_tasks_file: str, current_version: str) -> None:
|
|
306
|
-
codeunit_name: str = os.path.basename(GeneralUtilities.resolve_relative_path("..", os.path.dirname(common_tasks_file)))
|
|
307
|
-
codeunit_file: str = os.path.join(GeneralUtilities.resolve_relative_path("..", os.path.dirname(common_tasks_file)), f"{codeunit_name}.codeunit.xml")
|
|
308
|
-
self.write_version_to_codeunit_file(codeunit_file, current_version)
|
|
309
|
-
|
|
310
|
-
@GeneralUtilities.check_arguments
|
|
311
|
-
def t4_transform(self, commontasks_script_file_of_current_file: str, verbosity: int):
|
|
312
|
-
sc = ScriptCollectionCore()
|
|
313
|
-
codeunit_folder: str = str(Path(os.path.dirname(commontasks_script_file_of_current_file)).parent.absolute())
|
|
314
|
-
codeunitname: str = os.path.basename(str(Path(os.path.dirname(commontasks_script_file_of_current_file)).parent.absolute()))
|
|
315
|
-
csproj_folder = os.path.join(codeunit_folder, codeunitname)
|
|
316
|
-
for search_result in Path(csproj_folder).glob('**/*.tt'):
|
|
317
|
-
tt_file = str(search_result)
|
|
318
|
-
relative_path_to_tt_file = str(Path(tt_file).relative_to(Path(csproj_folder)))
|
|
319
|
-
sc.run_program("texttransform", relative_path_to_tt_file, csproj_folder, verbosity=verbosity)
|
|
320
|
-
|
|
321
|
-
@GeneralUtilities.check_arguments
|
|
322
|
-
def standardized_tasks_generate_reference_by_docfx(self, generate_reference_script_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]) -> None:
|
|
323
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
324
|
-
folder_of_current_file = os.path.dirname(generate_reference_script_file)
|
|
325
|
-
generated_reference_folder = GeneralUtilities.resolve_relative_path("../Artifacts/Reference", folder_of_current_file)
|
|
326
|
-
GeneralUtilities.ensure_directory_does_not_exist(generated_reference_folder)
|
|
327
|
-
GeneralUtilities.ensure_directory_exists(generated_reference_folder)
|
|
328
|
-
obj_folder = os.path.join(folder_of_current_file, "obj")
|
|
329
|
-
GeneralUtilities.ensure_directory_does_not_exist(obj_folder)
|
|
330
|
-
GeneralUtilities.ensure_directory_exists(obj_folder)
|
|
331
|
-
self.__sc.run_program("docfx", "docfx.json", folder_of_current_file, verbosity)
|
|
332
|
-
GeneralUtilities.ensure_directory_does_not_exist(obj_folder)
|
|
333
|
-
|
|
334
|
-
@GeneralUtilities.check_arguments
|
|
335
|
-
def __standardized_tasks_build_for_dotnet_build(self, csproj_file: str, buildconfiguration: str, originaloutputfolder: str, files_to_sign: dict[str, str], commitid: str,
|
|
336
|
-
verbosity: int, runtimes: list[str]):
|
|
337
|
-
for runtime in runtimes:
|
|
338
|
-
outputfolder = originaloutputfolder+runtime
|
|
339
|
-
csproj_file_folder = os.path.dirname(csproj_file)
|
|
340
|
-
csproj_file_name = os.path.basename(csproj_file)
|
|
341
|
-
self.__sc.run_program("dotnet", "clean", csproj_file_folder, verbosity=verbosity)
|
|
342
|
-
GeneralUtilities.ensure_directory_does_not_exist(os.path.join(csproj_file_folder, "bin"))
|
|
343
|
-
GeneralUtilities.ensure_directory_does_not_exist(os.path.join(csproj_file_folder, "obj"))
|
|
344
|
-
GeneralUtilities.ensure_directory_does_not_exist(outputfolder)
|
|
345
|
-
GeneralUtilities.ensure_directory_exists(outputfolder)
|
|
346
|
-
# TODO pass commitid, timestamp and if desired something like keypair, certificate to the src-code
|
|
347
|
-
self.__sc.run_program("dotnet", f"build {csproj_file_name} -c {buildconfiguration} -o {outputfolder} --runtime {runtime}", csproj_file_folder, verbosity=verbosity)
|
|
348
|
-
for file, keyfile in files_to_sign.items():
|
|
349
|
-
self.__sc.dotnet_sign_file(os.path.join(outputfolder, file), keyfile, verbosity)
|
|
350
|
-
|
|
351
|
-
@GeneralUtilities.check_arguments
|
|
352
|
-
def standardized_tasks_build_for_dotnet_project_in_common_project_structure(self, buildscript_file: str, default_target_environmenttype: str,
|
|
353
|
-
target_environmenttype_mapping: dict[str, str], runtimes: list[str], verbosity: int, commandline_arguments: list[str]):
|
|
354
|
-
# hint: arguments can be overwritten by commandline_arguments
|
|
355
|
-
# this function builds an exe or dll
|
|
356
|
-
target_environmenttype = self.get_targetenvironmenttype_from_commandline_arguments(commandline_arguments, default_target_environmenttype)
|
|
357
|
-
self.__standardized_tasks_build_for_dotnet_project_in_common_project_structure(
|
|
358
|
-
buildscript_file, target_environmenttype_mapping, default_target_environmenttype, verbosity, target_environmenttype, runtimes, commandline_arguments)
|
|
359
|
-
|
|
360
|
-
@GeneralUtilities.check_arguments
|
|
361
|
-
def standardized_tasks_build_for_dotnet_library_project_in_common_project_structure(self, buildscript_file: str, default_target_environmenttype: str,
|
|
362
|
-
target_environmenttype_mapping: dict[str, str], runtimes: list[str],
|
|
363
|
-
verbosity: int, commandline_arguments: list[str]):
|
|
364
|
-
# hint: arguments can be overwritten by commandline_arguments
|
|
365
|
-
# this function builds an exe or dll and converts it to a nupkg-file
|
|
366
|
-
target_environmenttype = self.get_targetenvironmenttype_from_commandline_arguments(commandline_arguments, default_target_environmenttype)
|
|
367
|
-
self.__standardized_tasks_build_for_dotnet_project_in_common_project_structure(
|
|
368
|
-
buildscript_file, target_environmenttype_mapping, default_target_environmenttype, verbosity, target_environmenttype, runtimes, commandline_arguments)
|
|
369
|
-
self.__standardized_tasks_build_nupkg_for_dotnet_create_package(buildscript_file, verbosity, commandline_arguments)
|
|
370
|
-
|
|
371
|
-
@GeneralUtilities.check_arguments
|
|
372
|
-
def __get_dotnet_buildconfiguration_by_target_environmenttype(self, targetenvironmenttype: str, default_value: str, commandline_arguments: list[str]):
|
|
373
|
-
if targetenvironmenttype == "Development":
|
|
374
|
-
return self.get_buildconfigurationdevelopment_from_commandline_arguments(commandline_arguments, default_value)
|
|
375
|
-
if targetenvironmenttype == "QualityCheck":
|
|
376
|
-
return self.get_buildconfigurationqualitycheck_from_commandline_arguments(commandline_arguments, default_value)
|
|
377
|
-
if targetenvironmenttype == "Productive":
|
|
378
|
-
return self.get_buildconfigurationproductive_from_commandline_arguments(commandline_arguments, "Release")
|
|
379
|
-
raise ValueError(f"Unknown build-environmenttype: {targetenvironmenttype}")
|
|
380
|
-
|
|
381
|
-
@GeneralUtilities.check_arguments
|
|
382
|
-
def get_default_target_environmenttype_mapping(self) -> dict[str, str]:
|
|
383
|
-
return {
|
|
384
|
-
"Development": "Development",
|
|
385
|
-
"QualityCheck": "QualityCheck",
|
|
386
|
-
"Productive": "Productive"
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
@GeneralUtilities.check_arguments
|
|
390
|
-
def __standardized_tasks_build_for_dotnet_project_in_common_project_structure(self, buildscript_file: str, target_environmenttype_mapping: dict[str, str],
|
|
391
|
-
default_build_configuration: str, verbosity: int, target_environmenttype: str,
|
|
392
|
-
runtimes: list[str], commandline_arguments: list[str]):
|
|
393
|
-
dotnet_build_configuration: str = target_environmenttype_mapping[target_environmenttype]
|
|
394
|
-
codeunitname: str = os.path.basename(str(Path(os.path.dirname(buildscript_file)).parent.parent.absolute()))
|
|
395
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
396
|
-
files_to_sign: dict[str, str] = TasksForCommonProjectStructure.get_filestosign_from_commandline_arguments(commandline_arguments, dict())
|
|
397
|
-
repository_folder: str = str(Path(os.path.dirname(buildscript_file)).parent.parent.parent.absolute())
|
|
398
|
-
commitid = self.__sc.git_get_commit_id(repository_folder)
|
|
399
|
-
outputfolder = GeneralUtilities.resolve_relative_path("../Artifacts", os.path.dirname(buildscript_file))
|
|
400
|
-
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
|
401
|
-
csproj_file = os.path.join(codeunit_folder, codeunitname, codeunitname+".csproj")
|
|
402
|
-
csproj_test_file = os.path.join(codeunit_folder, codeunitname+"Tests", codeunitname+"Tests.csproj")
|
|
403
|
-
buildconfiguration = self.__get_dotnet_buildconfiguration_by_target_environmenttype(dotnet_build_configuration, default_build_configuration, commandline_arguments)
|
|
404
|
-
|
|
405
|
-
self.__sc.run_program("dotnet", "restore", codeunit_folder, verbosity=verbosity)
|
|
406
|
-
self.__standardized_tasks_build_for_dotnet_build(csproj_file, buildconfiguration,
|
|
407
|
-
os.path.join(outputfolder, "BuildResult_DotNet_"), files_to_sign, commitid, verbosity, runtimes)
|
|
408
|
-
self.__standardized_tasks_build_for_dotnet_build(csproj_test_file, buildconfiguration,
|
|
409
|
-
os.path.join(outputfolder, "BuildResult_DotNetTests_"), files_to_sign, commitid, verbosity, runtimes)
|
|
410
|
-
self.generate_sbom_for_dotnet_project(codeunit_folder)
|
|
411
|
-
|
|
412
|
-
@GeneralUtilities.check_arguments
|
|
413
|
-
def __standardized_tasks_build_nupkg_for_dotnet_create_package(self, buildscript_file: str, verbosity: int, commandline_arguments: list[str]):
|
|
414
|
-
codeunitname: str = os.path.basename(str(Path(os.path.dirname(buildscript_file)).parent.parent.absolute()))
|
|
415
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
416
|
-
repository_folder: str = str(Path(os.path.dirname(buildscript_file)).parent.parent.parent.absolute())
|
|
417
|
-
build_folder = os.path.join(repository_folder, codeunitname, "Other", "Build")
|
|
418
|
-
outputfolder = GeneralUtilities.resolve_relative_path("../Artifacts/BuildResult_NuGet", os.path.dirname(buildscript_file))
|
|
419
|
-
root: etree._ElementTree = etree.parse(os.path.join(build_folder, f"{codeunitname}.nuspec"))
|
|
420
|
-
current_version = root.xpath("//*[name() = 'package']/*[name() = 'metadata']/*[name() = 'version']/text()")[0]
|
|
421
|
-
nupkg_filename = f"{codeunitname}.{current_version}.nupkg"
|
|
422
|
-
nupkg_file = f"{build_folder}/{nupkg_filename}"
|
|
423
|
-
GeneralUtilities.ensure_file_does_not_exist(nupkg_file)
|
|
424
|
-
commit_id = self.__sc.git_get_commit_id(repository_folder)
|
|
425
|
-
self.__sc.run_program("nuget", f"pack {codeunitname}.nuspec -Properties \"commitid={commit_id}\"", build_folder, verbosity=verbosity)
|
|
426
|
-
GeneralUtilities.ensure_directory_does_not_exist(outputfolder)
|
|
427
|
-
GeneralUtilities.ensure_directory_exists(outputfolder)
|
|
428
|
-
os.rename(nupkg_file, f"{outputfolder}/{nupkg_filename}")
|
|
429
|
-
|
|
430
|
-
@GeneralUtilities.check_arguments
|
|
431
|
-
def generate_sbom_for_dotnet_project(self, codeunit_folder: str) -> None:
|
|
432
|
-
codeunit_name = os.path.basename(codeunit_folder)
|
|
433
|
-
sc = ScriptCollectionCore()
|
|
434
|
-
bomfile_folder = "Other\\Artifacts\\BOM"
|
|
435
|
-
sc.run_program("dotnet", f"CycloneDX {codeunit_name}\\{codeunit_name}.csproj -o {bomfile_folder}", codeunit_folder)
|
|
436
|
-
target = f"{codeunit_folder}\\{bomfile_folder}\\{codeunit_name}.sbom.xml"
|
|
437
|
-
GeneralUtilities.ensure_file_does_not_exist(target)
|
|
438
|
-
os.rename(f"{codeunit_folder}\\{bomfile_folder}\\bom.xml", target)
|
|
439
|
-
|
|
440
|
-
@GeneralUtilities.check_arguments
|
|
441
|
-
def standardized_tasks_linting_for_python_codeunit_in_common_project_structure(self, linting_script_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]):
|
|
442
|
-
codeunitname: str = Path(os.path.dirname(linting_script_file)).parent.parent.name
|
|
443
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
444
|
-
repository_folder: str = str(Path(os.path.dirname(linting_script_file)).parent.parent.parent.absolute())
|
|
445
|
-
errors_found = False
|
|
446
|
-
GeneralUtilities.write_message_to_stdout(f"Check for linting-issues in codeunit {codeunitname}.")
|
|
447
|
-
src_folder = os.path.join(repository_folder, codeunitname, codeunitname)
|
|
448
|
-
tests_folder = src_folder+"Tests"
|
|
449
|
-
for file in GeneralUtilities.get_all_files_of_folder(src_folder)+GeneralUtilities.get_all_files_of_folder(tests_folder):
|
|
450
|
-
relative_file_path_in_repository = os.path.relpath(file, repository_folder)
|
|
451
|
-
if file.endswith(".py") and os.path.getsize(file) > 0 and not self.__sc.file_is_git_ignored(relative_file_path_in_repository, repository_folder):
|
|
452
|
-
GeneralUtilities.write_message_to_stdout(f"Check for linting-issues in {os.path.relpath(file,os.path.join(repository_folder,codeunitname))}.")
|
|
453
|
-
linting_result = self.__sc.python_file_has_errors(file, repository_folder)
|
|
454
|
-
if (linting_result[0]):
|
|
455
|
-
errors_found = True
|
|
456
|
-
for error in linting_result[1]:
|
|
457
|
-
GeneralUtilities.write_message_to_stderr(error)
|
|
458
|
-
if errors_found:
|
|
459
|
-
raise Exception("Linting-issues occurred.")
|
|
460
|
-
else:
|
|
461
|
-
GeneralUtilities.write_message_to_stdout("No linting-issues found.")
|
|
462
|
-
|
|
463
|
-
@GeneralUtilities.check_arguments
|
|
464
|
-
def standardized_tasks_generate_coverage_report(self, repository_folder: str, codeunitname: str, verbosity: int, generate_badges: bool, targetenvironmenttype: str,
|
|
465
|
-
commandline_arguments: list[str]):
|
|
466
|
-
"""This script expects that the file '<repositorybasefolder>/<codeunitname>/Other/Artifacts/TestCoverage/TestCoverage.xml'
|
|
467
|
-
which contains a test-coverage-report in the cobertura-format exists.
|
|
468
|
-
This script expectes that the testcoverage-reportfolder is '<repositorybasefolder>/<codeunitname>/Other/Artifacts/TestCoverageReport'.
|
|
469
|
-
This script expectes that a test-coverage-badges should be added to '<repositorybasefolder>/<codeunitname>/Other/Resources/Badges'."""
|
|
470
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
471
|
-
if verbosity == 0:
|
|
472
|
-
verbose_argument_for_reportgenerator = "Off"
|
|
473
|
-
if verbosity == 1:
|
|
474
|
-
verbose_argument_for_reportgenerator = "Error"
|
|
475
|
-
if verbosity == 2:
|
|
476
|
-
verbose_argument_for_reportgenerator = "Info"
|
|
477
|
-
if verbosity == 3:
|
|
478
|
-
verbose_argument_for_reportgenerator = "Verbose"
|
|
479
|
-
|
|
480
|
-
# Generating report
|
|
481
|
-
GeneralUtilities.ensure_directory_does_not_exist(os.path.join(repository_folder, codeunitname, f"{codeunitname}/Other/Artifacts/TestCoverageReport"))
|
|
482
|
-
GeneralUtilities.ensure_directory_exists(os.path.join(repository_folder, codeunitname, f"{codeunitname}/Other/Artifacts/TestCoverageReport"))
|
|
483
|
-
self.__sc.run_program("reportgenerator", f"-reports:{codeunitname}/Other/Artifacts/TestCoverage/TestCoverage.xml " +
|
|
484
|
-
f"-targetdir:{codeunitname}/Other/Artifacts/TestCoverageReport --verbosity={verbose_argument_for_reportgenerator}", repository_folder)
|
|
485
|
-
|
|
486
|
-
if generate_badges:
|
|
487
|
-
# Generating badges
|
|
488
|
-
testcoverageubfolger = f"{codeunitname}/Other/Resources/TestCoverageBadges"
|
|
489
|
-
fulltestcoverageubfolger = os.path.join(repository_folder, codeunitname, testcoverageubfolger)
|
|
490
|
-
GeneralUtilities.ensure_directory_does_not_exist(fulltestcoverageubfolger)
|
|
491
|
-
GeneralUtilities.ensure_directory_exists(fulltestcoverageubfolger)
|
|
492
|
-
self.__sc.run_program("reportgenerator", f"-reports:{codeunitname}/Other/Artifacts/TestCoverage/TestCoverage.xml -targetdir:{testcoverageubfolger} " +
|
|
493
|
-
f"-reporttypes:Badges --verbosity={verbose_argument_for_reportgenerator}", repository_folder, verbosity=verbosity)
|
|
494
|
-
|
|
495
|
-
@GeneralUtilities.check_arguments
|
|
496
|
-
def standardized_tasks_run_testcases_for_dotnet_project_in_common_project_structure(self, runtestcases_file: str, targetenvironmenttype: str, verbosity: int, generate_badges: bool,
|
|
497
|
-
commandline_arguments: list[str]):
|
|
498
|
-
codeunit_name: str = os.path.basename(str(Path(os.path.dirname(runtestcases_file)).parent.parent.absolute()))
|
|
499
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
500
|
-
repository_folder: str = str(Path(os.path.dirname(runtestcases_file)).parent.parent.parent.absolute())
|
|
501
|
-
testprojectname = codeunit_name+"Tests"
|
|
502
|
-
coverage_file_folder = os.path.join(repository_folder, codeunit_name, "Other/Artifacts/TestCoverage")
|
|
503
|
-
coveragefiletarget = os.path.join(coverage_file_folder, "TestCoverage.xml")
|
|
504
|
-
buildconfiguration = self.__get_dotnet_buildconfiguration_by_target_environmenttype(targetenvironmenttype, codeunit_name, commandline_arguments)
|
|
505
|
-
with tempfile.TemporaryDirectory() as temp_directory:
|
|
506
|
-
self.__sc.run_program_argsasarray("dotnet", ["test", f"{testprojectname}/{testprojectname}.csproj", "-c", buildconfiguration,
|
|
507
|
-
"--verbosity", "normal", "--collect", "XPlat Code Coverage", "--results-directory", temp_directory],
|
|
508
|
-
os.path.join(repository_folder, codeunit_name), verbosity=verbosity)
|
|
509
|
-
temp_directory_subdir = GeneralUtilities.get_direct_folders_of_folder(temp_directory)[0]
|
|
510
|
-
test_coverage_file = GeneralUtilities.get_direct_files_of_folder(temp_directory_subdir)[0]
|
|
511
|
-
GeneralUtilities.ensure_directory_exists(coverage_file_folder)
|
|
512
|
-
GeneralUtilities.ensure_file_does_not_exist(coveragefiletarget)
|
|
513
|
-
shutil.copy(test_coverage_file, coveragefiletarget)
|
|
514
|
-
self.standardized_tasks_generate_coverage_report(repository_folder, codeunit_name, verbosity, generate_badges, targetenvironmenttype, commandline_arguments)
|
|
515
|
-
self.check_testcoverage_for_project_in_common_project_structure(coveragefiletarget, repository_folder, codeunit_name)
|
|
516
|
-
self.update_path_of_source(repository_folder, codeunit_name)
|
|
517
|
-
|
|
518
|
-
@GeneralUtilities.check_arguments
|
|
519
|
-
def write_version_to_codeunit_file(self, codeunit_file: str, current_version: str) -> None:
|
|
520
|
-
versionregex = "\\d+\\.\\d+\\.\\d+"
|
|
521
|
-
versiononlyregex = f"^{versionregex}$"
|
|
522
|
-
pattern = re.compile(versiononlyregex)
|
|
523
|
-
if pattern.match(current_version):
|
|
524
|
-
GeneralUtilities.write_text_to_file(codeunit_file, re.sub(f"<cps:version>{versionregex}<\\/cps:version>",
|
|
525
|
-
f"<cps:version>{current_version}</cps:version>", GeneralUtilities.read_text_from_file(codeunit_file)))
|
|
526
|
-
else:
|
|
527
|
-
raise ValueError(f"Version '{current_version}' does not match version-regex '{versiononlyregex}'.")
|
|
528
|
-
|
|
529
|
-
@GeneralUtilities.check_arguments
|
|
530
|
-
def standardized_tasks_linting_for_dotnet_project_in_common_project_structure(self, linting_script_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]):
|
|
531
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
532
|
-
# TODO implement function
|
|
533
|
-
|
|
534
|
-
@GeneralUtilities.check_arguments
|
|
535
|
-
def __export_codeunit_reference_content_to_reference_repository(self, project_version_identifier: str, replace_existing_content: bool, target_folder_for_reference_repository: str,
|
|
536
|
-
repository: str, codeunitname, projectname: str, codeunit_version: str, public_repository_url: str, branch: str) -> None:
|
|
537
|
-
target_folder = os.path.join(target_folder_for_reference_repository, project_version_identifier, codeunitname)
|
|
538
|
-
if os.path.isdir(target_folder) and not replace_existing_content:
|
|
539
|
-
raise ValueError(f"Folder '{target_folder}' already exists.")
|
|
540
|
-
GeneralUtilities.ensure_directory_does_not_exist(target_folder)
|
|
541
|
-
GeneralUtilities.ensure_directory_exists(target_folder)
|
|
542
|
-
title = f"{codeunitname}-reference (codeunit v{codeunit_version}, conained in project {projectname} ({project_version_identifier}))"
|
|
543
|
-
if public_repository_url is None:
|
|
544
|
-
repo_url_html = ""
|
|
545
|
-
else:
|
|
546
|
-
repo_url_html = f'<a href="{public_repository_url}/tree/{branch}/{codeunitname}">Source-code</a><br>'
|
|
547
|
-
index_file_for_reference = os.path.join(target_folder, "index.html")
|
|
548
|
-
index_file_content = f"""<!DOCTYPE html>
|
|
549
|
-
<html lang="en">
|
|
550
|
-
<head>
|
|
551
|
-
<meta charset="UTF-8">
|
|
552
|
-
<title>{title}</title>
|
|
553
|
-
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
|
554
|
-
</head>
|
|
555
|
-
<body>
|
|
556
|
-
<h1 class="display-1">{title}</h1>
|
|
557
|
-
<hr/>
|
|
558
|
-
Available reference-content for {codeunitname}:<br>
|
|
559
|
-
{repo_url_html}
|
|
560
|
-
<a href="./Reference/index.html">Reference</a><br>
|
|
561
|
-
<a href="./TestCoverageReport/index.html">TestCoverageReport</a><br>
|
|
562
|
-
</body>
|
|
563
|
-
</html>
|
|
564
|
-
""" # see https://getbootstrap.com/docs/5.1/getting-started/introduction/
|
|
565
|
-
GeneralUtilities.ensure_file_exists(index_file_for_reference)
|
|
566
|
-
GeneralUtilities.write_text_to_file(index_file_for_reference, index_file_content)
|
|
567
|
-
other_folder_in_repository = os.path.join(repository, codeunitname, "Other")
|
|
568
|
-
source_generatedreference = os.path.join(other_folder_in_repository, "Artifacts", "Reference")
|
|
569
|
-
target_generatedreference = os.path.join(target_folder, "Reference")
|
|
570
|
-
shutil.copytree(source_generatedreference, target_generatedreference)
|
|
571
|
-
source_testcoveragereport = os.path.join(other_folder_in_repository, "Artifacts", "TestCoverageReport")
|
|
572
|
-
target_testcoveragereport = os.path.join(target_folder, "TestCoverageReport")
|
|
573
|
-
shutil.copytree(source_testcoveragereport, target_testcoveragereport)
|
|
574
|
-
|
|
575
|
-
@GeneralUtilities.check_arguments
|
|
576
|
-
def __standardized_tasks_release_buildartifact_for_project_in_common_project_format(self, information: CreateReleaseInformationForProjectInCommonProjectFormat) -> None:
|
|
577
|
-
# This function is intended to be called directly after standardized_tasks_merge_to_stable_branch_for_project_in_common_project_format
|
|
578
|
-
project_version = self.__sc.get_semver_version_from_gitversion(information.repository)
|
|
579
|
-
target_folder_base = os.path.join(information.artifacts_folder, information.projectname, project_version)
|
|
580
|
-
if os.path.isdir(target_folder_base):
|
|
581
|
-
raise ValueError(f"The folder '{target_folder_base}' already exists.")
|
|
582
|
-
GeneralUtilities.ensure_directory_exists(target_folder_base)
|
|
583
|
-
|
|
584
|
-
for codeunitname, codeunit_configuration in information.codeunits.items():
|
|
585
|
-
codeunit_folder = os.path.join(information.repository, codeunitname)
|
|
586
|
-
codeunit_version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
587
|
-
self.build_codeunit(os.path.join(information.repository, codeunitname), information.verbosity, information.target_environmenttype_for_productive,
|
|
588
|
-
codeunit_configuration.additional_arguments_file)
|
|
589
|
-
|
|
590
|
-
reference_repository_target_for_project = os.path.join(information.reference_repository, "ReferenceContent")
|
|
591
|
-
|
|
592
|
-
for codeunitname, codeunit_configuration in information.codeunits.items():
|
|
593
|
-
codeunit_folder = os.path.join(information.repository, codeunitname)
|
|
594
|
-
codeunit_version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
595
|
-
|
|
596
|
-
target_folder_for_codeunit = os.path.join(target_folder_base, codeunitname)
|
|
597
|
-
GeneralUtilities.ensure_directory_exists(target_folder_for_codeunit)
|
|
598
|
-
shutil.copytree(os.path.join(codeunit_folder, "Other", "Artifacts"), os.path.join(target_folder_for_codeunit, "Artifacts"))
|
|
599
|
-
|
|
600
|
-
for codeunitname, codeunit_configuration in information.codeunits.items():
|
|
601
|
-
push_artifact_to_registry_script = codeunit_configuration.push_to_registry_script
|
|
602
|
-
folder = os.path.dirname(push_artifact_to_registry_script)
|
|
603
|
-
file = os.path.basename(push_artifact_to_registry_script)
|
|
604
|
-
GeneralUtilities.write_message_to_stdout(f"Push buildartifact of codeunit {codeunitname}.")
|
|
605
|
-
self.__sc.run_program("python", file, folder, verbosity=information.verbosity, throw_exception_if_exitcode_is_not_zero=True)
|
|
606
|
-
|
|
607
|
-
# Copy reference of codeunit to reference-repository
|
|
608
|
-
self.__export_codeunit_reference_content_to_reference_repository(f"v{project_version}", False, reference_repository_target_for_project, information.repository,
|
|
609
|
-
codeunitname, information.projectname, codeunit_version, information.public_repository_url,
|
|
610
|
-
f"v{project_version}")
|
|
611
|
-
self.__export_codeunit_reference_content_to_reference_repository("Latest", True, reference_repository_target_for_project, information.repository,
|
|
612
|
-
codeunitname, information.projectname, codeunit_version, information.public_repository_url,
|
|
613
|
-
information.target_branch_name)
|
|
614
|
-
|
|
615
|
-
GeneralUtilities.write_message_to_stdout("Create entire reference")
|
|
616
|
-
all_available_version_identifier_folders_of_reference = list(
|
|
617
|
-
folder for folder in GeneralUtilities.get_direct_folders_of_folder(reference_repository_target_for_project))
|
|
618
|
-
all_available_version_identifier_folders_of_reference.reverse() # move newer versions above
|
|
619
|
-
all_available_version_identifier_folders_of_reference.insert(0, all_available_version_identifier_folders_of_reference.pop()) # move latest version to the top
|
|
620
|
-
reference_versions_html_lines = []
|
|
621
|
-
for all_available_version_identifier_folder_of_reference in all_available_version_identifier_folders_of_reference:
|
|
622
|
-
version_identifier_of_project = os.path.basename(all_available_version_identifier_folder_of_reference)
|
|
623
|
-
if version_identifier_of_project == "Latest":
|
|
624
|
-
latest_version_hint = f" (v {project_version})"
|
|
625
|
-
else:
|
|
626
|
-
latest_version_hint = ""
|
|
627
|
-
reference_versions_html_lines.append('<hr>')
|
|
628
|
-
reference_versions_html_lines.append(f'<h2 class="display-2">{version_identifier_of_project}{latest_version_hint}</h2>')
|
|
629
|
-
reference_versions_html_lines.append("Contained codeunits:<br>")
|
|
630
|
-
reference_versions_html_lines.append("<ul>")
|
|
631
|
-
for codeunit_reference_folder in list(folder for folder in GeneralUtilities.get_direct_folders_of_folder(all_available_version_identifier_folder_of_reference)):
|
|
632
|
-
codeunit_folder = os.path.join(information.repository, codeunitname)
|
|
633
|
-
codeunit_version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
634
|
-
reference_versions_html_lines.append(f'<li><a href="./{version_identifier_of_project}/{os.path.basename(codeunit_reference_folder)}/index.html">' +
|
|
635
|
-
f'{os.path.basename(codeunit_reference_folder)} {version_identifier_of_project}</a></li>')
|
|
636
|
-
reference_versions_html_lines.append("</ul>")
|
|
637
|
-
|
|
638
|
-
reference_versions_links_file_content = " \n".join(reference_versions_html_lines)
|
|
639
|
-
title = f"{information.projectname}-reference"
|
|
640
|
-
reference_index_file = os.path.join(reference_repository_target_for_project, "index.html")
|
|
641
|
-
reference_index_file_content = f"""<!DOCTYPE html>
|
|
642
|
-
<html lang="en">
|
|
643
|
-
|
|
644
|
-
<head>
|
|
645
|
-
<meta charset="UTF-8">
|
|
646
|
-
<title>{title}</title>
|
|
647
|
-
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
|
648
|
-
</head>
|
|
649
|
-
|
|
650
|
-
<body>
|
|
651
|
-
<h1 class="display-1">{title}</h1>
|
|
652
|
-
<hr/>
|
|
653
|
-
{reference_versions_links_file_content}
|
|
654
|
-
</body>
|
|
655
|
-
|
|
656
|
-
</html>
|
|
657
|
-
""" # see https://getbootstrap.com/docs/5.1/getting-started/introduction/
|
|
658
|
-
GeneralUtilities.write_text_to_file(reference_index_file, reference_index_file_content)
|
|
659
|
-
|
|
660
|
-
@GeneralUtilities.check_arguments
|
|
661
|
-
def push_nuget_build_artifact_for_project_in_standardized_project_structure(self, push_script_file: str, codeunitname: str,
|
|
662
|
-
registry_address: str, api_key: str):
|
|
663
|
-
# when pusing to "default public" nuget-server then use registry_address: "nuget.org"
|
|
664
|
-
build_artifact_folder = GeneralUtilities.resolve_relative_path(
|
|
665
|
-
f"../../Submodules/{codeunitname}/{codeunitname}/Other/Artifacts/BuildResult_NuGet", os.path.dirname(push_script_file))
|
|
666
|
-
self.__sc.push_nuget_build_artifact_of_repository_in_common_file_structure(self.__sc.find_file_by_extension(build_artifact_folder, "nupkg"),
|
|
667
|
-
registry_address, api_key)
|
|
668
|
-
|
|
669
|
-
@GeneralUtilities.check_arguments
|
|
670
|
-
def assert_no_uncommitted_changes(self, repository_folder: str):
|
|
671
|
-
if self.__sc.git_repository_has_uncommitted_changes(repository_folder):
|
|
672
|
-
raise ValueError(f"Repository '{repository_folder}' has uncommitted changes.")
|
|
673
|
-
|
|
674
|
-
@GeneralUtilities.check_arguments
|
|
675
|
-
def get_codeunits(self, repository_folder: str) -> list[str]:
|
|
676
|
-
result: list[str] = []
|
|
677
|
-
for direct_subfolder in GeneralUtilities.get_direct_folders_of_folder(repository_folder):
|
|
678
|
-
subfoldername = os.path.basename(direct_subfolder)
|
|
679
|
-
if os.path.isfile(os.path.join(direct_subfolder, f"{subfoldername}.codeunit.xml")):
|
|
680
|
-
result.append(subfoldername)
|
|
681
|
-
return result
|
|
682
|
-
|
|
683
|
-
@GeneralUtilities.check_arguments
|
|
684
|
-
def prepare_release_by_building_code_units_and_committing_changes(self, repository_folder: str, build_repository_folder: str, codeunits: dict[str, CodeUnitConfiguration],
|
|
685
|
-
new_version_branch_name: str = "other/next-release", main_branch_name: str = "main", verbosity: int = 1) -> None:
|
|
686
|
-
self.assert_no_uncommitted_changes(repository_folder)
|
|
687
|
-
repository_name = os.path.basename(repository_folder)
|
|
688
|
-
self.__sc.git_checkout(repository_folder, new_version_branch_name)
|
|
689
|
-
for codeunitname, codeunit_confoguration in codeunits.items():
|
|
690
|
-
self.build_codeunit(os.path.join(repository_folder, codeunitname), verbosity, "QualityCheck", codeunit_confoguration.additional_arguments_file)
|
|
691
|
-
self.__sc.git_commit(repository_folder, "Updates due to building code-units.")
|
|
692
|
-
self.__sc.git_merge(repository_folder, new_version_branch_name, main_branch_name, False, True, f'Merge branch {new_version_branch_name} into {main_branch_name}')
|
|
693
|
-
self.__sc.git_checkout(repository_folder, main_branch_name)
|
|
694
|
-
self.__sc.git_commit(build_repository_folder, f"Updated submodule {repository_name}")
|
|
695
|
-
|
|
696
|
-
@GeneralUtilities.check_arguments
|
|
697
|
-
def create_release_for_project_in_standardized_release_repository_format(self, create_release_file: str, createReleaseConfiguration: CreateReleaseConfiguration):
|
|
698
|
-
|
|
699
|
-
GeneralUtilities.write_message_to_stdout(f"Create release for project {createReleaseConfiguration.projectname}.")
|
|
700
|
-
folder_of_create_release_file_file = os.path.abspath(os.path.dirname(create_release_file))
|
|
701
|
-
|
|
702
|
-
build_repository_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}..", folder_of_create_release_file_file)
|
|
703
|
-
self.assert_no_uncommitted_changes(build_repository_folder)
|
|
704
|
-
|
|
705
|
-
self.__sc.git_checkout(build_repository_folder, createReleaseConfiguration.build_repository_branch)
|
|
706
|
-
|
|
707
|
-
repository_folder = GeneralUtilities.resolve_relative_path(f"Submodules{os.path.sep}{createReleaseConfiguration.projectname}", build_repository_folder)
|
|
708
|
-
mergeToStableBranchInformation = MergeToStableBranchInformationForProjectInCommonProjectFormat(repository_folder)
|
|
709
|
-
mergeToStableBranchInformation.verbosity = createReleaseConfiguration.verbosity
|
|
710
|
-
mergeToStableBranchInformation.push_target_branch = createReleaseConfiguration.remotename is not None
|
|
711
|
-
mergeToStableBranchInformation.push_target_branch_remote_name = createReleaseConfiguration.remotename
|
|
712
|
-
mergeToStableBranchInformation.push_source_branch = createReleaseConfiguration.remotename is not None
|
|
713
|
-
mergeToStableBranchInformation.push_source_branch_remote_name = createReleaseConfiguration.remotename
|
|
714
|
-
mergeToStableBranchInformation.codeunits = createReleaseConfiguration.codeunits
|
|
715
|
-
new_project_version = self.__standardized_tasks_merge_to_stable_branch_for_project_in_common_project_format(mergeToStableBranchInformation)
|
|
716
|
-
|
|
717
|
-
createReleaseInformation = CreateReleaseInformationForProjectInCommonProjectFormat(repository_folder, createReleaseConfiguration.artifacts_folder,
|
|
718
|
-
createReleaseConfiguration.projectname, createReleaseConfiguration.public_repository_url,
|
|
719
|
-
mergeToStableBranchInformation.targetbranch)
|
|
720
|
-
createReleaseInformation.verbosity = createReleaseConfiguration.verbosity
|
|
721
|
-
createReleaseInformation.codeunits = createReleaseConfiguration.codeunits
|
|
722
|
-
self.__standardized_tasks_release_buildartifact_for_project_in_common_project_format(createReleaseInformation)
|
|
723
|
-
|
|
724
|
-
self.__sc.git_commit(createReleaseInformation.reference_repository, f"Added reference of {createReleaseConfiguration.projectname} v{new_project_version}")
|
|
725
|
-
if createReleaseConfiguration.reference_repository_remote_name is not None:
|
|
726
|
-
self.__sc.git_push(createReleaseInformation.reference_repository, createReleaseConfiguration.reference_repository_remote_name, createReleaseConfiguration.reference_repository_branch_name,
|
|
727
|
-
createReleaseConfiguration.reference_repository_branch_name, verbosity=createReleaseConfiguration.verbosity)
|
|
728
|
-
self.__sc.git_commit(build_repository_folder, f"Added {createReleaseConfiguration.projectname} release v{new_project_version}")
|
|
729
|
-
GeneralUtilities.write_message_to_stdout(f"Finished release for project {createReleaseConfiguration.projectname} successfully.")
|
|
730
|
-
return new_project_version
|
|
731
|
-
|
|
732
|
-
@GeneralUtilities.check_arguments
|
|
733
|
-
def create_release_starter_for_repository_in_standardized_format(self, create_release_file: str, logfile: str, verbosity: int, addLogOverhead: bool,
|
|
734
|
-
commandline_arguments: list[str]):
|
|
735
|
-
# hint: arguments can be overwritten by commandline_arguments
|
|
736
|
-
folder_of_this_file = os.path.dirname(create_release_file)
|
|
737
|
-
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
738
|
-
self.__sc.run_program("python", f"CreateRelease.py --overwrite_verbosity={str(verbosity)}",
|
|
739
|
-
folder_of_this_file, verbosity=verbosity, log_file=logfile, addLogOverhead=addLogOverhead)
|
|
740
|
-
|
|
741
|
-
@GeneralUtilities.check_arguments
|
|
742
|
-
def __standardized_tasks_merge_to_stable_branch_for_project_in_common_project_format(self, information: MergeToStableBranchInformationForProjectInCommonProjectFormat) -> str:
|
|
743
|
-
|
|
744
|
-
src_branch_commit_id = self.__sc.git_get_commit_id(information.repository, information.sourcebranch)
|
|
745
|
-
if (src_branch_commit_id == self.__sc.git_get_commit_id(information.repository, information.targetbranch)):
|
|
746
|
-
GeneralUtilities.write_message_to_stderr(
|
|
747
|
-
f"Can not merge because the source-branch and the target-branch are on the same commit (commit-id: {src_branch_commit_id})")
|
|
748
|
-
|
|
749
|
-
self.assert_no_uncommitted_changes(information.repository)
|
|
750
|
-
self.__sc.git_checkout(information.repository, information.sourcebranch)
|
|
751
|
-
self.__sc.run_program("git", "clean -dfx", information.repository, verbosity=information.verbosity, throw_exception_if_exitcode_is_not_zero=True)
|
|
752
|
-
project_version = self.__sc.get_semver_version_from_gitversion(information.repository)
|
|
753
|
-
success = False
|
|
754
|
-
try:
|
|
755
|
-
for _, codeunit in information.codeunits.items():
|
|
756
|
-
GeneralUtilities.write_message_to_stdout(f"Start processing codeunit {codeunit.name}.")
|
|
757
|
-
self.build_codeunit(os.path.join(information.repository, codeunit.name), information.verbosity,
|
|
758
|
-
information.target_environmenttype_for_qualitycheck, codeunit.additional_arguments_file)
|
|
759
|
-
GeneralUtilities.write_message_to_stdout(f"Finished processing codeunit {codeunit.name}.")
|
|
760
|
-
|
|
761
|
-
self.assert_no_uncommitted_changes(information.repository)
|
|
762
|
-
success = True
|
|
763
|
-
except Exception as exception:
|
|
764
|
-
GeneralUtilities.write_exception_to_stderr(exception, "Error while doing merge-tasks. Merge will be aborted.")
|
|
765
|
-
|
|
766
|
-
if not success:
|
|
767
|
-
raise Exception("Release was not successful.")
|
|
768
|
-
|
|
769
|
-
commit_id = self.__sc.git_merge(information.repository, information.sourcebranch, information.targetbranch, True)
|
|
770
|
-
self.__sc.git_create_tag(information.repository, commit_id, f"v{project_version}", information.sign_git_tags)
|
|
771
|
-
|
|
772
|
-
if information.push_source_branch:
|
|
773
|
-
GeneralUtilities.write_message_to_stdout("Push source-branch...")
|
|
774
|
-
self.__sc.git_push(information.repository, information.push_source_branch_remote_name,
|
|
775
|
-
information.sourcebranch, information.sourcebranch, pushalltags=True, verbosity=information.verbosity)
|
|
776
|
-
|
|
777
|
-
if information.push_target_branch:
|
|
778
|
-
GeneralUtilities.write_message_to_stdout("Push target-branch...")
|
|
779
|
-
self.__sc.git_push(information.repository, information.push_target_branch_remote_name,
|
|
780
|
-
information.targetbranch, information.targetbranch, pushalltags=True, verbosity=information.verbosity)
|
|
781
|
-
|
|
782
|
-
return project_version
|
|
783
|
-
|
|
784
|
-
@GeneralUtilities.check_arguments
|
|
785
|
-
def standardized_tasks_build_for_docker_library_project_in_common_project_structure(self, build_script_file: str, build_configuration: str, verbosity: int, commandline_arguments: list[str]):
|
|
786
|
-
use_cache: bool = build_configuration == "QualityCheck"
|
|
787
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
788
|
-
sc: ScriptCollectionCore = ScriptCollectionCore()
|
|
789
|
-
codeunitname: str = Path(os.path.dirname(build_script_file)).parent.parent.name
|
|
790
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", str(os.path.dirname(build_script_file)))
|
|
791
|
-
|
|
792
|
-
codeunitname_lower = codeunitname.lower()
|
|
793
|
-
version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
794
|
-
args = ["image", "build", "--pull", "--force-rm", "--progress=plain", "--build-arg", f"environmenttypeStage={build_configuration}",
|
|
795
|
-
"--tag", f"{codeunitname_lower}:latest", "--tag", f"{codeunitname_lower}:{version}", "--file", "Dockerfile"]
|
|
796
|
-
if not use_cache:
|
|
797
|
-
args.append("--no-cache")
|
|
798
|
-
args.append(".")
|
|
799
|
-
codeunit_content_folder = os.path.join(codeunit_folder, codeunitname)
|
|
800
|
-
sc.run_program_argsasarray("docker", args, codeunit_content_folder, verbosity=verbosity, print_errors_as_information=True)
|
|
801
|
-
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
|
802
|
-
app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
|
|
803
|
-
GeneralUtilities.ensure_directory_does_not_exist(app_artifacts_folder)
|
|
804
|
-
GeneralUtilities.ensure_directory_exists(app_artifacts_folder)
|
|
805
|
-
sc.run_program_argsasarray("docker", ["save", "--output", f"{codeunitname}_v{version}.tar",
|
|
806
|
-
f"{codeunitname_lower}:{version}"], app_artifacts_folder, verbosity=verbosity, print_errors_as_information=True)
|
|
807
|
-
|
|
808
|
-
@GeneralUtilities.check_arguments
|
|
809
|
-
def push_docker_build_artifact_of_repository_in_common_file_structure(self, push_artifacts_file: str, registry: str, product_name: str, codeunitname: str,
|
|
810
|
-
verbosity: int, commandline_arguments: list[str]):
|
|
811
|
-
folder_of_this_file = os.path.dirname(push_artifacts_file)
|
|
812
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
813
|
-
repository_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}..{os.path.sep}Submodules{os.path.sep}{product_name}", folder_of_this_file)
|
|
814
|
-
codeunit_folder = os.path.join(repository_folder, codeunitname)
|
|
815
|
-
artifacts_folder = self.get_artifacts_folder_in_repository_in_common_repository_format(repository_folder, codeunitname)
|
|
816
|
-
applicationimage_folder = os.path.join(artifacts_folder, "ApplicationImage")
|
|
817
|
-
sc = ScriptCollectionCore()
|
|
818
|
-
image_file = sc.find_file_by_extension(applicationimage_folder, "tar")
|
|
819
|
-
image_filename = os.path.basename(image_file)
|
|
820
|
-
version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
|
821
|
-
image_tag_name = codeunitname.lower()
|
|
822
|
-
image_latest = f"{registry}/{image_tag_name}:latest"
|
|
823
|
-
image_version = f"{registry}/{image_tag_name}:{version}"
|
|
824
|
-
GeneralUtilities.write_message_to_stdout("Load image...")
|
|
825
|
-
sc.run_program("docker", f"load --input {image_filename}", applicationimage_folder, verbosity=verbosity)
|
|
826
|
-
GeneralUtilities.write_message_to_stdout("Tag image...")
|
|
827
|
-
sc.run_program("docker", f"tag {image_tag_name}:{version} {image_latest}", verbosity=verbosity)
|
|
828
|
-
sc.run_program("docker", f"tag {image_tag_name}:{version} {image_version}", verbosity=verbosity)
|
|
829
|
-
GeneralUtilities.write_message_to_stdout("Push image...")
|
|
830
|
-
sc.run_program("docker", f"push {image_latest}", verbosity=verbosity)
|
|
831
|
-
sc.run_program("docker", f"push {image_version}", verbosity=verbosity)
|
|
832
|
-
|
|
833
|
-
@GeneralUtilities.check_arguments
|
|
834
|
-
def get_dependent_code_units(self, codeunit_file: str) -> list[str]:
|
|
835
|
-
root: etree._ElementTree = etree.parse(codeunit_file)
|
|
836
|
-
return root.xpath('//cps:dependentcodeunit/text()', namespaces={
|
|
837
|
-
'cps': 'https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure'
|
|
838
|
-
})
|
|
839
|
-
|
|
840
|
-
@GeneralUtilities.check_arguments
|
|
841
|
-
def standardized_tasks_run_testcases_for_docker_project_in_common_project_structure(self, run_testcases_script_file: str, verbosity: int, targetenvironmenttype: str,
|
|
842
|
-
commandline_arguments: list[str]):
|
|
843
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", str(os.path.dirname(run_testcases_script_file)))
|
|
844
|
-
repository_folder: str = str(Path(os.path.dirname(run_testcases_script_file)).parent.parent.parent.absolute())
|
|
845
|
-
codeunitname: str = Path(os.path.dirname(run_testcases_script_file)).parent.parent.name
|
|
846
|
-
date = int(round(datetime.now().timestamp()))
|
|
847
|
-
# TODO generate real coverage report
|
|
848
|
-
dummy_test_coverage_file = f"""<?xml version="1.0" ?>
|
|
849
|
-
<coverage version="6.3.2" timestamp="{date}" lines-valid="0" lines-covered="0" line-rate="0" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
|
|
850
|
-
<sources>
|
|
851
|
-
<source>{codeunitname}</source>
|
|
852
|
-
</sources>
|
|
853
|
-
<packages>
|
|
854
|
-
<package name="{codeunitname}" line-rate="0" branch-rate="0" complexity="0">
|
|
855
|
-
</package>
|
|
856
|
-
</packages>
|
|
857
|
-
</coverage>"""
|
|
858
|
-
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
|
859
|
-
testcoverage_artifacts_folder = os.path.join(artifacts_folder, "TestCoverage")
|
|
860
|
-
GeneralUtilities.ensure_directory_exists(testcoverage_artifacts_folder)
|
|
861
|
-
testcoverage_file = os.path.join(testcoverage_artifacts_folder, "TestCoverage.xml")
|
|
862
|
-
GeneralUtilities.ensure_file_exists(testcoverage_file)
|
|
863
|
-
GeneralUtilities.write_text_to_file(testcoverage_file, dummy_test_coverage_file)
|
|
864
|
-
self.standardized_tasks_generate_coverage_report(repository_folder, codeunitname, verbosity, True, targetenvironmenttype, commandline_arguments)
|
|
865
|
-
self.update_path_of_source(repository_folder, codeunitname)
|
|
866
|
-
|
|
867
|
-
@GeneralUtilities.check_arguments
|
|
868
|
-
def standardized_tasks_linting_for_docker_project_in_common_project_structure(self, linting_script_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]) -> None:
|
|
869
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
870
|
-
# TODO
|
|
871
|
-
|
|
872
|
-
@GeneralUtilities.check_arguments
|
|
873
|
-
def standardized_tasks_do_common_tasks(self, common_tasks_scripts_file: str, version: str, verbosity: int, targetenvironmenttype: str, clear_artifacts_folder: bool,
|
|
874
|
-
additional_arguments_file: str, commandline_arguments: list[str]) -> None:
|
|
875
|
-
additional_arguments_file = self.get_additionalargumentsfile_from_commandline_arguments(commandline_arguments, additional_arguments_file)
|
|
876
|
-
target_environmenttype = self.get_targetenvironmenttype_from_commandline_arguments(commandline_arguments, targetenvironmenttype)
|
|
877
|
-
if commandline_arguments is None:
|
|
878
|
-
raise ValueError('The "commandline_arguments"-parameter is not defined.')
|
|
879
|
-
if len(commandline_arguments) == 0:
|
|
880
|
-
raise ValueError('An empty array as argument for the "commandline_arguments"-parameter is not valid.')
|
|
881
|
-
commandline_arguments = commandline_arguments[1:]
|
|
882
|
-
repository_folder: str = str(Path(os.path.dirname(common_tasks_scripts_file)).parent.parent.absolute())
|
|
883
|
-
codeunitname: str = str(os.path.basename(Path(os.path.dirname(common_tasks_scripts_file)).parent.absolute()))
|
|
884
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
885
|
-
GeneralUtilities.write_message_to_stdout(f"Build-environmenttype: {targetenvironmenttype}")
|
|
886
|
-
|
|
887
|
-
# Clear previously builded artifacts if desired:
|
|
888
|
-
if clear_artifacts_folder:
|
|
889
|
-
artifacts_folder = os.path.join(repository_folder, codeunitname, "Other", "Artifacts")
|
|
890
|
-
GeneralUtilities.ensure_directory_does_not_exist(artifacts_folder)
|
|
891
|
-
|
|
892
|
-
# Check codeunit-conformity
|
|
893
|
-
# TODO check if foldername=="<codeunitname>[.codeunit.xml]"==codeunitname in file
|
|
894
|
-
codeunitfile = os.path.join(repository_folder, codeunitname, f"{codeunitname}.codeunit.xml")
|
|
895
|
-
if not os.path.isfile(codeunitfile):
|
|
896
|
-
raise Exception(f'Codeunitfile "{codeunitfile}" does not exist.')
|
|
897
|
-
# TODO implement usage of self.reference_latest_version_of_xsd_when_generating_xml
|
|
898
|
-
namespaces = {'cps': 'https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure',
|
|
899
|
-
'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
|
|
900
|
-
root: etree._ElementTree = etree.parse(codeunitfile)
|
|
901
|
-
codeunit_file_version = root.xpath('//cps:codeunit/@codeunitspecificationversion', namespaces=namespaces)[0]
|
|
902
|
-
supported_codeunitspecificationversion = "1.1.0"
|
|
903
|
-
if codeunit_file_version != supported_codeunitspecificationversion:
|
|
904
|
-
raise ValueError(f"ScriptCollection only supports processing codeunits with codeunit-specification-version={supported_codeunitspecificationversion}.")
|
|
905
|
-
schemaLocation = root.xpath('//cps:codeunit/@xsi:schemaLocation', namespaces=namespaces)[0]
|
|
906
|
-
xmlschema.validate(codeunitfile, schemaLocation)
|
|
907
|
-
|
|
908
|
-
# Build dependent code units
|
|
909
|
-
self.build_dependent_code_units(repository_folder, codeunitname, verbosity, target_environmenttype, additional_arguments_file)
|
|
910
|
-
|
|
911
|
-
# Update version
|
|
912
|
-
self.update_version_of_codeunit_to_project_version(common_tasks_scripts_file, version)
|
|
913
|
-
|
|
914
|
-
# set default constants
|
|
915
|
-
self.set_default_constants(os.path.join(repository_folder, codeunitname))
|
|
916
|
-
|
|
917
|
-
# check for cycles in dependent code unitss
|
|
918
|
-
# TODO implement codeunit-sycle-check
|
|
919
|
-
|
|
920
|
-
# Check if changelog exists
|
|
921
|
-
changelog_folder = os.path.join(repository_folder, "Other", "Resources", "Changelog")
|
|
922
|
-
changelog_file = os.path.join(changelog_folder, f"v{version}.md")
|
|
923
|
-
if not os.path.isfile(changelog_file):
|
|
924
|
-
raise ValueError(f"Changelog-file '{changelog_file}' does not exist.")
|
|
925
|
-
|
|
926
|
-
@GeneralUtilities.check_arguments
|
|
927
|
-
def get_version_of_project(self, repository_folder: str):
|
|
928
|
-
return ScriptCollectionCore().get_semver_version_from_gitversion(repository_folder)
|
|
929
|
-
|
|
930
|
-
@GeneralUtilities.check_arguments
|
|
931
|
-
def replace_common_variables_in_nuspec_file(self, codeunit_folder: str):
|
|
932
|
-
codeunit_name = os.path.basename(codeunit_folder)
|
|
933
|
-
version = self.get_version_of_codeunit_folder(codeunit_folder)
|
|
934
|
-
nuspec_file = os.path.join(codeunit_folder, "Other", "Build", f"{codeunit_name}.nuspec")
|
|
935
|
-
self.__sc.replace_version_in_nuspec_file(nuspec_file, version)
|
|
936
|
-
|
|
937
|
-
@GeneralUtilities.check_arguments
|
|
938
|
-
def standardized_tasks_build_for_node_project_in_common_project_structure(self, build_script_file: str,
|
|
939
|
-
build_configuration: str, verbosity: int, commandline_arguments: list[str]):
|
|
940
|
-
# TODO use unused parameter
|
|
941
|
-
sc = ScriptCollectionCore()
|
|
942
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
943
|
-
sc.program_runner = ProgramRunnerEpew()
|
|
944
|
-
build_script_folder = os.path.dirname(build_script_file)
|
|
945
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", build_script_folder)
|
|
946
|
-
sc.run_program("npm", "run build", codeunit_folder)
|
|
947
|
-
|
|
948
|
-
@GeneralUtilities.check_arguments
|
|
949
|
-
def standardized_tasks_linting_for_node_project_in_common_project_structure(self, linting_script_file: str, verbosity: int,
|
|
950
|
-
target_environmenttype: str, commandline_arguments: list[str]):
|
|
951
|
-
# TODO use unused parameter
|
|
952
|
-
sc = ScriptCollectionCore()
|
|
953
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
954
|
-
sc.program_runner = ProgramRunnerEpew()
|
|
955
|
-
build_script_folder = os.path.dirname(linting_script_file)
|
|
956
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", build_script_folder)
|
|
957
|
-
sc.run_program("npm", "run lint", codeunit_folder)
|
|
958
|
-
|
|
959
|
-
@GeneralUtilities.check_arguments
|
|
960
|
-
def standardized_tasks_run_testcases_for_node_project_in_common_project_structure(self, runtestcases_script_file: str,
|
|
961
|
-
targetenvironmenttype: str, generate_badges: bool, verbosity: int,
|
|
962
|
-
commandline_arguments: list[str]):
|
|
963
|
-
# TODO really use targetenvironmenttype etc.
|
|
964
|
-
sc = ScriptCollectionCore()
|
|
965
|
-
verbosity = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
|
966
|
-
sc.program_runner = ProgramRunnerEpew()
|
|
967
|
-
build_script_folder = os.path.dirname(runtestcases_script_file)
|
|
968
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", build_script_folder)
|
|
969
|
-
sc.run_program("npm", "run test", codeunit_folder)
|
|
970
|
-
coverage_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "TestCoverage")
|
|
971
|
-
target_file = os.path.join(coverage_folder, "TestCoverage.xml")
|
|
972
|
-
GeneralUtilities.ensure_file_does_not_exist(target_file)
|
|
973
|
-
os.rename(os.path.join(coverage_folder, "cobertura-coverage.xml"), target_file)
|
|
974
|
-
repository_folder = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
|
|
975
|
-
codeunitname = os.path.basename(codeunit_folder)
|
|
976
|
-
self.check_testcoverage_for_project_in_common_project_structure(target_file, repository_folder, codeunitname)
|
|
977
|
-
self.standardized_tasks_generate_coverage_report(repository_folder, codeunitname, verbosity, generate_badges, targetenvironmenttype, commandline_arguments)
|
|
978
|
-
self.update_path_of_source(repository_folder, codeunitname)
|
|
979
|
-
|
|
980
|
-
@GeneralUtilities.check_arguments
|
|
981
|
-
def do_npm_install(self, package_json_folder: str, verbosity: int):
|
|
982
|
-
sc = ScriptCollectionCore()
|
|
983
|
-
sc.program_runner = ProgramRunnerEpew()
|
|
984
|
-
sc.run_program("npm", "install", package_json_folder, verbosity=verbosity)
|
|
985
|
-
|
|
986
|
-
@GeneralUtilities. check_arguments
|
|
987
|
-
def set_default_constants(self, codeunit_folder: str):
|
|
988
|
-
self.set_constant_for_commitid(codeunit_folder)
|
|
989
|
-
self.set_constant_for_commitdate(codeunit_folder)
|
|
990
|
-
|
|
991
|
-
@GeneralUtilities. check_arguments
|
|
992
|
-
def set_constant_for_commitid(self, codeunit_folder: str):
|
|
993
|
-
commit_id = self.__sc.git_get_commit_id(codeunit_folder)
|
|
994
|
-
self.set_constant(codeunit_folder, "commitid", commit_id)
|
|
995
|
-
|
|
996
|
-
@GeneralUtilities. check_arguments
|
|
997
|
-
def set_constant_for_commitdate(self, codeunit_folder: str):
|
|
998
|
-
commit_date: datetime = self.__sc.git_get_commit_date(codeunit_folder)
|
|
999
|
-
self.set_constant(codeunit_folder, "commitdate", GeneralUtilities.datetime_to_string(commit_date))
|
|
1000
|
-
|
|
1001
|
-
@GeneralUtilities. check_arguments
|
|
1002
|
-
def set_constant(self, codeunit_folder: str, constantname: str, constant_value: str, documentationsummary: str = None, constants_valuefile: str = None):
|
|
1003
|
-
if documentationsummary is None:
|
|
1004
|
-
documentationsummary = ""
|
|
1005
|
-
constants_folder = os.path.join(codeunit_folder, "Other", "Resources", "Constants")
|
|
1006
|
-
GeneralUtilities.ensure_directory_exists(constants_folder)
|
|
1007
|
-
constants_metafile = os.path.join(constants_folder, f"{constantname}.constant.xml")
|
|
1008
|
-
if constants_valuefile is None:
|
|
1009
|
-
constants_valuefile_folder = constants_folder
|
|
1010
|
-
constants_valuefile_name = f"{constantname}.value.xml"
|
|
1011
|
-
constants_valuefiler_reference = f"./{constants_valuefile_name}"
|
|
1012
|
-
else:
|
|
1013
|
-
constants_valuefile_folder = os.path.dirname(constants_valuefile)
|
|
1014
|
-
constants_valuefile_name = os.path.basename(constants_valuefile)
|
|
1015
|
-
constants_valuefiler_reference = os.path.join(constants_valuefile_folder, constants_valuefile_name)
|
|
1016
|
-
|
|
1017
|
-
# TODO implement usage of self.reference_latest_version_of_xsd_when_generating_xml
|
|
1018
|
-
GeneralUtilities.write_text_to_file(constants_metafile, f"""<?xml version="1.0" encoding="UTF-8" ?>
|
|
1019
|
-
<cps:constant xmlns:cps="https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure" constantspecificationversion="1.1.0"
|
|
1020
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/raw/main/Conventions/RepositoryStructure/CommonProjectStructure/constant.xsd">
|
|
1021
|
-
<cps:name>{constantname}</cps:name>
|
|
1022
|
-
<cps:documentationsummary>{documentationsummary}</cps:documentationsummary>
|
|
1023
|
-
<cps:path>{constants_valuefiler_reference}</cps:path>
|
|
1024
|
-
</cps:constant>""")
|
|
1025
|
-
# TODO validate generated xml against xsd
|
|
1026
|
-
GeneralUtilities.write_text_to_file(os.path.join(constants_valuefile_folder, constants_valuefile_name), constant_value)
|
|
1027
|
-
|
|
1028
|
-
@GeneralUtilities.check_arguments
|
|
1029
|
-
def generate_openapi_file(self, buildscript_file: str, runtime: str) -> None:
|
|
1030
|
-
codeunitname = os.path.basename(str(Path(os.path.dirname(buildscript_file)).parent.parent.absolute()))
|
|
1031
|
-
repository_folder = str(Path(os.path.dirname(buildscript_file)).parent.parent.parent.absolute())
|
|
1032
|
-
artifacts_folder = os.path.join(repository_folder, codeunitname, "Other", "Artifacts")
|
|
1033
|
-
GeneralUtilities.ensure_directory_exists(os.path.join(artifacts_folder, "APISpecification"))
|
|
1034
|
-
self.__sc.run_program("swagger", f"tofile --output APISpecification\\{codeunitname}.api.json BuildResult_DotNet_{runtime}\\{codeunitname}.dll v1", artifacts_folder)
|
|
1035
|
-
|
|
1036
|
-
@GeneralUtilities.check_arguments
|
|
1037
|
-
def replace_version_in_package_file(self: ScriptCollectionCore, package_json_file: str, version: str):
|
|
1038
|
-
filename = package_json_file
|
|
1039
|
-
with open(filename, 'r', encoding="utf-8") as f:
|
|
1040
|
-
data = json.load(f)
|
|
1041
|
-
data['version'] = version
|
|
1042
|
-
os.remove(filename)
|
|
1043
|
-
with open(filename, 'w', encoding="utf-8") as f:
|
|
1044
|
-
json.dump(data, f, indent=2)
|
|
1045
|
-
|
|
1046
|
-
@GeneralUtilities.check_arguments
|
|
1047
|
-
def build_dependent_code_units(self, repo_folder: str, codeunit_name: str, verbosity: int, target_environmenttype: str, additional_arguments_file: str) -> None:
|
|
1048
|
-
codeunit_file = os.path.join(repo_folder, codeunit_name, codeunit_name + ".codeunit.xml")
|
|
1049
|
-
dependent_codeunits = self.get_dependent_code_units(codeunit_file)
|
|
1050
|
-
dependent_codeunits_folder = os.path.join(repo_folder, codeunit_name, "Other", "Resources", "DependentCodeUnits")
|
|
1051
|
-
GeneralUtilities.ensure_directory_does_not_exist(dependent_codeunits_folder)
|
|
1052
|
-
if 0 < len(dependent_codeunits):
|
|
1053
|
-
GeneralUtilities.write_message_to_stdout(f"Start building dependent codeunits for {codeunit_name}.")
|
|
1054
|
-
for dependent_codeunit in dependent_codeunits:
|
|
1055
|
-
other_folder = os.path.join(repo_folder, dependent_codeunit, "Other")
|
|
1056
|
-
artifacts_folder = os.path.join(other_folder, "Artifacts")
|
|
1057
|
-
self.build_codeunit(os.path.join(repo_folder, dependent_codeunit), verbosity, target_environmenttype, additional_arguments_file)
|
|
1058
|
-
target_folder = os.path.join(dependent_codeunits_folder, dependent_codeunit)
|
|
1059
|
-
GeneralUtilities.ensure_directory_does_not_exist(target_folder)
|
|
1060
|
-
shutil.copytree(artifacts_folder, target_folder)
|
|
1061
|
-
GeneralUtilities.write_message_to_stdout(f"Finished building dependent codeunits for {codeunit_name}.")
|
|
1062
|
-
|
|
1063
|
-
@GeneralUtilities.check_arguments
|
|
1064
|
-
def add_github_release(self, productname: str, version: str, build_artifacts_folder: str, github_username: str, repository_folder: str):
|
|
1065
|
-
github_repo = f"{github_username}/{productname}"
|
|
1066
|
-
artifacts_file = f"{build_artifacts_folder}\\{productname}\\{version}\\{productname}.v{version}.artifacts.zip"
|
|
1067
|
-
release_title = f"Release v{version}"
|
|
1068
|
-
changelog_file = os.path.join(repository_folder, "Other", "Resources", "Changelog", f"v{version}.md")
|
|
1069
|
-
self.__sc.run_program_argsasarray("gh", ["release", "create", f"v{version}", "-R", github_repo,
|
|
1070
|
-
artifacts_file, "-F", changelog_file, "-t", release_title])
|
|
1071
|
-
|
|
1072
|
-
@GeneralUtilities.check_arguments
|
|
1073
|
-
def create_archive_of_artifacts(self, project_name: str, version: str, build_artifacts_folder: str):
|
|
1074
|
-
build_artifacts_folder_for_project = f"{build_artifacts_folder}\\{project_name}"
|
|
1075
|
-
folder = f"{build_artifacts_folder_for_project}\\{version}"
|
|
1076
|
-
filename_without_extension = f"{project_name}.v{version}.artifacts"
|
|
1077
|
-
filename = f"{filename_without_extension}.zip"
|
|
1078
|
-
GeneralUtilities.ensure_file_does_not_exist(filename)
|
|
1079
|
-
shutil.make_archive(filename_without_extension, 'zip', folder)
|
|
1080
|
-
shutil.move(filename, folder)
|
|
1081
|
-
|
|
1082
|
-
@GeneralUtilities.check_arguments
|
|
1083
|
-
def build_codeunits(self, repository_folder: str, verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None) -> None:
|
|
1084
|
-
codeunits = []
|
|
1085
|
-
subfolders = GeneralUtilities.get_direct_folders_of_folder(repository_folder)
|
|
1086
|
-
for subfolder in subfolders:
|
|
1087
|
-
codeunit_name = os.path.basename(subfolder)
|
|
1088
|
-
codeunit_file = os.path.join(subfolder, f"{codeunit_name}.codeunit.xml")
|
|
1089
|
-
if os.path.exists(codeunit_file):
|
|
1090
|
-
codeunits.append(codeunit_name)
|
|
1091
|
-
# TODO set order (the "last" should be first to not overwrite its artifacts)
|
|
1092
|
-
for codeunit in codeunits:
|
|
1093
|
-
self.build_codeunit(os.path.join(repository_folder, codeunit), verbosity, target_environmenttype, additional_arguments_file)
|
|
1094
|
-
|
|
1095
|
-
@GeneralUtilities.check_arguments
|
|
1096
|
-
def build_codeunit(self, codeunit_folder: str, verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None) -> None:
|
|
1097
|
-
now = datetime.now()
|
|
1098
|
-
codeunit_folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(codeunit_folder)
|
|
1099
|
-
codeunit_name: str = os.path.basename(codeunit_folder)
|
|
1100
|
-
codeunit_file = os.path.join(codeunit_folder, f"{codeunit_name}.codeunit.xml")
|
|
1101
|
-
if (not os.path.isfile(codeunit_file)):
|
|
1102
|
-
raise ValueError(f'"{codeunit_folder}" is no codeunit-folder.')
|
|
1103
|
-
artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts")
|
|
1104
|
-
GeneralUtilities.write_message_to_stdout(f"Start building codeunit {codeunit_name}.")
|
|
1105
|
-
GeneralUtilities.write_message_to_stdout(f"Build-environmenttype: {target_environmenttype}")
|
|
1106
|
-
|
|
1107
|
-
other_folder = os.path.join(codeunit_folder, "Other")
|
|
1108
|
-
build_folder = os.path.join(other_folder, "Build")
|
|
1109
|
-
quality_folder = os.path.join(other_folder, "QualityCheck")
|
|
1110
|
-
reference_folder = os.path.join(other_folder, "Reference")
|
|
1111
|
-
additional_arguments_c: str = ""
|
|
1112
|
-
additional_arguments_b: str = ""
|
|
1113
|
-
additional_arguments_r: str = ""
|
|
1114
|
-
additional_arguments_l: str = ""
|
|
1115
|
-
additional_arguments_g: str = ""
|
|
1116
|
-
general_argument = f'--overwrite_verbosity={str(verbosity)} --overwrite_targetenvironmenttype={target_environmenttype}'
|
|
1117
|
-
if additional_arguments_file is None:
|
|
1118
|
-
c_additional_argument = ""
|
|
1119
|
-
else:
|
|
1120
|
-
config = configparser.ConfigParser()
|
|
1121
|
-
config.read(additional_arguments_file)
|
|
1122
|
-
section_name = f"{codeunit_name}_Configuration"
|
|
1123
|
-
if config.has_option(section_name, "ArgumentsForCommonTasks"):
|
|
1124
|
-
additional_arguments_c = config.get(section_name, "ArgumentsForCommonTasks")
|
|
1125
|
-
if config.has_option(section_name, "ArgumentsForBuild"):
|
|
1126
|
-
additional_arguments_b = config.get(section_name, "ArgumentsForBuild")
|
|
1127
|
-
if config.has_option(section_name, "ArgumentsForRunTestcases"):
|
|
1128
|
-
additional_arguments_r = config.get(section_name, "ArgumentsForRunTestcases")
|
|
1129
|
-
if config.has_option(section_name, "ArgumentsForLinting"):
|
|
1130
|
-
additional_arguments_l = config.get(section_name, "ArgumentsForLinting")
|
|
1131
|
-
if config.has_option(section_name, "ArgumentsForGenerateReference"):
|
|
1132
|
-
additional_arguments_g = config.get(section_name, "ArgumentsForGenerateReference")
|
|
1133
|
-
c_additional_argument = f'--overwrite_additionalargumentsfile="{additional_arguments_file}"'
|
|
1134
|
-
|
|
1135
|
-
GeneralUtilities.write_message_to_stdout('Run "CommonTasks.py"...')
|
|
1136
|
-
self.__sc.run_program("python", f"CommonTasks.py {additional_arguments_c} {general_argument} {c_additional_argument}", other_folder, verbosity=verbosity)
|
|
1137
|
-
GeneralUtilities.write_message_to_stdout('Run "Build.py"...')
|
|
1138
|
-
self.__sc.run_program("python", f"Build.py {additional_arguments_b} {general_argument}", build_folder, verbosity=verbosity)
|
|
1139
|
-
GeneralUtilities.write_message_to_stdout('Run "RunTestcases.py"...')
|
|
1140
|
-
self.__sc.run_program("python", f"RunTestcases.py {additional_arguments_r} {general_argument}", quality_folder, verbosity=verbosity)
|
|
1141
|
-
GeneralUtilities.write_message_to_stdout('Run "Linting.py"...')
|
|
1142
|
-
self.__sc.run_program("python", f"Linting.py {additional_arguments_l} {general_argument}", quality_folder, verbosity=verbosity)
|
|
1143
|
-
GeneralUtilities.write_message_to_stdout('Run "GenerateReference.py"...')
|
|
1144
|
-
self.__sc.run_program("python", f"GenerateReference.py {additional_arguments_g} {general_argument}", reference_folder, verbosity=verbosity)
|
|
1145
|
-
|
|
1146
|
-
artifactsinformation_file = os.path.join(artifacts_folder, f"{codeunit_name}.artifactsinformation.xml")
|
|
1147
|
-
version = self.get_version_of_codeunit(codeunit_file)
|
|
1148
|
-
GeneralUtilities.ensure_file_exists(artifactsinformation_file)
|
|
1149
|
-
artifacts_list = []
|
|
1150
|
-
for artifact_folder in GeneralUtilities.get_direct_folders_of_folder(artifacts_folder):
|
|
1151
|
-
artifact_name = os.path.basename(artifact_folder)
|
|
1152
|
-
artifacts_list.append(f" <cps:artifact>{artifact_name}<cps:artifact>")
|
|
1153
|
-
artifacts = '\n'.join(artifacts_list)
|
|
1154
|
-
moment = GeneralUtilities.datetime_to_string(now)
|
|
1155
|
-
# TODO implement usage of self.reference_latest_version_of_xsd_when_generating_xml
|
|
1156
|
-
GeneralUtilities.write_text_to_file(artifactsinformation_file, f"""<?xml version="1.0" encoding="UTF-8" ?>
|
|
1157
|
-
<cps:artifactsinformation xmlns:cps="https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure" artifactsinformationspecificationversion="1.0.0"
|
|
1158
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://raw.githubusercontent.com/anionDev/ProjectTemplates/main/Templates/Conventions/RepositoryStructure/CommonProjectStructure/artifactsinformation.xsd">
|
|
1159
|
-
<cps:name>{codeunit_name}</cps:name>
|
|
1160
|
-
<cps:version>{version}</cps:version>
|
|
1161
|
-
<cps:timestamp>{moment}</cps:timestamp>
|
|
1162
|
-
<cps:targetenvironmenttype>{target_environmenttype}</cps:targetenvironmenttype>
|
|
1163
|
-
<cps:artifacts>
|
|
1164
|
-
{artifacts}
|
|
1165
|
-
</cps:artifacts>
|
|
1166
|
-
</cps:artifactsinformation>""")
|
|
1167
|
-
# TODO validate artifactsinformation_file against xsd
|
|
1168
|
-
shutil.copyfile(codeunit_file,
|
|
1169
|
-
os.path.join(artifacts_folder, f"{codeunit_name}.codeunit.xml"))
|
|
1170
|
-
GeneralUtilities.write_message_to_stdout(f"Finished building codeunit {codeunit_name}.")
|