ScriptCollection 4.0.50__py3-none-any.whl → 4.0.52__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/ProgramRunnerSudo.py +108 -0
- ScriptCollection/ScriptCollectionCore.py +9 -8
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py +5 -5
- ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py +0 -7
- ScriptCollection/TFCPS/TFCPS_Tools_General.py +52 -0
- {scriptcollection-4.0.50.dist-info → scriptcollection-4.0.52.dist-info}/METADATA +1 -1
- {scriptcollection-4.0.50.dist-info → scriptcollection-4.0.52.dist-info}/RECORD +10 -10
- ScriptCollection/ProgramRunnerEpew.py +0 -148
- {scriptcollection-4.0.50.dist-info → scriptcollection-4.0.52.dist-info}/WHEEL +0 -0
- {scriptcollection-4.0.50.dist-info → scriptcollection-4.0.52.dist-info}/entry_points.txt +0 -0
- {scriptcollection-4.0.50.dist-info → scriptcollection-4.0.52.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
from subprocess import Popen
|
2
|
+
from .GeneralUtilities import GeneralUtilities
|
3
|
+
from .ProgramRunnerBase import ProgramRunnerBase
|
4
|
+
from .ScriptCollectionCore import ScriptCollectionCore
|
5
|
+
|
6
|
+
|
7
|
+
class SudoPopenReader:
|
8
|
+
content: bytes = None
|
9
|
+
|
10
|
+
def __init__(self, content: bytes):
|
11
|
+
self.content = content
|
12
|
+
|
13
|
+
def readable(self) -> bool:
|
14
|
+
return True
|
15
|
+
|
16
|
+
def read(self) -> bytes:
|
17
|
+
return self.content
|
18
|
+
|
19
|
+
|
20
|
+
class SudoPopen:
|
21
|
+
returncode: int = None
|
22
|
+
stdout_str: str = None
|
23
|
+
stderr_str: str = None
|
24
|
+
pid: int = None
|
25
|
+
stdout: bytes = None
|
26
|
+
stderr: bytes = None
|
27
|
+
|
28
|
+
def __init__(self, exitcode: int, stdout: str, stderr: str, pid: int):
|
29
|
+
self.returncode: int = exitcode
|
30
|
+
self.stdout_str: str = stdout
|
31
|
+
self.stdout = str.encode(self.stdout_str)
|
32
|
+
self.stderr_str: str = stderr
|
33
|
+
self.stderr = str.encode(self.stderr_str)
|
34
|
+
self.pid = pid
|
35
|
+
|
36
|
+
def communicate(self):
|
37
|
+
return (self.stdout, self.stderr)
|
38
|
+
|
39
|
+
def wait(self):
|
40
|
+
return self.returncode
|
41
|
+
|
42
|
+
def poll(self) -> object:
|
43
|
+
return self.returncode
|
44
|
+
|
45
|
+
def __enter__(self):
|
46
|
+
return self
|
47
|
+
|
48
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
49
|
+
pass
|
50
|
+
|
51
|
+
|
52
|
+
class ProgramRunnerSudo(ProgramRunnerBase):
|
53
|
+
__sc: ScriptCollectionCore
|
54
|
+
__password: str
|
55
|
+
|
56
|
+
@GeneralUtilities.check_arguments
|
57
|
+
def __init__(self,user_password:str):
|
58
|
+
GeneralUtilities.assert_condition(GeneralUtilities.current_system_is_linux(), "SudoRunner can only be only executed on Linux.")
|
59
|
+
self.__sc = ScriptCollectionCore()
|
60
|
+
self.__password = user_password
|
61
|
+
|
62
|
+
@GeneralUtilities.check_arguments
|
63
|
+
def will_be_executed_locally(self) -> bool:
|
64
|
+
return True
|
65
|
+
|
66
|
+
@GeneralUtilities.check_arguments
|
67
|
+
def run_program_internal(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None) -> tuple[int, str, str, int]:
|
68
|
+
argument = program+" " + ' '.join(GeneralUtilities.args_array_surround_with_quotes_if_required(arguments_as_array))
|
69
|
+
argument = f"echo {self.__password} | sudo -k -S {argument}" # TODO maybe add "exit" somewhere before argument or before sudo to correctly return the exit-code"
|
70
|
+
result = self.__sc.run_program_argsasarray("sh", ["-c", argument], working_directory)
|
71
|
+
return result
|
72
|
+
|
73
|
+
@GeneralUtilities.check_arguments
|
74
|
+
def run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> Popen:
|
75
|
+
if interactive:
|
76
|
+
raise ValueError("Interactive execution is not supported in Sudo-runner")
|
77
|
+
r: tuple[int, str, str, int] = self.run_program_internal(program, arguments_as_array, working_directory, custom_argument)
|
78
|
+
popen: SudoPopen = SudoPopen(r[0], r[1], r[2], r[3])
|
79
|
+
return popen
|
80
|
+
|
81
|
+
# Return-values program_runner: Exitcode, StdOut, StdErr, Pid
|
82
|
+
@GeneralUtilities.check_arguments
|
83
|
+
def wait(self, process: Popen, custom_argument: object) -> tuple[int, str, str, int]:
|
84
|
+
raise ValueError("Wait is not supported in Sudo-runner")
|
85
|
+
|
86
|
+
# Return-values program_runner: Exitcode, StdOut, StdErr, Pid
|
87
|
+
@GeneralUtilities.check_arguments
|
88
|
+
def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
|
89
|
+
if interactive:
|
90
|
+
raise ValueError("Interactive execution is not supported in Sudo-runner")
|
91
|
+
return self.run_program_internal(program, arguments_as_array, working_directory, custom_argument)
|
92
|
+
|
93
|
+
# Return-values program_runner: Exitcode, StdOut, StdErr, Pid
|
94
|
+
@GeneralUtilities.check_arguments
|
95
|
+
def run_program(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
|
96
|
+
if interactive:
|
97
|
+
raise ValueError("Interactive execution is not supported in Sudo-runner")
|
98
|
+
return self.run_program_internal(program, arguments.split(" "), working_directory, custom_argument)
|
99
|
+
|
100
|
+
# Return-values program_runner: Pid
|
101
|
+
@GeneralUtilities.check_arguments
|
102
|
+
def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
|
103
|
+
raise ValueError("Async execution is not supported in Sudo-runner")
|
104
|
+
|
105
|
+
# Return-values program_runner: Pid
|
106
|
+
@GeneralUtilities.check_arguments
|
107
|
+
def run_program_async(self, program: str, arguments: str, working_directory: str, custom_argument: object, interactive: bool = False) -> int:
|
108
|
+
raise ValueError("Async execution is not supported in Sudo-runner")
|
@@ -34,10 +34,9 @@ from pypdf import PdfReader, PdfWriter
|
|
34
34
|
from .GeneralUtilities import GeneralUtilities
|
35
35
|
from .ProgramRunnerBase import ProgramRunnerBase
|
36
36
|
from .ProgramRunnerPopen import ProgramRunnerPopen
|
37
|
-
from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
|
38
37
|
from .SCLog import SCLog, LogLevel
|
39
38
|
|
40
|
-
version = "4.0.
|
39
|
+
version = "4.0.52"
|
41
40
|
__version__ = version
|
42
41
|
|
43
42
|
|
@@ -1549,8 +1548,6 @@ class ScriptCollectionCore:
|
|
1549
1548
|
|
1550
1549
|
@GeneralUtilities.check_arguments
|
1551
1550
|
def __run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, custom_argument: object = None, interactive: bool = False) -> Popen:
|
1552
|
-
if isinstance(self.program_runner, ProgramRunnerEpew):
|
1553
|
-
custom_argument = CustomEpewArgument(print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace,self.log.loglevel, arguments_for_log)
|
1554
1551
|
popen: Popen = self.program_runner.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive)
|
1555
1552
|
return popen
|
1556
1553
|
|
@@ -1833,10 +1830,14 @@ class ScriptCollectionCore:
|
|
1833
1830
|
pid: int
|
1834
1831
|
|
1835
1832
|
@GeneralUtilities.check_arguments
|
1836
|
-
def run_with_epew(self, program: str, argument: str = "", working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1833
|
+
def run_with_epew(self, program: str, argument: str = "", working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False,print_live_output:bool=False,encode_argument_in_base64:bool=False) -> tuple[int, str, str, int]:
|
1834
|
+
epew_argument=f"-p {program} -a {argument} -w {working_directory}"
|
1835
|
+
if encode_argument_in_base64:
|
1836
|
+
base64_bytes = base64.b64encode(argument)
|
1837
|
+
base64_string = base64_bytes.decode('utf-8')
|
1838
|
+
argument=base64.b64decode(base64_string)
|
1839
|
+
epew_argument=epew_argument+" -b"
|
1840
|
+
return self.run_program("epew", epew_argument, working_directory, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument, interactive,print_live_output=print_live_output)
|
1840
1841
|
|
1841
1842
|
|
1842
1843
|
# </run programs>
|
@@ -14,13 +14,13 @@ class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
14
14
|
|
15
15
|
@GeneralUtilities.check_arguments
|
16
16
|
def build(self) -> None:
|
17
|
-
self._protected_sc.run_with_epew("npm", "run build", self.get_codeunit_folder())
|
17
|
+
self._protected_sc.run_with_epew("npm", "run build", self.get_codeunit_folder(),print_live_output=self._protected_sc.log.loglevel==LogLevel.Diagnostic)
|
18
18
|
self.standardized_tasks_build_bom_for_node_project()
|
19
19
|
self.copy_source_files_to_output_directory()
|
20
20
|
|
21
21
|
@GeneralUtilities.check_arguments
|
22
22
|
def linting(self) -> None:
|
23
|
-
self._protected_sc.run_with_epew("npm", "run lint", self.get_codeunit_folder())
|
23
|
+
self._protected_sc.run_with_epew("npm", "run lint", self.get_codeunit_folder(),print_live_output=self._protected_sc.log.loglevel==LogLevel.Diagnostic)
|
24
24
|
|
25
25
|
@GeneralUtilities.check_arguments
|
26
26
|
def do_common_tasks(self,current_codeunit_version:str)-> None:
|
@@ -50,7 +50,7 @@ class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
50
50
|
repository_folder = os.path.dirname(codeunit_folder)
|
51
51
|
|
52
52
|
# run testcases
|
53
|
-
self._protected_sc.run_with_epew("npm", f"run test-{self.get_target_environment_type()}", self.get_codeunit_folder())
|
53
|
+
self._protected_sc.run_with_epew("npm", f"run test-{self.get_target_environment_type()}", self.get_codeunit_folder(),print_live_output=self._protected_sc.log.loglevel==LogLevel.Diagnostic)
|
54
54
|
|
55
55
|
# rename file
|
56
56
|
coverage_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "TestCoverage")
|
@@ -107,9 +107,9 @@ class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
|
|
107
107
|
|
108
108
|
|
109
109
|
@GeneralUtilities.check_arguments
|
110
|
-
def standardized_tasks_build_bom_for_node_project(self) -> None:
|
110
|
+
def standardized_tasks_build_bom_for_node_project(self) -> None:
|
111
111
|
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"
|
112
|
-
self._protected_sc.run_with_epew("cyclonedx-npm", f"--output-format xml --output-file {relative_path_to_bom_file}", self.get_codeunit_folder())
|
112
|
+
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)
|
113
113
|
self._protected_sc.format_xml_file(self.get_codeunit_folder()+"/"+relative_path_to_bom_file)
|
114
114
|
|
115
115
|
class TFCPS_CodeUnitSpecific_NodeJS_CLI:
|
@@ -180,13 +180,6 @@ class TFCPS_CodeUnitSpecific_Base(ABC):
|
|
180
180
|
# set default constants
|
181
181
|
self.tfcps_Tools_General.set_default_constants(os.path.join(codeunit_folder))
|
182
182
|
|
183
|
-
# Copy changelog-file
|
184
|
-
changelog_folder = os.path.join(repository_folder, "Other", "Resources", "Changelog")
|
185
|
-
changelog_file = os.path.join(changelog_folder, f"v{project_version}.md")
|
186
|
-
target_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "Changelog")
|
187
|
-
GeneralUtilities.ensure_directory_exists(target_folder)
|
188
|
-
shutil.copy(changelog_file, target_folder)
|
189
|
-
|
190
183
|
# Hints-file
|
191
184
|
hints_file = os.path.join(codeunit_folder, "Other", "Reference", "ReferenceContent", "Hints.md")
|
192
185
|
if not os.path.isfile(hints_file):
|
@@ -1211,3 +1211,55 @@ class TFCPS_Tools_General:
|
|
1211
1211
|
GeneralUtilities.ensure_directory_does_not_exist(trg_folder)
|
1212
1212
|
GeneralUtilities.ensure_directory_exists(trg_folder)
|
1213
1213
|
GeneralUtilities.copy_content_of_folder(src_folder, trg_folder)
|
1214
|
+
|
1215
|
+
@GeneralUtilities.check_arguments
|
1216
|
+
def start_dockerfile_example(self, current_file: str,remove_old_container: bool, remove_volumes_folder: bool, env_file: str) -> None:
|
1217
|
+
folder = os.path.dirname(current_file)
|
1218
|
+
example_name = os.path.basename(folder)
|
1219
|
+
oci_image_artifacts_folder = GeneralUtilities.resolve_relative_path("../../../../Artifacts/BuildResult_OCIImage", folder)
|
1220
|
+
image_filename = os.path.basename(self.__sc.find_file_by_extension(oci_image_artifacts_folder, "tar"))
|
1221
|
+
codeunit_name = os.path.basename(GeneralUtilities.resolve_relative_path("../../../../..", folder))
|
1222
|
+
if remove_old_container:
|
1223
|
+
docker_compose_file = f"{folder}/docker-compose.yml"
|
1224
|
+
container_names = []
|
1225
|
+
lines = GeneralUtilities.read_lines_from_file(docker_compose_file)
|
1226
|
+
for line in lines:
|
1227
|
+
if match := re.search("container_name:\\s*'?([^']+)'?", line):
|
1228
|
+
container_names.append(match.group(1))
|
1229
|
+
self.__sc.log.log(f"Ensure container of {docker_compose_file} do not exist...")
|
1230
|
+
for container_name in container_names:
|
1231
|
+
self.__sc.log.log(f"Ensure container {container_name} does not exist...")
|
1232
|
+
self.__sc.run_program("docker", f"container rm -f {container_name}", oci_image_artifacts_folder, throw_exception_if_exitcode_is_not_zero=False)
|
1233
|
+
if remove_volumes_folder:
|
1234
|
+
volumes_folder = os.path.join(folder, "Volumes")
|
1235
|
+
self.__sc.log.log(f"Ensure volumes-folder '{volumes_folder}' does not exist...")
|
1236
|
+
GeneralUtilities.ensure_directory_does_not_exist(volumes_folder)
|
1237
|
+
GeneralUtilities.ensure_directory_exists(volumes_folder)
|
1238
|
+
self.__sc.log.log("Load docker-image...")
|
1239
|
+
self.__sc.run_program("docker", f"load -i {image_filename}", oci_image_artifacts_folder)
|
1240
|
+
docker_project_name = f"{codeunit_name}_{example_name}".lower()
|
1241
|
+
self.__sc.log.log("Start docker-container...")
|
1242
|
+
argument = f"compose --project-name {docker_project_name}"
|
1243
|
+
if env_file is not None:
|
1244
|
+
argument = f"{argument} --env-file {env_file}"
|
1245
|
+
argument = f"{argument} up --detach"
|
1246
|
+
self.__sc.run_program("docker", argument, folder)
|
1247
|
+
|
1248
|
+
@GeneralUtilities.check_arguments
|
1249
|
+
def ensure_env_file_is_generated(self, current_file: str, env_file_name: str, env_values: dict[str, str]):
|
1250
|
+
folder = os.path.dirname(current_file)
|
1251
|
+
env_file = os.path.join(folder, env_file_name)
|
1252
|
+
if not os.path.isfile(env_file):
|
1253
|
+
lines = []
|
1254
|
+
for key, value in env_values.items():
|
1255
|
+
lines.append(f"{key}={value}")
|
1256
|
+
GeneralUtilities.write_lines_to_file(env_file, lines)
|
1257
|
+
|
1258
|
+
@GeneralUtilities.check_arguments
|
1259
|
+
def stop_dockerfile_example(self, current_file: str, remove_old_container: bool, remove_volumes_folder: bool) -> None:
|
1260
|
+
folder = os.path.dirname(current_file)
|
1261
|
+
example_name = os.path.basename(folder)
|
1262
|
+
codeunit_name = os.path.basename(GeneralUtilities.resolve_relative_path("../../../../..", folder))
|
1263
|
+
docker_project_name = f"{codeunit_name}_{example_name}".lower()
|
1264
|
+
self.__sc.log.log("Stop docker-container...")
|
1265
|
+
self.__sc.run_program("docker", f"compose --project-name {docker_project_name} down", folder)
|
@@ -5,13 +5,13 @@ ScriptCollection/GeneralUtilities.py,sha256=9Xd9aKPj3TkpVtdHXzFMILrRoXAfJCph69XR
|
|
5
5
|
ScriptCollection/ImageUpdater.py,sha256=qTe3yoqzQJY7LZdXBbjbWvrsSQaeHy1VwmOxaRzU2ig,29305
|
6
6
|
ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
|
7
7
|
ScriptCollection/ProgramRunnerBase.py,sha256=4A2eQgSg_rRgQcgSi-LYtUlM-uSQEpS7qFWn0tWt4uo,2171
|
8
|
-
ScriptCollection/ProgramRunnerEpew.py,sha256=TJdDx9zIMSiCaXh8X-ekrMlbXfGtmd0Mmyxj-tV_gHg,7338
|
9
8
|
ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrRjAPIwT5Y,37
|
10
9
|
ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
|
10
|
+
ScriptCollection/ProgramRunnerSudo.py,sha256=_khC3xuTdrPoLluBJZWfldltmmuKltABJPcbjZSFW-4,4835
|
11
11
|
ScriptCollection/SCLog.py,sha256=dxGOI4E9lG5v9jk_LajXCkM5nghliCDV8YB8Ihn160s,4541
|
12
|
-
ScriptCollection/ScriptCollectionCore.py,sha256=
|
12
|
+
ScriptCollection/ScriptCollectionCore.py,sha256=2EqLxmuiBYobgKIjQ2yBYZYkHmu1g3QsZykfhvU1SbI,142125
|
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=H9ampfCfJ4-ohN33VkYWTKwYaTV-y3AelZAiTduwHzw,25442
|
15
15
|
ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py,sha256=4rYKgTAga11NiDx8YUqz3K_Q4eX_n3kC6lvNdXEa24s,7389
|
16
16
|
ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py,sha256=f9oGnopuzn3iDHC1AksU7Qr60LbDe0eLjYeXGiDPhAk,7526
|
17
17
|
ScriptCollection/TFCPS/TFCPS_CreateRelease.py,sha256=bcJlfI062Eoq7MOIhun-_iNG7SdO1ZIuC_cylaoLI1s,6332
|
@@ -20,7 +20,7 @@ ScriptCollection/TFCPS/TFCPS_MergeToMain.py,sha256=41g219jaBRZ2VQCrWM4-Trvervrt8
|
|
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=nIOEeZ3UWzzD5S7RkMnJedDV8oHlPMaCc_2qPH1YxBY,79912
|
24
24
|
ScriptCollection/TFCPS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=ylPvcdiN7RuqXpM-3uNqs40v1kyhaC0guV4JA2pIt_M,5234
|
26
26
|
ScriptCollection/TFCPS/Docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -31,12 +31,12 @@ ScriptCollection/TFCPS/DotNet/TFCPS_CodeUnitSpecific_DotNet.py,sha256=ufeWuqtNOP
|
|
31
31
|
ScriptCollection/TFCPS/DotNet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
32
|
ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py,sha256=TIR95f6TVOnW25ieX9q4RUi1FogbYEfrlZOcZ1aE014,6969
|
33
33
|
ScriptCollection/TFCPS/Flutter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
|
-
ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=
|
34
|
+
ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=e2bvR_zzArIJcjDLixMOI7ItUQTNuK1zPb4v4sknihg,6531
|
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.52.dist-info/METADATA,sha256=5SNVHNlcuIWhu4ufQyC648iLMrNWuaMTHtSE7d6toQM,7688
|
39
|
+
scriptcollection-4.0.52.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
40
|
+
scriptcollection-4.0.52.dist-info/entry_points.txt,sha256=_izhaQEyHiyBIfM2zTYDaJ7qvgsP1WntkVChFnkWymE,4431
|
41
|
+
scriptcollection-4.0.52.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
|
42
|
+
scriptcollection-4.0.52.dist-info/RECORD,,
|
@@ -1,148 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import base64
|
3
|
-
import tempfile
|
4
|
-
from subprocess import Popen
|
5
|
-
from uuid import uuid4
|
6
|
-
|
7
|
-
from .GeneralUtilities import GeneralUtilities
|
8
|
-
from .ProgramRunnerBase import ProgramRunnerBase
|
9
|
-
from .ProgramRunnerPopen import ProgramRunnerPopen
|
10
|
-
from .SCLog import LogLevel
|
11
|
-
|
12
|
-
|
13
|
-
class CustomEpewArgument:
|
14
|
-
|
15
|
-
print_errors_as_information: bool
|
16
|
-
log_file: str
|
17
|
-
timeoutInSeconds: int
|
18
|
-
addLogOverhead: bool
|
19
|
-
title: str
|
20
|
-
log_namespace: str
|
21
|
-
verbosity: LogLevel
|
22
|
-
arguments_for_log: list[str]
|
23
|
-
tempdir = os.path.join(tempfile.gettempdir(), str(uuid4()))
|
24
|
-
stdoutfile = tempdir + ".epew.stdout.txt"
|
25
|
-
stderrfile = tempdir + ".epew.stderr.txt"
|
26
|
-
exitcodefile = tempdir + ".epew.exitcode.txt"
|
27
|
-
pidfile = tempdir + ".epew.pid.txt"
|
28
|
-
|
29
|
-
def __init__(self, print_errors_as_information: bool, log_file: str, timeoutInSeconds: int, addLogOverhead: bool, title: str, log_namespace: str, verbosity: LogLevel, arguments_for_log: list[str]):
|
30
|
-
self.print_errors_as_information = print_errors_as_information
|
31
|
-
self.log_file = log_file
|
32
|
-
self.timeoutInSeconds = timeoutInSeconds
|
33
|
-
self.addLogOverhead = addLogOverhead
|
34
|
-
self.title = title
|
35
|
-
self.log_namespace = log_namespace
|
36
|
-
self.verbosity = verbosity
|
37
|
-
self.arguments_for_log = arguments_for_log
|
38
|
-
|
39
|
-
|
40
|
-
class ProgramRunnerEpew(ProgramRunnerBase):
|
41
|
-
|
42
|
-
@GeneralUtilities.check_arguments
|
43
|
-
def run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> Popen:
|
44
|
-
if GeneralUtilities.epew_is_available():
|
45
|
-
custom_argument: CustomEpewArgument = custom_argument
|
46
|
-
args = []
|
47
|
-
|
48
|
-
base64argument = base64.b64encode(' '.join(arguments_as_array).encode('utf-8')).decode('utf-8')
|
49
|
-
args.append(f'-p "{program}"')
|
50
|
-
args.append(f'-a {base64argument}')
|
51
|
-
args.append('-b')
|
52
|
-
args.append(f'-w "{working_directory}"')
|
53
|
-
if custom_argument.stdoutfile is not None:
|
54
|
-
args.append(f'-o {custom_argument.stdoutfile}')
|
55
|
-
if custom_argument.stderrfile is not None:
|
56
|
-
args.append(f'-e {custom_argument.stderrfile}')
|
57
|
-
if custom_argument.exitcodefile is not None:
|
58
|
-
args.append(f'-x {custom_argument.exitcodefile}')
|
59
|
-
if custom_argument.pidfile is not None:
|
60
|
-
args.append(f'-r {custom_argument.pidfile}')
|
61
|
-
args.append(f'-d {str(custom_argument.timeoutInSeconds*1000)}')
|
62
|
-
if GeneralUtilities.string_has_content(custom_argument.title):
|
63
|
-
args.append(f'-t "{custom_argument.title}"')
|
64
|
-
if GeneralUtilities.string_has_content(custom_argument.log_namespace):
|
65
|
-
args.append(f'-l "{custom_argument.log_namespace}"')
|
66
|
-
if not GeneralUtilities.string_is_none_or_whitespace(custom_argument.log_file):
|
67
|
-
args.append(f'-f "{custom_argument.log_file}"')
|
68
|
-
if custom_argument.print_errors_as_information:
|
69
|
-
args.append("-i")
|
70
|
-
if custom_argument.addLogOverhead:
|
71
|
-
args.append("-g")
|
72
|
-
args.append("-v "+str(self.__get_microsoft_loglevel()))
|
73
|
-
return ProgramRunnerPopen().run_program_argsasarray_async_helper("epew", args, working_directory, custom_argument, interactive)
|
74
|
-
else:
|
75
|
-
raise ValueError("Epew is not available.")
|
76
|
-
|
77
|
-
def __get_microsoft_loglevel(self):
|
78
|
-
#see https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel
|
79
|
-
#match self.verbosity:
|
80
|
-
# case LogLevel.Quiet:
|
81
|
-
# return 6
|
82
|
-
# case LogLevel.Error:
|
83
|
-
# return 4
|
84
|
-
# case LogLevel.Warning:
|
85
|
-
# return 3
|
86
|
-
# case LogLevel.Information:
|
87
|
-
# return 5
|
88
|
-
# case LogLevel.Debug:
|
89
|
-
# return 1
|
90
|
-
# case LogLevel.Diagnostig:
|
91
|
-
# return 0
|
92
|
-
# case _:
|
93
|
-
# raise ValueError(f"Unhandled log level: {level}")
|
94
|
-
return 2#TODO
|
95
|
-
|
96
|
-
# Return-values program_runner: Exitcode, StdOut, StdErr, Pid
|
97
|
-
@GeneralUtilities.check_arguments
|
98
|
-
def wait(self, process: Popen, custom_argument: object = None) -> tuple[int, str, str, int]:
|
99
|
-
process.wait()
|
100
|
-
custom_argument: CustomEpewArgument = custom_argument
|
101
|
-
stdout = self.__load_text(custom_argument.output_file_for_stdout)
|
102
|
-
stderr = self.__load_text(custom_argument.output_file_for_stderr)
|
103
|
-
exit_code = self.__get_number_from_filecontent(self.__load_text(custom_argument.output_file_for_exit_code))
|
104
|
-
pid = self.__get_number_from_filecontent(self.__load_text(custom_argument.output_file_for_pid))
|
105
|
-
GeneralUtilities.ensure_directory_does_not_exist(custom_argument.tempdir)
|
106
|
-
result = (exit_code, stdout, stderr, pid)
|
107
|
-
return result
|
108
|
-
|
109
|
-
@GeneralUtilities.check_arguments
|
110
|
-
def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
|
111
|
-
process: Popen = self.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive)
|
112
|
-
return self.wait(process, custom_argument)
|
113
|
-
|
114
|
-
@GeneralUtilities.check_arguments
|
115
|
-
def run_program(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
|
116
|
-
return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, custom_argument, interactive)
|
117
|
-
|
118
|
-
@GeneralUtilities.check_arguments
|
119
|
-
def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
|
120
|
-
return self.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive).pid
|
121
|
-
|
122
|
-
@GeneralUtilities.check_arguments
|
123
|
-
def run_program_async(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
|
124
|
-
return self.run_program_argsasarray_async(program, GeneralUtilities.arguments_to_array(arguments), working_directory, custom_argument, interactive)
|
125
|
-
|
126
|
-
@GeneralUtilities.check_arguments
|
127
|
-
def __get_number_from_filecontent(self, filecontent: str) -> int:
|
128
|
-
for line in filecontent.splitlines():
|
129
|
-
try:
|
130
|
-
striped_line = GeneralUtilities.strip_new_line_character(line)
|
131
|
-
result = int(striped_line)
|
132
|
-
return result
|
133
|
-
except:
|
134
|
-
pass
|
135
|
-
raise ValueError(f"'{filecontent}' does not containe an int-line")
|
136
|
-
|
137
|
-
@GeneralUtilities.check_arguments
|
138
|
-
def __load_text(self, file: str) -> str:
|
139
|
-
if os.path.isfile(file):
|
140
|
-
content = GeneralUtilities.read_text_from_file(file).replace('\r', '')
|
141
|
-
os.remove(file)
|
142
|
-
return content
|
143
|
-
else:
|
144
|
-
raise ValueError(f"File '{file}' does not exist")
|
145
|
-
|
146
|
-
@GeneralUtilities.check_arguments
|
147
|
-
def will_be_executed_locally(self) -> bool:
|
148
|
-
return True
|
File without changes
|
File without changes
|
File without changes
|