scriptcollection 4.2.81__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 +199 -0
- ScriptCollection/CertificateUpdater.py +149 -0
- ScriptCollection/Executables.py +921 -0
- ScriptCollection/GeneralUtilities.py +1589 -0
- ScriptCollection/HTTPMaintenanceOverheadHelper.py +36 -0
- ScriptCollection/OCIImages/AbstractImageHandler.py +38 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerDebian.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerDebianSlim.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGeneric.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGenericV.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGitlabCE.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGitlabEE.py +20 -0
- ScriptCollection/OCIImages/ConcreteImageHandlers/__init__.py +0 -0
- ScriptCollection/OCIImages/OCIImageManager.py +190 -0
- ScriptCollection/OCIImages/__init__.py +0 -0
- ScriptCollection/ProcessesRunner.py +43 -0
- ScriptCollection/ProgramRunnerBase.py +47 -0
- ScriptCollection/ProgramRunnerMock.py +2 -0
- ScriptCollection/ProgramRunnerPopen.py +57 -0
- ScriptCollection/ProgramRunnerSudo.py +108 -0
- ScriptCollection/Resources/CultureChooser/CultureChooser.js +29 -0
- ScriptCollection/Resources/CultureChooser/index.html +15 -0
- ScriptCollection/Resources/MaintenanceSite/MaintenanceSite.html +15 -0
- ScriptCollection/SCLog.py +115 -0
- ScriptCollection/ScriptCollectionCore.py +3485 -0
- ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +192 -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 +547 -0
- ScriptCollection/TFCPS/DotNet/__init__.py +0 -0
- ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +137 -0
- ScriptCollection/TFCPS/Flutter/__init__.py +0 -0
- ScriptCollection/TFCPS/Go/TFCPS_CodeUnitSpecific_Go.py +72 -0
- ScriptCollection/TFCPS/Go/__init__.py +0 -0
- ScriptCollection/TFCPS/Maven/TFCPS_CodeUnitSpecific_Maven.py +42 -0
- ScriptCollection/TFCPS/Maven/__init__.py +0 -0
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +232 -0
- ScriptCollection/TFCPS/NodeJS/__init__.py +0 -0
- ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py +239 -0
- ScriptCollection/TFCPS/Python/__init__.py +0 -0
- ScriptCollection/TFCPS/Rust/TFCPS_CodeUnitSpecific_Rust.py +42 -0
- ScriptCollection/TFCPS/Rust/__init__.py +0 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +433 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py +135 -0
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +301 -0
- ScriptCollection/TFCPS/TFCPS_CreateRelease.py +98 -0
- ScriptCollection/TFCPS/TFCPS_Generic.py +44 -0
- ScriptCollection/TFCPS/TFCPS_MergeToMain.py +128 -0
- ScriptCollection/TFCPS/TFCPS_MergeToStable.py +356 -0
- ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py +48 -0
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +1565 -0
- ScriptCollection/TFCPS/__init__.py +0 -0
- ScriptCollection/__init__.py +0 -0
- ScriptCollection/__pycache__/GeneralUtilities.cpython-311.pyc +0 -0
- ScriptCollection/__pycache__/__init__.cpython-311.pyc +0 -0
- scriptcollection-4.2.81.dist-info/METADATA +169 -0
- scriptcollection-4.2.81.dist-info/RECORD +62 -0
- scriptcollection-4.2.81.dist-info/WHEEL +5 -0
- scriptcollection-4.2.81.dist-info/entry_points.txt +67 -0
- scriptcollection-4.2.81.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from datetime import datetime, timedelta,timezone
|
|
4
|
+
import yaml
|
|
5
|
+
from ..GeneralUtilities import GeneralUtilities
|
|
6
|
+
from ..ScriptCollectionCore import ScriptCollectionCore
|
|
7
|
+
from ..SCLog import LogLevel
|
|
8
|
+
from .TFCPS_CodeUnit_BuildCodeUnit import TFCPS_CodeUnit_BuildCodeUnit
|
|
9
|
+
from .TFCPS_Tools_General import TFCPS_Tools_General
|
|
10
|
+
|
|
11
|
+
class TFCPS_CodeUnit_BuildCodeUnits:
|
|
12
|
+
repository:str=None
|
|
13
|
+
tfcps_tools_general:TFCPS_Tools_General=None
|
|
14
|
+
sc:ScriptCollectionCore=None
|
|
15
|
+
target_environment_type:str=None
|
|
16
|
+
additionalargumentsfile:str=None
|
|
17
|
+
__use_cache:bool
|
|
18
|
+
__is_pre_merge:bool
|
|
19
|
+
|
|
20
|
+
def __init__(self,repository:str,loglevel:LogLevel,target_environment_type:str,additionalargumentsfile:str,use_cache:bool,is_pre_merge:bool):
|
|
21
|
+
self.sc=ScriptCollectionCore()
|
|
22
|
+
self.sc.log.loglevel=loglevel
|
|
23
|
+
self.__use_cache=use_cache
|
|
24
|
+
self.sc.assert_is_git_repository(repository)
|
|
25
|
+
self.repository=repository
|
|
26
|
+
self.tfcps_tools_general:TFCPS_Tools_General=TFCPS_Tools_General(self.sc)
|
|
27
|
+
allowed_target_environment_types=["Development","QualityCheck","Productive"]
|
|
28
|
+
GeneralUtilities.assert_condition(target_environment_type in allowed_target_environment_types,"Unknown target-environment-type. Allowed values are: "+", ".join(allowed_target_environment_types))
|
|
29
|
+
self.target_environment_type=target_environment_type
|
|
30
|
+
self.additionalargumentsfile=additionalargumentsfile
|
|
31
|
+
self.__is_pre_merge=is_pre_merge
|
|
32
|
+
|
|
33
|
+
@GeneralUtilities.check_arguments
|
|
34
|
+
def build_codeunits(self) -> None:
|
|
35
|
+
self.sc.log.log(GeneralUtilities.get_line())
|
|
36
|
+
start_time:datetime=GeneralUtilities.get_now()
|
|
37
|
+
self.sc.log.log(f"Start building codeunits at {GeneralUtilities.datetime_to_string_for_readable_entry(start_time,False)}. (Target environment-type: {self.target_environment_type})")
|
|
38
|
+
|
|
39
|
+
#check if changelog exists
|
|
40
|
+
changelog_file=os.path.join(self.repository,"Other","Resources","Changelog",f"v{self.tfcps_tools_general.get_version_of_project(self.repository)}.md")
|
|
41
|
+
GeneralUtilities.assert_file_exists(changelog_file,f"Changelogfile \"{changelog_file}\" does not exist. Try to create it for example using \"sccreatechangelogentry -m ...\".")
|
|
42
|
+
|
|
43
|
+
#run prepare-script
|
|
44
|
+
self.run_prepare_script()
|
|
45
|
+
|
|
46
|
+
#mark current version as supported
|
|
47
|
+
now = GeneralUtilities.get_now()
|
|
48
|
+
project_version:str=self.tfcps_tools_general.get_version_of_project(self.repository)
|
|
49
|
+
if not self.tfcps_tools_general.suport_information_exists(self.repository, project_version):
|
|
50
|
+
amount_of_years_for_support:int=1
|
|
51
|
+
support_time = timedelta(days=365*amount_of_years_for_support+30*3+1)
|
|
52
|
+
until = now + support_time
|
|
53
|
+
until_day = datetime(until.year, until.month, until.day, 0, 0, 0)
|
|
54
|
+
from_day = datetime(now.year, now.month, now.day, 0, 0, 0)
|
|
55
|
+
self.tfcps_tools_general.mark_current_version_as_supported(self.repository,project_version,from_day,until_day)
|
|
56
|
+
|
|
57
|
+
codeunits:list[str]=self.tfcps_tools_general.get_codeunits(self.repository)
|
|
58
|
+
GeneralUtilities.assert_condition(0<len(codeunits),f"No codeunits found in repository {self.repository}.")
|
|
59
|
+
self.sc.log.log("Codeunits will be built in the following order:")
|
|
60
|
+
for codeunit_name in codeunits:
|
|
61
|
+
self.sc.log.log(f" - {codeunit_name}")
|
|
62
|
+
for codeunit_name in codeunits:
|
|
63
|
+
tFCPS_CodeUnit_BuildCodeUnit:TFCPS_CodeUnit_BuildCodeUnit = TFCPS_CodeUnit_BuildCodeUnit(os.path.join(self.repository,codeunit_name),self.sc.log.loglevel,self.target_environment_type,self.additionalargumentsfile,self.use_cache(),self.is_pre_merge())
|
|
64
|
+
self.sc.log.log(GeneralUtilities.get_line())
|
|
65
|
+
tFCPS_CodeUnit_BuildCodeUnit.build_codeunit()
|
|
66
|
+
|
|
67
|
+
self.sc.log.log(GeneralUtilities.get_line())
|
|
68
|
+
self.__search_for_vulnerabilities()
|
|
69
|
+
self.__search_for_secrets()
|
|
70
|
+
if self.is_pre_merge():
|
|
71
|
+
self.__translate()
|
|
72
|
+
self.__collect_metrics()
|
|
73
|
+
self.__generate_loc_diagram()
|
|
74
|
+
end_time:datetime=GeneralUtilities.get_now()
|
|
75
|
+
duration=end_time-start_time
|
|
76
|
+
self.sc.log.log(f"Finished building codeunits at {GeneralUtilities.datetime_to_string_for_readable_entry(end_time,False)}. (Duration: {GeneralUtilities.timedelta_to_simple_string(duration)})")
|
|
77
|
+
self.sc.log.log(GeneralUtilities.get_line())
|
|
78
|
+
|
|
79
|
+
@GeneralUtilities.check_arguments
|
|
80
|
+
def run_prepare_script(self):
|
|
81
|
+
args=["--repository",self.repository,"--targetenvironmenttype",self.target_environment_type,"--verbosity",str(int(self.sc.log.loglevel))]
|
|
82
|
+
if GeneralUtilities.string_has_content(self.additionalargumentsfile):
|
|
83
|
+
args=args+["--additionalargumentsfile", self.additionalargumentsfile]
|
|
84
|
+
if not self.__use_cache:
|
|
85
|
+
if self.sc.git_repository_has_uncommitted_changes(self.repository):
|
|
86
|
+
self.sc.log.log("No-cache-option can not be applied because there are uncommited changes in the repository.",LogLevel.Warning)
|
|
87
|
+
else:
|
|
88
|
+
args=args+["--nocache"]
|
|
89
|
+
|
|
90
|
+
if os.path.isfile( os.path.join( self.sc.get_scriptcollection_configuration_folder(),"TFCPS","CustomPreCodeUnitBuildScript.py")):
|
|
91
|
+
self.sc.log.log("Run custom pre-codeunitbuild script...")
|
|
92
|
+
self.sc.run_program_argsasarray(GeneralUtilities.get_python_executable(),["CustomPreCodeUnitBuildScript.py"]+args, os.path.join( self.sc.get_scriptcollection_configuration_folder(),"TFCPS"),print_live_output=True)
|
|
93
|
+
|
|
94
|
+
if os.path.isfile( os.path.join(self.repository,"Other","Scripts","PrepareBuildCodeunits.py")):
|
|
95
|
+
self.sc.log.log("Prepare build codeunits...")
|
|
96
|
+
self.sc.run_program_argsasarray(GeneralUtilities.get_python_executable(),["PrepareBuildCodeunits.py"]+args, os.path.join(self.repository,"Other","Scripts"),print_live_output=True)
|
|
97
|
+
|
|
98
|
+
@GeneralUtilities.check_arguments
|
|
99
|
+
def build_codeunits_in_container(self) -> None:
|
|
100
|
+
raise ValueError("Not implemented.")
|
|
101
|
+
|
|
102
|
+
@GeneralUtilities.check_arguments
|
|
103
|
+
def __translate(self) -> None:
|
|
104
|
+
for taskfile_name in ("Taskfile.yml", "Taskfile.yaml"):
|
|
105
|
+
taskfile = os.path.join(self.repository, taskfile_name)
|
|
106
|
+
if os.path.isfile(taskfile):
|
|
107
|
+
with open(taskfile, "r", encoding="utf-8") as f:
|
|
108
|
+
taskfile_content = yaml.safe_load(f)
|
|
109
|
+
if isinstance(taskfile_content.get("tasks"), dict) and "Translate" in taskfile_content["tasks"]:
|
|
110
|
+
self.sc.run_program("task", "Translate", self.repository, print_live_output=self.sc.log.loglevel == LogLevel.Debug)
|
|
111
|
+
break
|
|
112
|
+
|
|
113
|
+
@GeneralUtilities.check_arguments
|
|
114
|
+
def __collect_metrics(self) -> None:
|
|
115
|
+
project_version: str=self.tfcps_tools_general.get_version_of_project(self.repository)
|
|
116
|
+
self.sc.log.log("Collect metrics...")
|
|
117
|
+
loc = self.sc.get_lines_of_code_with_default_excluded_patterns(self.repository)
|
|
118
|
+
loc_metric_folder = os.path.join(self.repository, "Other", "Metrics")
|
|
119
|
+
GeneralUtilities.ensure_directory_exists(loc_metric_folder)
|
|
120
|
+
loc_metric_file = os.path.join(loc_metric_folder, "RepositoryStatisticsPerCommit.csv")
|
|
121
|
+
GeneralUtilities.ensure_file_exists(loc_metric_file)
|
|
122
|
+
|
|
123
|
+
#remove legacy metrics-file. the following 2 lines should be removed after 2026-12-31
|
|
124
|
+
legacy_metrics_file = os.path.join(loc_metric_folder, "LinesOfCode.csv")
|
|
125
|
+
GeneralUtilities.ensure_file_does_not_exist(legacy_metrics_file)
|
|
126
|
+
|
|
127
|
+
old_lines = GeneralUtilities.read_nonempty_lines_from_file(loc_metric_file)
|
|
128
|
+
header_line="Version;Timestamp;LinesOfCode"
|
|
129
|
+
new_lines = [header_line]
|
|
130
|
+
current_version_string=f"v{project_version}"
|
|
131
|
+
for old_line in old_lines:
|
|
132
|
+
if not old_line.startswith(current_version_string+";") and old_line!=header_line:
|
|
133
|
+
new_lines.append(old_line)
|
|
134
|
+
c_date:datetime=GeneralUtilities.get_now().astimezone(timezone.utc)
|
|
135
|
+
commit_date=GeneralUtilities.datetime_to_string_for_logfile_entry(c_date,False)
|
|
136
|
+
new_lines.append(f"{current_version_string};{commit_date};{loc}")
|
|
137
|
+
GeneralUtilities.write_lines_to_file(loc_metric_file, new_lines)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@GeneralUtilities.check_arguments
|
|
141
|
+
def __generate_loc_diagram(self):
|
|
142
|
+
self.sc.log.log("Generate LoC-diagram...")
|
|
143
|
+
loc_metric_folder = os.path.join(self.repository, "Other", "Metrics")
|
|
144
|
+
GeneralUtilities.ensure_directory_exists(loc_metric_folder)
|
|
145
|
+
loc_metric_file = os.path.join(loc_metric_folder, "RepositoryStatisticsPerCommit.csv")
|
|
146
|
+
GeneralUtilities.ensure_file_exists(loc_metric_file)
|
|
147
|
+
|
|
148
|
+
filenamebase="LoC-Diagram"
|
|
149
|
+
|
|
150
|
+
diagram_definition_folder=os.path.join(self.repository, "Other", "Reference","Technical","Diagrams")
|
|
151
|
+
GeneralUtilities.ensure_directory_exists(diagram_definition_folder)
|
|
152
|
+
|
|
153
|
+
diagram_definition_file=os.path.join(diagram_definition_folder,f"{filenamebase}.json")
|
|
154
|
+
GeneralUtilities.ensure_file_exists(diagram_definition_file)
|
|
155
|
+
GeneralUtilities.write_text_to_file(diagram_definition_file,GeneralUtilities.empty_string)
|
|
156
|
+
|
|
157
|
+
loc_data_file=os.path.join(diagram_definition_folder,f"{filenamebase}.csv")
|
|
158
|
+
GeneralUtilities.ensure_file_exists(loc_data_file)
|
|
159
|
+
csv_lines=[]
|
|
160
|
+
for line in GeneralUtilities.read_lines_from_file(loc_metric_file):
|
|
161
|
+
if GeneralUtilities.string_has_content(line):
|
|
162
|
+
splitted=line.split(";")
|
|
163
|
+
v=splitted[0]
|
|
164
|
+
t=splitted[1]
|
|
165
|
+
loc=splitted[2]
|
|
166
|
+
csv_lines.append(f"{v},{t},{loc}")
|
|
167
|
+
GeneralUtilities.write_lines_to_file(loc_data_file,csv_lines)
|
|
168
|
+
diagram_json = {
|
|
169
|
+
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
|
|
170
|
+
"description": "Lines of Code over time",
|
|
171
|
+
"width": 800,
|
|
172
|
+
"height": 400,
|
|
173
|
+
"data": {
|
|
174
|
+
"url": f"./{filenamebase}.csv",
|
|
175
|
+
"format": {
|
|
176
|
+
"type": "csv"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"mark": {
|
|
180
|
+
"type": "line",
|
|
181
|
+
"point": True
|
|
182
|
+
},
|
|
183
|
+
"encoding": {
|
|
184
|
+
"x": {
|
|
185
|
+
"field": "Timestamp",
|
|
186
|
+
"type": "temporal",
|
|
187
|
+
"title": "Date"
|
|
188
|
+
},
|
|
189
|
+
"y": {
|
|
190
|
+
"field": "LinesOfCode",
|
|
191
|
+
"type": "quantitative",
|
|
192
|
+
"title": "Lines of Code"
|
|
193
|
+
},
|
|
194
|
+
"tooltip": [
|
|
195
|
+
{
|
|
196
|
+
"field": "Version",
|
|
197
|
+
"type": "ordinal"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"field": "LinesOfCode",
|
|
201
|
+
"type": "quantitative"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"field": "Timestamp",
|
|
205
|
+
"type": "temporal"
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
with open(diagram_definition_file, "w", encoding="utf-8") as f:
|
|
212
|
+
json.dump(
|
|
213
|
+
diagram_json,
|
|
214
|
+
f,
|
|
215
|
+
indent=2,
|
|
216
|
+
sort_keys=False,
|
|
217
|
+
ensure_ascii=False
|
|
218
|
+
)
|
|
219
|
+
diagram_svg_file=os.path.join(self.repository,"Other","Reference","Technical","Diagrams",f"{filenamebase}.svg")
|
|
220
|
+
GeneralUtilities.ensure_file_exists(diagram_svg_file)
|
|
221
|
+
GeneralUtilities.assert_condition(not self.sc.file_is_git_ignored(f"Other/Reference/Technical/Diagrams/{filenamebase}.svg",self.repository),f"Other/Reference/Technical/Diagrams/{filenamebase}.svg must not be git-ignored")#because it should be referencable in markdown-files and viewable without building the codeunits.
|
|
222
|
+
self.sc.generate_chart_diagram(diagram_definition_file,os.path.basename(diagram_svg_file))
|
|
223
|
+
self.sc.format_xml_file(diagram_svg_file)
|
|
224
|
+
|
|
225
|
+
@GeneralUtilities.check_arguments
|
|
226
|
+
def __search_for_vulnerabilities(self):
|
|
227
|
+
pass#TODO
|
|
228
|
+
|
|
229
|
+
@GeneralUtilities.check_arguments
|
|
230
|
+
def __search_for_secrets(self):
|
|
231
|
+
enabled:bool=False#TODO reenable when a solution is found to ignore false positives
|
|
232
|
+
if enabled:
|
|
233
|
+
exe_paths=self.tfcps_tools_general.ensure_trufflehog_is_available()
|
|
234
|
+
exe_path:str=None
|
|
235
|
+
if GeneralUtilities.current_system_is_windows():
|
|
236
|
+
exe_path=exe_paths["Windows"]
|
|
237
|
+
elif GeneralUtilities.current_system_is_linux():
|
|
238
|
+
exe_path=exe_paths["Linux"]
|
|
239
|
+
else:
|
|
240
|
+
raise ValueError("unsupported")#TODO check for macos
|
|
241
|
+
result=self.sc.run_program(exe_path,"filesystem . --json",self.repository)
|
|
242
|
+
|
|
243
|
+
self.sc.log.log("Secret-scan-result:")#TODO replace this by real analysis
|
|
244
|
+
for line in GeneralUtilities.string_to_lines(result[1]):
|
|
245
|
+
self.sc.log.log(line)
|
|
246
|
+
for line in GeneralUtilities.string_to_lines(result[2]):
|
|
247
|
+
self.sc.log.log(line,LogLevel.Error)
|
|
248
|
+
|
|
249
|
+
@GeneralUtilities.check_arguments
|
|
250
|
+
def use_cache(self) -> bool:
|
|
251
|
+
return self.__use_cache
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@GeneralUtilities.check_arguments
|
|
255
|
+
def is_pre_merge(self) -> bool:
|
|
256
|
+
return self.__is_pre_merge
|
|
257
|
+
|
|
258
|
+
@GeneralUtilities.check_arguments
|
|
259
|
+
def update_dependencies(self) -> None:
|
|
260
|
+
repository=self.repository
|
|
261
|
+
self.sc.log.log("Update dependencies...")
|
|
262
|
+
self.update_year_in_license_file()
|
|
263
|
+
self.sc.assert_is_git_repository(repository)
|
|
264
|
+
self.sc.assert_no_uncommitted_changes(repository)
|
|
265
|
+
self.run_prepare_script()
|
|
266
|
+
if os.path.isfile(os.path.join(repository,"Other","Scripts","UpdateDependencies.py")):
|
|
267
|
+
self.sc.run_program(GeneralUtilities.get_python_executable(),"UpdateDependencies.py",os.path.join(repository,"Other","Scripts"))
|
|
268
|
+
codeunits:list[str]=self.tfcps_tools_general.get_codeunits(repository)
|
|
269
|
+
for codeunit_name in codeunits:
|
|
270
|
+
self.sc.log.log(f"Update dependencies of codeunit {codeunit_name}...")
|
|
271
|
+
codeunit_folder=os.path.join(repository,codeunit_name)
|
|
272
|
+
tFCPS_CodeUnit_BuildCodeUnit:TFCPS_CodeUnit_BuildCodeUnit = TFCPS_CodeUnit_BuildCodeUnit(codeunit_folder,self.sc.log.loglevel,"QualityCheck",None,True,False)
|
|
273
|
+
tFCPS_CodeUnit_BuildCodeUnit.build_codeunit()#ensure requirements for updating are there (some programming-languages needs this)
|
|
274
|
+
if self.tfcps_tools_general.codeunit_has_updatable_dependencies(os.path.join(codeunit_folder,f"{codeunit_name}.codeunit.xml")):
|
|
275
|
+
self.sc.run_program(GeneralUtilities.get_python_executable(),"UpdateDependencies.py",os.path.join(codeunit_folder,"Other"))
|
|
276
|
+
tFCPS_CodeUnit_BuildCodeUnit.build_codeunit()#check if codeunit is still buildable
|
|
277
|
+
if self.sc.git_repository_has_uncommitted_changes(repository):
|
|
278
|
+
changelog_folder = os.path.join(repository, "Other", "Resources", "Changelog")
|
|
279
|
+
project_version:str=self.tfcps_tools_general.get_version_of_project(repository)
|
|
280
|
+
changelog_file = os.path.join(changelog_folder, f"v{project_version}.md")
|
|
281
|
+
if not os.path.isfile(changelog_file):
|
|
282
|
+
self.__ensure_changelog_file_is_added(repository, project_version)
|
|
283
|
+
t=TFCPS_CodeUnit_BuildCodeUnits(repository,self.sc.log.loglevel,"QualityCheck",None,True,False)
|
|
284
|
+
t.build_codeunits()#check codeunits are buildable at all
|
|
285
|
+
self.sc.git_commit(repository, "Updated dependencies", stage_all_changes=True)
|
|
286
|
+
|
|
287
|
+
@GeneralUtilities.check_arguments
|
|
288
|
+
def __ensure_changelog_file_is_added(self, repository_folder: str, version_of_project: str):
|
|
289
|
+
changelog_file = os.path.join(repository_folder, "Other", "Resources", "Changelog", f"v{version_of_project}.md")
|
|
290
|
+
if not os.path.isfile(changelog_file):
|
|
291
|
+
GeneralUtilities.ensure_file_exists(changelog_file)
|
|
292
|
+
GeneralUtilities.write_text_to_file(changelog_file, """# Release notes
|
|
293
|
+
|
|
294
|
+
## Changes
|
|
295
|
+
|
|
296
|
+
- Updated dependencies.
|
|
297
|
+
""")
|
|
298
|
+
|
|
299
|
+
@GeneralUtilities.check_arguments
|
|
300
|
+
def update_year_in_license_file(self) -> None:
|
|
301
|
+
self.sc.update_year_in_first_line_of_file(os.path.join(self.repository, "License.txt"))
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from ..GeneralUtilities import GeneralUtilities
|
|
3
|
+
from ..ScriptCollectionCore import ScriptCollectionCore
|
|
4
|
+
from ..SCLog import LogLevel
|
|
5
|
+
from .TFCPS_Tools_General import TFCPS_Tools_General
|
|
6
|
+
from .TFCPS_MergeToMain import TFCPS_MergeToMain,MergeToMainConfiguration
|
|
7
|
+
from .TFCPS_MergeToStable import TFCPS_MergeToStable,MergeToStableConfiguration
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TFCPS_CreateReleaseConfiguration:
|
|
11
|
+
|
|
12
|
+
product_name: str
|
|
13
|
+
branch_to_be_released:str
|
|
14
|
+
additional_arguments_file:str
|
|
15
|
+
log_level:LogLevel
|
|
16
|
+
main_branch:str
|
|
17
|
+
stable_branch:str
|
|
18
|
+
build_repository:str
|
|
19
|
+
repository:str
|
|
20
|
+
reference_repository:str
|
|
21
|
+
common_remote_name:str
|
|
22
|
+
build_repo_main_branch_name:str
|
|
23
|
+
reference_repo_main_branch_name:str
|
|
24
|
+
reference_remote_name:str
|
|
25
|
+
build_repo_remote_name:str
|
|
26
|
+
artifacts_target_folder:str
|
|
27
|
+
common_remote_url:str
|
|
28
|
+
|
|
29
|
+
def __init__(self, current_file: str, product_name: str,branch_to_be_released:str,log_level:LogLevel,additional_arguments_file:str,main_branch:str,stable_branch:str,common_remote_name:str,build_repo_main_branch_name:str,reference_repo_main_branch_name:str,reference_remote_name:str,build_repo_remote_name:str,artifacts_target_folder:str,common_remote_url:str):
|
|
30
|
+
self.product_name = product_name
|
|
31
|
+
self.branch_to_be_released=branch_to_be_released
|
|
32
|
+
self.additional_arguments_file=additional_arguments_file
|
|
33
|
+
self.log_level=log_level
|
|
34
|
+
self.main_branch=main_branch
|
|
35
|
+
self.stable_branch=stable_branch
|
|
36
|
+
self.build_repository=ScriptCollectionCore().search_repository_folder(current_file)
|
|
37
|
+
self.repository=os.path.join(self.build_repository,"Submodules",product_name)
|
|
38
|
+
self.reference_repository=os.path.join(self.build_repository,"Submodules",product_name+"Reference")
|
|
39
|
+
self.common_remote_name=common_remote_name
|
|
40
|
+
self.build_repo_main_branch_name=build_repo_main_branch_name
|
|
41
|
+
self.reference_repo_main_branch_name=reference_repo_main_branch_name
|
|
42
|
+
self.reference_remote_name=reference_remote_name
|
|
43
|
+
self.build_repo_remote_name=build_repo_remote_name
|
|
44
|
+
self.artifacts_target_folder=artifacts_target_folder
|
|
45
|
+
self.common_remote_url=common_remote_url
|
|
46
|
+
|
|
47
|
+
class TFCPS_CreateRelease:
|
|
48
|
+
|
|
49
|
+
sc:ScriptCollectionCore
|
|
50
|
+
tFCPS_Tools_General:TFCPS_Tools_General
|
|
51
|
+
|
|
52
|
+
def __init__(self):
|
|
53
|
+
self.sc=ScriptCollectionCore()
|
|
54
|
+
self.tFCPS_Tools_General=TFCPS_Tools_General(self.sc)
|
|
55
|
+
|
|
56
|
+
@GeneralUtilities.check_arguments
|
|
57
|
+
def do_release(self,tfcps_CreateReleaseConfiguration:TFCPS_CreateReleaseConfiguration)->bool:
|
|
58
|
+
self.sc.log.loglevel=tfcps_CreateReleaseConfiguration.log_level
|
|
59
|
+
return self.sc.do_and_log_task(f"Release {tfcps_CreateReleaseConfiguration.product_name}",lambda : self.__do(tfcps_CreateReleaseConfiguration))
|
|
60
|
+
|
|
61
|
+
@GeneralUtilities.check_arguments
|
|
62
|
+
def __do(self,tfcps_CreateReleaseConfiguration:TFCPS_CreateReleaseConfiguration)->bool:
|
|
63
|
+
self.sc.log.log("Do checks...",LogLevel.Information)
|
|
64
|
+
|
|
65
|
+
self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.build_repository)
|
|
66
|
+
self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.build_repository)
|
|
67
|
+
|
|
68
|
+
self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.repository)
|
|
69
|
+
self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.repository)
|
|
70
|
+
|
|
71
|
+
self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.reference_repository)
|
|
72
|
+
self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.reference_repository)
|
|
73
|
+
|
|
74
|
+
release_was_done:bool=False
|
|
75
|
+
|
|
76
|
+
branch_to_be_released_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.branch_to_be_released)
|
|
77
|
+
main_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.main_branch)
|
|
78
|
+
if branch_to_be_released_commit_id == main_branch_commit_id:
|
|
79
|
+
self.sc.log.log("Merge to main-branch will not be done because there are no changed which can be merged.")
|
|
80
|
+
else:
|
|
81
|
+
self.sc.log.log("Merge to main-branch...",LogLevel.Information)
|
|
82
|
+
mergeToMainConfiguration:MergeToMainConfiguration=MergeToMainConfiguration(tfcps_CreateReleaseConfiguration.current_file,tfcps_CreateReleaseConfiguration.product_name,tfcps_CreateReleaseConfiguration.product_name,tfcps_CreateReleaseConfiguration.branch_to_be_released,tfcps_CreateReleaseConfiguration.log_level,tfcps_CreateReleaseConfiguration.additional_arguments_file,tfcps_CreateReleaseConfiguration.main_branch,tfcps_CreateReleaseConfiguration.common_remote_name,tfcps_CreateReleaseConfiguration.build_repository)
|
|
83
|
+
tFCPS_MergeToMain:TFCPS_MergeToMain=TFCPS_MergeToMain(mergeToMainConfiguration)
|
|
84
|
+
tFCPS_MergeToMain.merge_to_main_branch()
|
|
85
|
+
|
|
86
|
+
main_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.main_branch)
|
|
87
|
+
stable_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.stable_branch)
|
|
88
|
+
if main_branch_commit_id == stable_branch_commit_id:
|
|
89
|
+
self.sc.log.log("Merge to stable-branch will not be done because there are no changed which can be released.")
|
|
90
|
+
else:
|
|
91
|
+
self.sc.log.log("Merge to stable-branch...",LogLevel.Information)
|
|
92
|
+
mergeToStableConfiguration:MergeToStableConfiguration=MergeToStableConfiguration(tfcps_CreateReleaseConfiguration.log_level,tfcps_CreateReleaseConfiguration.main_branch,tfcps_CreateReleaseConfiguration.stable_branch,tfcps_CreateReleaseConfiguration.repository,tfcps_CreateReleaseConfiguration.build_repository,tfcps_CreateReleaseConfiguration.common_remote_name,tfcps_CreateReleaseConfiguration.build_repo_main_branch_name,tfcps_CreateReleaseConfiguration.reference_repo_main_branch_name,tfcps_CreateReleaseConfiguration.reference_remote_name,tfcps_CreateReleaseConfiguration.build_repo_remote_name,tfcps_CreateReleaseConfiguration.artifacts_target_folder,tfcps_CreateReleaseConfiguration.common_remote_url,tfcps_CreateReleaseConfiguration.additional_arguments_file)
|
|
93
|
+
tFCPS_MergeToStable:TFCPS_MergeToStable=TFCPS_MergeToStable(mergeToStableConfiguration)
|
|
94
|
+
tFCPS_MergeToStable.merge_to_stable_branch()
|
|
95
|
+
|
|
96
|
+
release_was_done=True
|
|
97
|
+
|
|
98
|
+
return release_was_done
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from ..ScriptCollectionCore import ScriptCollectionCore
|
|
3
|
+
from ..SCLog import LogLevel
|
|
4
|
+
from .TFCPS_Tools_General import TFCPS_Tools_General
|
|
5
|
+
|
|
6
|
+
class TFCPS_Generic_Functions:
|
|
7
|
+
script_file:str
|
|
8
|
+
repository_folder:str=None
|
|
9
|
+
targetenvironmenttype:str
|
|
10
|
+
additionalargumentsfile:str
|
|
11
|
+
verbosity:LogLevel
|
|
12
|
+
sc:ScriptCollectionCore
|
|
13
|
+
tfcps_Tools_General:TFCPS_Tools_General
|
|
14
|
+
__use_cache:bool
|
|
15
|
+
|
|
16
|
+
def __init__(self,script_file:str,targetenvironmenttype:str,additionalargumentsfile:str,verbosity:LogLevel,use_cache:bool):
|
|
17
|
+
self.verbosity=verbosity
|
|
18
|
+
self.script_file=script_file
|
|
19
|
+
self.sc=ScriptCollectionCore()
|
|
20
|
+
self.sc.log.loglevel=self.verbosity
|
|
21
|
+
self.tfcps_Tools_General=TFCPS_Tools_General(self.sc)
|
|
22
|
+
self.repository_folder=self.sc.search_repository_folder(script_file)
|
|
23
|
+
self.targetenvironmenttype=targetenvironmenttype
|
|
24
|
+
self.__use_cache=use_cache
|
|
25
|
+
self.additionalargumentsfile=additionalargumentsfile
|
|
26
|
+
|
|
27
|
+
def use_cache(self)->bool:
|
|
28
|
+
return self.__use_cache
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TFCPS_Generic_CLI:
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def parse(file:str)->TFCPS_Generic_Functions:
|
|
35
|
+
parser = argparse.ArgumentParser()
|
|
36
|
+
verbosity_values = ", ".join(f"{lvl.value}={lvl.name}" for lvl in LogLevel)
|
|
37
|
+
parser.add_argument('-r', '--repository', required=False, default=None)
|
|
38
|
+
parser.add_argument('-e', '--targetenvironmenttype', required=False, default="QualityCheck")
|
|
39
|
+
parser.add_argument('-a', '--additionalargumentsfile', required=False, default=None)
|
|
40
|
+
parser.add_argument('-v', '--verbosity', required=False, default=3, help=f"Sets the loglevel. Possible values: {verbosity_values}")
|
|
41
|
+
parser.add_argument('-c', '--nocache', action='store_true', required=False, default=False)
|
|
42
|
+
args=parser.parse_args()
|
|
43
|
+
result:TFCPS_Generic_Functions=TFCPS_Generic_Functions(file,args.targetenvironmenttype,args.additionalargumentsfile,LogLevel(int(args.verbosity)),not args.nocache)
|
|
44
|
+
return result
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
from ..GeneralUtilities import GeneralUtilities
|
|
4
|
+
from ..SCLog import LogLevel
|
|
5
|
+
from ..ScriptCollectionCore import ScriptCollectionCore
|
|
6
|
+
from .TFCPS_Tools_General import TFCPS_Tools_General
|
|
7
|
+
from .TFCPS_CodeUnit_BuildCodeUnits import TFCPS_CodeUnit_BuildCodeUnits
|
|
8
|
+
from .TFCPS_Generic import TFCPS_Generic_Functions
|
|
9
|
+
|
|
10
|
+
class MergeToMainConfiguration:
|
|
11
|
+
product_name: str
|
|
12
|
+
merge_source_branch:str
|
|
13
|
+
additional_arguments_file:str
|
|
14
|
+
log_level:LogLevel
|
|
15
|
+
main_branch:str
|
|
16
|
+
repository_folder:str
|
|
17
|
+
tFCPS_Generic_Functions:TFCPS_Generic_Functions
|
|
18
|
+
common_remote_name:str
|
|
19
|
+
build_repo:str
|
|
20
|
+
sc:ScriptCollectionCore=ScriptCollectionCore()
|
|
21
|
+
|
|
22
|
+
def __init__(self, current_file: str,repository:str, product_name: str,merge_source_branch:str,log_level:LogLevel,additional_arguments_file:str,main_branch:str,common_remote_name:str,build_repo:str):
|
|
23
|
+
self.sc.log.loglevel=log_level
|
|
24
|
+
self.repository_folder = repository
|
|
25
|
+
self.product_name = product_name
|
|
26
|
+
self.merge_source_branch=merge_source_branch
|
|
27
|
+
self.additional_arguments_file=additional_arguments_file
|
|
28
|
+
self.log_level=log_level
|
|
29
|
+
self.main_branch=main_branch
|
|
30
|
+
self.common_remote_name=common_remote_name
|
|
31
|
+
self.build_repo=build_repo
|
|
32
|
+
|
|
33
|
+
class TFCPS_MergeToMain:
|
|
34
|
+
|
|
35
|
+
sc:ScriptCollectionCore
|
|
36
|
+
tFCPS_Tools_General:TFCPS_Tools_General
|
|
37
|
+
generic_prepare_new_release_arguments:MergeToMainConfiguration=None
|
|
38
|
+
|
|
39
|
+
def __init__(self,generic_prepare_new_release_arguments:MergeToMainConfiguration):
|
|
40
|
+
self.sc=ScriptCollectionCore()
|
|
41
|
+
self.tFCPS_Tools_General=TFCPS_Tools_General(self.sc)
|
|
42
|
+
self.generic_prepare_new_release_arguments=generic_prepare_new_release_arguments
|
|
43
|
+
|
|
44
|
+
@GeneralUtilities.check_arguments
|
|
45
|
+
def merge_to_main_branch(self ) -> None:
|
|
46
|
+
self.sc.log.loglevel=self.generic_prepare_new_release_arguments.log_level
|
|
47
|
+
self.sc.log.log("Merge to main-branch...")
|
|
48
|
+
fast_forward_source_branch: bool=True
|
|
49
|
+
source_branch: str=self.generic_prepare_new_release_arguments.merge_source_branch
|
|
50
|
+
target_branch: str=self.generic_prepare_new_release_arguments.main_branch
|
|
51
|
+
self.sc.assert_is_git_repository(self.generic_prepare_new_release_arguments.repository_folder)
|
|
52
|
+
|
|
53
|
+
if self.sc.git_get_commit_id(self.generic_prepare_new_release_arguments.repository_folder,source_branch)==self.sc.git_get_commit_id(self.generic_prepare_new_release_arguments.repository_folder,target_branch):
|
|
54
|
+
self.sc.log.log("Source- and target-branch are on the same commit.")
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
self.sc.assert_no_uncommitted_changes(self.generic_prepare_new_release_arguments.repository_folder)
|
|
58
|
+
self.sc.git_checkout(self.generic_prepare_new_release_arguments.repository_folder, source_branch)
|
|
59
|
+
self.sc.assert_no_uncommitted_changes(self.generic_prepare_new_release_arguments.repository_folder)
|
|
60
|
+
|
|
61
|
+
#premerge-build
|
|
62
|
+
#TODO the premerge-build is now supposed to be in MergeToStable
|
|
63
|
+
try:
|
|
64
|
+
tfcps_CodeUnit_BuildCodeUnits:TFCPS_CodeUnit_BuildCodeUnits=TFCPS_CodeUnit_BuildCodeUnits(self.generic_prepare_new_release_arguments.repository_folder,self.sc.log.loglevel,"QualityCheck",self.generic_prepare_new_release_arguments.additional_arguments_file,False,True)
|
|
65
|
+
tfcps_CodeUnit_BuildCodeUnits.build_codeunits()
|
|
66
|
+
except Exception:
|
|
67
|
+
self.sc.log.log(f"Branch {source_branch} is not buildable.",LogLevel.Error)
|
|
68
|
+
self.sc.git_undo_all_changes(self.generic_prepare_new_release_arguments.repository_folder)
|
|
69
|
+
raise
|
|
70
|
+
self.sc.git_commit(self.generic_prepare_new_release_arguments.repository_folder, 'Pre-merge-commit', stage_all_changes=True, no_changes_behavior=0)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if fast_forward_source_branch:
|
|
74
|
+
self.sc.git_checkout(self.generic_prepare_new_release_arguments.repository_folder, source_branch)
|
|
75
|
+
project_version:str=self.tFCPS_Tools_General.get_version_of_project(self.generic_prepare_new_release_arguments.repository_folder)
|
|
76
|
+
self.sc.git_merge(self.generic_prepare_new_release_arguments.repository_folder, source_branch, target_branch, False, True)
|
|
77
|
+
self.sc.git_merge(self.generic_prepare_new_release_arguments.repository_folder, target_branch, source_branch, True, True)
|
|
78
|
+
self.sc.git_create_tag(self.generic_prepare_new_release_arguments.repository_folder,target_branch,f"v{project_version}")
|
|
79
|
+
|
|
80
|
+
self.sc.log.log("Push branches...")
|
|
81
|
+
self.sc.git_push_with_retry(self.generic_prepare_new_release_arguments.repository_folder,self.generic_prepare_new_release_arguments.common_remote_name,source_branch,source_branch)
|
|
82
|
+
self.sc.git_push_with_retry(self.generic_prepare_new_release_arguments.repository_folder,self.generic_prepare_new_release_arguments.common_remote_name,target_branch,target_branch)
|
|
83
|
+
self.sc.git_commit(self.generic_prepare_new_release_arguments.build_repo,"Updated submodule")
|
|
84
|
+
|
|
85
|
+
class TFCPS_MergeToMain_CLI:
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
@GeneralUtilities.check_arguments
|
|
89
|
+
def get_with_overwritable_defaults(file:str,default_merge_source_branch:str=None,default_loglevel:LogLevel=None,default_additionalargumentsfile:str=None,default_main_branch:str=None,default_common_remote_name:str=None)->TFCPS_MergeToMain:
|
|
90
|
+
parser = argparse.ArgumentParser()
|
|
91
|
+
verbosity_values = ", ".join(f"{lvl.value}={lvl.name}" for lvl in LogLevel)
|
|
92
|
+
parser.add_argument('-s', '--mergesourcebranch', required=False)
|
|
93
|
+
parser.add_argument('-a', '--additionalargumentsfile', required=False)
|
|
94
|
+
parser.add_argument('-t', '--mainbranch', required=False)
|
|
95
|
+
parser.add_argument('-r', '--commonremotename', required=False)
|
|
96
|
+
parser.add_argument('-v', '--verbosity', required=False, help=f"Sets the loglevel. Possible values: {verbosity_values}")
|
|
97
|
+
args=parser.parse_args()
|
|
98
|
+
|
|
99
|
+
sc:ScriptCollectionCore=ScriptCollectionCore()
|
|
100
|
+
|
|
101
|
+
build_repo=GeneralUtilities.resolve_relative_path("../../..",file)
|
|
102
|
+
sc.assert_is_git_repository(build_repo)
|
|
103
|
+
|
|
104
|
+
default_product_name=os.path.basename(build_repo)[:-len("Build")]
|
|
105
|
+
|
|
106
|
+
if args.mergesourcebranch is not None:
|
|
107
|
+
default_merge_source_branch=args.mergesourcebranch#other/next-release
|
|
108
|
+
GeneralUtilities.assert_not_null(default_merge_source_branch,"mergesourcebranch is not set")
|
|
109
|
+
|
|
110
|
+
if args.verbosity is not None:
|
|
111
|
+
default_loglevel=LogLevel(int( args.verbosity))
|
|
112
|
+
GeneralUtilities.assert_not_null(default_loglevel,"verbosity is not set")
|
|
113
|
+
|
|
114
|
+
if args.additionalargumentsfile is not None:
|
|
115
|
+
default_additionalargumentsfile=args.additionalargumentsfile
|
|
116
|
+
|
|
117
|
+
if args.mainbranch is not None:
|
|
118
|
+
default_main_branch=args.mainbranch#main
|
|
119
|
+
GeneralUtilities.assert_not_null(default_main_branch,"mainbranch is not set")
|
|
120
|
+
|
|
121
|
+
if args.commonremotename is not None:
|
|
122
|
+
default_common_remote_name=args.commonremotename
|
|
123
|
+
GeneralUtilities.assert_not_null(default_common_remote_name,"commonremotename is not set")
|
|
124
|
+
|
|
125
|
+
repository=os.path.join(build_repo,"Submodules",default_product_name)
|
|
126
|
+
config:MergeToMainConfiguration=MergeToMainConfiguration(file,repository,default_product_name,default_merge_source_branch,default_loglevel,default_additionalargumentsfile,default_main_branch,default_common_remote_name,build_repo)
|
|
127
|
+
tFCPS_MergeToMain:TFCPS_MergeToMain=TFCPS_MergeToMain(config)
|
|
128
|
+
return tFCPS_MergeToMain
|