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.
@@ -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.50"
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
- sc: ScriptCollectionCore = ScriptCollectionCore()
1838
- sc.program_runner = ProgramRunnerEpew()
1839
- return sc.run_program(program, 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)
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 4.0.50
3
+ Version: 4.0.52
4
4
  Summary: The ScriptCollection is the place for reusable scripts.
5
5
  Home-page: https://github.com/anionDev/ScriptCollection
6
6
  Author: Marius Göcke
@@ -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=eUaqGyFjyecW9piNhdey5fOo3qct73RntNrt8I1tJsw,142113
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=2Ng-GyKWQ6FfTUmogd7g-xF6_XeTMxvkeJddagxFR5o,25853
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=R4LxdLLl1lVEr2aWsxi92FylpiS6CZKMPChi0Ty2XH4,76571
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=dnuDlQXThFmhe6EbUAWmGhx7AAYGL0lVUqsrhOgtmC8,6255
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.50.dist-info/METADATA,sha256=OCUAHupoepo7d7-Qcra-LmSc49TsQWn3LKWRIlqn4H4,7688
39
- scriptcollection-4.0.50.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- scriptcollection-4.0.50.dist-info/entry_points.txt,sha256=_izhaQEyHiyBIfM2zTYDaJ7qvgsP1WntkVChFnkWymE,4431
41
- scriptcollection-4.0.50.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
42
- scriptcollection-4.0.50.dist-info/RECORD,,
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