ScriptCollection 4.0.11__py3-none-any.whl → 4.0.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. ScriptCollection/AnionBuildPlatform.py +2 -0
  2. ScriptCollection/ScriptCollectionCore.py +1 -1
  3. ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +88 -0
  4. ScriptCollection/TFCPS/Docker/__init__.py +0 -0
  5. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationBase.py +8 -0
  6. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationGenerate.py +6 -0
  7. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationNoGenerate.py +7 -0
  8. ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py +479 -0
  9. ScriptCollection/TFCPS/DotNet/__init__.py +0 -0
  10. ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +43 -0
  11. ScriptCollection/TFCPS/Flutter/__init__.py +0 -0
  12. ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +123 -0
  13. ScriptCollection/TFCPS/NodeJS/__init__.py +0 -0
  14. ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py +114 -0
  15. ScriptCollection/TFCPS/Python/__init__.py +0 -0
  16. ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +417 -0
  17. ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py +120 -0
  18. ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +80 -0
  19. ScriptCollection/TFCPS/TFCPS_CreateRelease.py +97 -0
  20. ScriptCollection/TFCPS/TFCPS_Generic.py +43 -0
  21. ScriptCollection/TFCPS/TFCPS_MergeToMain.py +125 -0
  22. ScriptCollection/TFCPS/TFCPS_MergeToStable.py +361 -0
  23. ScriptCollection/TFCPS/TFCPS_Tools_Dependencies.py +16 -0
  24. ScriptCollection/TFCPS/TFCPS_Tools_General.py +1076 -0
  25. ScriptCollection/TFCPS/__init__.py +0 -0
  26. {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/METADATA +1 -1
  27. scriptcollection-4.0.13.dist-info/RECORD +41 -0
  28. scriptcollection-4.0.11.dist-info/RECORD +0 -17
  29. {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/WHEEL +0 -0
  30. {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/entry_points.txt +0 -0
  31. {scriptcollection-4.0.11.dist-info → scriptcollection-4.0.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,97 @@
1
+ import os
2
+ from ..ScriptCollectionCore import ScriptCollectionCore
3
+ from ..SCLog import LogLevel
4
+ from .TFCPS_Tools_General import TFCPS_Tools_General
5
+ from .TFCPS_MergeToMain import TFCPS_MergeToMain,MergeToMainConfiguration
6
+ from .TFCPS_MergeToStable import TFCPS_MergeToStable,MergeToStableConfiguration
7
+
8
+
9
+ class TFCPS_CreateReleaseConfiguration:
10
+
11
+ product_name: str
12
+ branch_to_be_released:str
13
+ additional_arguments_file:str
14
+ log_level:LogLevel
15
+ main_branch:str
16
+ stable_branch:str
17
+ build_repository:str
18
+ repository:str
19
+ reference_repository:str
20
+ reference_repo: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,reference_repo: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.reference_repo=reference_repo
40
+ self.common_remote_name=common_remote_name
41
+ self.build_repo_main_branch_name=build_repo_main_branch_name
42
+ self.reference_repo_main_branch_name=reference_repo_main_branch_name
43
+ self.reference_remote_name=reference_remote_name
44
+ self.build_repo_remote_name=build_repo_remote_name
45
+ self.artifacts_target_folder=artifacts_target_folder
46
+ self.common_remote_url=common_remote_url
47
+
48
+ class TFCPS_CreateRelease:
49
+
50
+ sc:ScriptCollectionCore
51
+ tFCPS_Tools_General:TFCPS_Tools_General
52
+
53
+ def __init__(self):
54
+ self.sc=ScriptCollectionCore()
55
+ self.tFCPS_Tools_General=TFCPS_Tools_General(self.sc)
56
+
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
+ def __do(self,tfcps_CreateReleaseConfiguration:TFCPS_CreateReleaseConfiguration)->bool:
62
+ self.sc.log.log("Do checks...",LogLevel.Information)
63
+
64
+ self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.build_repository)
65
+ self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.build_repository)
66
+
67
+ self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.repository)
68
+ self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.repository)
69
+
70
+ self.sc.assert_is_git_repository(tfcps_CreateReleaseConfiguration.reference_repository)
71
+ self.sc.assert_no_uncommitted_changes(tfcps_CreateReleaseConfiguration.reference_repository)
72
+
73
+ release_was_done:bool=False
74
+
75
+ branch_to_be_released_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.branch_to_be_released)
76
+ main_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.main_branch)
77
+ if branch_to_be_released_commit_id == main_branch_commit_id:
78
+ self.sc.log.log("Merge to main-branch will not be done because there are no changed which can be merged.")
79
+ else:
80
+ self.sc.log.log("Merge to main-branch...",LogLevel.Information)
81
+ 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)
82
+ tFCPS_MergeToMain:TFCPS_MergeToMain=TFCPS_MergeToMain(mergeToMainConfiguration)
83
+ tFCPS_MergeToMain.merge_to_main_branch()
84
+
85
+ main_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.main_branch)
86
+ stable_branch_commit_id = self.sc.git_get_commit_id(tfcps_CreateReleaseConfiguration.repository, tfcps_CreateReleaseConfiguration.stable_branch)
87
+ if main_branch_commit_id == stable_branch_commit_id:
88
+ self.sc.log.log("Merge to stable-branch will not be done because there are no changed which can be released.")
89
+ else:
90
+ self.sc.log.log("Merge to stable-branch...",LogLevel.Information)
91
+ mergeToStableConfiguration:MergeToStableConfiguration=MergeToStableConfiguration(tfcps_CreateReleaseConfiguration.log_level,tfcps_CreateReleaseConfiguration.main_branch,tfcps_CreateReleaseConfiguration.stable_branch,tfcps_CreateReleaseConfiguration.repository,tfcps_CreateReleaseConfiguration.build_repository,tfcps_CreateReleaseConfiguration.reference_repo,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.product_name,tfcps_CreateReleaseConfiguration.common_remote_url,tfcps_CreateReleaseConfiguration.additional_arguments_file)
92
+ tFCPS_MergeToStable:TFCPS_MergeToStable=TFCPS_MergeToStable(mergeToStableConfiguration)
93
+ tFCPS_MergeToStable.merge_to_stable_branch()
94
+
95
+ release_was_done=True
96
+
97
+ return release_was_done
@@ -0,0 +1,43 @@
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('-e', '--targetenvironmenttype', required=False, default="QualityCheck")
38
+ parser.add_argument('-a', '--additionalargumentsfile', required=False, default=None)
39
+ parser.add_argument('-v', '--verbosity', required=False, default=3, help=f"Sets the loglevel. Possible values: {verbosity_values}")
40
+ parser.add_argument('-c', '--nocache', action='store_true', required=False, default=False)
41
+ args=parser.parse_args()
42
+ result:TFCPS_Generic_Functions=TFCPS_Generic_Functions(file,args.targetenvironmenttype,args.additionalargumentsfile,LogLevel(int(args.verbosity)),not args.nocache)
43
+ return result
@@ -0,0 +1,125 @@
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
+ sc:ScriptCollectionCore=ScriptCollectionCore()
20
+
21
+ 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):
22
+ self.sc.log.loglevel=log_level
23
+ self.repository_folder = repository
24
+ self.product_name = product_name
25
+ self.merge_source_branch=merge_source_branch
26
+ self.additional_arguments_file=additional_arguments_file
27
+ self.log_level=log_level
28
+ self.main_branch=main_branch
29
+ self.common_remote_name=common_remote_name
30
+
31
+ class TFCPS_MergeToMain:
32
+
33
+ sc:ScriptCollectionCore
34
+ tFCPS_Tools_General:TFCPS_Tools_General
35
+ generic_prepare_new_release_arguments:MergeToMainConfiguration=None
36
+
37
+ def __init__(self,generic_prepare_new_release_arguments:MergeToMainConfiguration):
38
+ self.sc=ScriptCollectionCore()
39
+ self.tFCPS_Tools_General=TFCPS_Tools_General(self.sc)
40
+ self.generic_prepare_new_release_arguments=generic_prepare_new_release_arguments
41
+
42
+ @GeneralUtilities.check_arguments
43
+ def merge_to_main_branch(self ) -> None:
44
+ self.sc.log.loglevel=self.generic_prepare_new_release_arguments.log_level
45
+ self.sc.log.log("Merge to main-branch...")
46
+ fast_forward_source_branch: bool=True
47
+ source_branch: str=self.generic_prepare_new_release_arguments.merge_source_branch
48
+ target_branch: str=self.generic_prepare_new_release_arguments.main_branch
49
+ self.sc.assert_is_git_repository(self.generic_prepare_new_release_arguments.repository_folder)
50
+
51
+ GeneralUtilities.assert_condition(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),"Source- and target-branch must not be the same commit.")
52
+
53
+ self.sc.assert_no_uncommitted_changes(self.generic_prepare_new_release_arguments.repository_folder)
54
+ self.sc.git_checkout(self.generic_prepare_new_release_arguments.repository_folder, source_branch)
55
+ self.sc.assert_no_uncommitted_changes(self.generic_prepare_new_release_arguments.repository_folder)
56
+
57
+ 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)
58
+ try:
59
+ tfcps_CodeUnit_BuildCodeUnits.build_codeunits()
60
+ except Exception:
61
+ self.sc.git_undo_all_changes(self.generic_prepare_new_release_arguments.repository_folder)
62
+ raise
63
+
64
+ self.sc.git_commit(self.generic_prepare_new_release_arguments.repository_folder, 'Built codeunits', stage_all_changes=True, no_changes_behavior=0)
65
+
66
+ if fast_forward_source_branch:
67
+ self.sc.git_checkout(self.generic_prepare_new_release_arguments.repository_folder, source_branch)
68
+ project_version:str=self.tFCPS_Tools_General.get_version_of_project(self.generic_prepare_new_release_arguments.repository_folder)
69
+ self.sc.git_merge(self.generic_prepare_new_release_arguments.repository_folder, source_branch, target_branch, False, True)
70
+ self.sc.git_merge(self.generic_prepare_new_release_arguments.repository_folder, target_branch, source_branch, True, True)
71
+ self.sc.git_create_tag(self.generic_prepare_new_release_arguments.repository_folder,target_branch,f"v{project_version}")
72
+
73
+ self.sc.log.log("Push branches...")
74
+ 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)
75
+ 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)
76
+
77
+ class TFCPS_MergeToMain_CLI:
78
+
79
+ @staticmethod
80
+ def get_with_overwritable_defaults(file:str,default_product_name:str=None,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:
81
+ parser = argparse.ArgumentParser()
82
+ verbosity_values = ", ".join(f"{lvl.value}={lvl.name}" for lvl in LogLevel)
83
+ parser.add_argument('-n', '--productname', required=False,default=None)
84
+ parser.add_argument('-s', '--mergesourcebranch', required=False)
85
+ parser.add_argument('-e', '--targetenvironmenttype', required=False, default="QualityCheck")
86
+ parser.add_argument('-a', '--additionalargumentsfile', required=False, default=None)
87
+ parser.add_argument('-t', '--mainbranch', required=False, default="main")
88
+ parser.add_argument('-r', '--commonremotename', required=False, default=None)
89
+ parser.add_argument('-v', '--verbosity', required=False, default=3, help=f"Sets the loglevel. Possible values: {verbosity_values}")
90
+ args=parser.parse_args()
91
+
92
+ sc:ScriptCollectionCore=ScriptCollectionCore()
93
+
94
+ build_repo=GeneralUtilities.resolve_relative_path("../../..",file)
95
+ sc.assert_is_git_repository(build_repo)
96
+
97
+ if args.productname is not None:
98
+ default_product_name=args.productname
99
+ if default_product_name is None:
100
+ default_product_name=os.path.basename(build_repo)[:-len("Build")]
101
+ GeneralUtilities.assert_not_null(default_product_name,"productname is not set")
102
+
103
+ if args.mergesourcebranch is not None:
104
+ default_merge_source_branch=args.mergesourcebranch#other/next-release
105
+ GeneralUtilities.assert_not_null(default_merge_source_branch,"mergesourcebranch is not set")
106
+
107
+ if args.verbosity is not None:
108
+ default_loglevel=LogLevel(int( args.verbosity))
109
+ GeneralUtilities.assert_not_null(default_merge_source_branch,"verbosity is not set")
110
+
111
+ if args.additionalargumentsfile is not None:
112
+ default_additionalargumentsfile=args.additionalargumentsfile
113
+
114
+ if args.mainbranch is not None:
115
+ default_main_branch=args.mainbranch#main
116
+ GeneralUtilities.assert_not_null(default_main_branch,"mainbranch is not set")
117
+
118
+ if args.commonremotename is not None:
119
+ default_common_remote_name=args.commonremotename
120
+ GeneralUtilities.assert_not_null(default_common_remote_name,"commonremotename is not set")
121
+
122
+ repository=os.path.join(build_repo,"Submodules",default_product_name)
123
+ config:MergeToMainConfiguration=MergeToMainConfiguration(file,repository,default_product_name,default_merge_source_branch,default_loglevel,default_additionalargumentsfile,default_main_branch,default_common_remote_name)
124
+ tFCPS_MergeToMain:TFCPS_MergeToMain=TFCPS_MergeToMain(config)
125
+ return tFCPS_MergeToMain
@@ -0,0 +1,361 @@
1
+ import argparse
2
+ import os
3
+ import shutil
4
+ from functools import cmp_to_key
5
+ from ..GeneralUtilities import GeneralUtilities
6
+ from ..ScriptCollectionCore import ScriptCollectionCore
7
+ from ..SCLog import LogLevel
8
+ from .TFCPS_Tools_General import TFCPS_Tools_General
9
+ from .TFCPS_MergeToMain import TFCPS_MergeToMain
10
+ from .TFCPS_CodeUnit_BuildCodeUnits import TFCPS_CodeUnit_BuildCodeUnits
11
+
12
+
13
+
14
+ class MergeToStableConfiguration:
15
+ log_level:LogLevel
16
+ source_branch:str#main
17
+ target_branch:str#stable
18
+ repository:str
19
+ build_repo:str
20
+ reference_repo: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
+ product_name:str
28
+ common_remote_url:str
29
+ additional_arguments_file:str
30
+
31
+ def __init__(self,loglevel:LogLevel,source_branch:str,target_branch:str,repository:str,build_repo:str,reference_repo: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,product_name:str,common_remote_url:str,additional_arguments_file:str):
32
+ self.log_level=loglevel
33
+ self.source_branch=source_branch
34
+ self.target_branch=target_branch
35
+ self.repository=repository
36
+ self.build_repo=build_repo
37
+ self.reference_repo=reference_repo
38
+ self.common_remote_name=common_remote_name
39
+ self.build_repo_main_branch_name=build_repo_main_branch_name
40
+ self.reference_repo_main_branch_name=reference_repo_main_branch_name
41
+ self.reference_remote_name=reference_remote_name
42
+ self.build_repo_remote_name=build_repo_remote_name
43
+ self.artifacts_target_folder=artifacts_target_folder
44
+ self.product_name=product_name
45
+ self.common_remote_url=common_remote_url
46
+ self.additional_arguments_file=additional_arguments_file
47
+
48
+ class TFCPS_MergeToStable:
49
+
50
+ sc:ScriptCollectionCore
51
+ tFCPS_Tools_General:TFCPS_Tools_General
52
+ createRelease_configuration: MergeToStableConfiguration
53
+
54
+ def __init__(self, createRelease_configuration: MergeToStableConfiguration):
55
+ self.sc=ScriptCollectionCore()
56
+ self.tFCPS_Tools_General=TFCPS_Tools_General(self.sc)
57
+ self.createRelease_configuration=createRelease_configuration
58
+
59
+ @GeneralUtilities.check_arguments
60
+ def merge_to_stable_branch(self):
61
+ self.sc.log.loglevel=self.createRelease_configuration.log_level
62
+ self.sc.log.log("Merge to stable-branch...")
63
+ product_name:str=self.createRelease_configuration.product_name
64
+
65
+ GeneralUtilities.assert_condition(self.sc.git_get_commit_id(self.createRelease_configuration.repository,self.createRelease_configuration.source_branch)!=self.sc.git_get_commit_id(self.createRelease_configuration.repository,self.createRelease_configuration.target_branch),"Source- and target-branch must not be the same commit.")
66
+
67
+ self.sc.assert_is_git_repository(self.createRelease_configuration.repository)
68
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.repository)
69
+ self.sc.git_checkout(self.createRelease_configuration.repository, self.createRelease_configuration.source_branch)
70
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.repository)
71
+
72
+ self.sc.assert_is_git_repository(self.createRelease_configuration.reference_repo)
73
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.reference_repo)
74
+
75
+ self.sc.assert_is_git_repository(self.createRelease_configuration.build_repo)
76
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.build_repo)
77
+
78
+ product_version:str=self.tFCPS_Tools_General.get_version_of_project(self.createRelease_configuration.repository)
79
+
80
+ tfcps_CodeUnit_BuildCodeUnits:TFCPS_CodeUnit_BuildCodeUnits=TFCPS_CodeUnit_BuildCodeUnits(self.createRelease_configuration.repository,self.sc.log.loglevel,"Productive",self.createRelease_configuration.additional_arguments_file,False,False)
81
+ try:
82
+ tfcps_CodeUnit_BuildCodeUnits.build_codeunits()
83
+ except Exception:
84
+ self.sc.git_undo_all_changes(self.createRelease_configuration.repository)
85
+ raise
86
+
87
+ eov_enabled=False
88
+ if eov_enabled:
89
+ self.sc.log.log("Remove outdated versions...")
90
+ self.__remove_outdated_version()
91
+
92
+ self.sc.log.log("Release artifacts...")
93
+ for codeunit in self.tFCPS_Tools_General.get_codeunits(self.createRelease_configuration.repository):
94
+ self.sc.git_checkout(self.createRelease_configuration.repository, self.createRelease_configuration.source_branch, True,True)
95
+ if self.createRelease_configuration.artifacts_target_folder is not None:
96
+ #export artifacts to local target folder
97
+ self.sc.log.log(f"Export artifacts of codeunit {codeunit} to target-folder...")
98
+ source_folder:str=GeneralUtilities.resolve_relative_path(f"./{codeunit}/Other/Artifacts",self.createRelease_configuration.repository)
99
+ target_folder:str=GeneralUtilities.resolve_relative_path(f"./{product_name}/{product_version}/{codeunit}",self.createRelease_configuration.artifacts_target_folder)
100
+ GeneralUtilities.ensure_directory_exists(target_folder)
101
+ codeunit_version:str=self.tFCPS_Tools_General.get_version_of_codeunit(os.path.join(self.createRelease_configuration.repository,codeunit,f"{codeunit}.codeunit.xml"))
102
+ target_file:str=os.path.join(target_folder,f"{codeunit}.v{codeunit_version}.Artifacts.zip")
103
+ self.sc.run_program("tar",f"-cf {target_file} -C {source_folder} .")
104
+
105
+ #push artifacts
106
+ push_script:str=os.path.join( self.createRelease_configuration.build_repo,"Scripts","CreateRelease",f"PushArtifacts.{codeunit}.py")
107
+ if os.path.isfile(push_script):
108
+ self.sc.log.log(f"Push artifacts of codeunit {codeunit}...")
109
+ self.sc.run_program("python3",os.path.basename(push_script),os.path.dirname(push_script))
110
+ else:
111
+ self.sc.log.log(f"Codeunit {codeunit} does not have artifacts to push. (Scriptfile \"{push_script}\" does not exist.)",LogLevel.Debug)
112
+
113
+ # Generate reference
114
+ self.sc.log.log(f"Release artifacts of codeunit {codeunit}...")
115
+ reference_folder:str=os.path.join(self.createRelease_configuration.reference_repo,"ReferenceContent")
116
+ repository:str=self.createRelease_configuration.repository
117
+ project_version:str=self.tFCPS_Tools_General.get_version_of_project(repository)
118
+ projectname:str=self.createRelease_configuration.product_name
119
+ public_repository_url:str=self.createRelease_configuration.common_remote_url
120
+ main_branch_name:str=self.createRelease_configuration.source_branch
121
+ codeunit_version=self.tFCPS_Tools_General.get_version_of_codeunit(os.path.join(repository,codeunit,f"{codeunit}.codeunit.xml"))
122
+ self.__export_codeunit_reference_content_to_reference_repository(f"v{project_version}", False, reference_folder, repository, codeunit, projectname, codeunit_version, public_repository_url, f"v{project_version}")
123
+ self.__export_codeunit_reference_content_to_reference_repository("Latest", True, reference_folder, repository, codeunit, projectname, codeunit_version, public_repository_url, main_branch_name)
124
+ self.__generate_entire_reference(projectname, project_version, reference_folder)
125
+
126
+ self.sc.log.log("Finishing merging to stable...")
127
+ self.sc.git_commit(self.createRelease_configuration.reference_repo,f"Added reference for v{project_version}")
128
+
129
+ self.sc.git_merge(self.createRelease_configuration.repository, self.createRelease_configuration.source_branch,self.createRelease_configuration.target_branch, True,True,None,True,True)
130
+
131
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.repository)
132
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.reference_repo)
133
+ self.sc.assert_no_uncommitted_changes(self.createRelease_configuration.build_repo)
134
+
135
+ self.sc.git_push_with_retry(self.createRelease_configuration.repository,self.createRelease_configuration.common_remote_name,self.createRelease_configuration.target_branch,self.createRelease_configuration.target_branch)
136
+ self.sc.git_push_with_retry(self.createRelease_configuration.build_repo,self.createRelease_configuration.build_repo_remote_name,self.createRelease_configuration.build_repo_main_branch_name,self.createRelease_configuration.build_repo_main_branch_name)
137
+ self.sc.git_push_with_retry(self.createRelease_configuration.reference_repo,self.createRelease_configuration.reference_remote_name,self.createRelease_configuration.reference_repo_main_branch_name,self.createRelease_configuration.reference_repo_main_branch_name)
138
+
139
+ def __remove_outdated_version(self):
140
+ now = GeneralUtilities.get_now()
141
+ for unsupported_version in self.tFCPS_Tools_General.get_unsupported_versions(self.createRelease_configuration.repository, now):
142
+ unsupported_reference_folder = f"{self.createRelease_configuration.reference_repo}/ReferenceContent/v{unsupported_version[0]}"
143
+ GeneralUtilities.ensure_directory_does_not_exist(unsupported_reference_folder)
144
+
145
+
146
+ @GeneralUtilities.check_arguments
147
+ def __generate_entire_reference(self, projectname: str, project_version: str, reference_folder: str) -> None:
148
+ all_available_version_identifier_folders_of_reference: list[str] = list(folder for folder in GeneralUtilities.get_direct_folders_of_folder(reference_folder))
149
+ all_available_version_identifier_folders_of_reference = sorted(all_available_version_identifier_folders_of_reference, key=cmp_to_key(TFCPS_Tools_General.sort_reference_folder))
150
+ reference_versions_html_lines = []
151
+ reference_versions_html_lines.append(' <hr/>')
152
+ for all_available_version_identifier_folder_of_reference in all_available_version_identifier_folders_of_reference:
153
+ version_identifier_of_project = os.path.basename(all_available_version_identifier_folder_of_reference)
154
+ if version_identifier_of_project == "Latest":
155
+ latest_version_hint = f" (v{project_version})"
156
+ else:
157
+ latest_version_hint = GeneralUtilities.empty_string
158
+ reference_versions_html_lines.append(f' <h2>{version_identifier_of_project}{latest_version_hint}</h2>')
159
+ reference_versions_html_lines.append(" Contained codeunits:<br/>")
160
+ reference_versions_html_lines.append(" <ul>")
161
+ for codeunit_reference_folder in list(folder for folder in GeneralUtilities.get_direct_folders_of_folder(all_available_version_identifier_folder_of_reference)):
162
+ reference_versions_html_lines.append(f' <li><a href="./{version_identifier_of_project}/{os.path.basename(codeunit_reference_folder)}/index.html">' +
163
+ f'{os.path.basename(codeunit_reference_folder)} {version_identifier_of_project}</a></li>')
164
+ reference_versions_html_lines.append(" </ul>")
165
+ reference_versions_html_lines.append(' <hr/>')
166
+ if version_identifier_of_project == "Latest":
167
+ latest_version_hint = " <h2>History</h2>"
168
+
169
+ design_file = None
170
+ design = "ModestDark"
171
+ if design == "ModestDark":
172
+ design_file = GeneralUtilities.get_modest_dark_url()
173
+ # TODO make designs from customizable sources be available by a customizable name and outsource this to a class-property because this is duplicated code.
174
+ if design_file is None:
175
+ design_html = GeneralUtilities.empty_string
176
+ else:
177
+ design_html = f'<link type="text/css" rel="stylesheet" href="{design_file}" />'
178
+
179
+ reference_versions_links_file_content = " \n".join(reference_versions_html_lines)
180
+ title = f"{projectname}-reference"
181
+ reference_index_file = os.path.join(reference_folder, "index.html")
182
+ reference_index_file_content = f"""<!DOCTYPE html>
183
+ <html lang="en">
184
+
185
+ <head>
186
+ <meta charset="UTF-8">
187
+ <title>{title}</title>
188
+ {design_html}
189
+ </head>
190
+
191
+ <body>
192
+ <h1>{title}</h1>
193
+ {reference_versions_links_file_content}
194
+ </body>
195
+
196
+ </html>
197
+ """ # see https://getbootstrap.com/docs/5.1/getting-started/introduction/
198
+ GeneralUtilities.write_text_to_file(reference_index_file, reference_index_file_content)
199
+
200
+
201
+ @GeneralUtilities.check_arguments
202
+ def __export_codeunit_reference_content_to_reference_repository(self, project_version_identifier: str, replace_existing_content: bool, target_folder_for_reference_repository: str, repository: str, codeunitname: str, projectname: str, codeunit_version: str, public_repository_url: str, branch: str) -> None:
203
+ codeunit_folder = os.path.join(repository, codeunitname)
204
+ codeunit_file = os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml")
205
+ codeunit_has_testcases = self.tFCPS_Tools_General.codeunit_has_testable_sourcecode(codeunit_file)
206
+ target_folder = os.path.join(target_folder_for_reference_repository, project_version_identifier, codeunitname)
207
+ if os.path.isdir(target_folder) and not replace_existing_content:
208
+ raise ValueError(f"Folder '{target_folder}' already exists.")
209
+ GeneralUtilities.ensure_directory_does_not_exist(target_folder)
210
+ GeneralUtilities.ensure_directory_exists(target_folder)
211
+ codeunit_version_identifier = "Latest" if project_version_identifier == "Latest" else "v"+codeunit_version
212
+ page_title = f"{codeunitname} {codeunit_version_identifier} codeunit-reference"
213
+ diff_report = f"{repository}/{codeunitname}/Other/Artifacts/DiffReport/DiffReport.html"
214
+ diff_target_folder = os.path.join(target_folder, "DiffReport")
215
+ GeneralUtilities.ensure_directory_exists(diff_target_folder)
216
+ diff_target_file = os.path.join(diff_target_folder, "DiffReport.html")
217
+ title = (f'Reference of codeunit {codeunitname} {codeunit_version_identifier} (contained in project <a href="{public_repository_url}">{projectname}</a> {project_version_identifier})')
218
+ if public_repository_url is None:
219
+ repo_url_html = GeneralUtilities.empty_string
220
+ else:
221
+ repo_url_html = f'<a href="{public_repository_url}/tree/{branch}/{codeunitname}">Source-code</a>'
222
+ if codeunit_has_testcases:
223
+ coverage_report_link = '<a href="./TestCoverageReport/index.html">Test-coverage-report</a><br>'
224
+ else:
225
+ coverage_report_link = GeneralUtilities.empty_string
226
+ index_file_for_reference = os.path.join(target_folder, "index.html")
227
+
228
+ design_file = None
229
+ design = "ModestDark"
230
+ if design == "ModestDark":
231
+ design_file = GeneralUtilities.get_modest_dark_url()
232
+ # TODO make designs from customizable sources be available by a customizable name and outsource this to a class-property because this is duplicated code.
233
+ if design_file is None:
234
+ design_html = GeneralUtilities.empty_string
235
+ else:
236
+ design_html = f'<link type="text/css" rel="stylesheet" href="{design_file}" />'
237
+
238
+ index_file_content = f"""<!DOCTYPE html>
239
+ <html lang="en">
240
+
241
+ <head>
242
+ <meta charset="UTF-8">
243
+ <title>{page_title}</title>
244
+ {design_html}
245
+ </head>
246
+
247
+ <body>
248
+ <h1>{title}</h1>
249
+ <hr/>
250
+ Available reference-content for {codeunitname}:<br>
251
+ {repo_url_html}<br>
252
+ <!--TODO add artefacts-link: <a href="./x">Artefacts</a><br>-->
253
+ <a href="./Reference/index.html">Reference</a><br>
254
+ <a href="./DiffReport/DiffReport.html">Diff-report</a><br>
255
+ {coverage_report_link}
256
+ </body>
257
+
258
+ </html>
259
+ """
260
+
261
+ GeneralUtilities.ensure_file_exists(index_file_for_reference)
262
+ GeneralUtilities.write_text_to_file(index_file_for_reference, index_file_content)
263
+ other_folder_in_repository = os.path.join(repository, codeunitname, "Other")
264
+ source_generatedreference = os.path.join(other_folder_in_repository, "Artifacts", "Reference")
265
+ target_generatedreference = os.path.join(target_folder, "Reference")
266
+ shutil.copytree(source_generatedreference, target_generatedreference)
267
+
268
+ shutil.copyfile(diff_report, diff_target_file)
269
+
270
+ if codeunit_has_testcases:
271
+ source_testcoveragereport = os.path.join(other_folder_in_repository, "Artifacts", "TestCoverageReport")
272
+ if os.path.isdir(source_testcoveragereport): # check, because it is not a mandatory artifact. if the artifact is not available, the user gets already a warning.
273
+ target_testcoveragereport = os.path.join(target_folder, "TestCoverageReport")
274
+ shutil.copytree(source_testcoveragereport, target_testcoveragereport)
275
+
276
+
277
+
278
+ class TFCPS_MergeToStable_CLI:
279
+
280
+ @staticmethod
281
+ def get_with_overwritable_defaults(file:str,default_product_name:str=None,default_loglevel:LogLevel=None,default_source_branch:str=None,default_additionalargumentsfile:str=None,default_target_branch:str=None,default_reference_repo:str=None,common_remote_name:str=None,build_repo_main_branch_name:str=None,reference_repo_main_branch_name:str=None,reference_remote_name:str=None,build_repo_remote_name:str=None,artifacts_target_folder:str=None,common_remote_url:str=None)->TFCPS_MergeToMain:
282
+ parser = argparse.ArgumentParser()
283
+ verbosity_values = ", ".join(f"{lvl.value}={lvl.name}" for lvl in LogLevel)
284
+ parser.add_argument('-n', '--productname', required=False,default=None)
285
+ parser.add_argument('-a', '--additionalargumentsfile', required=False, default=None)
286
+ parser.add_argument('-s', '--sourcebranch', required=False, default="main")
287
+ parser.add_argument('-t', '--targetbranch', required=False, default="stable")
288
+ parser.add_argument( '--referencerepo', required=False, default=None)
289
+ parser.add_argument( '--commonremotename', required=False, default=None)
290
+ parser.add_argument( '--buildrepomainbranchname', required=False, default="main")
291
+ parser.add_argument( '--referencerepomainbranchname', required=False, default="main")
292
+ parser.add_argument( '--referenceremotename', required=False, default=None)
293
+ parser.add_argument( '--buildreporemotename', required=False, default=None)
294
+ parser.add_argument( '--artifactstargetfolder', required=False, default=None)
295
+ parser.add_argument( '--commonremoteurl', required=False, default=None)
296
+ parser.add_argument('-v', '--verbosity', required=False, default=3, help=f"Sets the loglevel. Possible values: {verbosity_values}")
297
+ args=parser.parse_args()
298
+
299
+ sc:ScriptCollectionCore=ScriptCollectionCore()
300
+
301
+ build_repo=GeneralUtilities.resolve_relative_path("../../..",file)
302
+ sc.assert_is_git_repository(build_repo)
303
+
304
+ if args.productname is not None:
305
+ default_product_name=args.productname
306
+ if default_product_name is None:
307
+ default_product_name=os.path.basename(build_repo)[:-len("Build")]
308
+ GeneralUtilities.assert_not_null(default_product_name,"productname is not set")
309
+
310
+ if args.verbosity is not None:
311
+ default_loglevel=LogLevel(int( args.verbosity))
312
+ GeneralUtilities.assert_not_null(default_loglevel,"verbosity is not set")
313
+
314
+ if args.additionalargumentsfile is not None:
315
+ default_additionalargumentsfile=args.additionalargumentsfile
316
+
317
+ if args.sourcebranch is not None:
318
+ default_source_branch=args.sourcebranch
319
+ GeneralUtilities.assert_not_null(default_source_branch,"sourcebranch is not set")
320
+
321
+ if args.targetbranch is not None:
322
+ default_target_branch=args.targetbranch
323
+ GeneralUtilities.assert_not_null(default_target_branch,"targetbranch is not set")
324
+
325
+ if args.referencerepo is not None:
326
+ default_reference_repo=args.referencerepo
327
+ if default_reference_repo is None:
328
+ default_reference_repo=os.path.join(build_repo,"Submodules",f"{default_product_name}Reference")
329
+ GeneralUtilities.assert_not_null(default_reference_repo,"referencerepo is not set")
330
+
331
+ if args.commonremotename is not None:
332
+ common_remote_name=args.commonremotename
333
+ GeneralUtilities.assert_not_null(common_remote_name,"commonremotename is not set")
334
+
335
+ if args.buildrepomainbranchname is not None:
336
+ build_repo_main_branch_name=args.buildrepomainbranchname
337
+ GeneralUtilities.assert_not_null(build_repo_main_branch_name,"buildrepomainbranchname is not set")
338
+
339
+ if args.referencerepomainbranchname is not None:
340
+ reference_repo_main_branch_name=args.referencerepomainbranchname
341
+ GeneralUtilities.assert_not_null(reference_repo_main_branch_name,"referencerepomainbranchname is not set")
342
+
343
+ if args.referenceremotename is not None:
344
+ reference_remote_name=args.referenceremotename
345
+ GeneralUtilities.assert_not_null(reference_remote_name,"referenceremotename is not set")
346
+
347
+ if args.buildreporemotename is not None:
348
+ build_repo_remote_name=args.buildreporemotename
349
+ GeneralUtilities.assert_not_null(build_repo_remote_name,"buildreporemotename is not set")
350
+
351
+ if args.artifactstargetfolder is not None:
352
+ artifacts_target_folder=args.artifactstargetfolder
353
+
354
+ if args.commonremoteurl is not None:
355
+ common_remote_url=args.commonremoteurl
356
+ GeneralUtilities.assert_not_null(common_remote_url,"commonremoteurl is not set")
357
+
358
+ repository=os.path.join(build_repo,"Submodules",default_product_name)
359
+ config:MergeToStableConfiguration=MergeToStableConfiguration(default_loglevel,default_source_branch,default_target_branch,repository,build_repo,default_reference_repo,common_remote_name,build_repo_main_branch_name,reference_repo_main_branch_name,reference_remote_name,build_repo_remote_name,artifacts_target_folder,default_product_name,common_remote_url,default_additionalargumentsfile)
360
+ tFCPS_MergeToMain:TFCPS_MergeToStable=TFCPS_MergeToStable(config)
361
+ return tFCPS_MergeToMain
@@ -0,0 +1,16 @@
1
+ from datetime import datetime
2
+
3
+ class Dependency:
4
+ name:str
5
+ current_version:str
6
+ latest_patch_version_for_current_minor_version:str
7
+ latest_minor_version_for_current_major_version:str
8
+ latest_version:str
9
+ date_of_latest_version:datetime
10
+
11
+ class TFCPS_Tools_Dependencies:
12
+
13
+ def get_dependencies(self)->list[Dependency]:
14
+ result:list[Dependency]=[]
15
+ #TODO
16
+ return result