ScriptCollection 3.4.56__py3-none-any.whl → 3.4.57__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.
@@ -12,8 +12,7 @@ def FilenameObfuscator() -> int:
12
12
  parser = argparse.ArgumentParser(description=''''Obfuscates the names of all files in the given folder.
13
13
  Caution: This script can cause harm if you pass a wrong inputfolder-argument.''')
14
14
 
15
- parser.add_argument('--printtableheadline', type=GeneralUtilities.string_to_boolean, const=True, default=True, nargs='?',
16
- help='Prints column-titles in the name-mapping-csv-file')
15
+ parser.add_argument('--printtableheadline', type=GeneralUtilities.string_to_boolean, const=True, default=True, nargs='?', help='Prints column-titles in the name-mapping-csv-file')
17
16
  parser.add_argument('--namemappingfile', default="NameMapping.csv", help='Specifies the file where the name-mapping will be written to')
18
17
  parser.add_argument('--extensions', default="exe,py,sh",
19
18
  help='Comma-separated list of file-extensions of files where this tool should be applied. Use "*" to obfuscate all')
@@ -58,8 +57,7 @@ def CalculateBitcoinBlockHash() -> int:
58
57
  args = parser.parse_args()
59
58
 
60
59
  args = parser.parse_args()
61
- GeneralUtilities.write_message_to_stdout(ScriptCollectionCore().SCCalculateBitcoinBlockHash(args.version, args.previousblockhash,
62
- args.transactionsmerkleroot, args.timestamp, args.target, args.nonce))
60
+ GeneralUtilities.write_message_to_stdout(ScriptCollectionCore().SCCalculateBitcoinBlockHash(args.version, args.previousblockhash, args.transactionsmerkleroot, args.timestamp, args.target, args.nonce))
63
61
  return 0
64
62
 
65
63
 
@@ -137,9 +135,7 @@ def OrganizeLinesInFile() -> int:
137
135
  parser.add_argument('--ignored_start_character', default="", help='Characters which should not be considered at the begin of a line')
138
136
 
139
137
  args = parser.parse_args()
140
- return ScriptCollectionCore().sc_organize_lines_in_file(args.file, args.encoding,
141
- args.sort, args.remove_duplicated_lines, args.ignore_first_line,
142
- args.remove_empty_lines, list(args.ignored_start_character))
138
+ return ScriptCollectionCore().sc_organize_lines_in_file(args.file, args.encoding, args.sort, args.remove_duplicated_lines, args.ignore_first_line, args.remove_empty_lines, list(args.ignored_start_character))
143
139
 
144
140
 
145
141
  def CreateHashOfAllFiles() -> int:
@@ -266,8 +262,7 @@ def BuildCodeUnit() -> int:
266
262
  parser.add_argument('--additionalargumentsfile', required=False, default=None)
267
263
  parser.add_argument('--assume_dependent_codeunits_are_already_built', type=GeneralUtilities.string_to_boolean, const=True, default=False, nargs='?')
268
264
  args = parser.parse_args()
269
- TasksForCommonProjectStructure().build_codeunit(args.codeunitfolder, int(args.verbosity), args.targetenvironment, args.additionalargumentsfile,
270
- False, None, args.assume_dependent_codeunits_are_already_built)
265
+ TasksForCommonProjectStructure().build_codeunit(args.codeunitfolder, int(args.verbosity), args.targetenvironment, args.additionalargumentsfile, False, None, args.assume_dependent_codeunits_are_already_built)
271
266
  return 0
272
267
 
273
268
 
@@ -322,8 +317,7 @@ def GenerateCertificate() -> int:
322
317
  parser.add_argument('--days_until_expire', required=False, default=None, type=int)
323
318
  parser.add_argument('--password', required=False, default=None)
324
319
  args = parser.parse_args()
325
- ScriptCollectionCore().generate_certificate(os.getcwd(), args.domain, args.filename, args.subj_c, args.subj_st,
326
- args.subj_l, args.subj_o, args.subj_ou, args.days_until_expire, args.password)
320
+ ScriptCollectionCore().generate_certificate(os.getcwd(), args.domain, args.filename, args.subj_c, args.subj_st, args.subj_l, args.subj_o, args.subj_ou, args.days_until_expire, args.password)
327
321
  return 0
328
322
 
329
323
 
@@ -51,15 +51,13 @@ class GeneralUtilities:
51
51
  # Check type of arguments if the type is a generic type seems to be impossible.
52
52
  if not GeneralUtilities.is_generic(function.__annotations__[parameters[index]]):
53
53
  if not isinstance(argument, function.__annotations__[parameters[index]]):
54
- raise TypeError(f"Argument with index {index} for function {function.__name__} ('{str(argument)}') is not of type " +
55
- f"{ function.__annotations__[parameters[index]]} but has type "+str(type(argument)))
54
+ raise TypeError(f"Argument with index {index} for function {function.__name__} ('{str(argument)}') is not of type { function.__annotations__[parameters[index]]} but has type "+str(type(argument)))
56
55
  for index, named_argument in enumerate(named_args):
57
56
  if named_args[named_argument] is not None:
58
57
  if parameters[index] in function.__annotations__:
59
58
  if not GeneralUtilities.is_generic(function.__annotations__.get(named_argument)):
60
59
  if not isinstance(named_args[named_argument], function.__annotations__.get(named_argument)):
61
- raise TypeError(f"Argument with name {named_argument} for function {function.__name__} ('{str(named_args[named_argument])}') " +
62
- f"is not of type { function.__annotations__.get(named_argument)}")
60
+ raise TypeError(f"Argument with name {named_argument} for function {function.__name__} ('{str(named_args[named_argument])}') is not of type { function.__annotations__.get(named_argument)}")
63
61
  return function(*args, **named_args)
64
62
  __check_function.__doc__ = function.__doc__
65
63
  return __check_function
@@ -69,9 +67,7 @@ class GeneralUtilities:
69
67
  @functools.wraps(func)
70
68
  def new_func(*args, **kwargs):
71
69
  warnings.simplefilter('always', DeprecationWarning)
72
- warnings.warn(f"Call to deprecated function {func.__name__}",
73
- category=DeprecationWarning,
74
- stacklevel=2)
70
+ warnings.warn(f"Call to deprecated function {func.__name__}", category=DeprecationWarning, stacklevel=2)
75
71
  warnings.simplefilter('default', DeprecationWarning)
76
72
  return func(*args, **kwargs)
77
73
  return new_func
@@ -1,4 +1,5 @@
1
1
  from datetime import timedelta, datetime
2
+ import json
2
3
  import binascii
3
4
  import filecmp
4
5
  import hashlib
@@ -27,7 +28,7 @@ from .ProgramRunnerPopen import ProgramRunnerPopen
27
28
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
28
29
 
29
30
 
30
- version = "3.4.56"
31
+ version = "3.4.57"
31
32
  __version__ = version
32
33
 
33
34
 
@@ -71,18 +72,15 @@ class ScriptCollectionCore:
71
72
 
72
73
  @GeneralUtilities.check_arguments
73
74
  def replace_version_in_dockerfile_file(self, dockerfile: str, new_version_value: str) -> None:
74
- GeneralUtilities.write_text_to_file(dockerfile, re.sub("ARG Version=\"\\d+\\.\\d+\\.\\d+\"", f"ARG Version=\"{new_version_value}\"",
75
- GeneralUtilities.read_text_from_file(dockerfile)))
75
+ GeneralUtilities.write_text_to_file(dockerfile, re.sub("ARG Version=\"\\d+\\.\\d+\\.\\d+\"", f"ARG Version=\"{new_version_value}\"", GeneralUtilities.read_text_from_file(dockerfile)))
76
76
 
77
77
  @GeneralUtilities.check_arguments
78
78
  def replace_version_in_python_file(self, file: str, new_version_value: str):
79
- GeneralUtilities.write_text_to_file(file, re.sub("version = \"\\d+\\.\\d+\\.\\d+\"", f"version = \"{new_version_value}\"",
80
- GeneralUtilities.read_text_from_file(file)))
79
+ GeneralUtilities.write_text_to_file(file, re.sub("version = \"\\d+\\.\\d+\\.\\d+\"", f"version = \"{new_version_value}\"", GeneralUtilities.read_text_from_file(file)))
81
80
 
82
81
  @GeneralUtilities.check_arguments
83
82
  def replace_version_in_ini_file(self, file: str, new_version_value: str):
84
- GeneralUtilities.write_text_to_file(file, re.sub("version = \\d+\\.\\d+\\.\\d+", f"version = {new_version_value}",
85
- GeneralUtilities.read_text_from_file(file)))
83
+ GeneralUtilities.write_text_to_file(file, re.sub("version = \\d+\\.\\d+\\.\\d+", f"version = {new_version_value}", GeneralUtilities.read_text_from_file(file)))
86
84
 
87
85
  @GeneralUtilities.check_arguments
88
86
  def replace_version_in_nuspec_file(self, nuspec_file: str, new_version: str) -> None:
@@ -91,8 +89,7 @@ class ScriptCollectionCore:
91
89
  versiononlyregex = f"^{versionregex}$"
92
90
  pattern = re.compile(versiononlyregex)
93
91
  if pattern.match(new_version):
94
- GeneralUtilities.write_text_to_file(nuspec_file, re.sub(f"<version>{versionregex}<\\/version>",
95
- f"<version>{new_version}</version>", GeneralUtilities.read_text_from_file(nuspec_file)))
92
+ GeneralUtilities.write_text_to_file(nuspec_file, re.sub(f"<version>{versionregex}<\\/version>", f"<version>{new_version}</version>", GeneralUtilities.read_text_from_file(nuspec_file)))
96
93
  else:
97
94
  raise ValueError(f"Version '{new_version}' does not match version-regex '{versiononlyregex}'")
98
95
 
@@ -103,8 +100,7 @@ class ScriptCollectionCore:
103
100
  pattern = re.compile(versiononlyregex)
104
101
  if pattern.match(current_version):
105
102
  for tag in ["Version", "AssemblyVersion", "FileVersion"]:
106
- GeneralUtilities.write_text_to_file(csproj_file, re.sub(f"<{tag}>{versionregex}(.\\d+)?<\\/{tag}>",
107
- f"<{tag}>{current_version}</{tag}>", GeneralUtilities.read_text_from_file(csproj_file)))
103
+ GeneralUtilities.write_text_to_file(csproj_file, re.sub(f"<{tag}>{versionregex}(.\\d+)?<\\/{tag}>", f"<{tag}>{current_version}</{tag}>", GeneralUtilities.read_text_from_file(csproj_file)))
108
104
  else:
109
105
  raise ValueError(f"Version '{current_version}' does not match version-regex '{versiononlyregex}'")
110
106
 
@@ -112,8 +108,7 @@ class ScriptCollectionCore:
112
108
  def push_nuget_build_artifact(self, nupkg_file: str, registry_address: str, api_key: str, verbosity: int = 1):
113
109
  nupkg_file_name = os.path.basename(nupkg_file)
114
110
  nupkg_file_folder = os.path.dirname(nupkg_file)
115
- self.run_program("dotnet", f"nuget push {nupkg_file_name} --force-english-output --source {registry_address} --api-key {api_key}",
116
- nupkg_file_folder, verbosity)
111
+ self.run_program("dotnet", f"nuget push {nupkg_file_name} --force-english-output --source {registry_address} --api-key {api_key}", nupkg_file_folder, verbosity)
117
112
 
118
113
  @GeneralUtilities.check_arguments
119
114
  def dotnet_build(self, repository_folder: str, projectname: str, configuration: str):
@@ -146,8 +141,7 @@ class ScriptCollectionCore:
146
141
 
147
142
  @GeneralUtilities.check_arguments
148
143
  def get_parent_commit_ids_of_commit(self, repository_folder: str, commit_id: str) -> str:
149
- return self.run_program("git", f'log --pretty=%P -n 1 "{commit_id}"',
150
- repository_folder, throw_exception_if_exitcode_is_not_zero=True)[1].replace("\r", "").replace("\n", "").split(" ")
144
+ return self.run_program("git", f'log --pretty=%P -n 1 "{commit_id}"', repository_folder, throw_exception_if_exitcode_is_not_zero=True)[1].replace("\r", "").replace("\n", "").split(" ")
151
145
 
152
146
  @GeneralUtilities.check_arguments
153
147
  def get_all_authors_and_committers_of_repository(self, repository_folder: str, subfolder: str = None, verbosity: int = 1) -> list[tuple[str, str]]:
@@ -156,8 +150,7 @@ class ScriptCollectionCore:
156
150
  subfolder_argument = ""
157
151
  else:
158
152
  subfolder_argument = f" -- {subfolder}"
159
- log_result = self.run_program("git", f'log --pretty=%aN{space_character}%aE%n%cN{space_character}%cE HEAD{subfolder_argument}',
160
- repository_folder, verbosity=0)
153
+ log_result = self.run_program("git", f'log --pretty=%aN{space_character}%aE%n%cN{space_character}%cE HEAD{subfolder_argument}', repository_folder, verbosity=0)
161
154
  plain_content: list[str] = list(set([line for line in log_result[1].split("\n") if len(line) > 0]))
162
155
  result: list[tuple[str, str]] = []
163
156
  for item in plain_content:
@@ -172,9 +165,7 @@ class ScriptCollectionCore:
172
165
  def get_commit_ids_between_dates(self, repository_folder: str, since: datetime, until: datetime, ignore_commits_which_are_not_in_history_of_head: bool = True) -> None:
173
166
  since_as_string = self.__datetime_to_string_for_git(since)
174
167
  until_as_string = self.__datetime_to_string_for_git(until)
175
- result = filter(lambda line: not GeneralUtilities.string_is_none_or_whitespace(line),
176
- self.run_program("git", f'log --since "{since_as_string}" --until "{until_as_string}" --pretty=format:"%H" --no-patch',
177
- repository_folder, throw_exception_if_exitcode_is_not_zero=True)[1].split("\n").replace("\r", ""))
168
+ result = filter(lambda line: not GeneralUtilities.string_is_none_or_whitespace(line), self.run_program("git", f'log --since "{since_as_string}" --until "{until_as_string}" --pretty=format:"%H" --no-patch', repository_folder, throw_exception_if_exitcode_is_not_zero=True)[1].split("\n").replace("\r", ""))
178
169
  if ignore_commits_which_are_not_in_history_of_head:
179
170
  result = [commit_id for commit_id in result if self.git_commit_is_ancestor(repository_folder, commit_id)]
180
171
  return result
@@ -185,8 +176,7 @@ class ScriptCollectionCore:
185
176
 
186
177
  @GeneralUtilities.check_arguments
187
178
  def git_commit_is_ancestor(self, repository_folder: str, ancestor: str, descendant: str = "HEAD") -> bool:
188
- exit_code = self.run_program_argsasarray("git", ["merge-base", "--is-ancestor", ancestor, descendant],
189
- repository_folder, throw_exception_if_exitcode_is_not_zero=False)[0]
179
+ exit_code = self.run_program_argsasarray("git", ["merge-base", "--is-ancestor", ancestor, descendant], repository_folder, throw_exception_if_exitcode_is_not_zero=False)[0]
190
180
  if exit_code == 0:
191
181
  return True
192
182
  elif exit_code == 1:
@@ -196,8 +186,7 @@ class ScriptCollectionCore:
196
186
 
197
187
  @GeneralUtilities.check_arguments
198
188
  def __git_changes_helper(self, repository_folder: str, arguments_as_array: list[str]) -> bool:
199
- lines = GeneralUtilities.string_to_lines(self.run_program_argsasarray("git", arguments_as_array, repository_folder,
200
- throw_exception_if_exitcode_is_not_zero=True, verbosity=0)[1], False)
189
+ lines = GeneralUtilities.string_to_lines(self.run_program_argsasarray("git", arguments_as_array, repository_folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=0)[1], False)
201
190
  for line in lines:
202
191
  if GeneralUtilities.string_has_content(line):
203
192
  return True
@@ -233,14 +222,12 @@ class ScriptCollectionCore:
233
222
 
234
223
  @GeneralUtilities.check_arguments
235
224
  def git_get_commit_id(self, repository_folder: str, commit: str = "HEAD") -> str:
236
- result: tuple[int, str, str, int] = self.run_program_argsasarray("git", ["rev-parse", "--verify", commit],
237
- repository_folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=0)
225
+ result: tuple[int, str, str, int] = self.run_program_argsasarray("git", ["rev-parse", "--verify", commit], repository_folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=0)
238
226
  return result[1].replace('\n', '')
239
227
 
240
228
  @GeneralUtilities.check_arguments
241
229
  def git_get_commit_date(self, repository_folder: str, commit: str = "HEAD") -> datetime:
242
- result: tuple[int, str, str, int] = self.run_program_argsasarray("git", ["show", "-s", "--format=%ci", commit],
243
- repository_folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=0)
230
+ result: tuple[int, str, str, int] = self.run_program_argsasarray("git", ["show", "-s", "--format=%ci", commit], repository_folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=0)
244
231
  date_as_string = result[1].replace('\n', '')
245
232
  result = datetime.strptime(date_as_string, '%Y-%m-%d %H:%M:%S %z')
246
233
  return result
@@ -264,8 +251,7 @@ class ScriptCollectionCore:
264
251
  argument.append("--force")
265
252
  if (pushalltags):
266
253
  argument.append("--tags")
267
- result: tuple[int, str, str, int] = self.run_program_argsasarray("git", argument, folder, throw_exception_if_exitcode_is_not_zero=True,
268
- verbosity=verbosity, print_errors_as_information=True)
254
+ result: tuple[int, str, str, int] = self.run_program_argsasarray("git", argument, folder, throw_exception_if_exitcode_is_not_zero=True, verbosity=verbosity, print_errors_as_information=True)
269
255
  return result[1].replace('\r', '').replace('\n', '')
270
256
 
271
257
  @GeneralUtilities.check_arguments
@@ -464,8 +450,7 @@ class ScriptCollectionCore:
464
450
  return tags
465
451
 
466
452
  @GeneralUtilities.check_arguments
467
- def git_move_tags_to_another_branch(self, repository: str, tag_source_branch: str, tag_target_branch: str,
468
- sign: bool = False, message: str = None) -> None:
453
+ def git_move_tags_to_another_branch(self, repository: str, tag_source_branch: str, tag_target_branch: str, sign: bool = False, message: str = None) -> None:
469
454
  tags = self.git_get_tags(repository)
470
455
  tags_count = len(tags)
471
456
  counter = 0
@@ -476,9 +461,7 @@ class ScriptCollectionCore:
476
461
  commit_id_old = self.git_get_commitid_of_tag(repository, tag)
477
462
  commit_date: datetime = self.git_get_commit_date(repository, commit_id_old)
478
463
  date_as_string = self.__datetime_to_string_for_git(commit_date)
479
- search_commit_result = self.run_program_argsasarray("git", ["log", f'--after="{date_as_string}"', f'--before="{date_as_string}"',
480
- "--pretty=format:%H", tag_target_branch], repository,
481
- throw_exception_if_exitcode_is_not_zero=False)
464
+ search_commit_result = self.run_program_argsasarray("git", ["log", f'--after="{date_as_string}"', f'--before="{date_as_string}"', "--pretty=format:%H", tag_target_branch], repository, throw_exception_if_exitcode_is_not_zero=False)
482
465
  if search_commit_result[0] != 0 or not GeneralUtilities.string_has_nonwhitespace_content(search_commit_result[1]):
483
466
  raise ValueError(f"Can not calculate corresponding commit for tag '{tag}'.")
484
467
  commit_id_new = search_commit_result[1]
@@ -503,6 +486,10 @@ class ScriptCollectionCore:
503
486
  result=[line for line in tresult.split("\n") if len(line)>0]
504
487
  return result
505
488
 
489
+ @GeneralUtilities.check_arguments
490
+ def git_repository_has_commits(self,repository_folder: str) -> bool:
491
+ return self.run_program_argsasarray("git",["rev-parse","--verify","HEAD"],repository_folder,throw_exception_if_exitcode_is_not_zero=False)[0]==0
492
+
506
493
  @GeneralUtilities.check_arguments
507
494
  def export_filemetadata(self, folder: str, target_file: str, encoding: str = "utf-8", filter_function=None) -> None:
508
495
  folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(folder)
@@ -724,8 +711,7 @@ class ScriptCollectionCore:
724
711
  self.git_remove_branch(repository, sourcebranch)
725
712
 
726
713
  @GeneralUtilities.check_arguments
727
- def sc_organize_lines_in_file(self, file: str, encoding: str, sort: bool = False, remove_duplicated_lines: bool = False, ignore_first_line: bool = False,
728
- remove_empty_lines: bool = True, ignored_start_character: list = list()) -> int:
714
+ def sc_organize_lines_in_file(self, file: str, encoding: str, sort: bool = False, remove_duplicated_lines: bool = False, ignore_first_line: bool = False, remove_empty_lines: bool = True, ignored_start_character: list = list()) -> int:
729
715
  if os.path.isfile(file):
730
716
 
731
717
  # read file
@@ -1164,9 +1150,7 @@ class ScriptCollectionCore:
1164
1150
  # <run programs>
1165
1151
 
1166
1152
  @GeneralUtilities.check_arguments
1167
- def __run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1,
1168
- print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False,
1169
- title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, custom_argument: object = None) -> Popen:
1153
+ def __run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1, 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) -> Popen:
1170
1154
  # Verbosity:
1171
1155
  # 0=Quiet (No output will be printed.)
1172
1156
  # 1=Normal (If the exitcode of the executed program is not 0 then the StdErr will be printed.)
@@ -1196,10 +1180,7 @@ class ScriptCollectionCore:
1196
1180
  # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
1197
1181
 
1198
1182
  @GeneralUtilities.check_arguments
1199
- def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1,
1200
- print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False,
1201
- title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None,
1202
- throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None) -> tuple[int, str, str, int]:
1183
+ def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1, 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) -> tuple[int, str, str, int]:
1203
1184
  mock_loader_result = self.__try_load_mock(program, ' '.join(arguments_as_array), working_directory)
1204
1185
  if mock_loader_result[0]:
1205
1186
  return mock_loader_result[1]
@@ -1218,8 +1199,7 @@ class ScriptCollectionCore:
1218
1199
  program_manages_output_itself = epew_will_be_used and False # TODO fix stdout-/stderr-reading-block below
1219
1200
  program_manages_logging_itself = epew_will_be_used
1220
1201
 
1221
- process = self.__run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, verbosity, print_errors_as_information, log_file,
1222
- timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1202
+ process = self.__run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1223
1203
  pid = process.pid
1224
1204
 
1225
1205
  if program_manages_output_itself:
@@ -1269,8 +1249,7 @@ class ScriptCollectionCore:
1269
1249
  if verbosity == 3:
1270
1250
  GeneralUtilities.write_message_to_stdout(stdout)
1271
1251
  self.__write_error_output(print_errors_as_information, stderr)
1272
- formatted = self.__format_program_execution_information(title=info_for_log, program=program,
1273
- argument=arguments_for_log_as_string, workingdirectory=working_directory)
1252
+ formatted = self.__format_program_execution_information(title=info_for_log, program=program, argument=arguments_for_log_as_string, workingdirectory=working_directory)
1274
1253
  GeneralUtilities.write_message_to_stdout(f"Finished '{info_for_log}'. Details: '{formatted}")
1275
1254
 
1276
1255
  if throw_exception_if_exitcode_is_not_zero and exit_code != 0:
@@ -1282,33 +1261,24 @@ class ScriptCollectionCore:
1282
1261
 
1283
1262
  # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
1284
1263
  @GeneralUtilities.check_arguments
1285
- def run_program(self, program: str, arguments: str = "", working_directory: str = None, verbosity: int = 1,
1286
- print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False,
1287
- title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True,
1288
- custom_argument: object = None) -> tuple[int, str, str, int]:
1289
- return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity, print_errors_as_information,
1290
- log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument)
1264
+ def run_program(self, program: str, arguments: str = "", working_directory: str = None, verbosity: int = 1, 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) -> tuple[int, str, str, int]:
1265
+ return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument)
1291
1266
 
1292
1267
  # Return-values program_runner: Pid
1293
1268
  @GeneralUtilities.check_arguments
1294
- def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1,
1295
- print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False,
1296
- title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, custom_argument: object = None) -> int:
1269
+ def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1, 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) -> int:
1297
1270
  mock_loader_result = self.__try_load_mock(program, ' '.join(arguments_as_array), working_directory)
1298
1271
  if mock_loader_result[0]:
1299
1272
  return mock_loader_result[1]
1300
1273
 
1301
- process: Popen = self.__run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, verbosity,
1302
- print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1274
+ process: Popen = self.__run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1303
1275
  return process.pid
1304
1276
 
1305
1277
  # Return-values program_runner: Pid
1306
1278
  @GeneralUtilities.check_arguments
1307
1279
  def run_program_async(self, program: str, arguments: str = "", working_directory: str = None, verbosity: int = 1,
1308
- print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False,
1309
- title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, custom_argument: object = None) -> int:
1310
- return self.run_program_argsasarray_async(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity,
1311
- print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1280
+ 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) -> int:
1281
+ return self.run_program_argsasarray_async(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, custom_argument)
1312
1282
 
1313
1283
  @GeneralUtilities.check_arguments
1314
1284
  def __try_load_mock(self, program: str, arguments: str, working_directory: str) -> tuple[bool, tuple[int, str, str, int]]:
@@ -1335,8 +1305,7 @@ class ScriptCollectionCore:
1335
1305
  GeneralUtilities.write_message_to_stderr(stderr)
1336
1306
 
1337
1307
  @GeneralUtilities.check_arguments
1338
- def __format_program_execution_information(self, exitcode: int = None, stdout: str = None, stderr: str = None, program: str = None, argument: str = None,
1339
- workingdirectory: str = None, title: str = None, pid: int = None, execution_duration: timedelta = None):
1308
+ def __format_program_execution_information(self, exitcode: int = None, stdout: str = None, stderr: str = None, program: str = None, argument: str = None, workingdirectory: str = None, title: str = None, pid: int = None, execution_duration: timedelta = None):
1340
1309
  result = ""
1341
1310
  if (exitcode is not None and stdout is not None and stderr is not None):
1342
1311
  result = f"{result} Exitcode: {exitcode}; StdOut: '{stdout}'; StdErr: '{stderr}'"
@@ -1366,8 +1335,7 @@ class ScriptCollectionCore:
1366
1335
  f"stderr: {GeneralUtilities.str_none_safe(str(r.stderr))})"
1367
1336
 
1368
1337
  @GeneralUtilities.check_arguments
1369
- def register_mock_program_call(self, program: str, argument: str, workingdirectory: str, result_exit_code: int, result_stdout: str, result_stderr: str,
1370
- result_pid: int, amount_of_expected_calls=1):
1338
+ def register_mock_program_call(self, program: str, argument: str, workingdirectory: str, result_exit_code: int, result_stdout: str, result_stderr: str, result_pid: int, amount_of_expected_calls=1):
1371
1339
  "This function is for test-purposes only"
1372
1340
  for _ in itertools.repeat(None, amount_of_expected_calls):
1373
1341
  mock_call = ScriptCollectionCore.__MockProgramCall()
@@ -1462,16 +1430,17 @@ class ScriptCollectionCore:
1462
1430
 
1463
1431
  @GeneralUtilities.check_arguments
1464
1432
  def get_semver_version_from_gitversion(self, repository_folder: str) -> str:
1465
- result = self.get_version_from_gitversion(repository_folder, "MajorMinorPatch")
1466
-
1467
- if self.git_repository_has_uncommitted_changes(repository_folder):
1468
- if self.get_current_git_branch_has_tag(repository_folder):
1469
- id_of_latest_tag = self.git_get_commitid_of_tag(repository_folder, self.get_latest_git_tag(repository_folder))
1470
- current_commit = self.git_get_commit_id(repository_folder)
1471
- current_commit_is_on_latest_tag = id_of_latest_tag == current_commit
1472
- if current_commit_is_on_latest_tag:
1473
- result = self.increment_version(result, False, False, True)
1474
-
1433
+ if(self.git_repository_has_commits(repository_folder)):
1434
+ result = self.get_version_from_gitversion(repository_folder, "MajorMinorPatch")
1435
+ if self.git_repository_has_uncommitted_changes(repository_folder):
1436
+ if self.get_current_git_branch_has_tag(repository_folder):
1437
+ id_of_latest_tag = self.git_get_commitid_of_tag(repository_folder, self.get_latest_git_tag(repository_folder))
1438
+ current_commit = self.git_get_commit_id(repository_folder)
1439
+ current_commit_is_on_latest_tag = id_of_latest_tag == current_commit
1440
+ if current_commit_is_on_latest_tag:
1441
+ result = self.increment_version(result, False, False, True)
1442
+ else:
1443
+ result="0.1.0"
1475
1444
  return result
1476
1445
 
1477
1446
  @staticmethod
@@ -1495,21 +1464,17 @@ class ScriptCollectionCore:
1495
1464
  days_until_expire = 1825
1496
1465
  if password is None:
1497
1466
  password = GeneralUtilities.generate_password()
1498
- self.run_program("openssl", f'req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days {days_until_expire} -nodes -x509 -subj ' +
1499
- f'/C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={name}/OU={subj_ou} -passout pass:{password} ' +
1500
- f'-keyout {name}.key -out {name}.crt', folder)
1467
+ self.run_program("openssl", f'req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days {days_until_expire} -nodes -x509 -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={name}/OU={subj_ou} -passout pass:{password} -keyout {name}.key -out {name}.crt', folder)
1501
1468
 
1502
1469
  @GeneralUtilities.check_arguments
1503
- def generate_certificate(self, folder: str, domain: str, filename: str, subj_c: str, subj_st: str, subj_l: str, subj_o: str, subj_ou: str,
1504
- days_until_expire: int = None, password: str = None) -> None:
1470
+ def generate_certificate(self, folder: str, domain: str, filename: str, subj_c: str, subj_st: str, subj_l: str, subj_o: str, subj_ou: str, days_until_expire: int = None, password: str = None) -> None:
1505
1471
  if days_until_expire is None:
1506
1472
  days_until_expire = 397
1507
1473
  if password is None:
1508
1474
  password = GeneralUtilities.generate_password()
1509
1475
  rsa_key_length = 4096
1510
1476
  self.run_program("openssl", f'genrsa -out {filename}.key {rsa_key_length}', folder)
1511
- self.run_program("openssl", f'req -new -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={domain}/OU={subj_ou} -x509 ' +
1512
- f'-key {filename}.key -out {filename}.unsigned.crt -days {days_until_expire}', folder)
1477
+ self.run_program("openssl", f'req -new -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={domain}/OU={subj_ou} -x509 -key {filename}.key -out {filename}.unsigned.crt -days {days_until_expire}', folder)
1513
1478
  self.run_program("openssl", f'pkcs12 -export -out {filename}.selfsigned.pfx -password pass:{password} -inkey {filename}.key -in {filename}.unsigned.crt', folder)
1514
1479
  GeneralUtilities.write_text_to_file(os.path.join(folder, f"{filename}.password"), password)
1515
1480
  GeneralUtilities.write_text_to_file(os.path.join(folder, f"{filename}.san.conf"), f"""[ req ]
@@ -1537,8 +1502,7 @@ DNS = {domain}
1537
1502
 
1538
1503
  @GeneralUtilities.check_arguments
1539
1504
  def generate_certificate_sign_request(self, folder: str, domain: str, filename: str, subj_c: str, subj_st: str, subj_l: str, subj_o: str, subj_ou: str) -> None:
1540
- self.run_program("openssl", f'req -new -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={domain}/OU={subj_ou} ' +
1541
- f'-key {filename}.key -out {filename}.csr -config {filename}.san.conf', folder)
1505
+ self.run_program("openssl", f'req -new -subj /C={subj_c}/ST={subj_st}/L={subj_l}/O={subj_o}/CN={domain}/OU={subj_ou} -key {filename}.key -out {filename}.csr -config {filename}.san.conf', folder)
1542
1506
 
1543
1507
  @GeneralUtilities.check_arguments
1544
1508
  def sign_certificate(self, folder: str, ca_folder: str, ca_name: str, domain: str, filename: str, days_until_expire: int = None) -> None:
@@ -1547,8 +1511,7 @@ DNS = {domain}
1547
1511
  ca = os.path.join(ca_folder, ca_name)
1548
1512
  password_file = os.path.join(folder, f"{filename}.password")
1549
1513
  password = GeneralUtilities.read_text_from_file(password_file)
1550
- self.run_program("openssl", f'x509 -req -in {filename}.csr -CA {ca}.crt -CAkey {ca}.key -CAcreateserial -CAserial {ca}.srl ' +
1551
- f'-out {filename}.crt -days {days_until_expire} -sha256 -extensions v3_req -extfile {filename}.san.conf', folder)
1514
+ self.run_program("openssl", f'x509 -req -in {filename}.csr -CA {ca}.crt -CAkey {ca}.key -CAcreateserial -CAserial {ca}.srl -out {filename}.crt -days {days_until_expire} -sha256 -extensions v3_req -extfile {filename}.san.conf', folder)
1552
1515
  self.run_program("openssl", f'pkcs12 -export -out {filename}.pfx -inkey {filename}.key -in {filename}.crt -password pass:{password}', folder)
1553
1516
 
1554
1517
  @GeneralUtilities.check_arguments
@@ -1674,12 +1637,9 @@ DNS = {domain}
1674
1637
 
1675
1638
  # create debfile
1676
1639
  deb_filename = f"{toolname}.deb"
1677
- self.run_program_argsasarray("tar", ["czf", f"../{entireresult_content_folder_name}/control.tar.gz", "*"],
1678
- packagecontent_control_folder, verbosity=verbosity)
1679
- self.run_program_argsasarray("tar", ["czf", f"../{entireresult_content_folder_name}/data.tar.gz", "*"],
1680
- packagecontent_data_folder, verbosity=verbosity)
1681
- self.run_program_argsasarray("ar", ["r", deb_filename, "debian-binary", "control.tar.gz", "data.tar.gz"],
1682
- packagecontent_entireresult_folder, verbosity=verbosity)
1640
+ self.run_program_argsasarray("tar", ["czf", f"../{entireresult_content_folder_name}/control.tar.gz", "*"], packagecontent_control_folder, verbosity=verbosity)
1641
+ self.run_program_argsasarray("tar", ["czf", f"../{entireresult_content_folder_name}/data.tar.gz", "*"], packagecontent_data_folder, verbosity=verbosity)
1642
+ self.run_program_argsasarray("ar", ["r", deb_filename, "debian-binary", "control.tar.gz", "data.tar.gz"], packagecontent_entireresult_folder, verbosity=verbosity)
1683
1643
  result_file = os.path.join(packagecontent_entireresult_folder, deb_filename)
1684
1644
  shutil.copy(result_file, os.path.join(deb_output_folder, deb_filename))
1685
1645
 
@@ -1708,3 +1668,25 @@ DNS = {domain}
1708
1668
  lines=GeneralUtilities.read_lines_from_file(file)
1709
1669
  lines[0]=re.sub("\\d\\d\\d\\d",current_year,lines[0])
1710
1670
  GeneralUtilities.write_lines_to_file(file,lines)
1671
+
1672
+ @GeneralUtilities.check_arguments
1673
+ def get_external_ip(self, proxy: str) -> str:
1674
+ information=self.get_externalnetworkinformation_as_json_string(proxy)
1675
+ parsed=json.loads(information)
1676
+ return parsed.ip
1677
+
1678
+ @GeneralUtilities.check_arguments
1679
+ def get_country_of_external_ip(self, proxy: str) -> str:
1680
+ information=self.get_externalnetworkinformation_as_json_string(proxy)
1681
+ parsed=json.loads(information)
1682
+ return parsed.country
1683
+
1684
+ @GeneralUtilities.check_arguments
1685
+ def get_externalnetworkinformation_as_json_string(self, proxy: str) -> str:
1686
+ proxies = None
1687
+ if GeneralUtilities.string_has_content(proxy):
1688
+ proxies = {"http": proxy}
1689
+ response = requests.get('https://ipinfo.io', proxies=proxies, timeout=5)
1690
+ network_information_as_json_string=GeneralUtilities.bytes_to_string(response.content)
1691
+ return network_information_as_json_string
1692
+