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.
Files changed (62) hide show
  1. ScriptCollection/AnionBuildPlatform.py +199 -0
  2. ScriptCollection/CertificateUpdater.py +149 -0
  3. ScriptCollection/Executables.py +921 -0
  4. ScriptCollection/GeneralUtilities.py +1589 -0
  5. ScriptCollection/HTTPMaintenanceOverheadHelper.py +36 -0
  6. ScriptCollection/OCIImages/AbstractImageHandler.py +38 -0
  7. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerDebian.py +20 -0
  8. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerDebianSlim.py +20 -0
  9. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGeneric.py +20 -0
  10. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGenericV.py +20 -0
  11. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGitlabCE.py +20 -0
  12. ScriptCollection/OCIImages/ConcreteImageHandlers/ImageHandlerGitlabEE.py +20 -0
  13. ScriptCollection/OCIImages/ConcreteImageHandlers/__init__.py +0 -0
  14. ScriptCollection/OCIImages/OCIImageManager.py +190 -0
  15. ScriptCollection/OCIImages/__init__.py +0 -0
  16. ScriptCollection/ProcessesRunner.py +43 -0
  17. ScriptCollection/ProgramRunnerBase.py +47 -0
  18. ScriptCollection/ProgramRunnerMock.py +2 -0
  19. ScriptCollection/ProgramRunnerPopen.py +57 -0
  20. ScriptCollection/ProgramRunnerSudo.py +108 -0
  21. ScriptCollection/Resources/CultureChooser/CultureChooser.js +29 -0
  22. ScriptCollection/Resources/CultureChooser/index.html +15 -0
  23. ScriptCollection/Resources/MaintenanceSite/MaintenanceSite.html +15 -0
  24. ScriptCollection/SCLog.py +115 -0
  25. ScriptCollection/ScriptCollectionCore.py +3485 -0
  26. ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py +192 -0
  27. ScriptCollection/TFCPS/Docker/__init__.py +0 -0
  28. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationBase.py +8 -0
  29. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationGenerate.py +6 -0
  30. ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationNoGenerate.py +7 -0
  31. ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py +547 -0
  32. ScriptCollection/TFCPS/DotNet/__init__.py +0 -0
  33. ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +137 -0
  34. ScriptCollection/TFCPS/Flutter/__init__.py +0 -0
  35. ScriptCollection/TFCPS/Go/TFCPS_CodeUnitSpecific_Go.py +72 -0
  36. ScriptCollection/TFCPS/Go/__init__.py +0 -0
  37. ScriptCollection/TFCPS/Maven/TFCPS_CodeUnitSpecific_Maven.py +42 -0
  38. ScriptCollection/TFCPS/Maven/__init__.py +0 -0
  39. ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +232 -0
  40. ScriptCollection/TFCPS/NodeJS/__init__.py +0 -0
  41. ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py +239 -0
  42. ScriptCollection/TFCPS/Python/__init__.py +0 -0
  43. ScriptCollection/TFCPS/Rust/TFCPS_CodeUnitSpecific_Rust.py +42 -0
  44. ScriptCollection/TFCPS/Rust/__init__.py +0 -0
  45. ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +433 -0
  46. ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py +135 -0
  47. ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +301 -0
  48. ScriptCollection/TFCPS/TFCPS_CreateRelease.py +98 -0
  49. ScriptCollection/TFCPS/TFCPS_Generic.py +44 -0
  50. ScriptCollection/TFCPS/TFCPS_MergeToMain.py +128 -0
  51. ScriptCollection/TFCPS/TFCPS_MergeToStable.py +356 -0
  52. ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py +48 -0
  53. ScriptCollection/TFCPS/TFCPS_Tools_General.py +1565 -0
  54. ScriptCollection/TFCPS/__init__.py +0 -0
  55. ScriptCollection/__init__.py +0 -0
  56. ScriptCollection/__pycache__/GeneralUtilities.cpython-311.pyc +0 -0
  57. ScriptCollection/__pycache__/__init__.cpython-311.pyc +0 -0
  58. scriptcollection-4.2.81.dist-info/METADATA +169 -0
  59. scriptcollection-4.2.81.dist-info/RECORD +62 -0
  60. scriptcollection-4.2.81.dist-info/WHEEL +5 -0
  61. scriptcollection-4.2.81.dist-info/entry_points.txt +67 -0
  62. scriptcollection-4.2.81.dist-info/top_level.txt +1 -0
@@ -0,0 +1,192 @@
1
+ import os
2
+ from urllib import request
3
+ import time
4
+ import ssl
5
+ from datetime import timedelta,datetime
6
+ from ...GeneralUtilities import GeneralUtilities, Platform
7
+ from ...SCLog import LogLevel
8
+ from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
9
+
10
+
11
+ class TFCPS_CodeUnitSpecific_Docker_Functions(TFCPS_CodeUnitSpecific_Base):
12
+
13
+ def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool,is_pre_merge:bool):
14
+ super().__init__(current_file, verbosity,targetenvironmenttype,use_cache,is_pre_merge)
15
+
16
+ @GeneralUtilities.check_arguments
17
+ def build(self,platforms:list[Platform],custom_arguments:dict[str,str]) -> None:
18
+ codeunitname: str =self.get_codeunit_name()
19
+ codeunit_folder =self.get_codeunit_folder()
20
+ codeunitname_lower = codeunitname.lower()
21
+ codeunit_file =self.get_codeunit_file()
22
+ codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(codeunit_file)
23
+ if custom_arguments is None:
24
+ custom_arguments=dict[str,str]()
25
+ artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
26
+ app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
27
+ GeneralUtilities.ensure_folder_exists_and_is_empty(app_artifacts_folder)
28
+ for platform in platforms:
29
+ #builder must be created once before with "docker buildx create --use"
30
+ args = ["buildx","build", "--platform",GeneralUtilities.platform_to_docker_platform_str(platform), "--pull", "--force-rm", "--progress=plain", "--build-arg", f"TargetEnvironmentType={self.get_target_environment_type()}", "--build-arg", f"CodeUnitName={codeunitname}", "--build-arg", f"CodeUnitVersion={codeunitversion}", "--build-arg", f"CodeUnitOwnerName={self.tfcps_Tools_General.get_codeunit_owner_name(self.get_codeunit_file())}", "--build-arg", f"CodeUnitOwnerEMailAddress={self.tfcps_Tools_General.get_codeunit_owner_emailaddress(self.get_codeunit_file())}", "--build-arg", f"Platform={GeneralUtilities.platform_to_dash_str(platform)}", "--build-arg", f"DotNetRuntime={GeneralUtilities.platform_to_dotnet_runtime_identifier(platform)}", "--build-arg", f"PlatformForGoVersion={GeneralUtilities.platform_to_go_runtime_identifier(platform)}"]
31
+ for custom_argument_key, custom_argument_value in custom_arguments.items():
32
+ args.append("--build-arg")
33
+ args.append(f"{custom_argument_key}={custom_argument_value}")
34
+ pip_args=self._protected_sc.get_pip_index_url_arguments_from_local_cache()
35
+ if len(pip_args)>0:
36
+ args.append("--build-arg")
37
+ args.append(f"PipIndexUrlArguments=\"{pip_args}\"")
38
+ args = args+["--tag", f"{codeunitname_lower}:latest", "--tag", f"{codeunitname_lower}:{codeunitversion}", "--file", f"{codeunitname}/Dockerfile"]
39
+ if not self.use_cache():
40
+ args.append("--no-cache")
41
+ target_file=os.path.join(app_artifacts_folder,f"{codeunitname}_v{codeunitversion}_{GeneralUtilities.platform_to_dash_str(platform)}.tar")
42
+ args.append("--output")
43
+ args.append(f"type=docker,dest={target_file}")
44
+ args.append(".")
45
+ time.sleep(5)
46
+ self._protected_sc.run_program_argsasarray_with_retry("docker", args, codeunit_folder, print_errors_as_information=True,print_live_output=self.get_verbosity()==LogLevel.Debug,amount_of_attempts=3,delay_in_seconds=5)
47
+ time.sleep(2)
48
+ self._protected_sc.run_program_argsasarray("docker", ["load", "-i", target_file], codeunit_folder, print_errors_as_information=True,print_live_output=self.get_verbosity()==LogLevel.Debug)
49
+
50
+ self.__generate_sbom_for_docker_image()
51
+ self.copy_source_files_to_output_directory()
52
+
53
+
54
+ @GeneralUtilities.check_arguments
55
+ def __generate_sbom_for_docker_image(self) -> None:
56
+ codeunitname=self.get_codeunit_name()
57
+ codeunit_folder =self.get_codeunit_folder()
58
+ artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
59
+ codeunitname_lower = codeunitname.lower()
60
+ sbom_folder = os.path.join(artifacts_folder, "BOM")
61
+ codeunitversion = self.tfcps_Tools_General.get_version_of_codeunit(self.get_codeunit_file())
62
+ GeneralUtilities.ensure_directory_exists(sbom_folder)
63
+ #TODO ensure syft-image-tag will be updated by update-dependencies-script.
64
+ self._protected_sc.run_program_argsasarray("docker", ["run","--rm","-v","/var/run/docker.sock:/var/run/docker.sock","-v","./BOM:/BOM",self.tfcps_Tools_General.oci_image_manager.get_registry_address_for_image_with_default_tag(self.get_repository_folder(),"Syft",True),f"{codeunitname_lower}:{codeunitversion}","-o",f"cyclonedx-xml=/BOM/{codeunitname}.{codeunitversion}.sbom.xml"], artifacts_folder, print_errors_as_information=True)
65
+ self._protected_sc.format_xml_file(sbom_folder+f"/{codeunitname}.{codeunitversion}.sbom.xml")
66
+
67
+ @GeneralUtilities.check_arguments
68
+ def linting(self) -> None:
69
+ pass#TODO
70
+
71
+ @GeneralUtilities.check_arguments
72
+ def do_common_tasks(self,current_codeunit_version:str )-> None:
73
+ codeunitname =self.get_codeunit_name()
74
+ codeunit_folder = self.get_codeunit_folder()
75
+ codeunit_version = current_codeunit_version
76
+ self._protected_sc.replace_version_in_dockerfile_file(GeneralUtilities.resolve_relative_path(f"./{codeunitname}/Dockerfile", codeunit_folder), codeunit_version)
77
+ self.do_common_tasks_base(current_codeunit_version)
78
+ self.tfcps_Tools_General.standardized_tasks_update_version_in_docker_examples(codeunit_folder,codeunit_version)
79
+
80
+ @GeneralUtilities.check_arguments
81
+ def generate_reference(self) -> None:
82
+ self.generate_reference_using_docfx()
83
+
84
+ @GeneralUtilities.check_arguments
85
+ def run_testcases(self) -> None:
86
+ pass#TODO
87
+
88
+ @GeneralUtilities.check_arguments
89
+ def get_dependencies(self)->dict[str,set[str]]:
90
+ return dict[str,set[str]]()#TODO
91
+
92
+ @GeneralUtilities.check_arguments
93
+ def get_available_versions(self,dependencyname:str)->list[str]:
94
+ return []#TODO
95
+
96
+ @GeneralUtilities.check_arguments
97
+ def set_dependency_version(self,name:str,new_version:str)->None:
98
+ raise ValueError(f"Operation is not implemented.")
99
+
100
+ @GeneralUtilities.check_arguments
101
+ def image_is_working(self,timeout:timedelta,environment_variables:dict[str,str],test_port:int,http_test_route:str,use_https_for_test:bool)->tuple[bool,str]:
102
+ if timeout is None:
103
+ timeout=timedelta(seconds=120)
104
+ if environment_variables is None:
105
+ environment_variables={}
106
+ current_platform = GeneralUtilities.get_current_platform()
107
+ platform_for_test:Platform=None
108
+ if current_platform == Platform.Windows_AMD64:
109
+ platform_for_test=Platform.Linux_AMD64
110
+ elif current_platform == Platform.Linux_AMD64:
111
+ platform_for_test=Platform.Linux_AMD64
112
+ elif current_platform == Platform.Linux_ARM64:
113
+ platform_for_test=Platform.Linux_ARM64
114
+ elif current_platform == Platform.MacOS_ARM64:
115
+ platform_for_test=Platform.Linux_ARM64
116
+ else:
117
+ raise ValueError(f"Current platform {current_platform} is not supported for testing.")
118
+ oci_image_artifacts_folder :str= GeneralUtilities.resolve_relative_path("Other/Artifacts/BuildResult_OCIImage", self.get_codeunit_folder())
119
+ container_name:str=f"{self.get_codeunit_name()}finaltest".lower()
120
+ self.tfcps_Tools_General.ensure_containers_are_not_running([container_name])
121
+ self.tfcps_Tools_General.load_docker_image(oci_image_artifacts_folder,platform_for_test)
122
+ codeunit_file:str=os.path.join(self.get_codeunit_folder(),f"{self.get_codeunit_name()}.codeunit.xml")
123
+ image=f"{self.get_codeunit_name()}:{self.tfcps_Tools_General.get_version_of_codeunit(codeunit_file)}".lower()
124
+ argument=f"run -d --name {container_name}"
125
+ if test_port is not None:
126
+ argument=f"{argument} -p {test_port}:{test_port}"
127
+ for k,v in environment_variables.items():
128
+ argument=f"{argument} -e {k}={v}"#TODO switch to argument-array to also allow values with white-space
129
+ argument=f"{argument} {image}"
130
+ GeneralUtilities.assert_condition(http_test_route is None or http_test_route.startswith("/"),"If a test-route is given then it must start with \"/\".")
131
+ try:
132
+ last_exception:Exception=None
133
+ self._protected_sc.run_program("docker",argument)
134
+ start:datetime=GeneralUtilities.get_now()
135
+ end:datetime=start+timeout
136
+ while GeneralUtilities.get_now()<end:
137
+ time.sleep(1)
138
+ try:
139
+ if not self._protected_sc.container_is_running_and_healthy(container_name):
140
+ raise ValueError("Container is not running and healthy.")
141
+ if http_test_route is not None:
142
+ url="http"
143
+ if use_https_for_test:
144
+ url=url+"s"
145
+ url=url+"://localhost"
146
+ if test_port is not None:
147
+ url=url+":"+str(test_port)
148
+ url=url+http_test_route
149
+ ctx = ssl.create_default_context()
150
+ ctx.check_hostname = False
151
+ ctx.verify_mode = ssl.CERT_NONE
152
+ with request.urlopen(url, context=ctx) as response:
153
+ status = response.status
154
+ if status < 200 or 300 <= status:
155
+ raise ValueError(f"Test-call \"GET {url}\" had response-statuscode {status}.")
156
+ return (True,None)
157
+ except Exception as e:
158
+ last_exception=e
159
+ container_output:str=None
160
+ if not self._protected_sc.container_is_exists(container_name):
161
+ return (False,f"Container \"{container_name}\" does not exist.")
162
+ try:
163
+ container_output="\nContainer-output:\n"+self._protected_sc.get_output_of_container(container_name)
164
+ except Exception:
165
+ container_output="\n(Container-output not retrievable.)"
166
+ exception_message=f"\nContainer was started with \"docker {argument}\"."
167
+ if last_exception is not None:
168
+ exception_message=exception_message+"\nLast exception: "+GeneralUtilities.exception_to_str(last_exception)
169
+ if not self._protected_sc.container_is_running(container_name):
170
+ return (False,f"Container \"{container_name}\" is not running.{exception_message}{container_output}")
171
+ if not self._protected_sc.container_is_healthy(container_name):
172
+ return (False,f"Container \"{container_name}\" is not healthy.{exception_message}{container_output}")
173
+ return (False,f"Container \"{container_name}\" is not working properly.{exception_message}{container_output}")
174
+ finally:
175
+ self.tfcps_Tools_General.ensure_containers_are_not_running([container_name])
176
+
177
+ @GeneralUtilities.check_arguments
178
+ def verify_image_is_working(self,timeout:timedelta,environment_variables:dict[str,str],test_port:int,http_test_route:str,use_https_for_test:bool):
179
+ check_result:tuple[bool,str]= self.image_is_working(timeout,environment_variables,test_port,http_test_route,use_https_for_test)
180
+ if not check_result[0]:
181
+ raise ValueError("Image not working: "+check_result[1])
182
+
183
+ class TFCPS_CodeUnitSpecific_Docker_CLI:
184
+
185
+ @staticmethod
186
+ @GeneralUtilities.check_arguments
187
+ def parse(file:str)->TFCPS_CodeUnitSpecific_Docker_Functions:
188
+ parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
189
+ #add custom parameter if desired
190
+ args=parser.parse_args()
191
+ result:TFCPS_CodeUnitSpecific_Docker_Functions=TFCPS_CodeUnitSpecific_Docker_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache,args.ispremerge)
192
+ return result
File without changes
@@ -0,0 +1,8 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class CertificateGeneratorInformationBase(ABC):
5
+
6
+ @abstractmethod
7
+ def generate_certificate(self)->bool:
8
+ raise ValueError("Method is abstract")
@@ -0,0 +1,6 @@
1
+ from .CertificateGeneratorInformationBase import CertificateGeneratorInformationBase
2
+
3
+ class CertificateGeneratorInformationGenerate(CertificateGeneratorInformationBase):
4
+
5
+ def generate_certificate(self)->bool:
6
+ return True
@@ -0,0 +1,7 @@
1
+ from .CertificateGeneratorInformationBase import CertificateGeneratorInformationBase
2
+
3
+
4
+ class CertificateGeneratorInformationNoGenerate(CertificateGeneratorInformationBase):
5
+
6
+ def generate_certificate(self)->bool:
7
+ return False