ScriptCollection 3.5.31__py3-none-any.whl → 3.5.33__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.
@@ -371,3 +371,19 @@ def GenerateARC42ReferenceTemplate() -> int:
371
371
  folder = os.getcwd()
372
372
  ScriptCollectionCore().generate_arc42_reference_template(folder, args.productname, args.subfolder)
373
373
  return 0
374
+
375
+
376
+ def CreateChangelogEntry() -> int:
377
+ parser = argparse.ArgumentParser()
378
+ parser.add_argument('-f', '--repositoryfolder', required=False, default=".")
379
+ parser.add_argument('-m', '--message', required=True)
380
+ parser.add_argument('-c', '--commit', action='store_true', required=False, default=False)
381
+ args = parser.parse_args()
382
+
383
+ folder: str = None
384
+ if os.path.isabs(args.repositoryfolder):
385
+ folder = args.repositoryfolder
386
+ else:
387
+ folder = GeneralUtilities.resolve_relative_path(args.repositoryfolder, os.getcwd())
388
+ TasksForCommonProjectStructure().create_changelog_entry(folder, args.message, args.commit)
389
+ return 0
@@ -383,10 +383,16 @@ class GeneralUtilities:
383
383
  with open(path, "a+", encoding="utf-8"):
384
384
  pass
385
385
 
386
+ @staticmethod
387
+ @check_arguments
388
+ def __remove_readonly(func, path, _):
389
+ os.chmod(path, stat.S_IWRITE)
390
+ func(path)
391
+
386
392
  @staticmethod
387
393
  @check_arguments
388
394
  def __rmtree(directory: str) -> None:
389
- shutil.rmtree(directory)
395
+ shutil.rmtree(directory, onerror=GeneralUtilities.__remove_readonly)
390
396
 
391
397
  @staticmethod
392
398
  @check_arguments
@@ -465,6 +471,16 @@ class GeneralUtilities:
465
471
  result.append(fileB)
466
472
  return result
467
473
 
474
+ @staticmethod
475
+ @check_arguments
476
+ def to_pascal_case(s: str) -> str:
477
+ return ''.join(current.lower() if prev.isalnum() else current.upper() for prev, current in zip(' ' + s, s) if current.isalnum())
478
+
479
+ @staticmethod
480
+ @check_arguments
481
+ def find_between(s: str, start: str, end: str) -> str:
482
+ return s.split(start)[1].split(end)[0]
483
+
468
484
  @staticmethod
469
485
  @check_arguments
470
486
  def write_lines_to_file(file: str, lines: list, encoding="utf-8") -> None:
@@ -732,8 +748,7 @@ class GeneralUtilities:
732
748
 
733
749
  @staticmethod
734
750
  @check_arguments
735
- def read_csv_file(file: str, ignore_first_line: bool = False, treat_number_sign_at_begin_of_line_as_comment: bool = True, trim_values: bool = True,
736
- encoding="utf-8", ignore_empty_lines: bool = True, separator_character: str = ";", values_are_surrounded_by_quotes: bool = False) -> list[list[str]]:
751
+ def read_csv_file(file: str, ignore_first_line: bool = False, treat_number_sign_at_begin_of_line_as_comment: bool = True, trim_values: bool = True, encoding="utf-8", ignore_empty_lines: bool = True, separator_character: str = ";", values_are_surrounded_by_quotes: bool = False) -> list[list[str]]:
737
752
  lines = GeneralUtilities.read_lines_from_file(file, encoding)
738
753
 
739
754
  if ignore_first_line:
@@ -31,7 +31,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
31
31
  from .ProgramRunnerPopen import ProgramRunnerPopen
32
32
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
33
33
 
34
- version = "3.5.31"
34
+ version = "3.5.33"
35
35
  __version__ = version
36
36
 
37
37
 
@@ -1719,26 +1719,22 @@ chmod {permission} {link_file}
1719
1719
  GeneralUtilities.write_lines_to_file(file, lines)
1720
1720
 
1721
1721
  @GeneralUtilities.check_arguments
1722
- def get_external_ip(self, proxy: str) -> str:
1723
- information = self.get_externalnetworkinformation_as_json_string(proxy)
1722
+ def get_external_ip(self) -> str:
1723
+ information = self.get_externalnetworkinformation_as_json_string()
1724
1724
  parsed = json.loads(information)
1725
- return parsed.ip
1725
+ return parsed.IPAddress
1726
1726
 
1727
1727
  @GeneralUtilities.check_arguments
1728
- def get_country_of_external_ip(self, proxy: str) -> str:
1729
- information = self.get_externalnetworkinformation_as_json_string(proxy)
1728
+ def get_country_of_external_ip(self) -> str:
1729
+ information = self.get_externalnetworkinformation_as_json_string()
1730
1730
  parsed = json.loads(information)
1731
- return parsed.country
1731
+ return parsed.Country
1732
1732
 
1733
1733
  @GeneralUtilities.check_arguments
1734
- def get_externalnetworkinformation_as_json_string(self, proxy: str) -> str:
1735
- proxies = None
1736
- if GeneralUtilities.string_has_content(proxy):
1737
- proxies = {"http": proxy}
1734
+ def get_externalnetworkinformation_as_json_string(self) -> str:
1738
1735
  headers = {'Cache-Control': 'no-cache'}
1739
- response = requests.get('https://ipinfo.io', proxies=proxies, timeout=5, headers=headers)
1740
- network_information_as_json_string = GeneralUtilities.bytes_to_string(
1741
- response.content)
1736
+ response = requests.get('https://clientinformation.anion327.de/API/v1/ClientInformationBackendController/Information', timeout=5, headers=headers)
1737
+ network_information_as_json_string = GeneralUtilities.bytes_to_string(response.content)
1742
1738
  return network_information_as_json_string
1743
1739
 
1744
1740
  @GeneralUtilities.check_arguments
@@ -1102,9 +1102,7 @@ class TasksForCommonProjectStructure:
1102
1102
  raise ValueError(f"Repository '{repository_folder}' has uncommitted changes.")
1103
1103
 
1104
1104
  @GeneralUtilities.check_arguments
1105
- def ensure_certificate_authority_for_development_purposes_is_generated(self, script_file: str):
1106
- folder_of_current_file = os.path.dirname(script_file)
1107
- product_folder: str = GeneralUtilities.resolve_relative_path("../..", folder_of_current_file)
1105
+ def ensure_certificate_authority_for_development_purposes_is_generated(self, product_folder: str):
1108
1106
  product_name: str = os.path.basename(product_folder)
1109
1107
  now = datetime.now()
1110
1108
  ca_name = f"{product_name}CA_{now.year:04}{now.month:02}{now.day:02}{now.hour:02}{now.min:02}{now.second:02}"
@@ -1112,13 +1110,22 @@ class TasksForCommonProjectStructure:
1112
1110
  generate_certificate = True
1113
1111
  if os.path.isdir(ca_folder):
1114
1112
  try:
1115
- ca_file = self.__sc.find_file_by_extension(ca_folder, "crt") # pylint: disable=unused-variable
1116
- certificate_is_valid = True # TODO check if certificate is not valid
1113
+ ca_file = [file for file in GeneralUtilities.get_direct_files_of_folder(ca_folder) if file.endswith(".crt")][-1] # pylint:disable=unused-variable
1114
+ certificate_is_valid = True # TODO check if certificate is really valid
1117
1115
  generate_certificate = not certificate_is_valid
1118
1116
  except FileNotFoundError:
1119
1117
  pass
1120
1118
  if generate_certificate:
1121
1119
  self.__sc.generate_certificate_authority(ca_folder, ca_name, "DE", "SubjST", "SubjL", "SubjO", "SubjOU")
1120
+ # TODO add switch to auto-install the script if desired
1121
+ # for windows: powershell Import-Certificate -FilePath ConSurvCA_20241121000236.crt -CertStoreLocation 'Cert:\CurrentUser\Root'
1122
+ # for linux: (TODO)
1123
+
1124
+ @GeneralUtilities.check_arguments
1125
+ def generate_certificate_for_development_purposes_for_product(self, repository_folder: str):
1126
+ product_name = os.path.basename(repository_folder)
1127
+ ca_folder: str = os.path.join(repository_folder, "Other", "Resources", "CA")
1128
+ self.__generate_certificate_for_development_purposes(product_name, os.path.join(repository_folder, "Other", "Resources"), ca_folder, None)
1122
1129
 
1123
1130
  @GeneralUtilities.check_arguments
1124
1131
  def generate_certificate_for_development_purposes_for_external_service(self, service_folder: str, domain: str = None):
@@ -1160,6 +1167,15 @@ class TasksForCommonProjectStructure:
1160
1167
  self.__sc.sign_certificate(certificate_folder, ca_folder, ca_name, domain, resource_content_filename)
1161
1168
  GeneralUtilities.ensure_file_does_not_exist(unsignedcertificate_file)
1162
1169
 
1170
+ @GeneralUtilities.check_arguments
1171
+ def copy_product_resource_to_codeunit_resource_folder(self, codeunit_folder: str, resourcename: str) -> None:
1172
+ src_folder = GeneralUtilities.resolve_relative_path(f"../Other/Resources/{resourcename}", codeunit_folder)
1173
+ GeneralUtilities.assert_condition(os.path.isdir(src_folder), f"Required product-resource {resourcename} does not exist. Expected folder: {src_folder}")
1174
+ trg_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resourcename}", codeunit_folder)
1175
+ GeneralUtilities.ensure_directory_does_not_exist(trg_folder)
1176
+ GeneralUtilities.ensure_directory_exists(trg_folder)
1177
+ GeneralUtilities.copy_content_of_folder(src_folder, trg_folder)
1178
+
1163
1179
  @GeneralUtilities.check_arguments
1164
1180
  def ensure_product_resource_is_imported(self, codeunit_folder: str, product_resource_name: str) -> None:
1165
1181
  product_folder = os.path.dirname(codeunit_folder)
@@ -1803,7 +1819,7 @@ class TasksForCommonProjectStructure:
1803
1819
 
1804
1820
  @GeneralUtilities.check_arguments
1805
1821
  def copy_development_certificate_to_default_development_directory(self, codeunit_folder: str, build_environment: str, domain: str = None, certificate_resource_name: str = "DevelopmentCertificate") -> None:
1806
- if build_environment == "Development":
1822
+ if build_environment != "Productive":
1807
1823
  codeunit_name: str = os.path.basename(codeunit_folder)
1808
1824
  if domain is None:
1809
1825
  domain = f"{codeunit_name}.test.local".lower()
@@ -1905,14 +1921,28 @@ class TasksForCommonProjectStructure:
1905
1921
  else:
1906
1922
  raise ValueError("Can not download OpenAPIGenerator.")
1907
1923
 
1924
+ @GeneralUtilities.check_arguments
1925
+ def generate_api_client_from_dependent_codeunit_in_angular(self, file: str, name_of_api_providing_codeunit: str, generated_program_part_name: str) -> None:
1926
+ codeunit_folder = GeneralUtilities.resolve_relative_path("../..", file)
1927
+ target_subfolder_in_codeunit = f"src/app/generated/{generated_program_part_name}"
1928
+ language = "typescript-angular"
1929
+ self.ensure_openapigenerator_is_available(codeunit_folder)
1930
+ openapigenerator_jar_file = os.path.join(codeunit_folder, "Other", "Resources", "OpenAPIGenerator", "open-api-generator.jar")
1931
+ 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")
1932
+ target_folder = os.path.join(codeunit_folder, target_subfolder_in_codeunit)
1933
+ GeneralUtilities.ensure_directory_exists(target_folder)
1934
+ 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)
1935
+
1936
+ @GeneralUtilities.check_arguments
1908
1937
  def generate_api_client_from_dependent_codeunit_in_dotnet(self, file: str, name_of_api_providing_codeunit: str, base_namespace: str) -> None:
1909
1938
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", file)
1910
1939
  codeunit_name = os.path.basename(codeunit_folder)
1911
1940
  client_subpath = f"{codeunit_name}/APIClients/{name_of_api_providing_codeunit}"
1912
1941
  namespace = f"{base_namespace}.APIClients.{name_of_api_providing_codeunit}"
1913
- self.generate_api_client_from_dependent_codeunit(file, name_of_api_providing_codeunit, client_subpath, "csharp", f"--additional-properties packageName={namespace}")
1942
+ target_subfolder_in_codeunit = client_subpath
1943
+ language = "csharp"
1944
+ additional_properties = f"--additional-properties packageName={namespace}"
1914
1945
 
1915
- def generate_api_client_from_dependent_codeunit(self, file: str, name_of_api_providing_codeunit: str, target_subfolder_in_codeunit: str, language: str, additional_properties: str) -> None:
1916
1946
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", file)
1917
1947
  self.ensure_openapigenerator_is_available(codeunit_folder)
1918
1948
  openapigenerator_jar_file = os.path.join(codeunit_folder, "Other", "Resources", "OpenAPIGenerator", "open-api-generator.jar")
@@ -2076,14 +2106,68 @@ class TasksForCommonProjectStructure:
2076
2106
  GeneralUtilities.write_message_to_stderr("Update dependencies resulted in an error.")
2077
2107
 
2078
2108
  @GeneralUtilities.check_arguments
2079
- def run_local_test_service(self, file: str):
2109
+ def generate_tasksfile_from_workspace_file(self, repository_folder: str) -> None:
2110
+ sc: ScriptCollectionCore = ScriptCollectionCore()
2111
+ workspace_file: str = sc.find_file_by_extension(repository_folder, "code-workspace")
2112
+ task_file: str = os.path.join(repository_folder, "Taskfile.yml")
2113
+ lines: list[str] = ["version: '3'", "", "tasks:", ""]
2114
+ workspace_file_content: str = GeneralUtilities.read_text_from_file(workspace_file)
2115
+ jsoncontent = json.loads(workspace_file_content)
2116
+ tasks = jsoncontent["tasks"]["tasks"]
2117
+ tasks.sort(key=lambda x: x["label"].split("/")[-1], reverse=False) # sort by the label of the task
2118
+ for task in tasks:
2119
+ if task["type"] == "shell":
2120
+ description: str = task["label"]
2121
+ name: str = GeneralUtilities.to_pascal_case(description)
2122
+ command = task["command"]
2123
+ relative_script_file = task["command"]
2124
+
2125
+ relative_script_file = "."
2126
+ if "options" in task:
2127
+ options = task["options"]
2128
+ if "cwd" in options:
2129
+ cwd: str = options["cwd"]
2130
+ cwd = cwd.replace("${workspaceFolder}", ".")
2131
+ relative_script_file = cwd
2132
+ if len(relative_script_file) == 0:
2133
+ relative_script_file = "."
2134
+
2135
+ command_with_args = command
2136
+ if "args" in task:
2137
+ args = task["args"]
2138
+ if len(args) > 1:
2139
+ command_with_args = f"{command_with_args} {' '.join(args)}"
2140
+
2141
+ lines.append(f" {name}:")
2142
+ lines.append(f' desc: "{description}"')
2143
+ lines.append(f' dir: "{cwd}"')
2144
+ lines.append(" cmds:")
2145
+ lines.append(f" - {command_with_args} {{{{.CLI_ARGS}}}}")
2146
+ lines.append(' aliases:')
2147
+ lines.append(f' - {name.lower()}')
2148
+ if "aliases" in task:
2149
+ aliases = task["aliases"]
2150
+ for alias in aliases:
2151
+ lines.append(f' - {alias}')
2152
+ lines.append("")
2153
+ GeneralUtilities.write_lines_to_file(task_file, lines)
2154
+
2155
+ @GeneralUtilities.check_arguments
2156
+ def start_local_test_service(self, file: str):
2080
2157
  example_folder = os.path.dirname(file)
2081
2158
  docker_compose_file = os.path.join(example_folder, "docker-compose.yml")
2082
2159
  for service in self.__sc.get_services_from_yaml_file(docker_compose_file):
2083
2160
  self.__sc.kill_docker_container(service)
2084
2161
  example_name = os.path.basename(example_folder)
2085
2162
  title = f"Test{example_name}"
2086
- self.__sc.run_program("docker", f"compose -p {title.lower()} up", example_folder, title=title)
2163
+ self.__sc.run_program("docker", f"compose -p {title.lower()} up -d --abort-on-container-exit", example_folder, title=title)
2164
+
2165
+ @GeneralUtilities.check_arguments
2166
+ def stop_local_test_service(self, file: str):
2167
+ example_folder = os.path.dirname(file)
2168
+ example_name = os.path.basename(example_folder)
2169
+ title = f"Test{example_name}"
2170
+ self.__sc.run_program("docker", f"compose -p {title.lower()} down", example_folder, title=title)
2087
2171
 
2088
2172
  @GeneralUtilities.check_arguments
2089
2173
  def standardized_tasks_update_version_in_docker_examples(self, file, codeunit_version) -> None:
@@ -2100,14 +2184,12 @@ class TasksForCommonProjectStructure:
2100
2184
  GeneralUtilities.write_text_to_file(docker_compose_file, replaced)
2101
2185
 
2102
2186
  @GeneralUtilities.check_arguments
2103
- def run_dockerfile_example(self, current_file: str, verbosity: int, remove_old_container: bool, remove_volumes_folder: bool, commandline_arguments: list[str]) -> None:
2187
+ def start_dockerfile_example(self, current_file: str, verbosity: int, remove_old_container: bool, remove_volumes_folder: bool, commandline_arguments: list[str]) -> None:
2104
2188
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
2105
2189
  folder = os.path.dirname(current_file)
2106
2190
  example_name = os.path.basename(folder)
2107
- GeneralUtilities.write_message_to_stdout(f'Run "{example_name}"-example')
2108
- sc = ScriptCollectionCore()
2109
2191
  oci_image_artifacts_folder = GeneralUtilities.resolve_relative_path("../../../../Artifacts/BuildResult_OCIImage", folder)
2110
- image_filename = os.path.basename(sc.find_file_by_extension(oci_image_artifacts_folder, "tar"))
2192
+ image_filename = os.path.basename(self.__sc.find_file_by_extension(oci_image_artifacts_folder, "tar"))
2111
2193
  codeunit_name = os.path.basename(GeneralUtilities.resolve_relative_path("../../../../..", folder))
2112
2194
  if remove_old_container:
2113
2195
  docker_compose_file = f"{folder}/docker-compose.yml"
@@ -2119,19 +2201,27 @@ class TasksForCommonProjectStructure:
2119
2201
  GeneralUtilities.write_message_to_stdout(f"Ensure container of {docker_compose_file} do not exist...")
2120
2202
  for container_name in container_names:
2121
2203
  GeneralUtilities.write_message_to_stdout(f"Ensure container of {container_name} does not exist")
2122
- sc.run_program("docker", f"container rm -f {container_name}", oci_image_artifacts_folder, verbosity=0, throw_exception_if_exitcode_is_not_zero=False)
2204
+ self.__sc.run_program("docker", f"container rm -f {container_name}", oci_image_artifacts_folder, verbosity=0, throw_exception_if_exitcode_is_not_zero=False)
2123
2205
  if remove_volumes_folder:
2124
2206
  volumes_folder = os.path.join(folder, "Volumes")
2125
2207
  GeneralUtilities.write_message_to_stdout(f"Ensure volumes-folder '{volumes_folder}' does not exist...")
2126
2208
  GeneralUtilities.ensure_directory_does_not_exist(volumes_folder)
2127
2209
  GeneralUtilities.ensure_directory_exists(volumes_folder)
2128
2210
  GeneralUtilities.write_message_to_stdout("Load docker-image...")
2129
- sc.run_program("docker", f"load -i {image_filename}", oci_image_artifacts_folder, verbosity=verbosity)
2211
+ self.__sc.run_program("docker", f"load -i {image_filename}", oci_image_artifacts_folder, verbosity=verbosity)
2130
2212
  docker_project_name = f"{codeunit_name}_{example_name}".lower()
2131
- sc_epew = ScriptCollectionCore()
2132
- sc_epew.program_runner = ProgramRunnerEpew()
2133
2213
  GeneralUtilities.write_message_to_stdout("Start docker-container...")
2134
- sc_epew.run_program("docker", f"compose --project-name {docker_project_name} up --abort-on-container-exit", folder, verbosity=verbosity)
2214
+ self.__sc.run_program("docker", f"compose --project-name {docker_project_name} up --abort-on-container-exit -d", folder, verbosity=verbosity)
2215
+
2216
+ @GeneralUtilities.check_arguments
2217
+ def stop_dockerfile_example(self, current_file: str, verbosity: int, remove_old_container: bool, remove_volumes_folder: bool, commandline_arguments: list[str]) -> None:
2218
+ verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
2219
+ folder = os.path.dirname(current_file)
2220
+ example_name = os.path.basename(folder)
2221
+ codeunit_name = os.path.basename(GeneralUtilities.resolve_relative_path("../../../../..", folder))
2222
+ docker_project_name = f"{codeunit_name}_{example_name}".lower()
2223
+ GeneralUtilities.write_message_to_stdout("Stop docker-container...")
2224
+ self.__sc.run_program("docker", f"compose --project-name {docker_project_name} down", folder, verbosity=verbosity)
2135
2225
 
2136
2226
  @GeneralUtilities.check_arguments
2137
2227
  def create_artifact_for_development_certificate(self, codeunit_folder: str):
@@ -2272,7 +2362,7 @@ class TasksForCommonProjectStructure:
2272
2362
  changelog_folder = os.path.join(repository_folder, "Other", "Resources", "Changelog")
2273
2363
  changelog_file = os.path.join(changelog_folder, f"v{project_version}.md")
2274
2364
  if not os.path.isfile(changelog_file):
2275
- raise ValueError(f"Changelog-file '{changelog_file}' does not exist.")
2365
+ raise ValueError(f"Changelog-file '{changelog_file}' does not exist. Try creating it using 'sccreatechangelogentry' for example.")
2276
2366
 
2277
2367
  @GeneralUtilities.check_arguments
2278
2368
  def __check_whether_security_txt_exists(self, repository_folder: str) -> None:
@@ -2743,6 +2833,21 @@ class TasksForCommonProjectStructure:
2743
2833
  self.commandline_arguments = commandline_arguments
2744
2834
  self.main_branch_name = "main"
2745
2835
 
2836
+ @GeneralUtilities.check_arguments
2837
+ def create_changelog_entry(self, repositoryfolder: str, message: str, commit: bool):
2838
+ current_version = self.get_version_of_project(repositoryfolder)
2839
+ changelog_file = os.path.join(repositoryfolder, "Other", "Resources", "Changelog", f"v{current_version}.md")
2840
+ if os.path.isdir(changelog_file):
2841
+ raise ValueError(f"Changelogfile {changelog_file} already exists.")
2842
+ else:
2843
+ GeneralUtilities.ensure_file_exists(changelog_file)
2844
+ GeneralUtilities.write_text_to_file(changelog_file, f"""# Release notes
2845
+
2846
+ ## Changes
2847
+
2848
+ - {message}
2849
+ """)
2850
+
2746
2851
  @GeneralUtilities.check_arguments
2747
2852
  def update_http_documentation(self, update_http_documentation_arguments: UpdateHTTPDocumentationArguments):
2748
2853
  GeneralUtilities.write_message_to_stdout(f"Update HTTP-documentation for for {update_http_documentation_arguments.product_name}.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ScriptCollection
3
- Version: 3.5.31
3
+ Version: 3.5.33
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
@@ -22,26 +22,26 @@ Classifier: Topic :: Terminals
22
22
  Classifier: Topic :: Utilities
23
23
  Requires-Python: >=3.10
24
24
  Description-Content-Type: text/markdown
25
- Requires-Dist: build >=1.2.2.post1
26
- Requires-Dist: coverage >=7.6.7
27
- Requires-Dist: cyclonedx-bom >=5.1.1
28
- Requires-Dist: defusedxml >=0.7.1
29
- Requires-Dist: keyboard >=0.13.5
30
- Requires-Dist: lcov-cobertura >=2.0.2
31
- Requires-Dist: lxml >=5.3.0
32
- Requires-Dist: ntplib >=0.4.0
33
- Requires-Dist: Pillow >=11.0.0
34
- Requires-Dist: pycdlib >=1.14.0
35
- Requires-Dist: Pygments >=2.18.0
36
- Requires-Dist: pylint >=3.3.1
37
- Requires-Dist: pyOpenSSL >=24.2.1
38
- Requires-Dist: PyPDF2 >=3.0.1
39
- Requires-Dist: pytest >=8.3.3
40
- Requires-Dist: PyYAML >=6.0.2
41
- Requires-Dist: qrcode >=8.0
42
- Requires-Dist: send2trash >=1.8.3
43
- Requires-Dist: twine >=5.1.1
44
- Requires-Dist: xmlschema >=3.4.3
25
+ Requires-Dist: build>=1.2.2.post1
26
+ Requires-Dist: coverage>=7.6.8
27
+ Requires-Dist: cyclonedx-bom>=5.1.1
28
+ Requires-Dist: defusedxml>=0.7.1
29
+ Requires-Dist: keyboard>=0.13.5
30
+ Requires-Dist: lcov-cobertura>=2.0.2
31
+ Requires-Dist: lxml>=5.3.0
32
+ Requires-Dist: ntplib>=0.4.0
33
+ Requires-Dist: Pillow>=11.0.0
34
+ Requires-Dist: pycdlib>=1.14.0
35
+ Requires-Dist: Pygments>=2.18.0
36
+ Requires-Dist: pylint>=3.3.1
37
+ Requires-Dist: pyOpenSSL>=24.2.1
38
+ Requires-Dist: PyPDF2>=3.0.1
39
+ Requires-Dist: pytest>=8.3.3
40
+ Requires-Dist: PyYAML>=6.0.2
41
+ Requires-Dist: qrcode>=8.0
42
+ Requires-Dist: send2trash>=1.8.3
43
+ Requires-Dist: twine>=5.1.1
44
+ Requires-Dist: xmlschema>=3.4.3
45
45
 
46
46
  # ScriptCollection
47
47
 
@@ -0,0 +1,16 @@
1
+ ScriptCollection/Executables.py,sha256=0JitZCU2j3N--HREXpTAckPbf7RQ-Q-DER79lnFidLE,20819
2
+ ScriptCollection/GeneralUtilities.py,sha256=S_JX32I4fMpjwIzIinZT72TZ2r7rM736QNSA-ke-ET8,36347
3
+ ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
4
+ ScriptCollection/ProgramRunnerBase.py,sha256=7QAjoqOz6XPmJH19F2k-Z1fFQB_uZnPFvn-T54IJcHQ,2324
5
+ ScriptCollection/ProgramRunnerEpew.py,sha256=C2Rs3YWOWWWJct7XmKphp5CF1tf0j4Fp-ljV2drLTfs,6349
6
+ ScriptCollection/ProgramRunnerPopen.py,sha256=G3LgQUVCfaq7XjBsGzalElH31Hbr0etttGR2_H87YzA,3512
7
+ ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
8
+ ScriptCollection/ScriptCollectionCore.py,sha256=Ua_HKThGL3Gk3SmsZsVpdbgfyMyVd_694ET9wCr88FA,101810
9
+ ScriptCollection/TasksForCommonProjectStructure.py,sha256=fr95VKSDk_WiqzypEPrNDEo07fvhTY7MNhkhtmN3uBo,201583
10
+ ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
11
+ ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ ScriptCollection-3.5.33.dist-info/METADATA,sha256=nr5rTtr40e-9LQWs68mEDlAnd6zQ670l3sVP1Fd0ZME,7664
13
+ ScriptCollection-3.5.33.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
14
+ ScriptCollection-3.5.33.dist-info/entry_points.txt,sha256=_O7BmQ81LdDfrj5uOhjshg9Xc-tABHQJIxDOyOGRzzI,2397
15
+ ScriptCollection-3.5.33.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
+ ScriptCollection-3.5.33.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.5.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -5,6 +5,7 @@ scbuildcodeunitsc = ScriptCollection.Executables:BuildCodeUnitsC
5
5
  sccalculatebitcoinblockhash = ScriptCollection.Executables:CalculateBitcoinBlockHash
6
6
  scchangefileextension = ScriptCollection.Executables:ChangeFileExtensions
7
7
  scchangehashofprogram = ScriptCollection.Executables:ChangeHashOfProgram
8
+ sccreatechangelogentry = ScriptCollection.Executables:CreateChangelogEntry
8
9
  sccreateemptyfilewithspecificsize = ScriptCollection.Executables:CreateEmptyFileWithSpecificSize
9
10
  sccreatehashofallfiles = ScriptCollection.Executables:CreateHashOfAllFiles
10
11
  sccreateisofilewithobfuscatedfiles = ScriptCollection.Executables:CreateISOFileWithObfuscatedFiles
@@ -1,16 +0,0 @@
1
- ScriptCollection/Executables.py,sha256=57f2bopoRUchbyyCZTseBk0ynEyHfXc2u4-LraxI7qg,20161
2
- ScriptCollection/GeneralUtilities.py,sha256=6tMhEThExEJse33i7HgfJEvRqndNkSOzoXDQA8lUfHw,35809
3
- ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
4
- ScriptCollection/ProgramRunnerBase.py,sha256=7QAjoqOz6XPmJH19F2k-Z1fFQB_uZnPFvn-T54IJcHQ,2324
5
- ScriptCollection/ProgramRunnerEpew.py,sha256=C2Rs3YWOWWWJct7XmKphp5CF1tf0j4Fp-ljV2drLTfs,6349
6
- ScriptCollection/ProgramRunnerPopen.py,sha256=G3LgQUVCfaq7XjBsGzalElH31Hbr0etttGR2_H87YzA,3512
7
- ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
8
- ScriptCollection/ScriptCollectionCore.py,sha256=OYVN6uOsQgwVk4CCGwNZPiuqblf7zaXLrO_G2Vq57ic,101921
9
- ScriptCollection/TasksForCommonProjectStructure.py,sha256=lrypLs_dF5a0CCKinMwZhbg0LxJkVHxlmqJF4B6I31U,195223
10
- ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
11
- ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- ScriptCollection-3.5.31.dist-info/METADATA,sha256=AmndyxGsXVmE1zsut5NOoZyk1sMChMoqGdcXiP6wA0w,7684
13
- ScriptCollection-3.5.31.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
14
- ScriptCollection-3.5.31.dist-info/entry_points.txt,sha256=yASwR6hWZ_b5d4W49YeX1htD8ngfWbwgjpfQiJdtUAU,2322
15
- ScriptCollection-3.5.31.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
- ScriptCollection-3.5.31.dist-info/RECORD,,