socx-cli 0.11.2__tar.gz → 0.11.4__tar.gz

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.
Files changed (104) hide show
  1. {socx_cli-0.11.2 → socx_cli-0.11.4}/PKG-INFO +1 -1
  2. {socx_cli-0.11.2 → socx_cli-0.11.4}/pyproject.toml +2 -1
  3. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/converters.py +22 -13
  4. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/encoder.py +4 -2
  5. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/serializer.py +4 -2
  6. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/visitor/protocol.py +8 -5
  7. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/visitor/traversal.py +7 -3
  8. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/regression.yaml +1 -1
  9. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/config/_config.py +1 -6
  10. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/rgr/_rgr.py +23 -32
  11. socx_cli-0.11.4/socx_plugins/rgr/callbacks.py +28 -0
  12. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/rgr/rgr.py +3 -4
  13. socx_cli-0.11.2/socx_plugins/rgr/callbacks.py +0 -42
  14. {socx_cli-0.11.2 → socx_cli-0.11.4}/.gitignore +0 -0
  15. {socx_cli-0.11.2 → socx_cli-0.11.4}/LICENSE +0 -0
  16. {socx_cli-0.11.2 → socx_cli-0.11.4}/README.md +0 -0
  17. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/__init__.py +0 -0
  18. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/__main__.py +0 -0
  19. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/__init__.py +0 -0
  20. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/_cli.py +0 -0
  21. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/_jinja.py +0 -0
  22. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/callbacks.py +0 -0
  23. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/cfg.py +0 -0
  24. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/cli.py +0 -0
  25. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/cli/params.py +0 -0
  26. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/__init__.py +0 -0
  27. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/_config.py +0 -0
  28. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/_settings.py +0 -0
  29. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/encoders.py +0 -0
  30. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/formatters.py +0 -0
  31. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/__init__.py +0 -0
  32. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/git/__init__.py +0 -0
  33. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/git/git.py +0 -0
  34. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/git/manifest.py +0 -0
  35. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/plugin.py +0 -0
  36. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/schema/types.py +0 -0
  37. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/serializers.py +0 -0
  38. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/config/validators.py +0 -0
  39. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/__init__.py +0 -0
  40. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/_paths.py +0 -0
  41. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/enums.py +0 -0
  42. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/funcs.py +0 -0
  43. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/metadata.py +0 -0
  44. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/paths.py +0 -0
  45. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/core/types.py +0 -0
  46. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/git/__init__.py +0 -0
  47. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/git/_git.py +0 -0
  48. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/git/_manifest.py +0 -0
  49. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/git/_ssh.py +0 -0
  50. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/io/__init__.py +0 -0
  51. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/io/console.py +0 -0
  52. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/io/decorators.py +0 -0
  53. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/io/log.py +0 -0
  54. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/__init__.py +0 -0
  55. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/mixins/__init__.py +0 -0
  56. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/mixins/proxy.py +0 -0
  57. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/mixins/uid.py +0 -0
  58. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/singleton/__init__.py +0 -0
  59. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/singleton/singleton.py +0 -0
  60. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/patterns/visitor/__init__.py +0 -0
  61. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/regression/__init__.py +0 -0
  62. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/regression/regression.py +0 -0
  63. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/regression/status.py +0 -0
  64. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/regression/test.py +0 -0
  65. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/regression/validator.py +0 -0
  66. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/cli.yaml +0 -0
  67. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/console.yaml +0 -0
  68. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/git.yaml +0 -0
  69. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/plugins.yaml +0 -0
  70. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/rich_click.yaml +0 -0
  71. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/settings/settings.yaml +0 -0
  72. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/static/sql/socx.sql +0 -0
  73. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/utils/__init__.py +0 -0
  74. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx/utils/decorators.py +0 -0
  75. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/config/__init__.py +0 -0
  76. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/config/edit.py +0 -0
  77. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/__init__.py +0 -0
  78. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/arguments.py +0 -0
  79. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/callbacks.py +0 -0
  80. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/cli.py +0 -0
  81. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/manifest.py +0 -0
  82. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/renderables.py +0 -0
  83. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/summary.py +0 -0
  84. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/git/utils.py +0 -0
  85. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/plugin/__init__.py +0 -0
  86. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/plugin/example.py +0 -0
  87. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/plugin/schema.py +0 -0
  88. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/rgr/__init__.py +0 -0
  89. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/version/__init__.py +0 -0
  90. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_plugins/version/__main__.py +0 -0
  91. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/__init__.py +0 -0
  92. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/__init__.py +0 -0
  93. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/__main__.py +0 -0
  94. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/app.py +0 -0
  95. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/bindings/__init__.py +0 -0
  96. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/bindings/vim/__init__.py +0 -0
  97. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/bindings/vim/mode.py +0 -0
  98. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/bindings/vim/vim.py +0 -0
  99. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/containers.py +0 -0
  100. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/mixins/__init__.py +0 -0
  101. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/mixins/composable.py +0 -0
  102. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/preview.py +0 -0
  103. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/screens.py +0 -0
  104. {socx_cli-0.11.2 → socx_cli-0.11.4}/socx_tui/regression/table.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: socx-cli
3
- Version: 0.11.2
3
+ Version: 0.11.4
4
4
  Summary: System on chip verification and tooling infrastructure.
5
5
  Project-URL: Issues, https://github.com/sagikimhi/socx-cli/issues
6
6
  Project-URL: Homepage, https://sagikimhi.dev/socx-cli
@@ -29,7 +29,7 @@ socx = 'socx.__main__:main'
29
29
  [project]
30
30
  name = "socx-cli"
31
31
  readme = "README.md"
32
- version = "0.11.2"
32
+ version = "0.11.4"
33
33
  license = "Apache-2.0"
34
34
  authors = [{ name = "Sagi Kimhi", email = "sagi.kim5@gmail.com" }]
35
35
  maintainers = [{ name = "Sagi Kimhi", email = "sagi.kim5@gmail.com" }]
@@ -107,6 +107,7 @@ dev = [
107
107
  "hatch-uvenv",
108
108
  "objexplore>=1.6.3",
109
109
  "ipython>=8.38.0",
110
+ "ty>=0.0.14",
110
111
  ]
111
112
  docs = [
112
113
  "mike",
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import os
5
6
  import sys
6
7
  import abc
7
8
  import runpy
@@ -17,6 +18,7 @@ from typing import (
17
18
  override,
18
19
  TypeVar,
19
20
  ClassVar,
21
+ Generic,
20
22
  )
21
23
  from pathlib import Path
22
24
  from importlib import import_module
@@ -52,8 +54,11 @@ _validate = validate_call(config=ConfigDict(arbitrary_types_allowed=True))
52
54
 
53
55
  logger = logging.getLogger(__name__)
54
56
 
57
+ TI = TypeVar("TI")
58
+ TO = TypeVar("TO")
55
59
 
56
- class Converter[TI, TO](abc.ABC):
60
+
61
+ class Converter(abc.ABC, Generic[TI, TO]):
57
62
  """Base protocol for Dynaconf converters used by SoCX."""
58
63
 
59
64
  @abc.abstractmethod
@@ -73,8 +78,6 @@ class Converter[TI, TO](abc.ABC):
73
78
  self, msg: str, *args: Any, exc: Exception | None = None, **kwargs: Any
74
79
  ) -> None:
75
80
  """Log a recoverable converter error message."""
76
- if exc is not None:
77
- exc.add_note(msg)
78
81
  self.logger.exception(msg, *args, **kwargs)
79
82
 
80
83
  def convert(self, value: TI, *args: Any, **kwargs: Any) -> TO:
@@ -417,7 +420,7 @@ class CommandConverter(
417
420
  return cli
418
421
 
419
422
  @singledispatchmethod
420
- def _run_shell_script(self, value, *args, **kwargs) -> int: ...
423
+ def _run_shell_script(self, value, *args, **kwargs): ...
421
424
 
422
425
  @_run_shell_script.register
423
426
  def _(
@@ -450,12 +453,15 @@ class CommandConverter(
450
453
  env = env or {}
451
454
  cwd = local.path(cwd)
452
455
 
453
- with local.env(), local.cwd(cwd):
456
+ if not fresh_env:
457
+ env = dict(os.environ, **env)
458
+
459
+ with local.env(env), local.cwd(cwd):
454
460
  if fresh_env:
455
461
  local.env.clear()
456
462
 
457
463
  local.env.update(env)
458
- cmd = value.with_cwd(cwd)
464
+ cmd = value.with_cwd(cwd).with_env(**env)
459
465
  cmd_str = str(cmd)
460
466
  cwd_str = str(cwd)
461
467
  env_str = "\n".join(f"\t{k}={v}" for k, v in local.env.items())
@@ -518,6 +524,7 @@ class CommandConverter(
518
524
  cwd = cwd or Path.cwd()
519
525
  ctx = click.get_current_context(silent=True)
520
526
  argv = sys.argv.copy()
527
+ environ = os.environ.copy()
521
528
 
522
529
  path, _, symbol = value.rpartition(":")
523
530
 
@@ -550,11 +557,11 @@ class CommandConverter(
550
557
  if self.is_script_path(path) or self.is_package_path(path):
551
558
  path = str(Path(path).resolve())
552
559
 
553
- with local.cwd(cwd), local.env():
560
+ with local.cwd(cwd):
554
561
  if fresh_env:
555
- local.env.clear()
562
+ os.environ.clear()
556
563
 
557
- local.env.update(env)
564
+ os.environ.update(env)
558
565
 
559
566
  try:
560
567
  if self.is_module_path(path) and symbol:
@@ -591,6 +598,8 @@ class CommandConverter(
591
598
  self.log_exception(err)
592
599
  finally:
593
600
  sys.argv = argv
601
+ os.environ.clear()
602
+ os.environ.update(environ)
594
603
 
595
604
  return rv
596
605
 
@@ -766,9 +775,9 @@ class ShConverter(
766
775
  def __call__( # pyright: ignore[reportIncompatibleMethodOverride]
767
776
  self,
768
777
  value,
769
- *args: Any,
770
- **kwargs: Any,
771
- ) -> Lazy | Script: ...
778
+ *args,
779
+ **kwargs,
780
+ ): ...
772
781
 
773
782
  @__call__.register
774
783
  def _(self, value: Lazy) -> Lazy:
@@ -821,7 +830,7 @@ class MarkdownConverter(Converter[str | Lazy | Markdown | None, str | Lazy]):
821
830
  return value
822
831
 
823
832
 
824
- class GenericConverter[TI, TO](Converter[TI, TO]):
833
+ class GenericConverter(Converter[TI, TO]):
825
834
  """Adapter turning plain callables into ``Converter`` instances."""
826
835
 
827
836
  def __init__(self, name: str, cvt: Callable[..., TO]) -> None:
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from typing import Any
4
+ from typing import Any, TypeVar, Generic
5
5
 
6
+ T = TypeVar("T")
6
7
 
7
- class Encoder[T](ABC):
8
+
9
+ class Encoder(ABC, Generic[T]):
8
10
  """Generic protocol for converting values into configuration payloads."""
9
11
 
10
12
  @classmethod
@@ -1,10 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from typing import Any
4
+ from typing import Any, TypeVar, Generic
5
5
 
6
+ T = TypeVar("T")
6
7
 
7
- class Serializer[T](ABC):
8
+
9
+ class Serializer(ABC, Generic[T]):
8
10
  """Generic protocol for converting values into configuration payloads."""
9
11
 
10
12
  @classmethod
@@ -2,11 +2,14 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Protocol
5
+ from typing import Protocol, TypeVar, Generic
6
6
  from collections.abc import Iterable
7
7
 
8
8
 
9
- class Visitor[NODE](Protocol):
9
+ NODE = TypeVar("NODE")
10
+
11
+
12
+ class Visitor(Protocol, Generic[NODE]):
10
13
  """Protocol describing objects that can visit nodes."""
11
14
 
12
15
  __slots__ = ()
@@ -16,7 +19,7 @@ class Visitor[NODE](Protocol):
16
19
  ...
17
20
 
18
21
 
19
- class Node[NODE](Protocol):
22
+ class Node(Protocol, Generic[NODE]):
20
23
  """Protocol for nodes that accept visitors."""
21
24
 
22
25
  __slots__ = ()
@@ -26,7 +29,7 @@ class Node[NODE](Protocol):
26
29
  ...
27
30
 
28
31
 
29
- class Structure[NODE](Protocol):
32
+ class Structure(Protocol, Generic[NODE]):
30
33
  """Protocol for structures exposing child relationships."""
31
34
 
32
35
  __slots__ = ()
@@ -37,7 +40,7 @@ class Structure[NODE](Protocol):
37
40
  ...
38
41
 
39
42
 
40
- class Traversal[NODE](Protocol):
43
+ class Traversal(Protocol, Generic[NODE]):
41
44
  """Adapter interface that controls how nodes accept visitors."""
42
45
 
43
46
  __slots__ = ()
@@ -1,13 +1,17 @@
1
1
  """Traversal strategies compatible with the visitor protocol."""
2
2
 
3
3
  from __future__ import annotations
4
+ from typing import TypeVar
4
5
 
5
6
  from socx.patterns.visitor.protocol import Visitor
6
7
  from socx.patterns.visitor.protocol import Structure
7
8
  from socx.patterns.visitor.protocol import Traversal
8
9
 
9
10
 
10
- class TopDownTraversal[NODE](Traversal[NODE]):
11
+ NODE = TypeVar("NODE")
12
+
13
+
14
+ class TopDownTraversal(Traversal[NODE]):
11
15
  """Pre-order traversal that visits parents before descendants."""
12
16
 
13
17
  @classmethod
@@ -19,7 +23,7 @@ class TopDownTraversal[NODE](Traversal[NODE]):
19
23
  cls.accept(c, v, p)
20
24
 
21
25
 
22
- class BottomUpTraversal[NODE](Traversal[NODE]):
26
+ class BottomUpTraversal(Traversal[NODE]):
23
27
  """Post-order traversal that visits descendants before parents."""
24
28
 
25
29
  @classmethod
@@ -31,7 +35,7 @@ class BottomUpTraversal[NODE](Traversal[NODE]):
31
35
  v.visit(n)
32
36
 
33
37
 
34
- class ByLevelTraversal[NODE](Traversal[NODE]):
38
+ class ByLevelTraversal(Traversal[NODE]):
35
39
  """Breadth-first traversal that visits nodes one level at a time."""
36
40
 
37
41
  @classmethod
@@ -5,6 +5,6 @@ regression:
5
5
  run:
6
6
  input:
7
7
  filename: small
8
- directory: "@path @format {this.paths.app_root_dir}/assets/rgr/inputs"
8
+ directory: "@path @jinja {{this.paths.app_root_dir}}/assets/rgr/inputs"
9
9
  output:
10
10
  directory: "@path workrun/regression"
@@ -20,12 +20,7 @@ def edit_config():
20
20
  Path(file).stem: Path(settings.app_settings_dir / file)
21
21
  for file in settings.dynaconf_include
22
22
  }
23
-
24
- for name in files:
25
- try:
26
- files[name] = files[name].resolve()
27
- except OSError:
28
- del files[name]
23
+ files = {k: v.resolve() for k, v in files.items() if v.exists()}
29
24
 
30
25
  file_choice = Prompt.ask(
31
26
  console=console,
@@ -28,17 +28,17 @@ def _input() -> Decorator:
28
28
  return click.argument(
29
29
  "input",
30
30
  help="A file containing a list of test commands to be ran.",
31
- metavar="[<args>...]",
31
+ metavar="<file>",
32
32
  required=True,
33
33
  callback=input_cb,
34
- expose_value=True,
34
+ expose_value=False,
35
35
  type=click.Path(
36
36
  exists=True,
37
- file_okay=True,
38
- dir_okay=False,
39
37
  readable=True,
40
- resolve_path=True,
38
+ dir_okay=False,
39
+ file_okay=True,
41
40
  path_type=Path,
41
+ resolve_path=True,
42
42
  ),
43
43
  )
44
44
 
@@ -51,19 +51,18 @@ def _output() -> Decorator:
51
51
  "output",
52
52
  help="Output directory for writing passed/failed run commands.",
53
53
  nargs=1,
54
+ metavar="[<directory>]",
54
55
  type=click.Path(
55
56
  exists=False,
56
- file_okay=False,
57
57
  dir_okay=True,
58
- resolve_path=True,
58
+ file_okay=False,
59
59
  path_type=Path,
60
+ resolve_path=True,
60
61
  ),
61
62
  default=settings.regression.run.output.directory,
62
63
  callback=output_cb,
63
- required=True,
64
- show_envvar=True,
65
64
  show_default=True,
66
- expose_value=True,
65
+ expose_value=False,
67
66
  )
68
67
 
69
68
 
@@ -72,28 +71,23 @@ def options() -> Decorator:
72
71
  return join_decorators(_input(), _output())
73
72
 
74
73
 
75
- def _correct_path_in(input_path: str | Path | None = None) -> Path:
74
+ def _get_input_path() -> Path:
76
75
  """Resolve the regression input path from CLI value or settings."""
77
- if input_path is None:
78
- input_cfg = settings.regression.run.input
79
- dir_in = input_cfg.directory
80
- file_in = input_cfg.filename
81
- input_path = Path(f"{dir_in}/{file_in}")
82
-
83
- if isinstance(input_path, str):
84
- input_path = Path(input_path)
85
-
86
- return input_path.resolve()
76
+ input_cfg = settings.regression.run.input
77
+ directory, filename = input_cfg.directory, input_cfg.filename
78
+ rv = (
79
+ (Path(directory) / filename)
80
+ if isinstance(directory, str)
81
+ else (directory / filename)
82
+ )
83
+ return rv.resolve()
87
84
 
88
85
 
89
- def _correct_paths_out(
90
- regression: Regression,
91
- output_path: str | Path | None = None,
92
- ) -> Path:
86
+ def _get_output_path(regression: Regression) -> Path:
93
87
  """Return timestamped output paths for passed and failed results."""
94
88
  now = time.strftime("%H-%M")
95
89
  today = time.strftime("%d-%m-%Y")
96
- dir_out = output_path or settings.regression.run.output.directory # pyright: ignore
90
+ dir_out = settings.regression.run.output.directory # pyright: ignore
97
91
  if isinstance(dir_out, str):
98
92
  dir_out = Path(dir_out)
99
93
  dir_out = dir_out / regression.name / today / now
@@ -166,14 +160,11 @@ def populate_regression(filepath: Path) -> Regression:
166
160
  )
167
161
 
168
162
 
169
- async def run_from_file(
170
- input: str | Path | None = None, # noqa: A002
171
- output: str | Path | None = None,
172
- ) -> Regression:
163
+ async def run_regression() -> Regression:
173
164
  """Run a regression using file inputs and persist the results."""
174
- path_in = _correct_path_in(input)
165
+ path_in = _get_input_path()
175
166
  regression = populate_regression(path_in)
176
- output_dir = _correct_paths_out(regression, output)
167
+ output_dir = _get_output_path(regression)
177
168
 
178
169
  try:
179
170
  async with asyncio.TaskGroup() as tg:
@@ -0,0 +1,28 @@
1
+ """Rich-Click callbacks for normalising regression CLI arguments."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ from socx import settings, log, log_it
8
+ from rich_click import Context, Parameter
9
+
10
+
11
+ logger = log.get_logger(__name__)
12
+
13
+
14
+ def input_cb(ctx: Context, param: Parameter, value: str | Path) -> Path:
15
+ """Normalise the regression input path and update configuration."""
16
+ path = Path(value) if isinstance(value, str) else value
17
+ settings.regression.run.input.update(
18
+ {"filename": path.name, "directory": path.parent}
19
+ )
20
+ return path
21
+
22
+
23
+ @log_it(logger=logger)
24
+ def output_cb(ctx: Context, param: Parameter, value: str | Path) -> Path:
25
+ """Normalise the regression output directory and update configuration."""
26
+ path = Path(value) if isinstance(value, str) else value
27
+ settings.regression.run.output.update({param.name: path})
28
+ return path
@@ -3,11 +3,10 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
- from pathlib import Path
7
6
 
8
7
  from socx import settings, group, command
9
8
 
10
- from socx_plugins.rgr._rgr import options, run_from_file
9
+ from socx_plugins.rgr._rgr import options, run_regression
11
10
 
12
11
 
13
12
  @group()
@@ -25,7 +24,7 @@ def tui() -> None:
25
24
 
26
25
  @command(parent=cli, no_args_is_help=True)
27
26
  @options()
28
- def run(input: Path, output: Path): # noqa: A002
27
+ def run():
29
28
  r"""Run a regression of multiple tests defined in FILE.
30
29
 
31
30
  The FILE argument is a file containing a list of test commands to be ran.
@@ -48,7 +47,7 @@ def run(input: Path, output: Path): # noqa: A002
48
47
  """
49
48
  try:
50
49
  regression = asyncio.run(
51
- run_from_file(input, output),
50
+ run_regression(),
52
51
  debug=settings.cli.params.debug,
53
52
  )
54
53
  except (asyncio.CancelledError, KeyboardInterrupt):
@@ -1,42 +0,0 @@
1
- """Rich-Click callbacks for normalising regression CLI arguments."""
2
-
3
- # type: ignore
4
- from __future__ import annotations
5
-
6
- from pathlib import Path
7
-
8
- from socx import settings, log, log_it
9
- from rich_click import Context, Parameter
10
-
11
-
12
- logger = log.get_logger(__name__)
13
-
14
-
15
- def input_cb(ctx: Context, param: Parameter, value: str | Path) -> Path:
16
- """Normalise the regression input path and update configuration."""
17
- if value and isinstance(value, str):
18
- path = Path(value)
19
-
20
- if path.exists() and path.is_file():
21
- input_ = {"filename": path.name, "directory": path.parent}
22
- settings.set("regression.run.input", input_, merge=True)
23
-
24
- file: str = settings.get("regression.run.input.filename")
25
- directory: Path = Path(settings.get("regression.run.input.directory"))
26
- input_path = directory / file
27
- return input_path
28
-
29
-
30
- @log_it(logger=logger)
31
- def output_cb(ctx: Context, param: Parameter, value: str) -> str:
32
- """Normalise the regression output directory and update configuration."""
33
- if value:
34
- path = Path(value)
35
-
36
- if path.exists() and path.is_dir():
37
- settings.set(
38
- "regression.run.output", {"directory": path}, merge=True
39
- )
40
-
41
- output_path: Path = Path(settings.get("regression.run.output.directory"))
42
- return output_path
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes