ScriptCollection 3.5.93__py3-none-any.whl → 3.5.94__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,6 +12,7 @@ import math
12
12
  import os
13
13
  from queue import Queue, Empty
14
14
  from concurrent.futures import ThreadPoolExecutor
15
+ import xml.etree.ElementTree as ET
15
16
  from pathlib import Path
16
17
  from subprocess import Popen
17
18
  import re
@@ -32,7 +33,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
32
33
  from .ProgramRunnerPopen import ProgramRunnerPopen
33
34
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
34
35
 
35
- version = "3.5.93"
36
+ version = "3.5.94"
36
37
  __version__ = version
37
38
 
38
39
 
@@ -2052,7 +2053,7 @@ chmod {permission} {link_file}
2052
2053
  if productname is None:
2053
2054
  productname = os.path.basename(repository)
2054
2055
  if subfolder is None:
2055
- subfolder = "Other/Resources/Reference"
2056
+ subfolder = "Other/Reference"
2056
2057
  reference_root_folder = f"{repository}/{subfolder}"
2057
2058
  reference_content_folder = reference_root_folder + "/Technical"
2058
2059
  if os.path.isdir(reference_root_folder):
@@ -2152,7 +2153,6 @@ TXDX
2152
2153
  - [Repository](TXDX)
2153
2154
  - [Productive-System](TXDX)
2154
2155
  - [QualityCheck-system](TXDX)
2155
-
2156
2156
  """.replace("XDX", "ODO"))
2157
2157
 
2158
2158
  @GeneralUtilities.check_arguments
@@ -2242,3 +2242,10 @@ TXDX
2242
2242
  raise ValueError(f"Folder '{folder}' does not exist.")
2243
2243
 
2244
2244
  GeneralUtilities.ensure_directory_exists(path)
2245
+
2246
+ @GeneralUtilities.check_arguments
2247
+ def format_xml_file(self, file: str) -> None:
2248
+ encoding = "utf-8"
2249
+ element = ET.XML(GeneralUtilities.read_text_from_file(file, encoding))
2250
+ ET.indent(element)
2251
+ GeneralUtilities.write_text_to_file(file, ET.tostring(element, encoding="unicode"), encoding)
@@ -307,6 +307,7 @@ class TasksForCommonProjectStructure:
307
307
  @GeneralUtilities.check_arguments
308
308
  def generate_bom_for_python_project(self, verbosity: int, codeunit_folder: str, codeunitname: str, commandline_arguments: list[str]) -> None:
309
309
  self.assert_is_codeunit_folder(codeunit_folder)
310
+ repository_folder = os.path.dirname(codeunit_folder)
310
311
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
311
312
  codeunitversion = self.get_version_of_codeunit_folder(codeunit_folder)
312
313
  bom_folder = "Other/Artifacts/BOM"
@@ -316,9 +317,20 @@ class TasksForCommonProjectStructure:
316
317
  raise ValueError(f"Codeunit {codeunitname} does not have a 'requirements.txt'-file.")
317
318
  # TODO check that all values from setup.cfg are contained in requirements.txt
318
319
  result = self.__sc.run_program("cyclonedx-py", "requirements", codeunit_folder, verbosity=verbosity)
319
- bom_file = os.path.join(codeunit_folder, f"{bom_folder}/{codeunitname}.{codeunitversion}.bom.json")
320
- GeneralUtilities.ensure_file_exists(bom_file)
321
- GeneralUtilities.write_text_to_file(bom_file, result[1])
320
+ bom_file_relative_json = f"{bom_folder}/{codeunitname}.{codeunitversion}.bom.json"
321
+ bom_file_relative_xml = f"{bom_folder}/{codeunitname}.{codeunitversion}.bom.xml"
322
+ bom_file_json = os.path.join(codeunit_folder, bom_file_relative_json)
323
+ bom_file_xml = os.path.join(codeunit_folder, bom_file_relative_xml)
324
+
325
+ GeneralUtilities.ensure_file_exists(bom_file_json)
326
+ GeneralUtilities.write_text_to_file(bom_file_json, result[1])
327
+ self.ensure_cyclonedxcli_is_available(repository_folder)
328
+ cyclonedx_exe = os.path.join(repository_folder, "Other/Resources/CycloneDXCLI/cyclonedx-cli")
329
+ if GeneralUtilities.current_system_is_windows():
330
+ cyclonedx_exe = cyclonedx_exe+".exe"
331
+ self.__sc.run_program(cyclonedx_exe, f"convert --input-file ./{codeunitname}/{bom_file_relative_json} --input-format json --output-file ./{codeunitname}/{bom_file_relative_xml} --output-format xml", repository_folder)
332
+ self.__sc.format_xml_file(bom_file_xml)
333
+ GeneralUtilities.ensure_file_does_not_exist(bom_file_json)
322
334
 
323
335
  @GeneralUtilities.check_arguments
324
336
  def standardized_tasks_push_wheel_file_to_registry(self, wheel_file: str, api_key: str, repository: str, gpg_identity: str, verbosity: int) -> None:
@@ -759,7 +771,7 @@ class TasksForCommonProjectStructure:
759
771
  target = f"{codeunit_folder}\\{bomfile_folder}\\{codeunit_name}.{codeunitversion}.sbom.xml"
760
772
  GeneralUtilities.ensure_file_does_not_exist(target)
761
773
  os.rename(f"{codeunit_folder}\\{bomfile_folder}\\bom.xml", target)
762
- # TODO format the sbom.xml-file
774
+ self.__sc.format_xml_file(target)
763
775
 
764
776
  @GeneralUtilities.check_arguments
765
777
  def standardized_tasks_run_linting_for_flutter_project_in_common_project_structure(self, script_file: str, default_verbosity: int, args: list[str]):
@@ -1358,15 +1370,19 @@ class TasksForCommonProjectStructure:
1358
1370
  GeneralUtilities.assert_file_exists(os.path.join(repository_folder, target_sbom_file))
1359
1371
  target_original_sbom_file = os.path.dirname(target_sbom_file)+"/"+os.path.basename(target_sbom_file)+".original.xml"
1360
1372
  os.rename(os.path.join(repository_folder, target_sbom_file), os.path.join(repository_folder, target_original_sbom_file))
1361
- ScriptCollectionCore().run_program("docker", f"run --rm -v {repository_folder}:/Repository cyclonedx/cyclonedx-cli merge --input-files /Repository/{source_sbom_file} /Repository/{target_original_sbom_file} --output-file /Repository/{target_sbom_file}")
1373
+
1374
+ self.ensure_cyclonedxcli_is_available(repository_folder)
1375
+ cyclonedx_exe = os.path.join(repository_folder, "Other/Resources/CycloneDXCLI/cyclonedx-cli")
1376
+ if GeneralUtilities.current_system_is_windows():
1377
+ cyclonedx_exe = cyclonedx_exe+".exe"
1378
+ self.__sc.run_program("cyclonedx_exe", f"merge --input-files {source_sbom_file} {target_original_sbom_file} --output-file {target_sbom_file}")
1362
1379
  GeneralUtilities.ensure_file_does_not_exist(os.path.join(repository_folder, target_original_sbom_file))
1363
- # TODO format the sbom.xml-file
1380
+ self.__sc.format_xml_file(target_original_sbom_file)
1364
1381
 
1365
1382
  @GeneralUtilities.check_arguments
1366
1383
  def standardized_tasks_build_for_docker_project_with_additional_build_arguments(self, build_script_file: str, target_environment_type: str, verbosity: int, commandline_arguments: list[str], custom_arguments: dict[str, str]) -> None:
1367
1384
  use_cache: bool = False
1368
1385
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
1369
- sc: ScriptCollectionCore = ScriptCollectionCore()
1370
1386
  codeunitname: str = Path(os.path.dirname(build_script_file)).parent.parent.name
1371
1387
  codeunit_folder = GeneralUtilities.resolve_relative_path("../..", str(os.path.dirname(build_script_file)))
1372
1388
  codeunitname_lower = codeunitname.lower()
@@ -1381,7 +1397,7 @@ class TasksForCommonProjectStructure:
1381
1397
  args.append("--no-cache")
1382
1398
  args.append(".")
1383
1399
  codeunit_content_folder = os.path.join(codeunit_folder)
1384
- sc.run_program_argsasarray("docker", args, codeunit_content_folder, verbosity=verbosity, print_errors_as_information=True)
1400
+ self.__sc.run_program_argsasarray("docker", args, codeunit_content_folder, verbosity=verbosity, print_errors_as_information=True)
1385
1401
  artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
1386
1402
  app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
1387
1403
  GeneralUtilities.ensure_directory_does_not_exist(app_artifacts_folder)
@@ -1400,7 +1416,7 @@ class TasksForCommonProjectStructure:
1400
1416
  codeunitversion = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
1401
1417
  GeneralUtilities.ensure_directory_exists(sbom_folder)
1402
1418
  self.__sc.run_program_argsasarray("docker", ["sbom", "--format", "cyclonedx", f"{codeunitname_lower}:{codeunitversion}", "--output", f"{codeunitname}.{codeunitversion}.sbom.xml"], sbom_folder, verbosity=verbosity, print_errors_as_information=True)
1403
- # TODO format the sbom.xml-file
1419
+ self.__sc.format_xml_file(sbom_folder+f"/{codeunitname}.{codeunitversion}.sbom.xml")
1404
1420
 
1405
1421
  @GeneralUtilities.check_arguments
1406
1422
  def push_docker_build_artifact(self, push_artifacts_file: str, registry: str, verbosity: int, push_readme: bool, commandline_arguments: list[str], repository_folder_name: str) -> None:
@@ -1730,8 +1746,9 @@ class TasksForCommonProjectStructure:
1730
1746
  def standardized_tasks_build_bom_for_node_project(self, codeunit_folder: str, verbosity: int, commandline_arguments: list[str]) -> None:
1731
1747
  self.assert_is_codeunit_folder(codeunit_folder)
1732
1748
  verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
1733
- self.run_with_epew("cyclonedx-npm", f"--output-format xml --output-file Other/Artifacts/BOM/{os.path.basename(codeunit_folder)}.{self.get_version_of_codeunit_folder(codeunit_folder)}.sbom.xml", codeunit_folder, verbosity=verbosity)
1734
- # TODO format the sbom.xml-file
1749
+ relative_path_to_bom_file = f"Other/Artifacts/BOM/{os.path.basename(codeunit_folder)}.{self.get_version_of_codeunit_folder(codeunit_folder)}.sbom.xml"
1750
+ self.run_with_epew("cyclonedx-npm", f"--output-format xml --output-file {relative_path_to_bom_file}", codeunit_folder, verbosity=verbosity)
1751
+ self.__sc.format_xml_file(codeunit_folder+"/"+relative_path_to_bom_file)
1735
1752
 
1736
1753
  @GeneralUtilities.check_arguments
1737
1754
  def standardized_tasks_linting_for_angular_codeunit(self, linting_script_file: str, verbosity: int, build_environment_target_type: str, commandline_arguments: list[str]) -> None:
@@ -2536,11 +2553,10 @@ class TasksForCommonProjectStructure:
2536
2553
  i = i+1
2537
2554
  GeneralUtilities.write_message_to_stdout(f"{i}.: {codeunit}")
2538
2555
  self.__do_repository_checks(repository_folder, project_version)
2539
- line = "----------"
2540
2556
  for codeunit in sorted_codeunits:
2541
- GeneralUtilities.write_message_to_stdout(line)
2557
+ GeneralUtilities.write_message_to_stdout(GeneralUtilities.get_line())
2542
2558
  self.__build_codeunit(os.path.join(repository_folder, codeunit), verbosity, target_environmenttype, additional_arguments_file, is_pre_merge, assume_dependent_codeunits_are_already_built, commandline_arguments)
2543
- GeneralUtilities.write_message_to_stdout(line)
2559
+ GeneralUtilities.write_message_to_stdout(GeneralUtilities.get_line())
2544
2560
  contains_uncommitted_changes_at_end = self.__sc.git_repository_has_uncommitted_changes(repository_folder)
2545
2561
  if contains_uncommitted_changes_at_end and not is_pre_merge:
2546
2562
  if contains_uncommitted_changes_at_begin:
@@ -2551,6 +2567,7 @@ class TasksForCommonProjectStructure:
2551
2567
  GeneralUtilities.write_message_to_stderr(f"Warning: {message}")
2552
2568
  else:
2553
2569
  raise ValueError(message)
2570
+
2554
2571
  if export_target_directory is not None:
2555
2572
  project_name = self.get_project_name(repository_folder)
2556
2573
  for codeunit in sorted_codeunits:
@@ -2574,9 +2591,14 @@ class TasksForCommonProjectStructure:
2574
2591
  self.__sc.assert_is_git_repository(repository_folder)
2575
2592
  self.__check_if_changelog_exists(repository_folder, project_version)
2576
2593
  self.__check_whether_security_txt_exists(repository_folder)
2594
+ self.__check_whether_general_reference_exists(repository_folder)
2577
2595
  self.__check_whether_workspace_file_exists(repository_folder)
2578
2596
  self.__check_for_staged_or_committed_ignored_files(repository_folder)
2579
2597
 
2598
+ @GeneralUtilities.check_arguments
2599
+ def __check_whether_general_reference_exists(self, repository_folder: str) -> None:
2600
+ GeneralUtilities.assert_file_exists(os.path.join(repository_folder, "Other", "Reference", "Reference.md"))
2601
+
2580
2602
  @GeneralUtilities.check_arguments
2581
2603
  def __check_if_changelog_exists(self, repository_folder: str, project_version: str) -> None:
2582
2604
  self.__sc.assert_is_git_repository(repository_folder)
@@ -2693,6 +2715,17 @@ class TasksForCommonProjectStructure:
2693
2715
  def ensure_androidappbundletool_is_available(self, target_folder: str) -> None:
2694
2716
  self.ensure_file_from_github_assets_is_available(target_folder, "google", "bundletool", "AndroidAppBundleTool", "bundletool.jar", lambda latest_version: f"bundletool-all-{latest_version}.jar")
2695
2717
 
2718
+ @GeneralUtilities.check_arguments
2719
+ def ensure_cyclonedxcli_is_available(self, target_folder: str) -> None:
2720
+ local_filename = "cyclonedx-cli"
2721
+ filename_on_github: str
2722
+ if GeneralUtilities.current_system_is_windows():
2723
+ filename_on_github = "cyclonedx-win-x64.exe"
2724
+ local_filename = local_filename+".exe"
2725
+ else:
2726
+ filename_on_github = "cyclonedx-linux-x64"
2727
+ self.ensure_file_from_github_assets_is_available(target_folder, "CycloneDX", "cyclonedx-cli", "CycloneDXCLI", local_filename, lambda latest_version: filename_on_github)
2728
+
2696
2729
  @GeneralUtilities.check_arguments
2697
2730
  def ensure_file_from_github_assets_is_available(self, target_folder: str, githubuser: str, githubprojectname: str, resource_name: str, local_filename: str, get_filename_on_github) -> None:
2698
2731
  resource_folder = os.path.join(target_folder, "Other", "Resources", resource_name)
@@ -2703,11 +2736,11 @@ class TasksForCommonProjectStructure:
2703
2736
  GeneralUtilities.ensure_directory_does_not_exist(resource_folder)
2704
2737
  GeneralUtilities.ensure_directory_exists(resource_folder)
2705
2738
  headers = {'Cache-Control': 'no-cache'}
2706
- response = requests.get(f"https://api.github.com/repos/{githubuser}/{githubprojectname}/releases/latest", timeout=5, headers=headers)
2707
- latest_version = response.json()["name"]
2739
+ response = requests.get(f"https://api.github.com/repos/{githubuser}/{githubprojectname}/releases/latest", timeout=10, headers=headers)
2740
+ latest_version = response.json()["tag_name"]
2708
2741
  filename_on_github = get_filename_on_github(latest_version)
2709
- jar_link = f"https://github.com/{githubuser}/{githubprojectname}/releases/download/{latest_version}/{filename_on_github}"
2710
- urllib.request.urlretrieve(jar_link, file)
2742
+ link = f"https://github.com/{githubuser}/{githubprojectname}/releases/download/{latest_version}/{filename_on_github}"
2743
+ urllib.request.urlretrieve(link, file)
2711
2744
  else:
2712
2745
  if file_exists:
2713
2746
  GeneralUtilities.write_message_to_stdout(f"Warning: Can not check for updates of {resource_name} due to missing internet-connection.")
@@ -2715,22 +2748,49 @@ class TasksForCommonProjectStructure:
2715
2748
  raise ValueError(f"Can not download {resource_name}.")
2716
2749
 
2717
2750
  @GeneralUtilities.check_arguments
2718
- def generate_svg_files_from_plantuml_files(self, target_folder: str) -> None:
2719
- self.ensure_plantuml_is_available(target_folder)
2720
- plant_uml_folder = os.path.join(target_folder, "Other", "Resources", "PlantUML")
2721
- files_folder = os.path.join(target_folder, "Other", "Resources", "Reference")
2751
+ def generate_svg_files_from_plantuml_files_for_repository(self, repository_folder: str) -> None:
2752
+ self.__sc.assert_is_git_repository(repository_folder)
2753
+ self.ensure_plantuml_is_available(repository_folder)
2754
+ plant_uml_folder = os.path.join(repository_folder, "Other", "Resources", "PlantUML")
2755
+ target_folder = os.path.join(repository_folder, "Other", "Reference")
2756
+ self.__generate_svg_files_from_plantuml(target_folder, plant_uml_folder)
2757
+
2758
+ @GeneralUtilities.check_arguments
2759
+ def generate_svg_files_from_plantuml_files_for_codeunit(self, codeunit_folder: str) -> None:
2760
+ self.assert_is_codeunit_folder(codeunit_folder)
2761
+ repository_folder = os.path.dirname(codeunit_folder)
2762
+ self.ensure_plantuml_is_available(repository_folder)
2763
+ plant_uml_folder = os.path.join(repository_folder, "Other", "Resources", "PlantUML")
2764
+ target_folder = os.path.join(codeunit_folder, "Other", "Reference")
2765
+ self.__generate_svg_files_from_plantuml(target_folder, plant_uml_folder)
2766
+
2767
+ @GeneralUtilities.check_arguments
2768
+ def __generate_svg_files_from_plantuml(self, diagrams_files_folder: str, plant_uml_folder: str) -> None:
2722
2769
  sc = ScriptCollectionCore()
2723
- for file in GeneralUtilities.get_all_files_of_folder(files_folder):
2770
+ for file in GeneralUtilities.get_all_files_of_folder(diagrams_files_folder):
2724
2771
  if file.endswith(".plantuml"):
2725
- argument = ['-jar', f'{plant_uml_folder}/plantuml.jar', os.path.basename(file).replace("\\", "/"), '-tsvg']
2726
- sc.run_program_argsasarray("java", argument, os.path.dirname(file), verbosity=0)
2727
- # TODO format content of file
2772
+ output_filename = self.get_output_filename_for_plantuml_filename(file)
2773
+ argument = ['-jar', f'{plant_uml_folder}/plantuml.jar', '-tsvg', os.path.basename(file)]
2774
+ folder = os.path.dirname(file)
2775
+ sc.run_program_argsasarray("java", argument, folder, verbosity=0)
2776
+ result_file = folder+"/" + output_filename
2777
+ GeneralUtilities.assert_file_exists(result_file)
2778
+ self.__sc.format_xml_file(result_file)
2779
+
2780
+ @GeneralUtilities.check_arguments
2781
+ def get_output_filename_for_plantuml_filename(self, plantuml_file: str) -> str:
2782
+ for line in GeneralUtilities.read_lines_from_file(plantuml_file):
2783
+ prefix = "@startuml "
2784
+ if line.startswith(prefix):
2785
+ title = line[len(prefix):]
2786
+ return title+".svg"
2787
+ return Path(plantuml_file).stem+".svg"
2728
2788
 
2729
2789
  @GeneralUtilities.check_arguments
2730
2790
  def generate_codeunits_overview_diagram(self, repository_folder: str) -> None:
2731
2791
  self.__sc.assert_is_git_repository(repository_folder)
2732
2792
  project_name: str = os.path.basename(repository_folder)
2733
- target_folder = os.path.join(repository_folder, "Other", "Resources", "Reference", "Technical", "Diagrams")
2793
+ target_folder = os.path.join(repository_folder, "Other", "Reference", "Technical", "Diagrams")
2734
2794
  GeneralUtilities.ensure_directory_exists(target_folder)
2735
2795
  target_file = os.path.join(target_folder, "CodeUnits-Overview.plantuml")
2736
2796
  lines = ["@startuml CodeUnits-Overview"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ScriptCollection
3
- Version: 3.5.93
3
+ Version: 3.5.94
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
@@ -6,12 +6,12 @@ ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1
6
6
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
7
7
  ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
8
8
  ScriptCollection/SCLog.py,sha256=l4aekBiGoNkKGtvO_Er3NY_K7ts4ZWtIGlhq07I-4LY,30
9
- ScriptCollection/ScriptCollectionCore.py,sha256=IGIu5wl1wm25-KnLo7MLOaNFkVZuQjEr69PGHxkCFGg,123625
10
- ScriptCollection/TasksForCommonProjectStructure.py,sha256=UICi0p_m_uGOLP3c-Rk-dCxN0IzXIM0O_FwwRGNoHCM,221680
9
+ ScriptCollection/ScriptCollectionCore.py,sha256=kuiMlekPcD_BTbCjqKgsEQjeMWL7consYcplP1lTByU,123973
10
+ ScriptCollection/TasksForCommonProjectStructure.py,sha256=QqpfA-9sLtUogsOqg4uHHS2kucwZkTuzhDs24OdFIrE,225316
11
11
  ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
12
12
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- scriptcollection-3.5.93.dist-info/METADATA,sha256=USfCKrvr35eIM7vkEptzfc9tbnXP1IGw7D2dluFS5dA,7664
14
- scriptcollection-3.5.93.dist-info/WHEEL,sha256=EaM1zKIUYa7rQnxGiOCGhzJABRwy4WO57rWMR3_tj4I,91
15
- scriptcollection-3.5.93.dist-info/entry_points.txt,sha256=fYCGWGNGijBQHhFe6UAO-BEpfEOxLyNJemukt5ElSzs,3644
16
- scriptcollection-3.5.93.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
17
- scriptcollection-3.5.93.dist-info/RECORD,,
13
+ scriptcollection-3.5.94.dist-info/METADATA,sha256=UrFm_ztejp_WXvuM7uom8cka14YxGvMC_wPzpf6rdjw,7664
14
+ scriptcollection-3.5.94.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
15
+ scriptcollection-3.5.94.dist-info/entry_points.txt,sha256=fYCGWGNGijBQHhFe6UAO-BEpfEOxLyNJemukt5ElSzs,3644
16
+ scriptcollection-3.5.94.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
17
+ scriptcollection-3.5.94.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.9.1)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5