ScriptCollection 3.5.151__py3-none-any.whl → 3.5.153__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.
@@ -715,11 +715,14 @@ def UpdateImagesInDockerComposeFile() -> int:
715
715
  iu: ImageUpdater = ImageUpdater()
716
716
  parser = argparse.ArgumentParser()
717
717
  parser.add_argument('-f', '--file', required=False, default=None)
718
- # TODO add option to specify ignored services and versionecholon
718
+ parser.add_argument('-v', '--versionecholon', required=False, default=VersionEcholon.Newest.name, dest="Possible values are: " + ", ".join([e.name for e in VersionEcholon]))
719
+ parser.add_argument("-s", "--servicename", required=True, default=None)
720
+ parser.add_argument("-u", "--updatertype", required=True, default=None)
719
721
  args = parser.parse_args()
720
722
  if args.file is None:
721
723
  args.file = os.path.join(os.getcwd(), "docker-compose.yml")
722
- iu.update_all_services_in_docker_compose_file(args.file, VersionEcholon.LatestPatch, [])
724
+ versionecholonTyped = VersionEcholon[args.versionecholon]
725
+ iu.update_services_in_docker_compose_file(args.file, [args.servicename], versionecholonTyped, args.updatertype)
723
726
  return 0
724
727
 
725
728
 
@@ -748,3 +751,12 @@ def GenerateTaskfileFromWorkspacefile() -> int:
748
751
  t = TasksForCommonProjectStructure()
749
752
  t.generate_tasksfile_from_workspace_file(args.repositoryfolder)
750
753
  return 0
754
+
755
+
756
+ def UpdateTimestampInFile() -> int:
757
+ parser = argparse.ArgumentParser(description="Update the timestamp in a comment in a file")
758
+ parser.add_argument('-f', '--file', required=True)
759
+ args = parser.parse_args()
760
+ sc = ScriptCollectionCore()
761
+ sc.update_timestamp_in_file(args.file)
762
+ return 0
@@ -35,6 +35,7 @@ class VersionEcholon(Enum):
35
35
 
36
36
  class GeneralUtilities:
37
37
 
38
+ __datetime_format_with_offset: str = "%Y-%m-%d %H:%M:%S %z"
38
39
  __datetime_format: str = "%Y-%m-%dT%H:%M:%S"
39
40
  __date_format: str = "%Y-%m-%d"
40
41
 
@@ -133,6 +134,11 @@ class GeneralUtilities:
133
134
  value = datetime(year=value.year, month=value.month, day=value.day, hour=value.hour, minute=value.minute, second=value.second)
134
135
  return value.strftime(GeneralUtilities.__datetime_format) # returns "2022-10-06T19:26:01" for example
135
136
 
137
+ @staticmethod
138
+ @check_arguments
139
+ def datetime_to_string_with_timezone(value: datetime) -> str:
140
+ return value.strftime(GeneralUtilities.__datetime_format_with_offset) # returns "2025-08-21 15:30:00 +0200" for example
141
+
136
142
  @staticmethod
137
143
  @check_arguments
138
144
  def string_to_date(value: str) -> date:
@@ -352,13 +358,21 @@ class GeneralUtilities:
352
358
 
353
359
  @staticmethod
354
360
  @check_arguments
355
- def datetime_to_string_for_logfile_name(datetime_object: datetime) -> str:
356
- return datetime_object.strftime('%Y-%m-%d_%H-%M-%S')
361
+ def datetime_to_string_for_logfile_name(datetime_object: datetime, add_timezone_info_to_log: bool = True) -> str:
362
+ base_pattern: str = "%Y-%m-%d_%H-%M-%S"
363
+ if add_timezone_info_to_log:
364
+ return datetime_object.strftime(f'{base_pattern}_%z')
365
+ else:
366
+ return datetime_object.strftime(base_pattern)
357
367
 
358
368
  @staticmethod
359
369
  @check_arguments
360
- def datetime_to_string_for_logfile_entry(datetime_object: datetime) -> str:
361
- return datetime_object.strftime('%Y-%m-%d %H:%M:%S')
370
+ def datetime_to_string_for_logfile_entry(datetime_object: datetime, add_timezone_info_to_log: bool = True) -> str:
371
+ base_pattern: str = "%Y-%m-%d %H:%M:%S"
372
+ if add_timezone_info_to_log:
373
+ return datetime_object.strftime(f'{base_pattern} %z')
374
+ else:
375
+ return datetime_object.strftime(base_pattern)
362
376
 
363
377
  @staticmethod
364
378
  @check_arguments
@@ -132,6 +132,11 @@ class ConcreteImageUpdater:
132
132
  def get_version_from_tag(self, image: str, tag: str) -> Version:
133
133
  raise NotImplementedError
134
134
 
135
+ @abstractmethod
136
+ @GeneralUtilities.check_arguments
137
+ def get_name(self, image: str, tag: str) -> str:
138
+ raise NotImplementedError
139
+
135
140
 
136
141
  class ConcreteImageUpdaterForNginx(ConcreteImageUpdater):
137
142
 
@@ -154,6 +159,11 @@ class ConcreteImageUpdaterForNginx(ConcreteImageUpdater):
154
159
  def get_version_from_tag(self, image: str, tag: str) -> Version:
155
160
  return ve.parse(tag)
156
161
 
162
+ @abstractmethod
163
+ @GeneralUtilities.check_arguments
164
+ def get_name(self, image: str, tag: str) -> str:
165
+ return "Nginx"
166
+
157
167
 
158
168
  class ConcreteImageUpdaterForWordpress(ConcreteImageUpdater):
159
169
 
@@ -176,6 +186,11 @@ class ConcreteImageUpdaterForWordpress(ConcreteImageUpdater):
176
186
  def get_version_from_tag(self, image: str, tag: str) -> Version:
177
187
  return ve.parse(tag)
178
188
 
189
+ @abstractmethod
190
+ @GeneralUtilities.check_arguments
191
+ def get_name(self, image: str, tag: str) -> str:
192
+ return "Wordpress"
193
+
179
194
 
180
195
  class ConcreteImageUpdaterForGitLab(ConcreteImageUpdater):
181
196
 
@@ -195,6 +210,11 @@ class ConcreteImageUpdaterForGitLab(ConcreteImageUpdater):
195
210
  def get_version_from_tag(self, image: str, tag: str) -> Version:
196
211
  raise NotImplementedError
197
212
 
213
+ @abstractmethod
214
+ @GeneralUtilities.check_arguments
215
+ def get_name(self, image: str, tag: str) -> str:
216
+ return "GitLab"
217
+
198
218
 
199
219
  class ConcreteImageUpdaterForRegistry(ConcreteImageUpdater):
200
220
 
@@ -218,6 +238,11 @@ class ConcreteImageUpdaterForRegistry(ConcreteImageUpdater):
218
238
  def get_version_from_tag(self, image: str, tag: str) -> Version:
219
239
  return ve.parse(tag)
220
240
 
241
+ @abstractmethod
242
+ @GeneralUtilities.check_arguments
243
+ def get_name(self, image: str, tag: str) -> str:
244
+ return "Registry"
245
+
221
246
 
222
247
  class ConcreteImageUpdaterForPrometheus(ConcreteImageUpdater):
223
248
 
@@ -240,6 +265,11 @@ class ConcreteImageUpdaterForPrometheus(ConcreteImageUpdater):
240
265
  def get_version_from_tag(self, image: str, tag: str) -> Version:
241
266
  return ve.parse(tag[1:])
242
267
 
268
+ @abstractmethod
269
+ @GeneralUtilities.check_arguments
270
+ def get_name(self, image: str, tag: str) -> str:
271
+ return "Prometheus"
272
+
243
273
 
244
274
  class ConcreteImageUpdaterForPrometheusBlackboxExporter(ConcreteImageUpdater):
245
275
 
@@ -262,6 +292,11 @@ class ConcreteImageUpdaterForPrometheusBlackboxExporter(ConcreteImageUpdater):
262
292
  def get_version_from_tag(self, image: str, tag: str) -> Version:
263
293
  return ve.parse(tag[1:])
264
294
 
295
+ @abstractmethod
296
+ @GeneralUtilities.check_arguments
297
+ def get_name(self, image: str, tag: str) -> str:
298
+ return "PrometheusBlackboxExporter"
299
+
265
300
 
266
301
  class ConcreteImageUpdaterForPrometheusNginxExporter(ConcreteImageUpdater):
267
302
 
@@ -284,6 +319,11 @@ class ConcreteImageUpdaterForPrometheusNginxExporter(ConcreteImageUpdater):
284
319
  def get_version_from_tag(self, image: str, tag: str) -> Version:
285
320
  return ve.parse(tag[1:])
286
321
 
322
+ @abstractmethod
323
+ @GeneralUtilities.check_arguments
324
+ def get_name(self, image: str, tag: str) -> str:
325
+ return "NginxPrometheusExporter"
326
+
287
327
 
288
328
  class ConcreteImageUpdaterForPrometheusNodeExporter(ConcreteImageUpdater):
289
329
 
@@ -306,6 +346,11 @@ class ConcreteImageUpdaterForPrometheusNodeExporter(ConcreteImageUpdater):
306
346
  def get_version_from_tag(self, image: str, tag: str) -> Version:
307
347
  return ve.parse(tag[1:])
308
348
 
349
+ @abstractmethod
350
+ @GeneralUtilities.check_arguments
351
+ def get_name(self, image: str, tag: str) -> str:
352
+ return "PrometheusNodeExporter"
353
+
309
354
 
310
355
  class ConcreteImageUpdaterForKeycloak(ConcreteImageUpdater):
311
356
 
@@ -325,6 +370,11 @@ class ConcreteImageUpdaterForKeycloak(ConcreteImageUpdater):
325
370
  def get_version_from_tag(self, image: str, tag: str) -> Version:
326
371
  raise NotImplementedError
327
372
 
373
+ @abstractmethod
374
+ @GeneralUtilities.check_arguments
375
+ def get_name(self, image: str, tag: str) -> str:
376
+ return "KeyCloak"
377
+
328
378
 
329
379
  class ConcreteImageUpdaterForMariaDB(ConcreteImageUpdater):
330
380
 
@@ -347,6 +397,11 @@ class ConcreteImageUpdaterForMariaDB(ConcreteImageUpdater):
347
397
  def get_version_from_tag(self, image: str, tag: str) -> Version:
348
398
  return ve.parse(tag)
349
399
 
400
+ @abstractmethod
401
+ @GeneralUtilities.check_arguments
402
+ def get_name(self, image: str, tag: str) -> str:
403
+ return "MariaDB"
404
+
350
405
 
351
406
  class ConcreteImageUpdaterForPostgreSQL(ConcreteImageUpdater):
352
407
 
@@ -369,6 +424,11 @@ class ConcreteImageUpdaterForPostgreSQL(ConcreteImageUpdater):
369
424
  def get_version_from_tag(self, image: str, tag: str) -> Version:
370
425
  return ve.parse(tag+".0")
371
426
 
427
+ @abstractmethod
428
+ @GeneralUtilities.check_arguments
429
+ def get_name(self, image: str, tag: str) -> str:
430
+ return "PostgreSQL"
431
+
372
432
 
373
433
  class ConcreteImageUpdaterForAdminer(ConcreteImageUpdater):
374
434
 
@@ -391,6 +451,65 @@ class ConcreteImageUpdaterForAdminer(ConcreteImageUpdater):
391
451
  def get_version_from_tag(self, image: str, tag: str) -> Version:
392
452
  return ve.parse(tag)
393
453
 
454
+ @abstractmethod
455
+ @GeneralUtilities.check_arguments
456
+ def get_name(self, image: str, tag: str) -> str:
457
+ return "Adminer"
458
+
459
+
460
+ class ConcreteImageUpdaterForGeneric(ConcreteImageUpdater):
461
+
462
+ @GeneralUtilities.check_arguments
463
+ def version_to_tag(self, version: Version) -> str:
464
+ return f"{version.major}.{version.minor}.{version.micro}"
465
+
466
+ @GeneralUtilities.check_arguments
467
+ def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
468
+ versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
469
+ newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
470
+ result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
471
+ return result
472
+
473
+ @GeneralUtilities.check_arguments
474
+ def get_supported_images(self) -> list[str]:
475
+ return [".*"]
476
+
477
+ @GeneralUtilities.check_arguments
478
+ def get_version_from_tag(self, image: str, tag: str) -> Version:
479
+ return ve.parse(tag)
480
+
481
+ @abstractmethod
482
+ @GeneralUtilities.check_arguments
483
+ def get_name(self, image: str, tag: str) -> str:
484
+ return "Generic"
485
+
486
+
487
+ class ConcreteImageUpdaterForGenericV(ConcreteImageUpdater):
488
+
489
+ @GeneralUtilities.check_arguments
490
+ def version_to_tag(self, version: Version) -> str:
491
+ return f"v{version.major}.{version.minor}.{version.micro}"
492
+
493
+ @GeneralUtilities.check_arguments
494
+ def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
495
+ versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^v\\d+\\.\\d+\\.\\d+$", 999)
496
+ newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
497
+ result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
498
+ return result
499
+
500
+ @GeneralUtilities.check_arguments
501
+ def get_supported_images(self) -> list[str]:
502
+ return [".*"]
503
+
504
+ @GeneralUtilities.check_arguments
505
+ def get_version_from_tag(self, image: str, tag: str) -> Version:
506
+ return ve.parse(tag[1:])
507
+
508
+ @abstractmethod
509
+ @GeneralUtilities.check_arguments
510
+ def get_name(self, image: str, tag: str) -> str:
511
+ return "GenericV"
512
+
394
513
 
395
514
  class ImageUpdater:
396
515
 
@@ -434,16 +553,16 @@ class ImageUpdater:
434
553
  return newer_version_available
435
554
 
436
555
  @GeneralUtilities.check_arguments
437
- def update_all_services_in_docker_compose_file(self, dockercompose_file: str, version_echolon: VersionEcholon, except_services: list[str] = []):
556
+ def update_all_services_in_docker_compose_file(self, dockercompose_file: str, version_echolon: VersionEcholon, except_services: list[str] = [], updatertype: str = None):
438
557
  all_services = self.get_services_from_docker_compose_file(dockercompose_file)
439
558
  services_to_update = [service for service in all_services if service not in except_services]
440
- self.update_services_in_docker_compose_file(dockercompose_file, services_to_update, version_echolon)
559
+ self.update_services_in_docker_compose_file(dockercompose_file, services_to_update, version_echolon, updatertype)
441
560
 
442
561
  @GeneralUtilities.check_arguments
443
- def update_services_in_docker_compose_file(self, dockercompose_file: str, service_names: list[str], version_echolon: VersionEcholon):
562
+ def update_services_in_docker_compose_file(self, dockercompose_file: str, service_names: list[str], version_echolon: VersionEcholon, updatertype: str = None):
444
563
  for service_name in service_names:
445
564
  if self.service_has_image_information(dockercompose_file, service_name):
446
- self.update_service_in_docker_compose_file(dockercompose_file, service_name, version_echolon)
565
+ self.update_service_in_docker_compose_file(dockercompose_file, service_name, version_echolon, updatertype)
447
566
 
448
567
  @GeneralUtilities.check_arguments
449
568
  def service_has_image_information(self, dockercompose_file: str, service_name: str) -> bool:
@@ -454,9 +573,9 @@ class ImageUpdater:
454
573
  return image is not None
455
574
 
456
575
  @GeneralUtilities.check_arguments
457
- def update_service_in_docker_compose_file(self, dockercompose_file: str, service_name: str, version_echolon: VersionEcholon):
576
+ def update_service_in_docker_compose_file(self, dockercompose_file: str, service_name: str, version_echolon: VersionEcholon, updatertype: str = None):
458
577
  imagename, existing_tag, existing_version = self.get_current_version_of_service_from_docker_compose_file(dockercompose_file, service_name) # pylint:disable=unused-variable
459
- result = self.get_latest_version_of_image(imagename, version_echolon, existing_version)
578
+ result = self.get_latest_version_of_image(imagename, version_echolon, existing_version, updatertype)
460
579
  newest_version = result[0]
461
580
  newest_tag = result[1]
462
581
  # TODO write info to console if there is a newwer version available if versionecoholon==latest would have been chosen
@@ -495,20 +614,35 @@ class ImageUpdater:
495
614
  raise ValueError(f"Service '{service_name}' in '{dockercompose_file}'")
496
615
 
497
616
  @GeneralUtilities.check_arguments
498
- def __get_updater_for_image(self, image: str) -> str:
617
+ def __get_updater_for_image(self, image: str) -> ConcreteImageUpdater:
499
618
  for updater in self.updater:
500
- if image in updater.get_supported_images():
501
- return updater
619
+ for supported_image_regex in updater.get_supported_images():
620
+ r = re.compile("^"+supported_image_regex+"$")
621
+ if r.match(supported_image_regex):
622
+ return updater
502
623
  raise ValueError(f"No updater available for image '{image}'")
503
624
 
625
+ @GeneralUtilities.check_arguments
626
+ def __get_updater_by_name(self, updater_name: str) -> ConcreteImageUpdater:
627
+ for updater in self.updater:
628
+ if updater.get_name() == updater_name:
629
+ return updater
630
+ raise ValueError(f"No updater available with name '{updater_name}'")
631
+
504
632
  @GeneralUtilities.check_arguments
505
633
  def get_docker_version_from_tag(self, image: str, tag: str) -> Version:
506
- updater: ImageUpdater = self.__get_updater_for_image(image)
634
+ updater: ConcreteImageUpdater = self.__get_updater_for_image(image)
507
635
  return updater.get_version_from_tag(image, tag)
508
636
 
509
637
  @GeneralUtilities.check_arguments
510
- def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> tuple[Version, str]:
511
- updater: ImageUpdater = self.__get_updater_for_image(image)
638
+ def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version, updatertype: str = None) -> tuple[Version, str]:
639
+
640
+ updater: ConcreteImageUpdater = None
641
+ if updatertype is None:
642
+ self.__get_updater_for_image(image)
643
+ else:
644
+ self.__get_updater_by_name(updatertype)
645
+
512
646
  newest_version: Version = updater.get_latest_version_of_image(image, version_echolon, current_version)
513
647
  newest_tag: str = updater.version_to_tag(newest_version)
514
648
  return (newest_version, newest_tag)
ScriptCollection/SCLog.py CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  from enum import Enum
3
- from datetime import datetime, timezone
3
+ from datetime import datetime
4
4
  from .GeneralUtilities import GeneralUtilities
5
5
 
6
6
 
@@ -22,7 +22,6 @@ class SCLog:
22
22
  add_overhead_to_console: bool
23
23
  add_overhead_to_logfile: bool
24
24
  print_as_color: bool
25
- zone_of_time: timezone = None
26
25
 
27
26
  def __init__(self, log_file: str = None, loglevel: LogLevel = None, print_as_color: bool = True):
28
27
  self.log_file = log_file
@@ -69,13 +68,9 @@ class SCLog:
69
68
  if loglevel == LogLevel.Diagnostic:
70
69
  part3 = f"Diagnostic: {message}"
71
70
 
72
- moment: datetime = None
73
- if self.zone_of_time is None:
74
- moment = datetime.now()
75
- else:
76
- moment = datetime.now(self.zone_of_time)
71
+ moment: datetime = datetime.now(datetime.now().astimezone().tzinfo)
77
72
 
78
- part1 = f"[{GeneralUtilities.datetime_to_string_for_logfile_entry(moment)}] ["
73
+ part1 = f"[{GeneralUtilities.datetime_to_string_for_logfile_entry(moment, True)}] ["
79
74
  if loglevel == LogLevel.Information:
80
75
  part2 = f"Information"
81
76
  elif loglevel == LogLevel.Error:
@@ -1,3 +1,4 @@
1
+ import traceback
1
2
  from datetime import timedelta, datetime
2
3
  import json
3
4
  import binascii
@@ -34,7 +35,7 @@ from .ProgramRunnerPopen import ProgramRunnerPopen
34
35
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
35
36
  from .SCLog import SCLog, LogLevel
36
37
 
37
- version = "3.5.151"
38
+ version = "3.5.153"
38
39
  __version__ = version
39
40
 
40
41
 
@@ -2436,3 +2437,28 @@ OCR-content:
2436
2437
  if has_staged_changes:
2437
2438
  changed_ocr_file_relative_path = os.path.relpath(changed_ocr_file, folder)
2438
2439
  self.run_program_argsasarray("git", ["add", changed_ocr_file_relative_path], folder)
2440
+
2441
+ @GeneralUtilities.check_arguments
2442
+ def update_timestamp_in_file(self, target_file: str) -> None:
2443
+ lines = GeneralUtilities.read_lines_from_file(target_file)
2444
+ new_lines = []
2445
+ prefix: str = "# last update: "
2446
+ for line in lines:
2447
+ if line.startswith(prefix):
2448
+ new_lines.append(prefix+GeneralUtilities.datetime_to_string_with_timezone(datetime.now()))
2449
+ else:
2450
+ new_lines.append(line)
2451
+ GeneralUtilities.write_lines_to_file(target_file, new_lines)
2452
+
2453
+ def do_and_log_task(self,name_of_task:str,task):
2454
+ try:
2455
+ self.log.log(f"Start {name_of_task}", LogLevel.Information)
2456
+ result= task()
2457
+ if result is None:
2458
+ result=0
2459
+ return result
2460
+ except Exception as e:
2461
+ self.log.log_exception(f"Error while {name_of_task}.", e, traceback)
2462
+ return 1
2463
+ finally:
2464
+ self.log.log(f"Finished {name_of_task}.", LogLevel.Information)
@@ -240,10 +240,9 @@ class TasksForCommonProjectStructure:
240
240
  @GeneralUtilities.check_arguments
241
241
  def copy_source_files_to_output_directory(self, buildscript_file: str) -> None:
242
242
  GeneralUtilities.write_message_to_stdout("Copy sourcecode...")
243
- sc = ScriptCollectionCore()
244
243
  folder = os.path.dirname(os.path.realpath(buildscript_file))
245
244
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", folder)
246
- result = sc.run_program_argsasarray("git", ["ls-tree", "-r", "HEAD", "--name-only"], codeunit_folder)
245
+ result = self.__sc.run_program_argsasarray("git", ["ls-tree", "-r", "HEAD", "--name-only"], codeunit_folder)
247
246
  files = [f for f in result[1].split('\n') if len(f) > 0]
248
247
  for file in files:
249
248
  full_source_file = os.path.join(codeunit_folder, file)
@@ -271,7 +270,6 @@ class TasksForCommonProjectStructure:
271
270
  }
272
271
  for target in targets:
273
272
  GeneralUtilities.write_message_to_stdout(f"Build package {package_name} for target {target_names[target]}...")
274
- sc = ScriptCollectionCore()
275
273
  self.run_with_epew("flutter", f"build {target}", src_folder, verbosity)
276
274
  if target == "web":
277
275
  web_relase_folder = os.path.join(src_folder, "build/web")
@@ -300,7 +298,7 @@ class TasksForCommonProjectStructure:
300
298
  GeneralUtilities.ensure_directory_does_not_exist(apk_folder)
301
299
  GeneralUtilities.ensure_directory_exists(apk_folder)
302
300
  apks_file = f"{apk_folder}/{codeunit_name}.apks"
303
- sc.run_program("java", f"-jar {bundletool} build-apks --bundle={aab_file} --output={apks_file} --mode=universal", aab_relase_folder, verbosity)
301
+ self.__sc.run_program("java", f"-jar {bundletool} build-apks --bundle={aab_file} --output={apks_file} --mode=universal", aab_relase_folder, verbosity)
304
302
  with zipfile.ZipFile(apks_file, "r") as zip_ref:
305
303
  zip_ref.extract("universal.apk", apk_folder)
306
304
  GeneralUtilities.ensure_file_does_not_exist(apks_file)
@@ -485,7 +483,7 @@ class TasksForCommonProjectStructure:
485
483
  self.write_version_to_codeunit_file(codeunit_file, current_version)
486
484
 
487
485
  @GeneralUtilities.check_arguments
488
- def t4_transform(self, commontasks_script_file_of_current_file: str, verbosity: int,ignore_git_ignored_files:bool=True):
486
+ def t4_transform(self, commontasks_script_file_of_current_file: str, verbosity: int, ignore_git_ignored_files: bool = True):
489
487
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", commontasks_script_file_of_current_file)
490
488
  self.__ensure_grylibrary_is_available(codeunit_folder)
491
489
  repository_folder: str = os.path.dirname(codeunit_folder)
@@ -494,51 +492,19 @@ class TasksForCommonProjectStructure:
494
492
  for search_result in Path(codeunit_folder).glob('**/*.tt'):
495
493
  tt_file = str(search_result)
496
494
  relative_path_to_tt_file_from_repository = str(Path(tt_file).relative_to(repository_folder))
497
- if (not ignore_git_ignored_files) or (ignore_git_ignored_files and not self.__sc.file_is_git_ignored(relative_path_to_tt_file_from_repository,repository_folder)):
495
+ if (not ignore_git_ignored_files) or (ignore_git_ignored_files and not self.__sc.file_is_git_ignored(relative_path_to_tt_file_from_repository, repository_folder)):
498
496
  relative_path_to_tt_file_from_codeunit_file = str(Path(tt_file).relative_to(codeunit_folder))
499
497
  argument = [f"--parameter=repositoryFolder={repository_folder}", f"--parameter=codeUnitName={codeunitname}", relative_path_to_tt_file_from_codeunit_file]
500
498
  self.__sc.run_program_argsasarray("t4", argument, codeunit_folder, verbosity=verbosity)
501
499
 
502
500
  @GeneralUtilities.check_arguments
503
- def get_resource_from_global_resource(self,codeunit_folder:str,resource_name:str):
504
- repository_folder:str= GeneralUtilities.resolve_relative_path("..", codeunit_folder)
505
- source_folder:str=os.path.join(repository_folder,"Other","Resources",resource_name)
506
- target_folder:str=os.path.join(codeunit_folder,"Other","Resources",resource_name)
501
+ def get_resource_from_global_resource(self, codeunit_folder: str, resource_name: str):
502
+ repository_folder: str = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
503
+ source_folder: str = os.path.join(repository_folder, "Other", "Resources", resource_name)
504
+ target_folder: str = os.path.join(codeunit_folder, "Other", "Resources", resource_name)
507
505
  GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder)
508
506
  GeneralUtilities.copy_content_of_folder(source_folder, target_folder)
509
507
 
510
- @GeneralUtilities.check_arguments
511
- def clone_repository_as_resource(self,local_repository_folder:str,remote_repository_link:str, resource_name:str,repository_subname:str=None)->str:
512
- commit_id:str=None
513
- target_folder:str=os.path.join(local_repository_folder,"Other","Resources",resource_name)
514
- if repository_subname is not None:
515
- target_folder=os.path.join(target_folder,repository_subname)
516
- if not os.path.isdir(target_folder):
517
- GeneralUtilities.ensure_directory_exists(target_folder)
518
- GeneralUtilities.write_message_to_stdout(f"Clone {remote_repository_link} into {target_folder}...")
519
- self.__sc.run_program("git",f"clone --recurse-submodules {remote_repository_link} {target_folder}")
520
-
521
- self.__sc.git_get_commit_id(target_folder)
522
-
523
- git_folders:list[str]=[]
524
- git_files:list[str]=[]
525
- for dirpath, dirnames, filenames in os.walk(target_folder):
526
- for dirname in dirnames:
527
- if dirname == ".git":
528
- full_path = os.path.join(dirpath, dirname)
529
- git_folders.append(full_path)
530
- for filename in filenames:
531
- if filename == ".git":
532
- full_path = os.path.join(dirpath, filename)
533
- git_files.append(full_path)
534
- for git_folder in git_folders:
535
- if os.path.isdir(git_folder):
536
- GeneralUtilities.ensure_directory_does_not_exist(git_folder)
537
- for git_file in git_files:
538
- if os.path.isdir(git_file):
539
- GeneralUtilities.ensure_file_does_not_exist(git_file)
540
- return commit_id
541
-
542
508
  @GeneralUtilities.check_arguments
543
509
  def standardized_tasks_generate_reference_by_docfx(self, generate_reference_script_file: str, verbosity: int, targetenvironmenttype: str, commandline_arguments: list[str]) -> None:
544
510
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
@@ -821,10 +787,9 @@ class TasksForCommonProjectStructure:
821
787
  GeneralUtilities.write_message_to_stdout("Generate SBOM...")
822
788
  self.assert_is_codeunit_folder(codeunit_folder)
823
789
  codeunit_name = os.path.basename(codeunit_folder)
824
- sc = ScriptCollectionCore()
825
790
  bomfile_folder = "Other\\Artifacts\\BOM"
826
791
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
827
- sc.run_program_argsasarray("dotnet", ["CycloneDX", f"{codeunit_name}\\{codeunit_name}.csproj", "-o", bomfile_folder, "--disable-github-licenses"], codeunit_folder, verbosity=verbosity)
792
+ self.__sc.run_program_argsasarray("dotnet", ["CycloneDX", f"{codeunit_name}\\{codeunit_name}.csproj", "-o", bomfile_folder, "--disable-github-licenses"], codeunit_folder, verbosity=verbosity)
828
793
  codeunitversion = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunit_name}.codeunit.xml"))
829
794
  target = f"{codeunit_folder}\\{bomfile_folder}\\{codeunit_name}.{codeunitversion}.sbom.xml"
830
795
  GeneralUtilities.ensure_file_does_not_exist(target)
@@ -1495,8 +1460,7 @@ class TasksForCommonProjectStructure:
1495
1460
  codeunit_folder = os.path.join(repository_folder, codeunitname)
1496
1461
  artifacts_folder = self.get_artifacts_folder(repository_folder, codeunitname)
1497
1462
  applicationimage_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
1498
- sc = ScriptCollectionCore()
1499
- image_file = sc.find_file_by_extension(applicationimage_folder, "tar")
1463
+ image_file = self.__sc.find_file_by_extension(applicationimage_folder, "tar")
1500
1464
  image_filename = os.path.basename(image_file)
1501
1465
  codeunit_version = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
1502
1466
  if remote_image_name is None:
@@ -1507,15 +1471,15 @@ class TasksForCommonProjectStructure:
1507
1471
  remote_image_latest = f"{remote_repo}:latest"
1508
1472
  remote_image_version = f"{remote_repo}:{codeunit_version}"
1509
1473
  GeneralUtilities.write_message_to_stdout("Load image...")
1510
- sc.run_program("docker", f"load --input {image_filename}", applicationimage_folder, verbosity=verbosity)
1474
+ self.__sc.run_program("docker", f"load --input {image_filename}", applicationimage_folder, verbosity=verbosity)
1511
1475
  GeneralUtilities.write_message_to_stdout("Tag image...")
1512
- sc.run_program("docker", f"tag {local_image_name}:{codeunit_version} {remote_image_latest}", verbosity=verbosity)
1513
- sc.run_program("docker", f"tag {local_image_name}:{codeunit_version} {remote_image_version}", verbosity=verbosity)
1476
+ self.__sc.run_program("docker", f"tag {local_image_name}:{codeunit_version} {remote_image_latest}", verbosity=verbosity)
1477
+ self.__sc.run_program("docker", f"tag {local_image_name}:{codeunit_version} {remote_image_version}", verbosity=verbosity)
1514
1478
  GeneralUtilities.write_message_to_stdout("Push image...")
1515
- sc.run_program("docker", f"push {remote_image_latest}", verbosity=verbosity)
1516
- sc.run_program("docker", f"push {remote_image_version}", verbosity=verbosity)
1479
+ self.__sc.run_program("docker", f"push {remote_image_latest}", verbosity=verbosity)
1480
+ self.__sc.run_program("docker", f"push {remote_image_version}", verbosity=verbosity)
1517
1481
  if push_readme:
1518
- sc.run_program("docker-pushrm", f"{remote_repo}", codeunit_folder, verbosity=verbosity)
1482
+ self.__sc.run_program("docker-pushrm", f"{remote_repo}", codeunit_folder, verbosity=verbosity)
1519
1483
 
1520
1484
  @GeneralUtilities.check_arguments
1521
1485
  def get_dependent_code_units(self, codeunit_file: str) -> list[str]:
@@ -1797,7 +1761,7 @@ class TasksForCommonProjectStructure:
1797
1761
  @GeneralUtilities.check_arguments
1798
1762
  def get_version_of_project(self, repository_folder: str) -> str:
1799
1763
  self.__sc.assert_is_git_repository(repository_folder)
1800
- return ScriptCollectionCore().get_semver_version_from_gitversion(repository_folder)
1764
+ return self.__sc.get_semver_version_from_gitversion(repository_folder)
1801
1765
 
1802
1766
  @GeneralUtilities.check_arguments
1803
1767
  def replace_common_variables_in_nuspec_file(self, codeunit_folder: str) -> None:
@@ -2248,7 +2212,7 @@ class TasksForCommonProjectStructure:
2248
2212
  openapi_spec_file = os.path.join(codeunit_folder, "Other", "Resources", "DependentCodeUnits", name_of_api_providing_codeunit, "APISpecification", f"{name_of_api_providing_codeunit}.latest.api.json")
2249
2213
  target_folder = os.path.join(codeunit_folder, target_subfolder_in_codeunit)
2250
2214
  GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder)
2251
- ScriptCollectionCore().run_program("java", f'-jar {openapigenerator_jar_file} generate -i {openapi_spec_file} -g {language} -o {target_folder} --global-property supportingFiles --global-property models --global-property apis', codeunit_folder)
2215
+ self.__sc.run_program("java", f'-jar {openapigenerator_jar_file} generate -i {openapi_spec_file} -g {language} -o {target_folder} --global-property supportingFiles --global-property models --global-property apis', codeunit_folder)
2252
2216
 
2253
2217
  @GeneralUtilities.check_arguments
2254
2218
  def generate_api_client_from_dependent_codeunit_in_dotnet(self, file: str, name_of_api_providing_codeunit: str, base_namespace: str) -> None:
@@ -2266,7 +2230,7 @@ class TasksForCommonProjectStructure:
2266
2230
  openapi_spec_file = os.path.join(codeunit_folder, "Other", "Resources", "DependentCodeUnits", name_of_api_providing_codeunit, "APISpecification", f"{name_of_api_providing_codeunit}.latest.api.json")
2267
2231
  target_folder = os.path.join(codeunit_folder, target_subfolder_in_codeunit)
2268
2232
  GeneralUtilities.ensure_directory_exists(target_folder)
2269
- ScriptCollectionCore().run_program("java", f'-jar {openapigenerator_jar_file} generate -i {openapi_spec_file} -g {language} -o {target_folder} --global-property supportingFiles --global-property models --global-property apis {additional_properties}', codeunit_folder)
2233
+ self.__sc.run_program("java", f'-jar {openapigenerator_jar_file} generate -i {openapi_spec_file} -g {language} -o {target_folder} --global-property supportingFiles --global-property models --global-property apis {additional_properties}', codeunit_folder)
2270
2234
 
2271
2235
  # move docs to correct folder
2272
2236
  target_folder_docs = os.path.join(target_folder, "docs")
@@ -2464,11 +2428,13 @@ class TasksForCommonProjectStructure:
2464
2428
  relative_script_file = task["command"]
2465
2429
 
2466
2430
  relative_script_file = "."
2431
+ cwd: str = None
2467
2432
  if "options" in task:
2468
2433
  options = task["options"]
2469
2434
  if "cwd" in options:
2470
- cwd: str = options["cwd"]
2435
+ cwd = options["cwd"]
2471
2436
  cwd = cwd.replace("${workspaceFolder}", ".")
2437
+ cwd = cwd.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
2472
2438
  relative_script_file = cwd
2473
2439
  if len(relative_script_file) == 0:
2474
2440
  relative_script_file = "."
@@ -2486,15 +2452,16 @@ class TasksForCommonProjectStructure:
2486
2452
  if append_cli_args_at_end:
2487
2453
  command_with_args = f"{command_with_args} {{{{.CLI_ARGS}}}}"
2488
2454
 
2489
- cwd_literal = cwd.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
2490
2455
  description_literal = description.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
2456
+ command_with_args = command_with_args.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
2491
2457
 
2492
2458
  lines.append(f" {name}:")
2493
2459
  lines.append(f' desc: "{description_literal}"')
2494
2460
  lines.append(' silent: true')
2495
- lines.append(f' dir: "{cwd_literal}"')
2461
+ if cwd is not None:
2462
+ lines.append(f' dir: "{cwd}"')
2496
2463
  lines.append(" cmds:")
2497
- lines.append(f" - {command_with_args}")
2464
+ lines.append(f' - "{command_with_args}"')
2498
2465
  lines.append(' aliases:')
2499
2466
  lines.append(f' - {name.lower()}')
2500
2467
  if "aliases" in task:
@@ -2685,6 +2652,7 @@ class TasksForCommonProjectStructure:
2685
2652
 
2686
2653
  @GeneralUtilities.check_arguments
2687
2654
  def build_specific_codeunits(self, repository_folder: str, codeunits: list[str], verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None, is_pre_merge: bool = False, export_target_directory: str = None, assume_dependent_codeunits_are_already_built: bool = True, commandline_arguments: list[str] = [], do_git_clean_when_no_changes: bool = False, note: str = None, check_for_new_files: bool = True) -> None:
2655
+ now_begin: datetime = datetime.now()
2688
2656
  codeunits_list = "{"+", ".join(["a", "b"])+"}"
2689
2657
  if verbosity > 2:
2690
2658
  GeneralUtilities.write_message_to_stdout(f"Start building codeunits ({codeunits_list}) in repository '{repository_folder}'...")
@@ -2708,7 +2676,7 @@ class TasksForCommonProjectStructure:
2708
2676
  sorted_codeunits = [codeunit for codeunit in sorted_codeunits if codeunit in codeunits]
2709
2677
  project_version = self.get_version_of_project(repository_folder)
2710
2678
 
2711
- message = f"Build codeunits in product {repository_name}..."
2679
+ message = f"Build codeunits in product {repository_name}... (Started: {GeneralUtilities.datetime_to_string(now_begin)})"
2712
2680
  if note is not None:
2713
2681
  message = f"{message} ({note})"
2714
2682
  GeneralUtilities.write_message_to_stdout(message)
@@ -2750,7 +2718,8 @@ class TasksForCommonProjectStructure:
2750
2718
  archive_file = os.path.join(os.getcwd(), f"{filename_without_extension}.zip")
2751
2719
  shutil.move(archive_file, target_folder)
2752
2720
 
2753
- message2 = f"Finished build codeunits in product {repository_name}."
2721
+ now_end: datetime = datetime.now()
2722
+ message2 = f"Finished build codeunits in product {repository_name}. (Finished: {GeneralUtilities.datetime_to_string(now_end)})"
2754
2723
  if note is not None:
2755
2724
  message2 = f"{message2} ({note})"
2756
2725
  GeneralUtilities.write_message_to_stdout(message2)
@@ -2963,13 +2932,12 @@ class TasksForCommonProjectStructure:
2963
2932
 
2964
2933
  @GeneralUtilities.check_arguments
2965
2934
  def __generate_svg_files_from_plantuml(self, diagrams_files_folder: str, plant_uml_folder: str) -> None:
2966
- sc = ScriptCollectionCore()
2967
2935
  for file in GeneralUtilities.get_all_files_of_folder(diagrams_files_folder):
2968
2936
  if file.endswith(".plantuml"):
2969
2937
  output_filename = self.get_output_filename_for_plantuml_filename(file)
2970
2938
  argument = ['-jar', f'{plant_uml_folder}/plantuml.jar', '-tsvg', os.path.basename(file)]
2971
2939
  folder = os.path.dirname(file)
2972
- sc.run_program_argsasarray("java", argument, folder, verbosity=0)
2940
+ self.__sc.run_program_argsasarray("java", argument, folder, verbosity=0)
2973
2941
  result_file = folder+"/" + output_filename
2974
2942
  GeneralUtilities.assert_file_exists(result_file)
2975
2943
  self.__sc.format_xml_file(result_file)
@@ -3067,7 +3035,7 @@ class TasksForCommonProjectStructure:
3067
3035
  artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts", artifact_name_of_zip)
3068
3036
  manifest_folder = os.path.join(codeunit_folder, "Other", "Artifacts", "WinGet-Manifest")
3069
3037
  GeneralUtilities.assert_folder_exists(artifacts_folder)
3070
- artifacts_file = ScriptCollectionCore().find_file_by_extension(artifacts_folder, "zip")
3038
+ artifacts_file = self.__sc.find_file_by_extension(artifacts_folder, "zip")
3071
3039
  winget_template_file = os.path.join(build_folder, "WinGet-Template.yaml")
3072
3040
  winget_manifest_file = os.path.join(manifest_folder, "WinGet-Manifest.yaml")
3073
3041
  GeneralUtilities.assert_file_exists(winget_template_file)
@@ -3502,3 +3470,57 @@ class TasksForCommonProjectStructure:
3502
3470
  excluded = ["opendms"]
3503
3471
  iu.update_all_services_in_docker_compose_file(dockercomposefile, VersionEcholon.LatestPatchOrLatestMinor, excluded)
3504
3472
  iu.check_for_newest_version(dockercomposefile, excluded)
3473
+
3474
+ @GeneralUtilities.check_arguments
3475
+ def clone_repository_as_resource(self, local_repository_folder: str, remote_repository_link: str, resource_name: str, repository_subname: str = None) -> None:
3476
+ GeneralUtilities.write_message_to_stdout(f'Clone resource {resource_name}...')
3477
+ resrepo_commit_id_folder: str = os.path.join(local_repository_folder, "Other", "Resources", f"{resource_name}Version")
3478
+ resrepo_commit_id_file: str = os.path.join(resrepo_commit_id_folder, f"{resource_name}Version.txt")
3479
+ latest_version: str = GeneralUtilities.read_text_from_file(resrepo_commit_id_file)
3480
+ resrepo_data_folder: str = os.path.join(local_repository_folder, "Other", "Resources", resource_name).replace("\\", "/")
3481
+ current_version: str = None
3482
+ resrepo_data_version: str = os.path.join(resrepo_data_folder, f"{resource_name}Version.txt")
3483
+ if os.path.isdir(resrepo_data_folder):
3484
+ if os.path.isfile(resrepo_data_version):
3485
+ current_version = GeneralUtilities.read_text_from_file(resrepo_data_version)
3486
+ if (current_version is None) or (current_version != latest_version):
3487
+ target_folder: str = resrepo_data_folder
3488
+ if repository_subname is not None:
3489
+ target_folder = f"{resrepo_data_folder}/{repository_subname}"
3490
+ GeneralUtilities.ensure_folder_exists_and_is_empty(target_folder)
3491
+ self.__sc.run_program("git", f"clone --recurse-submodules {remote_repository_link} {target_folder}")
3492
+ self.__sc.run_program("git", f"checkout {latest_version}", target_folder)
3493
+ GeneralUtilities.write_text_to_file(resrepo_data_version, latest_version)
3494
+
3495
+ git_folders: list[str] = []
3496
+ git_files: list[str] = []
3497
+ for dirpath, dirnames, filenames in os.walk(target_folder):
3498
+ for dirname in dirnames:
3499
+ if dirname == ".git":
3500
+ full_path = os.path.join(dirpath, dirname)
3501
+ git_folders.append(full_path)
3502
+ for filename in filenames:
3503
+ if filename == ".git":
3504
+ full_path = os.path.join(dirpath, filename)
3505
+ git_files.append(full_path)
3506
+ for git_folder in git_folders:
3507
+ if os.path.isdir(git_folder):
3508
+ GeneralUtilities.ensure_directory_does_not_exist(git_folder)
3509
+ for git_file in git_files:
3510
+ if os.path.isdir(git_file):
3511
+ GeneralUtilities.ensure_file_does_not_exist(git_file)
3512
+
3513
+ def set_latest_version_for_clone_repository_as_resource(self, resourcename: str, github_link: str, branch: str = "main"):
3514
+ current_file = str(Path(__file__).absolute())
3515
+ repository_folder = GeneralUtilities.resolve_relative_path("../../..", current_file)
3516
+
3517
+ resrepo_commit_id_folder: str = os.path.join(repository_folder, "Other", "Resources", f"{resourcename}Version")
3518
+ resrepo_commit_id_file: str = os.path.join(resrepo_commit_id_folder, f"{resourcename}Version.txt")
3519
+ current_version: str = GeneralUtilities.read_text_from_file(resrepo_commit_id_file)
3520
+
3521
+ stdOut = [l.split("\t") for l in GeneralUtilities.string_to_lines(self.__sc.run_program("git", f"ls-remote {github_link}")[1])]
3522
+ stdOut = [l for l in stdOut if l[1] == f"refs/heads/{branch}"]
3523
+ GeneralUtilities.assert_condition(len(stdOut) == 1)
3524
+ latest_version: str = stdOut[0][0]
3525
+ if current_version != latest_version:
3526
+ GeneralUtilities.write_text_to_file(resrepo_commit_id_file, latest_version)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 3.5.151
3
+ Version: 3.5.153
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
@@ -23,12 +23,12 @@ Classifier: Topic :: Utilities
23
23
  Requires-Python: >=3.10
24
24
  Description-Content-Type: text/markdown
25
25
  Requires-Dist: build>=1.3.0
26
- Requires-Dist: coverage>=7.10.2
26
+ Requires-Dist: coverage>=7.10.5
27
27
  Requires-Dist: cyclonedx-bom>=7.0.0
28
28
  Requires-Dist: defusedxml>=0.7.1
29
29
  Requires-Dist: keyboard>=0.13.5
30
30
  Requires-Dist: lcov-cobertura>=2.1.1
31
- Requires-Dist: lxml>=6.0.0
31
+ Requires-Dist: lxml>=6.0.1
32
32
  Requires-Dist: ntplib>=0.4.0
33
33
  Requires-Dist: Pillow>=11.3.0
34
34
  Requires-Dist: psutil>=7.0.0
@@ -36,7 +36,7 @@ Requires-Dist: pycdlib>=1.14.0
36
36
  Requires-Dist: Pygments>=2.19.2
37
37
  Requires-Dist: pylint>=3.3.8
38
38
  Requires-Dist: pyOpenSSL>=25.1.0
39
- Requires-Dist: PyPDF>=5.9.0
39
+ Requires-Dist: PyPDF>=6.0.0
40
40
  Requires-Dist: pytest>=8.4.1
41
41
  Requires-Dist: PyYAML>=6.0.2
42
42
  Requires-Dist: qrcode>=8.2
@@ -0,0 +1,17 @@
1
+ ScriptCollection/CertificateUpdater.py,sha256=OAxrG21k_o3W3niOOGNSZzUPJlvolOWc1lRB2dMhc3g,9212
2
+ ScriptCollection/Executables.py,sha256=BojgHGBYn5QqpsdIgn8r8raxb8bE_BUyb-fZ_rCEN0A,37050
3
+ ScriptCollection/GeneralUtilities.py,sha256=t8xp0s10V-MrWYQQiMx0ae3LLTM8G2wPyyWXqeIteXQ,48023
4
+ ScriptCollection/ImageUpdater.py,sha256=qTe3yoqzQJY7LZdXBbjbWvrsSQaeHy1VwmOxaRzU2ig,29305
5
+ ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
6
+ ScriptCollection/ProgramRunnerBase.py,sha256=2kMIAqdc65UjBAddOZkzy_aFx9h5roZ5a4bQNM6RV6Y,2480
7
+ ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1X43regfU,6477
8
+ ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
9
+ ScriptCollection/SCLog.py,sha256=49NlLEmK_f-icw_uEPq9U3qv-oBTMRcIqSg3jaO8VsA,4360
10
+ ScriptCollection/ScriptCollectionCore.py,sha256=XzMdqcTRG9UAV3uyZjvWYsa-hbMbSoT3Axb3OqIRMig,139119
11
+ ScriptCollection/TasksForCommonProjectStructure.py,sha256=glEoCoC9FotsG4jRu5-LgvvTB_qFntKlXT1kGhgy3s4,247136
12
+ ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ scriptcollection-3.5.153.dist-info/METADATA,sha256=JvDOgE8UQCgopI-CORbEa3VeFodQY-YJgXORPqjoUfc,7689
14
+ scriptcollection-3.5.153.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ scriptcollection-3.5.153.dist-info/entry_points.txt,sha256=yZlEK0r5Ie7xrSLdlWZgFqzLZiIctsIAUJvDCgrYBRo,4193
16
+ scriptcollection-3.5.153.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
17
+ scriptcollection-3.5.153.dist-info/RECORD,,
@@ -56,4 +56,5 @@ scshowmissingfiles = ScriptCollection.Executables:ShowMissingFiles
56
56
  scsigncertificate = ScriptCollection.Executables:SignCertificate
57
57
  scupdateimagesindockercomposefile = ScriptCollection.Executables:UpdateImagesInDockerComposeFile
58
58
  scupdatenugetpackagesincsharpproject = ScriptCollection.Executables:UpdateNugetpackagesInCsharpProject
59
+ scupdatetimestampinfile = ScriptCollection.Executables:UpdateTimestampInFile
59
60
  scuploadfile = ScriptCollection.Executables:UploadFile
@@ -1,17 +0,0 @@
1
- ScriptCollection/CertificateUpdater.py,sha256=OAxrG21k_o3W3niOOGNSZzUPJlvolOWc1lRB2dMhc3g,9212
2
- ScriptCollection/Executables.py,sha256=eX94RLNBarpWoZKeDo02gcP_qzmJDZcIx8XBZFVCFNc,36396
3
- ScriptCollection/GeneralUtilities.py,sha256=PKdzq382RYVSWeSG_6z6FiHu-SiTOi2BavJKvP-0slU,47308
4
- ScriptCollection/ImageUpdater.py,sha256=3B5pgAMnyne3ZogWz-suqglZGIB9FAKyWn31P9E1ST0,24491
5
- ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
6
- ScriptCollection/ProgramRunnerBase.py,sha256=2kMIAqdc65UjBAddOZkzy_aFx9h5roZ5a4bQNM6RV6Y,2480
7
- ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1X43regfU,6477
8
- ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
9
- ScriptCollection/SCLog.py,sha256=GJ44S6VaBVwX5Dd6MIrdZn6I0dpaaYKVq9w-N0nMXlo,4496
10
- ScriptCollection/ScriptCollectionCore.py,sha256=YJ6uOGQa224jtsva_OX3r8h2aIzGR9GAfJH4h-9iIAc,138093
11
- ScriptCollection/TasksForCommonProjectStructure.py,sha256=9vccEWsxlW7xGXFLc2RPPFMWCkmoGxbSGu7hi9NxkeU,244959
12
- ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- scriptcollection-3.5.151.dist-info/METADATA,sha256=-EuHJHBjH-Oe9njZujrMzqr5aUXDVt_20DyCPY_81RE,7689
14
- scriptcollection-3.5.151.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- scriptcollection-3.5.151.dist-info/entry_points.txt,sha256=AvmVO9iyWImExpvzL3YYQ9AOEiUIN9guPRRG_W_VNWY,4116
16
- scriptcollection-3.5.151.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
17
- scriptcollection-3.5.151.dist-info/RECORD,,