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,137 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import re
|
|
4
|
+
import zipfile
|
|
5
|
+
from ...GeneralUtilities import GeneralUtilities
|
|
6
|
+
from ...SCLog import LogLevel
|
|
7
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
|
8
|
+
|
|
9
|
+
class TFCPS_CodeUnitSpecific_Flutter_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
10
|
+
|
|
11
|
+
def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool,is_pre_merge:bool):
|
|
12
|
+
super().__init__(current_file, verbosity,targetenvironmenttype,use_cache,is_pre_merge)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@GeneralUtilities.check_arguments
|
|
16
|
+
def build(self,package_name:str,targets:list[str]) -> None:
|
|
17
|
+
codeunit_folder = self.get_codeunit_folder()
|
|
18
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
|
19
|
+
src_folder: str = None
|
|
20
|
+
if package_name is None:
|
|
21
|
+
src_folder = codeunit_folder
|
|
22
|
+
else:
|
|
23
|
+
src_folder = GeneralUtilities.resolve_relative_path(package_name, codeunit_folder) # TODO replace packagename
|
|
24
|
+
artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts")
|
|
25
|
+
|
|
26
|
+
target_names: dict[str, str] = {
|
|
27
|
+
"web": "WebApplication",
|
|
28
|
+
"windows": "Windows",
|
|
29
|
+
"ios": "IOS",
|
|
30
|
+
"appbundle": "Android",
|
|
31
|
+
}
|
|
32
|
+
for target in targets:
|
|
33
|
+
self._protected_sc.log.log(f"Build flutter-codeunit {codeunit_name} for target {target_names[target]}...")
|
|
34
|
+
self._protected_sc.run_with_epew("flutter", f"build {target}", src_folder)
|
|
35
|
+
if target == "web":
|
|
36
|
+
web_relase_folder = os.path.join(src_folder, "build/web")
|
|
37
|
+
web_folder = os.path.join(artifacts_folder, "BuildResult_WebApplication")
|
|
38
|
+
GeneralUtilities.ensure_directory_does_not_exist(web_folder)
|
|
39
|
+
GeneralUtilities.ensure_directory_exists(web_folder)
|
|
40
|
+
GeneralUtilities.copy_content_of_folder(web_relase_folder, web_folder)
|
|
41
|
+
elif target == "windows":
|
|
42
|
+
enabled=False
|
|
43
|
+
if enabled:#TODO move to external because this is not platform indepent
|
|
44
|
+
windows_release_folder = os.path.join(src_folder, "build/windows/x64/runner/Release")
|
|
45
|
+
windows_folder = os.path.join(artifacts_folder, "BuildResult_Windows")
|
|
46
|
+
GeneralUtilities.ensure_directory_does_not_exist(windows_folder)
|
|
47
|
+
GeneralUtilities.ensure_directory_exists(windows_folder)
|
|
48
|
+
GeneralUtilities.copy_content_of_folder(windows_release_folder, windows_folder)
|
|
49
|
+
elif target == "ios":
|
|
50
|
+
enabled=False
|
|
51
|
+
if enabled:#TODO move to external because this is not platform indepent
|
|
52
|
+
raise ValueError("building for ios is not implemented yet")
|
|
53
|
+
elif target == "appbundle":
|
|
54
|
+
enabled=False
|
|
55
|
+
if enabled:#TODO move to external because this is not platform indepent
|
|
56
|
+
aab_folder = os.path.join(artifacts_folder, "BuildResult_AAB")
|
|
57
|
+
GeneralUtilities.ensure_directory_does_not_exist(aab_folder)
|
|
58
|
+
GeneralUtilities.ensure_directory_exists(aab_folder)
|
|
59
|
+
aab_relase_folder = os.path.join(src_folder, "build/app/outputs/bundle/release")
|
|
60
|
+
aab_file_original = self._protected_sc.find_file_by_extension(aab_relase_folder, "aab")
|
|
61
|
+
aab_file = os.path.join(aab_folder, f"{codeunit_name}.aab")
|
|
62
|
+
shutil.copyfile(aab_file_original, aab_file)
|
|
63
|
+
|
|
64
|
+
bundletool = self.tfcps_Tools_General.ensure_androidappbundletool_is_available(None,self.use_cache())
|
|
65
|
+
apk_folder = os.path.join(artifacts_folder, "BuildResult_APK")
|
|
66
|
+
GeneralUtilities.ensure_directory_does_not_exist(apk_folder)
|
|
67
|
+
GeneralUtilities.ensure_directory_exists(apk_folder)
|
|
68
|
+
apks_file = f"{apk_folder}/{codeunit_name}.apks"
|
|
69
|
+
self._protected_sc.run_program("java", f"-jar {bundletool} build-apks --bundle={aab_file} --output={apks_file} --mode=universal", aab_relase_folder)
|
|
70
|
+
with zipfile.ZipFile(apks_file, "r") as zip_ref:
|
|
71
|
+
zip_ref.extract("universal.apk", apk_folder)
|
|
72
|
+
GeneralUtilities.ensure_file_does_not_exist(apks_file)
|
|
73
|
+
os.rename(f"{apk_folder}/universal.apk", f"{apk_folder}/{codeunit_name}.apk")
|
|
74
|
+
else:
|
|
75
|
+
raise ValueError(f"Not supported target: {target}")
|
|
76
|
+
self.copy_source_files_to_output_directory()
|
|
77
|
+
|
|
78
|
+
@GeneralUtilities.check_arguments
|
|
79
|
+
def linting(self) -> None:
|
|
80
|
+
pass#TODO
|
|
81
|
+
|
|
82
|
+
@GeneralUtilities.check_arguments
|
|
83
|
+
def do_common_tasks(self,current_codeunit_version:str )-> None:
|
|
84
|
+
self.do_common_tasks_base(current_codeunit_version)
|
|
85
|
+
|
|
86
|
+
@GeneralUtilities.check_arguments
|
|
87
|
+
def generate_reference(self) -> None:
|
|
88
|
+
self.generate_reference_using_docfx()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@GeneralUtilities.check_arguments
|
|
92
|
+
def run_testcases(self,package_name:str) -> None:
|
|
93
|
+
codeunit_folder = self.get_codeunit_folder()
|
|
94
|
+
repository_folder = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
|
|
95
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
|
96
|
+
src_folder = GeneralUtilities.resolve_relative_path(package_name, codeunit_folder)
|
|
97
|
+
|
|
98
|
+
self._protected_sc.run_with_epew("flutter", "test --coverage", src_folder)
|
|
99
|
+
test_coverage_folder_relative = "Other/Artifacts/TestCoverage"
|
|
100
|
+
test_coverage_folder = GeneralUtilities.resolve_relative_path(test_coverage_folder_relative, codeunit_folder)
|
|
101
|
+
GeneralUtilities.ensure_directory_exists(test_coverage_folder)
|
|
102
|
+
coverage_file_relative = f"{test_coverage_folder_relative}/TestCoverage.xml"
|
|
103
|
+
coverage_file = GeneralUtilities.resolve_relative_path(coverage_file_relative, codeunit_folder)
|
|
104
|
+
self._protected_sc.run_with_epew("lcov_cobertura", f"coverage/lcov.info --base-dir . --excludes test --output ../{coverage_file_relative} --demangle", src_folder)
|
|
105
|
+
|
|
106
|
+
# format correctly
|
|
107
|
+
content = GeneralUtilities.read_text_from_file(coverage_file)
|
|
108
|
+
content = re.sub('<![^<]+>', '', content)
|
|
109
|
+
content = re.sub('\\\\', '/', content)
|
|
110
|
+
content = re.sub('\\ name=\\"lib\\"', '', content)
|
|
111
|
+
content = re.sub('\\ filename=\\"lib/', f' filename="{package_name}/lib/', content)
|
|
112
|
+
GeneralUtilities.write_text_to_file(coverage_file, content)
|
|
113
|
+
self.tfcps_Tools_General.merge_packages(coverage_file, self.get_codeunit_name())
|
|
114
|
+
self.tfcps_Tools_General.calculate_entire_line_rate(coverage_file)
|
|
115
|
+
self.run_testcases_common_post_task(repository_folder, codeunit_name, True, self.get_target_environment_type())
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def get_dependencies(self)->dict[str,set[str]]:
|
|
119
|
+
return dict[str,set[str]]()#TODO
|
|
120
|
+
|
|
121
|
+
@GeneralUtilities.check_arguments
|
|
122
|
+
def get_available_versions(self,dependencyname:str)->list[str]:
|
|
123
|
+
return []#TODO
|
|
124
|
+
|
|
125
|
+
def set_dependency_version(self,name:str,new_version:str)->None:
|
|
126
|
+
raise ValueError(f"Operation is not implemented.")
|
|
127
|
+
|
|
128
|
+
class TFCPS_CodeUnitSpecific_Flutter_CLI:
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
@GeneralUtilities.check_arguments
|
|
132
|
+
def parse(file:str)->TFCPS_CodeUnitSpecific_Flutter_Functions:
|
|
133
|
+
parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
|
134
|
+
#add custom parameter if desired
|
|
135
|
+
args=parser.parse_args()
|
|
136
|
+
result:TFCPS_CodeUnitSpecific_Flutter_Functions=TFCPS_CodeUnitSpecific_Flutter_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache,args.ispremerge)
|
|
137
|
+
return result
|
|
File without changes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from lxml import etree
|
|
3
|
+
from ...GeneralUtilities import GeneralUtilities
|
|
4
|
+
from ...ScriptCollectionCore import ScriptCollectionCore
|
|
5
|
+
from ...SCLog import LogLevel
|
|
6
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
|
7
|
+
|
|
8
|
+
class TFCPS_CodeUnitSpecific_Go_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
9
|
+
|
|
10
|
+
def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool,is_pre_merge:bool):
|
|
11
|
+
super().__init__(current_file, verbosity,targetenvironmenttype,use_cache,is_pre_merge)
|
|
12
|
+
|
|
13
|
+
@GeneralUtilities.check_arguments
|
|
14
|
+
def build(self) -> None:
|
|
15
|
+
#TODO
|
|
16
|
+
self.__generate_sbom_for_go_image()
|
|
17
|
+
|
|
18
|
+
@GeneralUtilities.check_arguments
|
|
19
|
+
def __generate_sbom_for_go_image(self) -> None:
|
|
20
|
+
pass#TODO
|
|
21
|
+
|
|
22
|
+
@GeneralUtilities.check_arguments
|
|
23
|
+
def linting(self) -> None:
|
|
24
|
+
pass#TODO
|
|
25
|
+
|
|
26
|
+
@GeneralUtilities.check_arguments
|
|
27
|
+
def __update_coverage_file(self,coverage_file:str) -> None:
|
|
28
|
+
tree = etree.parse(coverage_file)
|
|
29
|
+
root = tree.getroot()
|
|
30
|
+
for package in root.findall(".//package"):
|
|
31
|
+
package.set("name",self.get_codeunit_name())
|
|
32
|
+
for cls in root.findall(".//class"):
|
|
33
|
+
filename = cls.get("filename")
|
|
34
|
+
if filename:
|
|
35
|
+
cls.set("filename", f"./{filename}")
|
|
36
|
+
cls.set("name",str(filename).rsplit("/", 1)[-1])
|
|
37
|
+
tree.write(coverage_file, encoding="utf-8", xml_declaration=True, pretty_print=True)
|
|
38
|
+
|
|
39
|
+
@GeneralUtilities.check_arguments
|
|
40
|
+
def run_testcases(self) -> None:
|
|
41
|
+
test_coverage_folder = os.path.join(self.get_codeunit_folder(), "Other", "Artifacts", "TestCoverage").replace("\\", "/")
|
|
42
|
+
GeneralUtilities.ensure_directory_exists(test_coverage_folder)
|
|
43
|
+
src_folder = GeneralUtilities.resolve_relative_path(self.get_codeunit_name(), self.get_codeunit_folder())
|
|
44
|
+
sc: ScriptCollectionCore = ScriptCollectionCore()
|
|
45
|
+
sc.run_program_argsasarray("go", ["install", "github.com/t-yuki/gocover-cobertura@latest"], src_folder)
|
|
46
|
+
sc.run_program_argsasarray("go", ["test", "-coverprofile=coverage.out", "./..."], src_folder)
|
|
47
|
+
coverage_file:str=f"{test_coverage_folder}/TestCoverage.xml"
|
|
48
|
+
sc.run_program_argsasarray("sh", ["-c", f"gocover-cobertura < coverage.out > {coverage_file}"], src_folder)
|
|
49
|
+
self.__update_coverage_file(coverage_file)
|
|
50
|
+
self.run_testcases_common_post_task(self.get_repository_folder(),self.get_codeunit_name(),True,self.get_type_environment_type())
|
|
51
|
+
|
|
52
|
+
def get_dependencies(self)->dict[str,set[str]]:
|
|
53
|
+
return dict[str,set[str]]()#TODO
|
|
54
|
+
|
|
55
|
+
@GeneralUtilities.check_arguments
|
|
56
|
+
def get_available_versions(self,dependencyname:str)->list[str]:
|
|
57
|
+
return []#TODO
|
|
58
|
+
|
|
59
|
+
@GeneralUtilities.check_arguments
|
|
60
|
+
def set_dependency_version(self,name:str,new_version:str)->None:
|
|
61
|
+
raise ValueError(f"Operation is not implemented.")
|
|
62
|
+
|
|
63
|
+
class TFCPS_CodeUnitSpecific_Go_CLI:
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
@GeneralUtilities.check_arguments
|
|
67
|
+
def parse(file:str)->TFCPS_CodeUnitSpecific_Go_Functions:
|
|
68
|
+
parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
|
69
|
+
#add custom parameter if desired
|
|
70
|
+
args=parser.parse_args()
|
|
71
|
+
result:TFCPS_CodeUnitSpecific_Go_Functions=TFCPS_CodeUnitSpecific_Go_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache,args.ispremerge)
|
|
72
|
+
return result
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from ...GeneralUtilities import GeneralUtilities
|
|
2
|
+
from ...SCLog import LogLevel
|
|
3
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base, TFCPS_CodeUnitSpecific_Base_CLI
|
|
4
|
+
|
|
5
|
+
class TFCPS_CodeUnitSpecific_Maven_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
6
|
+
|
|
7
|
+
def __init__(self, current_file: str, verbosity: LogLevel, targetenvironmenttype: str, use_cache: bool, is_pre_merge: bool):
|
|
8
|
+
super().__init__(current_file, verbosity, targetenvironmenttype, use_cache, is_pre_merge)
|
|
9
|
+
|
|
10
|
+
@GeneralUtilities.check_arguments
|
|
11
|
+
def build(self) -> None:
|
|
12
|
+
pass#TODO
|
|
13
|
+
|
|
14
|
+
@GeneralUtilities.check_arguments
|
|
15
|
+
def linting(self) -> None:
|
|
16
|
+
pass#TODO
|
|
17
|
+
|
|
18
|
+
@GeneralUtilities.check_arguments
|
|
19
|
+
def run_testcases(self) -> None:
|
|
20
|
+
pass#TODO
|
|
21
|
+
|
|
22
|
+
def get_dependencies(self) -> dict[str, set[str]]:
|
|
23
|
+
return dict[str, set[str]]()#TODO
|
|
24
|
+
|
|
25
|
+
@GeneralUtilities.check_arguments
|
|
26
|
+
def get_available_versions(self, dependencyname: str) -> list[str]:
|
|
27
|
+
return []#TODO
|
|
28
|
+
|
|
29
|
+
@GeneralUtilities.check_arguments
|
|
30
|
+
def set_dependency_version(self, name: str, new_version: str) -> None:
|
|
31
|
+
raise ValueError("Operation is not implemented.")
|
|
32
|
+
|
|
33
|
+
class TFCPS_CodeUnitSpecific_Maven_CLI:
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
@GeneralUtilities.check_arguments
|
|
37
|
+
def parse(file: str) -> TFCPS_CodeUnitSpecific_Maven_Functions:
|
|
38
|
+
parser = TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
|
39
|
+
#add custom parameter if desired
|
|
40
|
+
args = parser.parse_args()
|
|
41
|
+
result: TFCPS_CodeUnitSpecific_Maven_Functions = TFCPS_CodeUnitSpecific_Maven_Functions(file, LogLevel(int(args.verbosity)), args.targetenvironmenttype, not args.nocache, args.ispremerge)
|
|
42
|
+
return result
|
|
File without changes
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import xml.etree.ElementTree as ET
|
|
6
|
+
from lxml import etree
|
|
7
|
+
from ...GeneralUtilities import GeneralUtilities
|
|
8
|
+
from ...SCLog import LogLevel
|
|
9
|
+
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
|
10
|
+
from ...HTTPMaintenanceOverheadHelper import HTTPMaintenanceOverheadHelper
|
|
11
|
+
|
|
12
|
+
class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def __init__(self,current_file:str,verbosity:LogLevel,targetenvironmenttype:str,use_cache:bool,is_pre_merge:bool):
|
|
16
|
+
super().__init__(current_file, verbosity,targetenvironmenttype,use_cache,is_pre_merge)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@GeneralUtilities.check_arguments
|
|
20
|
+
def build(self) -> None:
|
|
21
|
+
self._protected_sc.run_with_epew("npm", "run build", self.get_codeunit_folder(),print_live_output=self.get_verbosity()==LogLevel.Debug,encode_argument_in_base64=True)
|
|
22
|
+
self.standardized_tasks_build_bom_for_node_project()
|
|
23
|
+
self.copy_source_files_to_output_directory()
|
|
24
|
+
|
|
25
|
+
@GeneralUtilities.check_arguments
|
|
26
|
+
def linting(self) -> None:
|
|
27
|
+
src_folder = os.path.join(self.get_codeunit_folder(), "src")
|
|
28
|
+
for file in GeneralUtilities.get_all_files_of_folder(src_folder):
|
|
29
|
+
if file.endswith(".html"):
|
|
30
|
+
self._protected_sc.format_html_file(file, os.path.basename(file) == "index.html")
|
|
31
|
+
self._protected_sc.run_with_epew("npm", "run lint", self.get_codeunit_folder(),print_live_output=self.get_verbosity()==LogLevel.Debug,encode_argument_in_base64=True)
|
|
32
|
+
|
|
33
|
+
@GeneralUtilities.check_arguments
|
|
34
|
+
def do_common_tasks(self,current_codeunit_version:str)-> None:
|
|
35
|
+
codeunit_version = current_codeunit_version
|
|
36
|
+
codeunit_folder = self.get_codeunit_folder()
|
|
37
|
+
self.do_common_tasks_base(current_codeunit_version)
|
|
38
|
+
self.tfcps_Tools_General.replace_version_in_packagejson_file(GeneralUtilities.resolve_relative_path("./package.json", codeunit_folder), codeunit_version)
|
|
39
|
+
self.tfcps_Tools_General.do_npm_install(codeunit_folder, True,self.use_cache())
|
|
40
|
+
#if generateAPIClientBase.generate_api_client():
|
|
41
|
+
# generateAPIClientGenerate:GenerateAPIClientGenerate=generateAPIClientBase
|
|
42
|
+
# self.tfcps_Tools_General.generate_api_client_from_dependent_codeunit_in_angular(codeunit_folder, generateAPIClientGenerate.name_of_api_providing_codeunit,generateAPIClientGenerate.generate_api_client)
|
|
43
|
+
|
|
44
|
+
@GeneralUtilities.check_arguments
|
|
45
|
+
def generate_reference(self) -> None:
|
|
46
|
+
self.generate_reference_using_docfx()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@GeneralUtilities.check_arguments
|
|
50
|
+
def run_testcases(self) -> None:
|
|
51
|
+
# prepare
|
|
52
|
+
codeunit_name: str =self.get_codeunit_name()
|
|
53
|
+
|
|
54
|
+
codeunit_folder =self.get_codeunit_folder()
|
|
55
|
+
repository_folder = os.path.dirname(codeunit_folder)
|
|
56
|
+
|
|
57
|
+
# run testcases
|
|
58
|
+
self._protected_sc.run_with_epew("npm", f"run test-{self.get_target_environment_type()}", self.get_codeunit_folder(),print_live_output=self.get_verbosity()==LogLevel.Debug,encode_argument_in_base64=True)
|
|
59
|
+
|
|
60
|
+
# rename file
|
|
61
|
+
coverage_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "TestCoverage")
|
|
62
|
+
target_file = os.path.join(coverage_folder, "TestCoverage.xml")
|
|
63
|
+
GeneralUtilities.ensure_file_does_not_exist(target_file)
|
|
64
|
+
os.rename(os.path.join(coverage_folder, "cobertura-coverage.xml"), target_file)
|
|
65
|
+
self.__rename_packagename_in_coverage_file(target_file, codeunit_name)
|
|
66
|
+
|
|
67
|
+
# adapt backslashs to slashs
|
|
68
|
+
content = GeneralUtilities.read_text_from_file(target_file)
|
|
69
|
+
content = re.sub('\\\\', '/', content)
|
|
70
|
+
GeneralUtilities.write_text_to_file(target_file, content)
|
|
71
|
+
|
|
72
|
+
# aggregate packages in testcoverage-file
|
|
73
|
+
roottree: etree._ElementTree = etree.parse(target_file)
|
|
74
|
+
existing_classes = list(roottree.xpath('//coverage/packages/package/classes/class'))
|
|
75
|
+
|
|
76
|
+
old_packages_list = roottree.xpath('//coverage/packages/package')
|
|
77
|
+
for package in old_packages_list:
|
|
78
|
+
package.getparent().remove(package)
|
|
79
|
+
|
|
80
|
+
root = roottree.getroot()
|
|
81
|
+
packages_element = root.find("packages")
|
|
82
|
+
package_element = etree.SubElement(packages_element, "package")
|
|
83
|
+
package_element.attrib['name'] = codeunit_name
|
|
84
|
+
package_element.attrib['lines-valid'] = root.attrib["lines-valid"]
|
|
85
|
+
package_element.attrib['lines-covered'] = root.attrib["lines-covered"]
|
|
86
|
+
package_element.attrib['line-rate'] = root.attrib["line-rate"]
|
|
87
|
+
package_element.attrib['branches-valid'] = root.attrib["branches-valid"]
|
|
88
|
+
package_element.attrib['branches-covered'] = root.attrib["branches-covered"]
|
|
89
|
+
package_element.attrib['branch-rate'] = root.attrib["branch-rate"]
|
|
90
|
+
package_element.attrib['timestamp'] = root.attrib["timestamp"]
|
|
91
|
+
package_element.attrib['complexity'] = root.attrib["complexity"]
|
|
92
|
+
|
|
93
|
+
classes_element = etree.SubElement(package_element, "classes")
|
|
94
|
+
|
|
95
|
+
for existing_class in existing_classes:
|
|
96
|
+
classes_element.append(existing_class)
|
|
97
|
+
|
|
98
|
+
result = etree.tostring(roottree, pretty_print=True).decode("utf-8")
|
|
99
|
+
GeneralUtilities.write_text_to_file(target_file, result)
|
|
100
|
+
|
|
101
|
+
# post tasks
|
|
102
|
+
self.run_testcases_common_post_task(repository_folder, codeunit_name, True, self.get_target_environment_type())
|
|
103
|
+
|
|
104
|
+
@GeneralUtilities.check_arguments
|
|
105
|
+
def __rename_packagename_in_coverage_file(self, file: str, codeunit_name: str) -> None:
|
|
106
|
+
root: etree._ElementTree = etree.parse(file)
|
|
107
|
+
packages = root.xpath('//coverage/packages/package')
|
|
108
|
+
for package in packages:
|
|
109
|
+
package.attrib['name'] = codeunit_name
|
|
110
|
+
result = etree.tostring(root).decode("utf-8")
|
|
111
|
+
GeneralUtilities.write_text_to_file(file, result)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@GeneralUtilities.check_arguments
|
|
115
|
+
def standardized_tasks_build_bom_for_node_project(self) -> None:
|
|
116
|
+
relative_path_to_bom_file = f"Other/Artifacts/BOM/{os.path.basename(self.get_codeunit_folder())}.{self.tfcps_Tools_General.get_version_of_codeunit(self.get_codeunit_file())}.sbom.xml"
|
|
117
|
+
self._protected_sc.run_with_epew("cyclonedx-npm", f"--output-format xml --output-file {relative_path_to_bom_file}", self.get_codeunit_folder(),print_live_output=self._protected_sc.log.loglevel==LogLevel.Diagnostic,encode_argument_in_base64=True)
|
|
118
|
+
self._protected_sc.format_xml_file(self.get_codeunit_folder()+"/"+relative_path_to_bom_file)
|
|
119
|
+
|
|
120
|
+
def get_dependencies(self)->dict[str,set[str]]:
|
|
121
|
+
return dict[str,set[str]]()#TODO
|
|
122
|
+
|
|
123
|
+
@GeneralUtilities.check_arguments
|
|
124
|
+
def get_available_versions(self,dependencyname:str)->list[str]:
|
|
125
|
+
return []#TODO
|
|
126
|
+
|
|
127
|
+
@GeneralUtilities.check_arguments
|
|
128
|
+
def set_dependency_version(self,name:str,new_version:str)->None:
|
|
129
|
+
raise ValueError(f"Operation is not implemented.")
|
|
130
|
+
|
|
131
|
+
@GeneralUtilities.check_arguments
|
|
132
|
+
def add_culture_chooser(self,site_title:str,supported_cultures:list[str])->None:
|
|
133
|
+
output_folder=self.get_codeunit_folder()+"/Other/Artifacts/BuildResult_WebApplication/browser"
|
|
134
|
+
GeneralUtilities.assert_folder_exists(output_folder)
|
|
135
|
+
cc:HTTPMaintenanceOverheadHelper=HTTPMaintenanceOverheadHelper()
|
|
136
|
+
|
|
137
|
+
index_html_file=output_folder+"/index.html"
|
|
138
|
+
GeneralUtilities.ensure_file_exists(index_html_file)
|
|
139
|
+
index_html_content=cc.get_index_html(site_title)
|
|
140
|
+
GeneralUtilities.write_text_to_file(index_html_file, index_html_content)
|
|
141
|
+
|
|
142
|
+
cc_script_file=output_folder+"/CultureChooser.js"
|
|
143
|
+
GeneralUtilities.ensure_file_exists(cc_script_file)
|
|
144
|
+
cc_script_content=cc.get_culture_chooser_script(supported_cultures)
|
|
145
|
+
GeneralUtilities.write_text_to_file(cc_script_file, cc_script_content)
|
|
146
|
+
|
|
147
|
+
@GeneralUtilities.check_arguments
|
|
148
|
+
def add_maintenance_site(self,site_title:str)->None:
|
|
149
|
+
output_folder_base=self.get_codeunit_folder()+"/Other/Artifacts/BuildResult_WebApplication"
|
|
150
|
+
GeneralUtilities.assert_folder_exists(output_folder_base)
|
|
151
|
+
output_folder=os.path.join(output_folder_base,"maintenance")
|
|
152
|
+
GeneralUtilities.ensure_directory_exists(output_folder)
|
|
153
|
+
cc:HTTPMaintenanceOverheadHelper=HTTPMaintenanceOverheadHelper()
|
|
154
|
+
|
|
155
|
+
maintenance_file=output_folder+"/MaintenanceSite.html"
|
|
156
|
+
GeneralUtilities.ensure_file_exists(maintenance_file)
|
|
157
|
+
maintenance_content=cc.get_maintenance_file(site_title)
|
|
158
|
+
GeneralUtilities.write_text_to_file(maintenance_file, maintenance_content)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@GeneralUtilities.check_arguments
|
|
162
|
+
def get_available_cultures_for_angular_app(self)->None:
|
|
163
|
+
return self._protected_sc.get_available_cultures_for_angular_app(self.get_codeunit_folder()+"/angular.json")
|
|
164
|
+
|
|
165
|
+
@GeneralUtilities.check_arguments
|
|
166
|
+
def __ensure_translations_exist(self,languages:list[str])->None:
|
|
167
|
+
base_file=os.path.join(self.get_codeunit_folder(),"Other","Resources","Translations",f"messages.xlf")
|
|
168
|
+
for language in languages:
|
|
169
|
+
target_file=os.path.join(self.get_codeunit_folder(),"Other","Resources","Translations",f"messages.{language}.xlf")
|
|
170
|
+
if not os.path.isfile(target_file):
|
|
171
|
+
GeneralUtilities.ensure_file_exists(target_file)
|
|
172
|
+
GeneralUtilities.write_text_to_file(target_file, GeneralUtilities.read_text_from_file(base_file))
|
|
173
|
+
#set new attribute
|
|
174
|
+
tree = ET.parse(target_file)
|
|
175
|
+
root = tree.getroot()
|
|
176
|
+
ns_prefix = "{urn:oasis:names:tc:xliff:document:2.0}"
|
|
177
|
+
for unit in root.findall(f".//{ns_prefix}unit"):
|
|
178
|
+
for segment in unit.findall(f"{ns_prefix}segment"):
|
|
179
|
+
segment.set("state", "initial")
|
|
180
|
+
tree.write(target_file, encoding="utf-8", xml_declaration=True)
|
|
181
|
+
|
|
182
|
+
angular_json_file=self.get_codeunit_folder()+"/angular.json"
|
|
183
|
+
if os.path.isfile(angular_json_file):
|
|
184
|
+
angular_json_path = Path(angular_json_file)
|
|
185
|
+
with angular_json_path.open(encoding="utf-8") as f:
|
|
186
|
+
angular_config = json.load(f)
|
|
187
|
+
i18n_config = angular_config["projects"][self.get_codeunit_name()]["i18n"]
|
|
188
|
+
new_locales = {
|
|
189
|
+
lang: f"Other/Resources/Translations/messages.{lang}.xlf"
|
|
190
|
+
for lang in languages
|
|
191
|
+
}
|
|
192
|
+
i18n_config.setdefault("locales", {}).update(new_locales)
|
|
193
|
+
with angular_json_path.open("w", encoding="utf-8") as f:
|
|
194
|
+
json.dump(angular_config, f, ensure_ascii=False, indent=2)
|
|
195
|
+
|
|
196
|
+
@GeneralUtilities.check_arguments
|
|
197
|
+
def organize_translations(self,languages:list[str])->None:
|
|
198
|
+
self._protected_sc.run_with_epew("npm","run extract-translations",self.get_codeunit_folder())
|
|
199
|
+
self.__ensure_translations_exist(languages)
|
|
200
|
+
self._protected_sc.sync_xlf2_files("messages",languages,os.path.join(self.get_codeunit_folder(),"Other","Resources","Translations"))
|
|
201
|
+
|
|
202
|
+
@GeneralUtilities.check_arguments
|
|
203
|
+
def translate_safe(self,base_language:str="en", throw_if_no_credentials:bool=False)->None:
|
|
204
|
+
"""Translates XLF files if a translation service is configured. The translation service can be configured by creating a file at ~/.ScriptCollection/TranslationServiceProperties.txt with the content 'LibreTranslateAPI=your_api_server_url'."""
|
|
205
|
+
translationservice_file:str=self._protected_sc.get_global_cache_folder()+"/TranslationServiceProperties.txt"
|
|
206
|
+
api_server:str=None
|
|
207
|
+
if os.path.isfile(translationservice_file):
|
|
208
|
+
lines=GeneralUtilities.read_nonempty_lines_from_file(translationservice_file)
|
|
209
|
+
for line in lines:
|
|
210
|
+
if line.startswith("LibreTranslateAPI="):
|
|
211
|
+
api_server=line.replace("LibreTranslateAPI=","").strip()
|
|
212
|
+
if api_server is None:
|
|
213
|
+
if throw_if_no_credentials:
|
|
214
|
+
raise ValueError("No translation service configured. Please create a file at ~/.ScriptCollection/TranslationServiceProperties.txt with the content 'LibreTranslateAPI=your_api_server_url' to enable automatic translation of XLF files.")
|
|
215
|
+
else:
|
|
216
|
+
self.translate(api_server,base_language)
|
|
217
|
+
|
|
218
|
+
@GeneralUtilities.check_arguments
|
|
219
|
+
def translate(self,api_server:str,base_language:str="en")->None:
|
|
220
|
+
folder:str=os.path.join(self.get_codeunit_folder(),"Other","Resources","Translations")
|
|
221
|
+
self._protected_sc.translate_xlf_files_in_folder(folder, base_language, api_server)
|
|
222
|
+
|
|
223
|
+
class TFCPS_CodeUnitSpecific_NodeJS_CLI:
|
|
224
|
+
|
|
225
|
+
@staticmethod
|
|
226
|
+
@GeneralUtilities.check_arguments
|
|
227
|
+
def parse(file:str)->TFCPS_CodeUnitSpecific_NodeJS_Functions:
|
|
228
|
+
parser=TFCPS_CodeUnitSpecific_Base_CLI.get_base_parser()
|
|
229
|
+
#add custom parameter if desired
|
|
230
|
+
args=parser.parse_args()
|
|
231
|
+
result:TFCPS_CodeUnitSpecific_NodeJS_Functions=TFCPS_CodeUnitSpecific_NodeJS_Functions(file,LogLevel(int(args.verbosity)),args.targetenvironmenttype,not args.nocache,args.ispremerge)
|
|
232
|
+
return result
|
|
File without changes
|