ScriptCollection 4.0.42__py3-none-any.whl → 4.0.44__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/ScriptCollectionCore.py +19 -2
- ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py +2 -2
- ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py +84 -4
- ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +1 -1
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py +39 -3
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +66 -10
- {scriptcollection-4.0.42.dist-info → scriptcollection-4.0.44.dist-info}/METADATA +1 -1
- {scriptcollection-4.0.42.dist-info → scriptcollection-4.0.44.dist-info}/RECORD +11 -11
- {scriptcollection-4.0.42.dist-info → scriptcollection-4.0.44.dist-info}/entry_points.txt +1 -0
- {scriptcollection-4.0.42.dist-info → scriptcollection-4.0.44.dist-info}/WHEEL +0 -0
- {scriptcollection-4.0.42.dist-info → scriptcollection-4.0.44.dist-info}/top_level.txt +0 -0
@@ -37,7 +37,7 @@ from .ProgramRunnerPopen import ProgramRunnerPopen
|
|
37
37
|
from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
|
38
38
|
from .SCLog import SCLog, LogLevel
|
39
39
|
|
40
|
-
version = "4.0.
|
40
|
+
version = "4.0.44"
|
41
41
|
__version__ = version
|
42
42
|
|
43
43
|
|
@@ -2473,7 +2473,7 @@ OCR-content:
|
|
2473
2473
|
def get_lines_of_code(self, repository: str, excluded_pattern: list[str]) -> int:
|
2474
2474
|
self.assert_is_git_repository(repository)
|
2475
2475
|
result: int = 0
|
2476
|
-
self.log.log(f"Calculate lines of code in repository '{repository}' with excluded patterns: {', '.join(excluded_pattern)}")
|
2476
|
+
self.log.log(f"Calculate lines of code in repository '{repository}' with excluded patterns: {', '.join(excluded_pattern)}",LogLevel.Debug)
|
2477
2477
|
git_response = self.run_program("git", "ls-files", repository)
|
2478
2478
|
files: list[str] = GeneralUtilities.string_to_lines(git_response[1])
|
2479
2479
|
for file in files:
|
@@ -2509,3 +2509,20 @@ OCR-content:
|
|
2509
2509
|
file_path = os.path.join(root, file)
|
2510
2510
|
arcname = os.path.relpath(file_path, start=folder)
|
2511
2511
|
zipf.write(file_path, arcname)
|
2512
|
+
|
2513
|
+
@GeneralUtilities.check_arguments
|
2514
|
+
def start_local_test_service(self, file: str):
|
2515
|
+
example_folder = os.path.dirname(file)
|
2516
|
+
docker_compose_file = os.path.join(example_folder, "docker-compose.yml")
|
2517
|
+
for service in self.get_services_from_yaml_file(docker_compose_file):
|
2518
|
+
self.kill_docker_container(service)
|
2519
|
+
example_name = os.path.basename(example_folder)
|
2520
|
+
title = f"Test{example_name}"
|
2521
|
+
self.run_program("docker", f"compose -p {title.lower()} up --detach", example_folder, title=title)
|
2522
|
+
|
2523
|
+
@GeneralUtilities.check_arguments
|
2524
|
+
def stop_local_test_service(self, file: str):
|
2525
|
+
example_folder = os.path.dirname(file)
|
2526
|
+
example_name = os.path.basename(example_folder)
|
2527
|
+
title = f"Test{example_name}"
|
2528
|
+
self.run_program("docker", f"compose -p {title.lower()} down", example_folder, title=title)
|
@@ -427,11 +427,11 @@ class TFCPS_CodeUnitSpecific_DotNet_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
427
427
|
GeneralUtilities.ensure_directory_exists(temp_folder)
|
428
428
|
runsettings_file = "runsettings.xml"
|
429
429
|
codeunit_folder = f"{repository_folder}/{codeunit_name}"
|
430
|
-
arg = f"test . -c {dotnet_build_configuration}
|
430
|
+
arg = f"test . -c {dotnet_build_configuration}"
|
431
431
|
if os.path.isfile(os.path.join(codeunit_folder, runsettings_file)):
|
432
432
|
arg = f"{arg} --settings {runsettings_file}"
|
433
433
|
arg = f"{arg} /p:CollectCoverage=true /p:CoverletOutput=../Other/Artifacts/TestCoverage/Testcoverage /p:CoverletOutputFormat=cobertura"
|
434
|
-
self._protected_sc.run_program("dotnet", arg, codeunit_folder, print_live_output=True)
|
434
|
+
test_run_result=self._protected_sc.run_program("dotnet", arg, codeunit_folder, print_live_output=True)#pylint:disable=unused-variable
|
435
435
|
target_file = os.path.join(coverage_file_folder, "TestCoverage.xml")
|
436
436
|
GeneralUtilities.ensure_file_does_not_exist(target_file)
|
437
437
|
os.rename(os.path.join(coverage_file_folder, "Testcoverage.cobertura.xml"), target_file)
|
@@ -1,3 +1,7 @@
|
|
1
|
+
import os
|
2
|
+
import shutil
|
3
|
+
import re
|
4
|
+
import zipfile
|
1
5
|
from ...GeneralUtilities import GeneralUtilities
|
2
6
|
from ...SCLog import LogLevel
|
3
7
|
from ..TFCPS_CodeUnitSpecific_Base import TFCPS_CodeUnitSpecific_Base,TFCPS_CodeUnitSpecific_Base_CLI
|
@@ -9,8 +13,62 @@ class TFCPS_CodeUnitSpecific_Flutter_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
9
13
|
|
10
14
|
|
11
15
|
@GeneralUtilities.check_arguments
|
12
|
-
def build(self) -> None:
|
13
|
-
|
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
|
+
windows_release_folder = os.path.join(src_folder, "build/windows/x64/runner/Release")
|
43
|
+
windows_folder = os.path.join(artifacts_folder, "BuildResult_Windows")
|
44
|
+
GeneralUtilities.ensure_directory_does_not_exist(windows_folder)
|
45
|
+
GeneralUtilities.ensure_directory_exists(windows_folder)
|
46
|
+
GeneralUtilities.copy_content_of_folder(windows_release_folder, windows_folder)
|
47
|
+
elif target == "ios":
|
48
|
+
raise ValueError("building for ios is not implemented yet")
|
49
|
+
elif target == "appbundle":
|
50
|
+
aab_folder = os.path.join(artifacts_folder, "BuildResult_AAB")
|
51
|
+
GeneralUtilities.ensure_directory_does_not_exist(aab_folder)
|
52
|
+
GeneralUtilities.ensure_directory_exists(aab_folder)
|
53
|
+
aab_relase_folder = os.path.join(src_folder, "build/app/outputs/bundle/release")
|
54
|
+
aab_file_original = self._protected_sc.find_file_by_extension(aab_relase_folder, "aab")
|
55
|
+
aab_file = os.path.join(aab_folder, f"{codeunit_name}.aab")
|
56
|
+
shutil.copyfile(aab_file_original, aab_file)
|
57
|
+
|
58
|
+
bundletool = self.tfcps_Tools_General.ensure_androidappbundletool_is_available(None,self.use_cache())
|
59
|
+
apk_folder = os.path.join(artifacts_folder, "BuildResult_APK")
|
60
|
+
GeneralUtilities.ensure_directory_does_not_exist(apk_folder)
|
61
|
+
GeneralUtilities.ensure_directory_exists(apk_folder)
|
62
|
+
apks_file = f"{apk_folder}/{codeunit_name}.apks"
|
63
|
+
self._protected_sc.run_program("java", f"-jar {bundletool} build-apks --bundle={aab_file} --output={apks_file} --mode=universal", aab_relase_folder)
|
64
|
+
with zipfile.ZipFile(apks_file, "r") as zip_ref:
|
65
|
+
zip_ref.extract("universal.apk", apk_folder)
|
66
|
+
GeneralUtilities.ensure_file_does_not_exist(apks_file)
|
67
|
+
os.rename(f"{apk_folder}/universal.apk", f"{apk_folder}/{codeunit_name}.apk")
|
68
|
+
else:
|
69
|
+
raise ValueError(f"Not supported target: {target}")
|
70
|
+
self.copy_source_files_to_output_directory()
|
71
|
+
#TODO check for updateable dependencies (in a unified way)
|
14
72
|
|
15
73
|
@GeneralUtilities.check_arguments
|
16
74
|
def linting(self) -> None:
|
@@ -29,9 +87,31 @@ class TFCPS_CodeUnitSpecific_Flutter_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
29
87
|
pass#TODO
|
30
88
|
|
31
89
|
@GeneralUtilities.check_arguments
|
32
|
-
def run_testcases(self) -> None:
|
33
|
-
|
90
|
+
def run_testcases(self,package_name:str) -> None:
|
91
|
+
codeunit_folder = self.get_codeunit_folder()
|
92
|
+
repository_folder = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
|
93
|
+
codeunit_name = os.path.basename(codeunit_folder)
|
94
|
+
src_folder = GeneralUtilities.resolve_relative_path(package_name, codeunit_folder)
|
95
|
+
|
96
|
+
self._protected_sc.run_with_epew("flutter", "test --coverage", src_folder)
|
97
|
+
test_coverage_folder_relative = "Other/Artifacts/TestCoverage"
|
98
|
+
test_coverage_folder = GeneralUtilities.resolve_relative_path(test_coverage_folder_relative, codeunit_folder)
|
99
|
+
GeneralUtilities.ensure_directory_exists(test_coverage_folder)
|
100
|
+
coverage_file_relative = f"{test_coverage_folder_relative}/TestCoverage.xml"
|
101
|
+
coverage_file = GeneralUtilities.resolve_relative_path(coverage_file_relative, codeunit_folder)
|
102
|
+
self._protected_sc.run_with_epew("lcov_cobertura", f"coverage/lcov.info --base-dir . --excludes test --output ../{coverage_file_relative} --demangle", src_folder)
|
34
103
|
|
104
|
+
# format correctly
|
105
|
+
content = GeneralUtilities.read_text_from_file(coverage_file)
|
106
|
+
content = re.sub('<![^<]+>', '', content)
|
107
|
+
content = re.sub('\\\\', '/', content)
|
108
|
+
content = re.sub('\\ name=\\"lib\\"', '', content)
|
109
|
+
content = re.sub('\\ filename=\\"lib/', f' filename="{package_name}/lib/', content)
|
110
|
+
GeneralUtilities.write_text_to_file(coverage_file, content)
|
111
|
+
self.tfcps_Tools_General.merge_packages(coverage_file, self.get_codeunit_name())
|
112
|
+
self.tfcps_Tools_General.calculate_entire_line_rate(coverage_file)
|
113
|
+
self.run_testcases_common_post_task(repository_folder, codeunit_name, True, self.get_target_environment_type())
|
114
|
+
|
35
115
|
class TFCPS_CodeUnitSpecific_Flutter_CLI:
|
36
116
|
|
37
117
|
@staticmethod
|
@@ -369,7 +369,7 @@ class TFCPS_CodeUnitSpecific_Base(ABC):
|
|
369
369
|
found_existing_files = True
|
370
370
|
else:
|
371
371
|
coverage_report_class.getparent().remove(coverage_report_class)
|
372
|
-
GeneralUtilities.assert_condition(found_existing_files, f"No existing files in
|
372
|
+
GeneralUtilities.assert_condition(found_existing_files, f"No existing files in testcoverage-report-file \"{testcoveragefile}\".")
|
373
373
|
result = etree.tostring(root).decode("utf-8")
|
374
374
|
GeneralUtilities.write_text_to_file(testcoveragefile, result)
|
375
375
|
|
@@ -28,6 +28,21 @@ class TFCPS_CodeUnit_BuildCodeUnits:
|
|
28
28
|
self.additionalargumentsfile=additionalargumentsfile
|
29
29
|
self.__is_pre_merge=is_pre_merge
|
30
30
|
|
31
|
+
@GeneralUtilities.check_arguments
|
32
|
+
def __save_lines_of_code(self, repository_folder: str, project_version: str) -> None:
|
33
|
+
loc = self.sc.get_lines_of_code_with_default_excluded_patterns(repository_folder)
|
34
|
+
loc_metric_folder = os.path.join(repository_folder, "Other", "Metrics")
|
35
|
+
GeneralUtilities.ensure_directory_exists(loc_metric_folder)
|
36
|
+
loc_metric_file = os.path.join(loc_metric_folder, "LinesOfCode.csv")
|
37
|
+
GeneralUtilities.ensure_file_exists(loc_metric_file)
|
38
|
+
old_lines = GeneralUtilities.read_lines_from_file(loc_metric_file)
|
39
|
+
new_lines = []
|
40
|
+
for line in old_lines:
|
41
|
+
if not line.startswith(f"v{project_version};"):
|
42
|
+
new_lines.append(line)
|
43
|
+
new_lines.append(f"v{project_version};{loc}")
|
44
|
+
GeneralUtilities.write_lines_to_file(loc_metric_file, new_lines)
|
45
|
+
|
31
46
|
@GeneralUtilities.check_arguments
|
32
47
|
def build_codeunits(self) -> None:
|
33
48
|
self.sc.log.log(GeneralUtilities.get_line())
|
@@ -61,9 +76,6 @@ class TFCPS_CodeUnit_BuildCodeUnits:
|
|
61
76
|
from_day = datetime(now.year, now.month, now.day, 0, 0, 0)
|
62
77
|
self.tFCPS_Other.mark_current_version_as_supported(self.repository,project_version,from_day,until_day)
|
63
78
|
|
64
|
-
#TODO search for secrets using TruffleHog
|
65
|
-
#TODO run static code analysis tool to search for vulnerabilities
|
66
|
-
|
67
79
|
codeunits:list[str]=self.tFCPS_Other.get_codeunits(self.repository)
|
68
80
|
self.sc.log.log("Codeunits will be built in the following order:")
|
69
81
|
for codeunit_name in codeunits:
|
@@ -72,10 +84,34 @@ class TFCPS_CodeUnit_BuildCodeUnits:
|
|
72
84
|
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())
|
73
85
|
self.sc.log.log(GeneralUtilities.get_line())
|
74
86
|
tFCPS_CodeUnit_BuildCodeUnit.build_codeunit()
|
87
|
+
|
88
|
+
#TODO run static code analysis tool to search for vulnerabilities
|
89
|
+
self.__search_for_secrets()
|
90
|
+
self.__save_lines_of_code(self.repository,self.tFCPS_Other.get_version_of_project(self.repository))
|
91
|
+
|
75
92
|
self.sc.log.log(GeneralUtilities.get_line())
|
76
93
|
self.sc.log.log("Finished building codeunits.")
|
77
94
|
self.sc.log.log(GeneralUtilities.get_line())
|
78
95
|
|
96
|
+
def __search_for_secrets(self):
|
97
|
+
exe_paths=self.tFCPS_Other.ensure_trufflehog_is_available()
|
98
|
+
exe_path:str=None
|
99
|
+
if GeneralUtilities.current_system_is_windows():
|
100
|
+
exe_path=exe_paths["Windows"]
|
101
|
+
elif GeneralUtilities.current_system_is_linux():
|
102
|
+
exe_path=exe_paths["Linux"]
|
103
|
+
else:
|
104
|
+
raise ValueError("unsupported")#TODO check for macos
|
105
|
+
result=self.sc.run_program(exe_path,"filesystem . --json",self.repository)
|
106
|
+
|
107
|
+
enabled:bool=False
|
108
|
+
if enabled:
|
109
|
+
self.sc.log.log("Secret-scan-result:")#TODO replace this by real analysis
|
110
|
+
for line in GeneralUtilities.string_to_lines(result[1]):
|
111
|
+
self.sc.log.log(line)
|
112
|
+
for line in GeneralUtilities.string_to_lines(result[2]):
|
113
|
+
self.sc.log.log(line,LogLevel.Error)
|
114
|
+
|
79
115
|
@GeneralUtilities.check_arguments
|
80
116
|
def use_cache(self) -> bool:
|
81
117
|
return self.__use_cache
|
@@ -5,6 +5,7 @@ from pathlib import Path
|
|
5
5
|
import shutil
|
6
6
|
import zipfile
|
7
7
|
import tarfile
|
8
|
+
import time
|
8
9
|
import re
|
9
10
|
import sys
|
10
11
|
import json
|
@@ -61,15 +62,18 @@ class TFCPS_Tools_General:
|
|
61
62
|
if not file_exists:
|
62
63
|
self.__sc.log.log(f"Download Asset \"{githubuser}/{githubprojectname}: {resource_name}\" from GitHub to global cache...", LogLevel.Information)
|
63
64
|
GeneralUtilities.ensure_folder_exists_and_is_empty(resource_folder)
|
64
|
-
headers = { 'User-Agent': 'Mozilla/5.0
|
65
|
+
headers = { 'User-Agent': 'Mozilla/5.0'}
|
65
66
|
self.__add_github_api_key_if_available(headers)
|
66
67
|
url = f"https://api.github.com/repos/{githubuser}/{githubprojectname}/releases/latest"
|
67
68
|
self.__sc.log.log(f"Download \"{url}\"...", LogLevel.Debug)
|
69
|
+
time.sleep(2)
|
68
70
|
response = requests.get(url, headers=headers, allow_redirects=True, timeout=(10, 10))
|
69
|
-
|
71
|
+
response_json=response.json()
|
72
|
+
latest_version = response_json["tag_name"]
|
70
73
|
filename_on_github = get_filename_on_github(latest_version)
|
71
74
|
link = f"https://github.com/{githubuser}/{githubprojectname}/releases/download/{latest_version}/{filename_on_github}"
|
72
|
-
|
75
|
+
time.sleep(2)
|
76
|
+
with requests.get(link, headers=headers, stream=True, allow_redirects=True, timeout=(5, 600)) as r:
|
73
77
|
r.raise_for_status()
|
74
78
|
total_size = int(r.headers.get("Content-Length", 0))
|
75
79
|
downloaded = 0
|
@@ -555,6 +559,38 @@ class TFCPS_Tools_General:
|
|
555
559
|
lines.append("@enduml")
|
556
560
|
|
557
561
|
GeneralUtilities.write_lines_to_file(target_file, lines)
|
562
|
+
|
563
|
+
@GeneralUtilities.check_arguments
|
564
|
+
def ensure_trufflehog_is_available(self,enforce_update:bool=False) -> dict[str,str]:
|
565
|
+
def download_and_extract(osname: str, osname_in_github_asset: str, extension: str):
|
566
|
+
resource_name: str = f"TruffleHog_{osname}"
|
567
|
+
zip_filename: str = f"{resource_name}.{extension}"
|
568
|
+
target_folder_unextracted = os.path.join(self.get_global_cache_folder(),"Tools",resource_name+"_Unextracted")
|
569
|
+
target_folder_extracted = os.path.join(self.get_global_cache_folder(),"Tools",resource_name)
|
570
|
+
update:bool=not os.path.isdir(target_folder_extracted) or GeneralUtilities.folder_is_empty(target_folder_extracted) or enforce_update
|
571
|
+
if update:
|
572
|
+
downloaded_file=self.ensure_file_from_github_assets_is_available_with_retry(target_folder_unextracted, "trufflesecurity", "trufflehog", resource_name+"_Unextracted", zip_filename, lambda latest_version: f"trufflehog_{latest_version[1:]}_{osname_in_github_asset}_amd64.tar.gz",enforce_update=enforce_update)
|
573
|
+
#TODO add option to also download arm-version
|
574
|
+
local_zip_file: str = downloaded_file
|
575
|
+
GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder_extracted)
|
576
|
+
if extension == "zip":
|
577
|
+
with zipfile.ZipFile(local_zip_file, 'r') as zip_ref:
|
578
|
+
zip_ref.extractall(target_folder_extracted)
|
579
|
+
elif extension == "tar.gz":
|
580
|
+
with tarfile.open(local_zip_file, "r:gz") as tar:
|
581
|
+
tar.extractall(path=target_folder_extracted)
|
582
|
+
else:
|
583
|
+
raise ValueError(f"Unknown extension: \"{extension}\"")
|
584
|
+
GeneralUtilities.ensure_directory_does_not_exist(target_folder_unextracted)
|
585
|
+
GeneralUtilities.assert_folder_exists(target_folder_extracted)
|
586
|
+
executable=[f for f in GeneralUtilities.get_all_files_of_folder(target_folder_extracted) if os.path.basename(f).startswith("trufflehog")][0]
|
587
|
+
return executable
|
588
|
+
|
589
|
+
result=dict[str,str]()
|
590
|
+
result["Windows"]=download_and_extract("Windows", "windows", "tar.gz")
|
591
|
+
result["Linux"]=download_and_extract("Linux", "linux", "tar.gz")
|
592
|
+
result["MacOS"]=download_and_extract("MacOS", "darwin", "tar.gz")
|
593
|
+
return result
|
558
594
|
|
559
595
|
@GeneralUtilities.check_arguments
|
560
596
|
def generate_tasksfile_from_workspace_file(self, repository_folder: str, append_cli_args_at_end: bool = False) -> None:
|
@@ -671,9 +707,9 @@ class TFCPS_Tools_General:
|
|
671
707
|
if repository_subname is not None:
|
672
708
|
target_folder = f"{resrepo_data_folder}/{repository_subname}"
|
673
709
|
|
674
|
-
update:bool=GeneralUtilities.folder_is_empty(target_folder) or not use_cache
|
710
|
+
update:bool=not os.path.isdir(target_folder) or GeneralUtilities.folder_is_empty(target_folder) or not use_cache
|
675
711
|
if update:
|
676
|
-
self.__sc.
|
712
|
+
self.__sc.log.log(f"Clone {remote_repository_link} as resource...", LogLevel.Information)
|
677
713
|
GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder)
|
678
714
|
self.__sc.run_program("git", f"clone --recurse-submodules {remote_repository_link} {target_folder}")
|
679
715
|
self.__sc.run_program("git", f"checkout {latest_version}", target_folder)
|
@@ -755,7 +791,7 @@ class TFCPS_Tools_General:
|
|
755
791
|
@GeneralUtilities.check_arguments
|
756
792
|
def do_npm_install(self, package_json_folder: str, npm_force: bool,use_cache:bool) -> None:
|
757
793
|
target_folder:str=os.path.join(package_json_folder,"node_modules")
|
758
|
-
update:bool=
|
794
|
+
update:bool=not os.path.isdir(target_folder) or GeneralUtilities.folder_is_empty(target_folder) or not use_cache
|
759
795
|
if update:
|
760
796
|
self.__sc.log.log("Do npm-install...")
|
761
797
|
argument1 = "install"
|
@@ -897,7 +933,7 @@ class TFCPS_Tools_General:
|
|
897
933
|
GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder)
|
898
934
|
GeneralUtilities.copy_content_of_folder(source_folder, target_folder)
|
899
935
|
|
900
|
-
|
936
|
+
|
901
937
|
@GeneralUtilities.check_arguments
|
902
938
|
def merge_packages(self,coverage_file:str,package_name:str) -> None:
|
903
939
|
tree = etree.parse(coverage_file)
|
@@ -906,7 +942,7 @@ class TFCPS_Tools_General:
|
|
906
942
|
all_classes = []
|
907
943
|
for pkg in packages:
|
908
944
|
pkg_name:str=pkg.get("name")
|
909
|
-
if pkg_name==package_name or pkg_name.startswith(f"{package_name}."):
|
945
|
+
if len(packages)==1 or ( pkg_name==package_name or pkg_name.startswith(f"{package_name}.")):
|
910
946
|
classes = pkg.find("classes")
|
911
947
|
if classes is not None:
|
912
948
|
all_classes.extend(classes.findall("class"))
|
@@ -918,11 +954,11 @@ class TFCPS_Tools_General:
|
|
918
954
|
packages_node.clear()
|
919
955
|
packages_node.append(new_package)
|
920
956
|
tree.write(coverage_file, pretty_print=True, xml_declaration=True, encoding="UTF-8")
|
921
|
-
self.
|
957
|
+
self.calculate_entire_line_rate(coverage_file)
|
922
958
|
|
923
959
|
|
924
960
|
@GeneralUtilities.check_arguments
|
925
|
-
def
|
961
|
+
def calculate_entire_line_rate(self,coverage_file:str) -> None:
|
926
962
|
tree = etree.parse(coverage_file)
|
927
963
|
root = tree.getroot()
|
928
964
|
package = root.find("./packages/package")
|
@@ -943,6 +979,7 @@ class TFCPS_Tools_General:
|
|
943
979
|
package.set("line-rate", str(line_rate))
|
944
980
|
tree.write(coverage_file, pretty_print=True, xml_declaration=True, encoding="UTF-8")
|
945
981
|
|
982
|
+
|
946
983
|
@GeneralUtilities.check_arguments
|
947
984
|
def generate_api_client_from_dependent_codeunit_for_angular(self, codeunit_folder:str, name_of_api_providing_codeunit: str, generated_program_part_name: str,language:str,use_cache:bool) -> None:
|
948
985
|
target_subfolder_in_codeunit = f"src/app/generated/{generated_program_part_name}"
|
@@ -1150,3 +1187,22 @@ class TFCPS_Tools_General:
|
|
1150
1187
|
self.__sc.run_program_with_retry("docker", f"push {remote_image_version}")
|
1151
1188
|
if push_readme:
|
1152
1189
|
self.__sc.run_program_with_retry("docker-pushrm", f"{remote_repo}", codeunit_folder)
|
1190
|
+
|
1191
|
+
def prepare_building_codeunits(self,repository_folder:str,use_cache:bool,generate_development_certificate:bool):
|
1192
|
+
if generate_development_certificate:
|
1193
|
+
self.ensure_certificate_authority_for_development_purposes_is_generated(repository_folder)
|
1194
|
+
self.generate_certificate_for_development_purposes_for_product(repository_folder)
|
1195
|
+
self.generate_tasksfile_from_workspace_file(repository_folder)
|
1196
|
+
self.generate_codeunits_overview_diagram(repository_folder)
|
1197
|
+
self.generate_svg_files_from_plantuml_files_for_repository(repository_folder,use_cache)
|
1198
|
+
|
1199
|
+
@GeneralUtilities.check_arguments
|
1200
|
+
def copy_product_resource_to_codeunit_resource_folder(self, codeunit_folder: str, resourcename: str) -> None:
|
1201
|
+
repository_folder = GeneralUtilities.resolve_relative_path(f"..", codeunit_folder)
|
1202
|
+
self.__sc.assert_is_git_repository(repository_folder)
|
1203
|
+
src_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resourcename}", repository_folder)
|
1204
|
+
GeneralUtilities.assert_condition(os.path.isdir(src_folder), f"Required product-resource {resourcename} does not exist. Expected folder: {src_folder}")
|
1205
|
+
trg_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resourcename}", codeunit_folder)
|
1206
|
+
GeneralUtilities.ensure_directory_does_not_exist(trg_folder)
|
1207
|
+
GeneralUtilities.ensure_directory_exists(trg_folder)
|
1208
|
+
GeneralUtilities.copy_content_of_folder(src_folder, trg_folder)
|
@@ -9,34 +9,34 @@ ScriptCollection/ProgramRunnerEpew.py,sha256=TJdDx9zIMSiCaXh8X-ekrMlbXfGtmd0Mmyx
|
|
9
9
|
ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrRjAPIwT5Y,37
|
10
10
|
ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
|
11
11
|
ScriptCollection/SCLog.py,sha256=dxGOI4E9lG5v9jk_LajXCkM5nghliCDV8YB8Ihn160s,4541
|
12
|
-
ScriptCollection/ScriptCollectionCore.py,sha256=
|
12
|
+
ScriptCollection/ScriptCollectionCore.py,sha256=XzWxKdyl8w0b5_7dBpu2Wiv52siu_jNjvRfWClQ2Rls,142113
|
13
13
|
ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py,sha256=
|
14
|
+
ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py,sha256=2Ng-GyKWQ6FfTUmogd7g-xF6_XeTMxvkeJddagxFR5o,25853
|
15
15
|
ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py,sha256=4rYKgTAga11NiDx8YUqz3K_Q4eX_n3kC6lvNdXEa24s,7389
|
16
|
-
ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py,sha256=
|
16
|
+
ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py,sha256=EH5yV33emYfbYqdikrPgW9UdF7UYV6rpBS1JGHNxA6M,7483
|
17
17
|
ScriptCollection/TFCPS/TFCPS_CreateRelease.py,sha256=bcJlfI062Eoq7MOIhun-_iNG7SdO1ZIuC_cylaoLI1s,6332
|
18
18
|
ScriptCollection/TFCPS/TFCPS_Generic.py,sha256=O-0guM_LJCcZmPZJhMgTvXD2RXUJEBWWv6Bt6hDFhvM,1943
|
19
19
|
ScriptCollection/TFCPS/TFCPS_MergeToMain.py,sha256=41g219jaBRZ2VQCrWM4-Trvervrt8b5oATPwIIGNpag,7244
|
20
20
|
ScriptCollection/TFCPS/TFCPS_MergeToStable.py,sha256=ifB1K6A903vvfH0LvtiFbZgYSgR94thfEI-jjf40LpU,21653
|
21
21
|
ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py,sha256=CxdwUklhZVuJGp0vcokoH_KMXFzmlUlZwj77xFYijho,2242
|
22
22
|
ScriptCollection/TFCPS/TFCPS_Tools_Dependencies.py,sha256=o7HI3ki3WWqlAiUsrh3Lky_w6UhYh9hdjYPGOhubQGA,414
|
23
|
-
ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=
|
23
|
+
ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=ONdapcG29BCh1CwJR_8jHzll0W5QuyZ-EPJrxMcMIqU,76441
|
24
24
|
ScriptCollection/TFCPS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=-g8h2gCf9rh0KJXUBeQD5d0qLJgBU3Q8DNZXM1UXC04,5259
|
26
26
|
ScriptCollection/TFCPS/Docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationBase.py,sha256=bT6Gd5pQpZCw4OQz6HWkPCSn5z__eUUEisABLDSxd0o,200
|
28
28
|
ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationGenerate.py,sha256=QyjOfMY22JWCvKjMelHiDWbJiWqotOfebpJpgDUaoO4,237
|
29
29
|
ScriptCollection/TFCPS/DotNet/CertificateGeneratorInformationNoGenerate.py,sha256=i0zEGehj0sttxjjZtoq2KFSKp_ulxVyWp_ZgAhIY_So,241
|
30
|
-
ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py,sha256=
|
30
|
+
ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py,sha256=ufeWuqtNOPAtEyHayxHGPdjiJsT0lxYR2gAWle9p7T4,31031
|
31
31
|
ScriptCollection/TFCPS/DotNet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
|
-
ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py,sha256=
|
32
|
+
ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py,sha256=TIR95f6TVOnW25ieX9q4RUi1FogbYEfrlZOcZ1aE014,6969
|
33
33
|
ScriptCollection/TFCPS/Flutter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
34
|
ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=dnuDlQXThFmhe6EbUAWmGhx7AAYGL0lVUqsrhOgtmC8,6255
|
35
35
|
ScriptCollection/TFCPS/NodeJS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py,sha256=q7msAxCb5VIZ-xhFg1MfzUvWomQRKYldqmW42KFhyMU,6868
|
37
37
|
ScriptCollection/TFCPS/Python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
|
-
scriptcollection-4.0.
|
39
|
-
scriptcollection-4.0.
|
40
|
-
scriptcollection-4.0.
|
41
|
-
scriptcollection-4.0.
|
42
|
-
scriptcollection-4.0.
|
38
|
+
scriptcollection-4.0.44.dist-info/METADATA,sha256=DaIE8QIbw3p85KpjMgddKuS4AgEynTUTTauJD5LL8lo,7688
|
39
|
+
scriptcollection-4.0.44.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
40
|
+
scriptcollection-4.0.44.dist-info/entry_points.txt,sha256=RhfJxpWvSMIkdQ_1Pan1uXPTgYCTD1EcP0ZshkA2vtA,4366
|
41
|
+
scriptcollection-4.0.44.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
|
42
|
+
scriptcollection-4.0.44.dist-info/RECORD,,
|
@@ -56,6 +56,7 @@ scsetcontentoffile = ScriptCollection.Executables:SetContentOfFile
|
|
56
56
|
scshow2faasqrcode = ScriptCollection.Executables:Show2FAAsQRCode
|
57
57
|
scshowmissingfiles = ScriptCollection.Executables:ShowMissingFiles
|
58
58
|
scsigncertificate = ScriptCollection.Executables:SignCertificate
|
59
|
+
scupdatedependencies = ScriptCollection.Executables:UpdateDependencies
|
59
60
|
scupdateimagesindockercomposefile = ScriptCollection.Executables:UpdateImagesInDockerComposeFile
|
60
61
|
scupdatenugetpackagesincsharpproject = ScriptCollection.Executables:UpdateNugetpackagesInCsharpProject
|
61
62
|
scupdatetimestampinfile = ScriptCollection.Executables:UpdateTimestampInFile
|
File without changes
|
File without changes
|