ScriptCollection 4.2.75__py3-none-any.whl → 4.2.77__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.
@@ -390,7 +390,7 @@ def GenerateARC42ReferenceTemplate() -> int:
390
390
  def CreateChangelogEntry() -> int:
391
391
  parser = argparse.ArgumentParser()
392
392
  parser.add_argument('-p', '--repositorypath', required=False, default=".")
393
- parser.add_argument('-m', '--message', required=False, default="Updates.")
393
+ parser.add_argument('-m', '--message', required=False, default=None)
394
394
  parser.add_argument('-c', '--commit', action='store_true', required=False, default=False)
395
395
  parser.add_argument('-f', '--force', action='store_true', required=False, default=False)
396
396
  args = parser.parse_args()
@@ -910,4 +910,4 @@ def SyncXlfFiles()->int:
910
910
  languages=str(args.languages).split(",")
911
911
  folder=GeneralUtilities.resolve_relative_path(args.folder, os.getcwd())
912
912
  sc.sync_xlf2_files(args.prefix, languages, folder)
913
- return 0
913
+ return 0
@@ -13,6 +13,7 @@ import zipfile
13
13
  import math
14
14
  import base64
15
15
  import os
16
+ from html.parser import HTMLParser
16
17
  from queue import Queue, Empty
17
18
  from concurrent.futures import ThreadPoolExecutor
18
19
  import xml.etree.ElementTree as ET
@@ -37,7 +38,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
37
38
  from .ProgramRunnerPopen import ProgramRunnerPopen
38
39
  from .SCLog import SCLog, LogLevel
39
40
 
40
- version = "4.2.75"
41
+ version = "4.2.77"
41
42
  __version__ = version
42
43
 
43
44
  class VSCodeWorkspaceShellTask:
@@ -2622,7 +2623,7 @@ TXDX
2622
2623
  self.run_program("docker", f"network create {network_name}")
2623
2624
 
2624
2625
  @GeneralUtilities.check_arguments
2625
- def format_xml_file(self, file: str) -> None:
2626
+ def format_xml_file(self, file: str,add_xml_declaration:bool=True) -> None:
2626
2627
  encoding = "utf-8"
2627
2628
  element = ET.XML(GeneralUtilities.read_text_from_file(file, encoding))
2628
2629
  def trim_texts(elem: ET.Element):
@@ -2638,12 +2639,119 @@ TXDX
2638
2639
  file,
2639
2640
  ET.tostring(
2640
2641
  element,
2641
- xml_declaration=True,
2642
+ xml_declaration=add_xml_declaration,
2642
2643
  encoding="unicode"
2643
2644
  ),
2644
2645
  encoding
2645
2646
  )
2646
2647
 
2648
+ @GeneralUtilities.check_arguments
2649
+ def format_html_file(self, file: str, add_html_declaration: bool = False) -> None:
2650
+ encoding = "utf-8"
2651
+ content = GeneralUtilities.read_text_from_file(file, encoding)
2652
+ content=self.format_html_content(content, add_html_declaration)
2653
+ GeneralUtilities.write_text_to_file(file, content, encoding)
2654
+
2655
+ @GeneralUtilities.check_arguments
2656
+ def format_html_content(self, content: str, add_html_declaration: bool = False) -> str:
2657
+
2658
+ VOID_ELEMENTS = {"area", "base", "br", "col", "embed", "hr", "img", "input",
2659
+ "link", "meta", "param", "source", "track", "wbr"}
2660
+
2661
+ class _Node:
2662
+ __slots__ = ("tag", "attrs", "children", "text", "is_void", "raw")
2663
+ def __init__(self, tag=None, attrs=(), text=None, is_void=False, raw=None):
2664
+ self.tag = tag
2665
+ self.attrs = list(attrs)
2666
+ self.children = []
2667
+ self.text = text
2668
+ self.is_void = is_void
2669
+ self.raw = raw
2670
+
2671
+ class _Builder(HTMLParser):
2672
+ def __init__(self):
2673
+ super().__init__(convert_charrefs=False)
2674
+ self.root = _Node()
2675
+ self.stack = [self.root]
2676
+
2677
+ def _top(self):
2678
+ return self.stack[-1]
2679
+
2680
+ def handle_starttag(self, tag, attrs):
2681
+ raw = self.get_starttag_text()
2682
+ raw_lower = raw.lower()
2683
+ original_attrs = []
2684
+ pos = 1 + len(tag)
2685
+ for lc_name, value in attrs:
2686
+ idx = raw_lower.index(lc_name, pos)
2687
+ original_attrs.append((raw[idx:idx + len(lc_name)], value))
2688
+ pos = idx + len(lc_name)
2689
+ node = _Node(tag=tag, attrs=original_attrs, is_void=tag.lower() in VOID_ELEMENTS)
2690
+ self._top().children.append(node)
2691
+ if not node.is_void:
2692
+ self.stack.append(node)
2693
+
2694
+ def handle_endtag(self, tag):
2695
+ if len(self.stack) > 1 and self.stack[-1].tag == tag:
2696
+ self.stack.pop()
2697
+
2698
+ def handle_data(self, data):
2699
+ t = " ".join(data.split())
2700
+ if t:
2701
+ self._top().children.append(_Node(text=t))
2702
+
2703
+ def handle_entityref(self, name):
2704
+ self._top().children.append(_Node(text=f"&{name};"))
2705
+
2706
+ def handle_charref(self, name):
2707
+ self._top().children.append(_Node(text=f"&#{name};"))
2708
+
2709
+ def handle_comment(self, data):
2710
+ self._top().children.append(_Node(raw=f"<!--{data}-->"))
2711
+
2712
+ def handle_decl(self, decl):
2713
+ self._top().children.append(_Node(raw=f"<!{decl}>"))
2714
+
2715
+ def handle_pi(self, data):
2716
+ self._top().children.append(_Node(raw=f"<?{data}>"))
2717
+
2718
+ builder = _Builder()
2719
+ builder.feed(content)
2720
+ ind = " "
2721
+
2722
+ def _serialize(node: _Node, depth: int) -> list:
2723
+ prefix = ind * depth
2724
+ if node.raw is not None:
2725
+ return [prefix + node.raw]
2726
+ if node.text is not None:
2727
+ return [node.text]
2728
+ if node.tag is None:
2729
+ out = []
2730
+ for c in node.children:
2731
+ out.extend(_serialize(c, depth))
2732
+ return out
2733
+ attr_str = "".join(f" {n}" if v is None else f' {n}="{v}"' for n, v in node.attrs)
2734
+ if node.is_void:
2735
+ return [f"{prefix}<{node.tag}{attr_str}>"]
2736
+ has_elem_children = any(c.tag is not None for c in node.children)
2737
+ if not has_elem_children:
2738
+ inner = "".join(c.text or "" for c in node.children)
2739
+ return [f"{prefix}<{node.tag}{attr_str}>{inner}</{node.tag}>"]
2740
+ lines = [f"{prefix}<{node.tag}{attr_str}>"]
2741
+ for c in node.children:
2742
+ child_lines = _serialize(c, depth + 1)
2743
+ if c.text is not None:
2744
+ lines.append(ind * (depth + 1) + child_lines[0])
2745
+ else:
2746
+ lines.extend(child_lines)
2747
+ lines.append(f"{prefix}</{node.tag}>")
2748
+ return lines
2749
+
2750
+ result = "\n".join(_serialize(builder.root, 0))
2751
+ if add_html_declaration and not result.lstrip().startswith("<!DOCTYPE"):
2752
+ result = "<!DOCTYPE html>\n" + result
2753
+ return result
2754
+
2647
2755
  @GeneralUtilities.check_arguments
2648
2756
  def get_pip_index_url_arguments_from_local_cache(self)->list[str]:
2649
2757
  arguments=[]
@@ -3264,7 +3372,9 @@ OCR-content:
3264
3372
  tree = ET.parse(file)
3265
3373
  root = tree.getroot()
3266
3374
 
3267
- for segment in root.findall(".//xliff:segment[@state='initial']", ns):
3375
+ for segment in root.findall(".//xliff:segment", ns):
3376
+ if segment.get("state", "initial") != "initial":
3377
+ continue
3268
3378
  source_el = segment.find("xliff:source", ns)
3269
3379
  if source_el is None or not source_el.text:
3270
3380
  continue
@@ -3337,12 +3447,14 @@ OCR-content:
3337
3447
  @GeneralUtilities.check_arguments
3338
3448
  def get_all_commits_in_git_repository(self,repository_folder:str,include_all_heads:bool=False) -> list[str]:
3339
3449
  """Returns a textual visualization of all commits in a git-repository."""
3340
- #do 'git log --reverse --all --pretty=format:"%ci | %H | %cn <%ce> | %s"'
3341
- args = ["log", "--reverse", "--pretty=format:%ci | %H | %cn <%ce> | %s"]
3450
+ #do 'git log --reverse --all --pretty=format:"%ci | %H | %cn <%ce> | %d | %s"'
3451
+ args = ["log", "--reverse", "--pretty=format:%ci | %H | %cn <%ce> | %D | %s"]
3342
3452
  if include_all_heads:
3343
3453
  args.append("--all")
3344
3454
  result=self.run_program_argsasarray("git", args, repository_folder, throw_exception_if_exitcode_is_not_zero=True)
3345
- return result[1]
3455
+ output= result[1]
3456
+ result=output.splitlines()
3457
+ return result
3346
3458
 
3347
3459
  @GeneralUtilities.check_arguments
3348
3460
  def write_commit_list_for_repository(self,repository_folder:str,target_file:str,include_all_heads:bool=False) -> None:
@@ -24,6 +24,10 @@ class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
24
24
 
25
25
  @GeneralUtilities.check_arguments
26
26
  def linting(self) -> None:
27
+ src_folder = os.path.join(self.get_codeunit_folder(), "src")
28
+ for file in GeneralUtilities.get_all_files_of_folder(src_folder):
29
+ if file.endswith(".html"):
30
+ self._protected_sc.format_html_file(file, os.path.basename(file) == "index.html")
27
31
  self._protected_sc.run_with_epew("npm", "run lint", self.get_codeunit_folder(),print_live_output=self.get_verbosity()==LogLevel.Debug,encode_argument_in_base64=True)
28
32
 
29
33
  @GeneralUtilities.check_arguments
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import json
3
3
  from datetime import datetime, timedelta,timezone
4
+ import yaml
4
5
  from ..GeneralUtilities import GeneralUtilities
5
6
  from ..ScriptCollectionCore import ScriptCollectionCore
6
7
  from ..SCLog import LogLevel
@@ -67,6 +68,7 @@ class TFCPS_CodeUnit_BuildCodeUnits:
67
68
  self.__search_for_vulnerabilities()
68
69
  self.__search_for_secrets()
69
70
  if self.is_pre_merge():
71
+ self.__translate()
70
72
  self.__collect_metrics()
71
73
  self.__generate_loc_diagram()
72
74
  end_time:datetime=GeneralUtilities.get_now()
@@ -97,6 +99,17 @@ class TFCPS_CodeUnit_BuildCodeUnits:
97
99
  def build_codeunits_in_container(self) -> None:
98
100
  raise ValueError("Not implemented.")
99
101
 
102
+ @GeneralUtilities.check_arguments
103
+ def __translate(self) -> None:
104
+ for taskfile_name in ("Taskfile.yml", "Taskfile.yaml"):
105
+ taskfile = os.path.join(self.repository, taskfile_name)
106
+ if os.path.isfile(taskfile):
107
+ with open(taskfile, "r", encoding="utf-8") as f:
108
+ taskfile_content = yaml.safe_load(f)
109
+ if isinstance(taskfile_content.get("tasks"), dict) and "Translate" in taskfile_content["tasks"]:
110
+ self.sc.run_program("task", "Translate", self.repository, print_live_output=self.sc.log.loglevel == LogLevel.Debug)
111
+ break
112
+
100
113
  @GeneralUtilities.check_arguments
101
114
  def __collect_metrics(self) -> None:
102
115
  project_version: str=self.tfcps_tools_general.get_version_of_project(self.repository)
@@ -437,9 +437,23 @@ class TFCPS_Tools_General:
437
437
  self.__sc.assert_is_git_repository(repositoryfolder)
438
438
  return self.__sc.get_semver_version_from_gitversion(repositoryfolder)
439
439
 
440
+ @GeneralUtilities.check_arguments
441
+ def __try_calculate_changelog_message(self, repositoryfolder: str):
442
+ self.__sc.assert_is_git_repository(repositoryfolder)
443
+ message = self.__sc.run_program("git", "log -1 --pretty=%B", repositoryfolder)[1]
444
+ message = message.strip()
445
+ if len(message) == 0:
446
+ raise ValueError("No commit message found.")
447
+ return message
448
+
440
449
  @GeneralUtilities.check_arguments
441
450
  def create_changelog_entry(self, repositoryfolder: str, message: str, commit: bool, force: bool):
442
451
  self.__sc.assert_is_git_repository(repositoryfolder)
452
+ if message is None:
453
+ try:
454
+ message=self.__try_calculate_changelog_message(repositoryfolder)
455
+ except:
456
+ message="Update."
443
457
  random_file = os.path.join(repositoryfolder, str(uuid.uuid4()))
444
458
  try:
445
459
  if force and not self.__sc.git_repository_has_uncommitted_changes(repositoryfolder):
@@ -1548,4 +1562,4 @@ class TFCPS_Tools_General:
1548
1562
 
1549
1563
 
1550
1564
  def update_dependent_oci_images(self,repo:str):
1551
- pass#TODO update all image-tags in repo/.ScriptCollection/OCIImages/ImageDefinition.csv if possible using the custom defined registries in ~/.ScriptCollection if possible.
1565
+ pass#TODO update all image-tags in repo/.ScriptCollection/OCIImages/ImageDefinition.csv if possible using the custom defined registries in ~/.ScriptCollection if possible.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 4.2.75
3
+ Version: 4.2.77
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
@@ -1,6 +1,6 @@
1
1
  ScriptCollection/AnionBuildPlatform.py,sha256=K-PHarX802A0PU8uRu0GNcEZiXujFoXHACe-X9YJsAQ,11711
2
2
  ScriptCollection/CertificateUpdater.py,sha256=Pa6eyjQSx7IIvj4PQVMI0IwMs01KQrNSB7Qa-7lRfBs,9375
3
- ScriptCollection/Executables.py,sha256=SsA3zeDL8QEsh7GxjDjatv5P4eFeDBPqB0F8pNXoYzA,44234
3
+ ScriptCollection/Executables.py,sha256=Y1nzSLWjU7wQxh7BR8RKQM51pauhIeXJawC6SM5uWcw,44229
4
4
  ScriptCollection/GeneralUtilities.py,sha256=3Fgp0fAXF-rfcohy6k1RsRcMXEVRF15fHl8QJnViKIg,65497
5
5
  ScriptCollection/HTTPMaintenanceOverheadHelper.py,sha256=TToNtyO1XzsMbBsTBf3o0xgOK0v4Jf03qw2Z0xb2nCk,2007
6
6
  ScriptCollection/ProcessesRunner.py,sha256=o5raxIt3lknNPoPrjNzJ2bprRPJ3SnL0rrR7crraD7E,1523
@@ -9,7 +9,7 @@ ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrR
9
9
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
10
10
  ScriptCollection/ProgramRunnerSudo.py,sha256=_khC3xuTdrPoLluBJZWfldltmmuKltABJPcbjZSFW-4,4835
11
11
  ScriptCollection/SCLog.py,sha256=8TRy1LeYMsPOIuWUcnUNNbO5pd-cNBS-3cn-kdzP8FU,4768
12
- ScriptCollection/ScriptCollectionCore.py,sha256=zymaRBLpPzYa3RJpmT5_VM4sMgtHwMftUjTrI62AbfI,182101
12
+ ScriptCollection/ScriptCollectionCore.py,sha256=bZ8OSO0sYRrPO2Jq11AROlh0c8Y2f7C-5r8I4vMmoWg,186755
13
13
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  ScriptCollection/OCIImages/AbstractImageHandler.py,sha256=83qDMILwxhH9DbC0sb358Vu8PXEysmJJyap_6gECZqs,1627
15
15
  ScriptCollection/OCIImages/OCIImageManager.py,sha256=aBogkSXNDyi8NO11N-s03nuFJEv7PyJ-wjHuYYeZfvs,6662
@@ -24,13 +24,13 @@ ScriptCollection/Resources/CultureChooser/index.html,sha256=gxQzbrSp4WU52TqN-gcB
24
24
  ScriptCollection/Resources/MaintenanceSite/MaintenanceSite.html,sha256=CX9S1bdOz6xU2aGfr03tJRGczQrlpn-IeODc15d5kc0,232
25
25
  ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py,sha256=EMNDgkUem87aH1csz7eoSBBEKkiZMLZqZhnxKSPQWe0,27845
26
26
  ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py,sha256=MieeAAKm1y58qXp1cCUN5mj5vwpq4Pc1uusUjPQzpvc,8237
27
- ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py,sha256=3Mo8XrTDD1Z7_K1PLxSPYA-fePQ95sIAeNKGj0matiw,15109
27
+ ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnits.py,sha256=2CNCmngOgygvhJrBdMbrq5W6LZ-xxchlxeThaDQZ-TA,15792
28
28
  ScriptCollection/TFCPS/TFCPS_CreateRelease.py,sha256=yqGstRjRfVVGbqrcBgtYStqth2x2SvBb3y2Ht8GsuMQ,6554
29
29
  ScriptCollection/TFCPS/TFCPS_Generic.py,sha256=Tpzgiz6m3-cYCkObZOG5Uu7oM-EMoWFzzRpLl3Lblqo,2023
30
30
  ScriptCollection/TFCPS/TFCPS_MergeToMain.py,sha256=-Ev9D3bZDlUk2WFQhcmvzQ3FCS97OdsVUd0koAdmpZc,7474
31
31
  ScriptCollection/TFCPS/TFCPS_MergeToStable.py,sha256=Ajfy2pLajTuU6UpwItHt4C2a-gLF3gPc4z6BktL3Cio,22163
32
32
  ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py,sha256=f0Uq1cA_4LvmL72cal0crrbKF6PcxL13D9wBKuQ1YBw,2328
33
- ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=H8qve4dwY6XjLAKrh8jAJohk8DGdtnqa_-frkrME8pU,100769
33
+ ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=VbS3qdpCc4ZgbwlwxHdLB_ras8dDmJDBklRrWIrhbDQ,101356
34
34
  ScriptCollection/TFCPS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=sPO4Gf6oRbGH9QRA3p2nmTAeHtkyYr31ucLbJP09JeY,12139
36
36
  ScriptCollection/TFCPS/Docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,12 +43,12 @@ ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py,sha256=KAjyFyEj
43
43
  ScriptCollection/TFCPS/Flutter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  ScriptCollection/TFCPS/Go/TFCPS_CodeUnitSpecific_Go.py,sha256=kyx26AnT1-LySFA46wfJ9yZUKYdMWTD0U2XZfSQbuB0,3497
45
45
  ScriptCollection/TFCPS/Go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=GQLE6FeR-XNRlLDwionndM-oGLPIbgNhSAx5rc3nnDY,12900
46
+ ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=57I7xbLtCtH-Edt1QKCSXF7wnGyAhbGMdghD_VFZIIY,13184
47
47
  ScriptCollection/TFCPS/NodeJS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py,sha256=9XK7XnbeOnq_4siVoWovogStoKFiZLhGh3C_f2YaznI,13621
49
49
  ScriptCollection/TFCPS/Python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- scriptcollection-4.2.75.dist-info/METADATA,sha256=uAmn_kWmbQn8rdmRBj3VatLg0j8LNhwY62kOrS-i7nQ,7691
51
- scriptcollection-4.2.75.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
52
- scriptcollection-4.2.75.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
53
- scriptcollection-4.2.75.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
54
- scriptcollection-4.2.75.dist-info/RECORD,,
50
+ scriptcollection-4.2.77.dist-info/METADATA,sha256=LBW1YBdUMBmRbKX0zeYVI6g6IOxw7bH93ojqb7mInqU,7691
51
+ scriptcollection-4.2.77.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
52
+ scriptcollection-4.2.77.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
53
+ scriptcollection-4.2.77.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
54
+ scriptcollection-4.2.77.dist-info/RECORD,,