apexcodexpy 0.7.2__tar.gz → 0.7.3__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 (25) hide show
  1. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/PKG-INFO +1 -1
  2. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/program.py +5 -2
  3. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/pyproject.py +53 -8
  4. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/reporters.py +4 -2
  5. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/result.py +4 -2
  6. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/service.py +4 -1
  7. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/tools.py +4 -1
  8. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/base.py +4 -1
  9. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/ci.py +4 -1
  10. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/lock.py +3 -2
  11. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/yamler.py +5 -3
  12. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/pyproject.toml +19 -1
  13. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/LICENSE +0 -0
  14. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/README.md +0 -0
  15. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/__init__.py +0 -0
  16. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/__init__.py +0 -0
  17. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/typer/__init__.py +0 -0
  18. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/typer/device.py +0 -0
  19. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/typer/root.py +0 -0
  20. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/typer/testing.py +0 -0
  21. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/__init__.py +1 -1
  22. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/build.py +0 -0
  23. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/dependabot.py +0 -0
  24. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/infra/workflows/validate.py +0 -0
  25. {apexcodexpy-0.7.2 → apexcodexpy-0.7.3}/codex/runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexcodexpy
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: The Non-Destructive Configuration Steward for Python Projects.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -1,12 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import subprocess
4
- from collections.abc import Callable, Iterable, Iterator, MutableSequence
5
4
  from dataclasses import dataclass, field, replace
6
- from typing import Any, Protocol
5
+ from typing import TYPE_CHECKING, Any, Protocol
7
6
 
8
7
  from codex.infra.result import ComboResult, ProgramResult, TaskResult
9
8
 
9
+ if TYPE_CHECKING:
10
+ from collections.abc import Callable, Iterable, Iterator, MutableSequence
11
+
10
12
 
11
13
  @dataclass(frozen=True)
12
14
  class Program:
@@ -22,6 +24,7 @@ class Program:
22
24
  text=True,
23
25
  encoding="utf-8",
24
26
  capture_output=True,
27
+ check=False,
25
28
  )
26
29
  ),
27
30
  )
@@ -1,14 +1,20 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import hashlib
3
4
  from dataclasses import dataclass, field
4
5
  from pathlib import Path
5
- from typing import Any
6
+ from typing import TYPE_CHECKING, Any, Self
6
7
 
7
8
  import tomlkit
9
+ from tomlkit import TOMLDocument
8
10
 
9
- from codex.infra.program import Executable
10
11
  from codex.infra.result import ProgramResult
11
12
 
13
+ if TYPE_CHECKING:
14
+ from collections.abc import Mapping, MutableMapping
15
+
16
+ from codex.infra.program import Executable
17
+
12
18
 
13
19
  def _mypy_config() -> dict[str, Any]:
14
20
  return {
@@ -38,8 +44,21 @@ def _ruff_config() -> dict[str, Any]:
38
44
  "I",
39
45
  "N",
40
46
  "UP",
47
+ "RUF",
48
+ "FURB",
49
+ "PERF",
50
+ "LOG",
51
+ "PIE",
52
+ "SLF",
53
+ "DTZ",
54
+ "PTH",
55
+ "TRY",
56
+ "PL",
57
+ "TCH",
41
58
  ],
42
- "mccabe": {"max-complexity": 10},
59
+ "mccabe": {
60
+ "max-complexity": 10,
61
+ },
43
62
  }
44
63
  }
45
64
 
@@ -79,10 +98,9 @@ class PyProjectToml:
79
98
  if not pyproject.exists():
80
99
  return self._result.fail(message=f"{self.NAME} not found.")
81
100
 
82
- document = tomlkit.parse(pyproject.read_text(encoding="utf-8"))
83
- original = tomlkit.dumps(document)
84
- deep_merge(STANDARDS, document)
85
- modified = tomlkit.dumps(document)
101
+ document = Tomler.read(pyproject)
102
+ original = document.dumps()
103
+ modified = document.update_with(STANDARDS).dumps()
86
104
 
87
105
  if original == modified:
88
106
  return self._result.no_changes()
@@ -94,8 +112,35 @@ class PyProjectToml:
94
112
  def toml_on(self, path: Path) -> Path:
95
113
  return path / self.NAME
96
114
 
115
+ @staticmethod
116
+ def latest() -> Tomler:
117
+ return Tomler.read(Path("pyproject.toml")).update_with(STANDARDS)
118
+
119
+
120
+ @dataclass(frozen=True)
121
+ class Tomler:
122
+ document: TOMLDocument
123
+
124
+ @classmethod
125
+ def read(cls, path: Path) -> Tomler:
126
+ return cls(tomlkit.parse(path.read_text(encoding="utf-8")))
127
+
128
+ def dumps(self) -> str:
129
+ return tomlkit.dumps(self.document)
130
+
131
+ def update_with(self, source: Mapping[str, Any]) -> Self:
132
+ deep_merge(source, self.document)
133
+
134
+ return self
135
+
136
+ def hashed(self) -> str:
137
+ return hashlib.sha256(self.dumps().encode()).hexdigest()
138
+
97
139
 
98
- def deep_merge(source: dict[str, Any], destination: dict[str, Any]) -> None:
140
+ def deep_merge(
141
+ source: Mapping[str, Any],
142
+ destination: MutableMapping[str, Any],
143
+ ) -> None:
99
144
  """Recursively merges the source into destination with TOML formatting."""
100
145
  for key, value in source.items():
101
146
  match value:
@@ -1,11 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from typing import Protocol
4
+ from typing import TYPE_CHECKING, Protocol
5
5
 
6
- from codex.infra.result import Reporter
7
6
  from codex.infra.typer.device import TyperDevice
8
7
 
8
+ if TYPE_CHECKING:
9
+ from codex.infra.result import Reporter
10
+
9
11
 
10
12
  @dataclass(frozen=True)
11
13
  class SimpleReporter:
@@ -1,8 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field
4
- from subprocess import CompletedProcess
5
- from typing import Any, Protocol
4
+ from typing import TYPE_CHECKING, Any, Protocol
5
+
6
+ if TYPE_CHECKING:
7
+ from subprocess import CompletedProcess
6
8
 
7
9
 
8
10
  class TaskResult(Protocol):
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass
4
- from pathlib import Path
5
4
  from time import time
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  from codex.infra.program import Command, Executable, MultiProgram, Program
8
8
  from codex.infra.pyproject import PyProjectToml
@@ -24,6 +24,9 @@ from codex.infra.workflows import (
24
24
  )
25
25
  from codex.infra.workflows.lock import CodexLockWorkflow
26
26
 
27
+ if TYPE_CHECKING:
28
+ from pathlib import Path
29
+
27
30
 
28
31
  @dataclass(frozen=True)
29
32
  class Codex:
@@ -4,6 +4,7 @@ import sys
4
4
  from dataclasses import dataclass, field
5
5
  from importlib import metadata
6
6
  from pathlib import Path
7
+ from typing import TYPE_CHECKING
7
8
 
8
9
  from codex.infra.program import (
9
10
  BoundedProgram,
@@ -11,7 +12,9 @@ from codex.infra.program import (
11
12
  MultiProgram,
12
13
  Program,
13
14
  )
14
- from codex.infra.result import TaskResult
15
+
16
+ if TYPE_CHECKING:
17
+ from codex.infra.result import TaskResult
15
18
 
16
19
 
17
20
  @dataclass(frozen=True, kw_only=True)
@@ -3,13 +3,16 @@ from __future__ import annotations
3
3
  from abc import ABC, abstractmethod
4
4
  from dataclasses import dataclass
5
5
  from datetime import UTC, datetime
6
- from pathlib import Path
6
+ from typing import TYPE_CHECKING
7
7
 
8
8
  from codex.infra.program import Executable, LazyExecutable
9
9
  from codex.infra.result import ProgramResult
10
10
  from codex.infra.tools import Version
11
11
  from codex.infra.yamler import Yamler
12
12
 
13
+ if TYPE_CHECKING:
14
+ from pathlib import Path
15
+
13
16
 
14
17
  @dataclass(frozen=True, kw_only=True)
15
18
  class YamlWorkflow(ABC):
@@ -1,10 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import MutableMapping, MutableSequence
4
3
  from dataclasses import dataclass, field, replace
4
+ from typing import TYPE_CHECKING
5
5
 
6
6
  from codex.infra.yamler import Yamler
7
7
 
8
+ if TYPE_CHECKING:
9
+ from collections.abc import MutableMapping, MutableSequence
10
+
8
11
 
9
12
  @dataclass(frozen=True)
10
13
  class CiWorkflow:
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
 
7
7
  from codex.infra.yamler import Yamler
8
8
 
9
+ from ..pyproject import PyProjectToml
9
10
  from .base import YamlWorkflow
10
11
 
11
12
 
@@ -24,10 +25,10 @@ class CodexLockWorkflow(YamlWorkflow):
24
25
  return Yamler.parse(
25
26
  {
26
27
  "hashes": {
27
- "pyproject": hash_of(Path("pyproject.toml")),
28
+ "pyproject": PyProjectToml.latest().hashed(),
28
29
  },
29
30
  }
30
31
  )
31
32
 
32
33
  def verify(self) -> bool:
33
- return self.path.exists() and self.standards == Yamler.read(self.path)
34
+ return not self.path.exists() or self.standards == Yamler.read(self.path)
@@ -1,14 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable, Mapping
4
3
  from dataclasses import dataclass
5
- from pathlib import Path
6
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
7
5
 
8
6
  from ruamel.yaml import YAML
9
7
  from ruamel.yaml.comments import CommentedMap
10
8
  from ruamel.yaml.scalarstring import FoldedScalarString
11
9
 
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Iterable, Mapping
12
+ from pathlib import Path
13
+
12
14
 
13
15
  @dataclass(frozen=True, kw_only=True)
14
16
  class Yamler:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexcodexpy"
3
- version = "0.7.2"
3
+ version = "0.7.3"
4
4
  description = "The Non-Destructive Configuration Steward for Python Projects."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -54,6 +54,24 @@ select = [
54
54
  "I",
55
55
  "N",
56
56
  "UP",
57
+ "RUF",
58
+ "FURB",
59
+ "PERF",
60
+ "LOG",
61
+ "PIE",
62
+ "SLF",
63
+ "DTZ",
64
+ "PTH",
65
+ "TRY",
66
+ "PL",
67
+ "TCH",
68
+ ]
69
+
70
+ ignore = [
71
+ "TRY003",
72
+ "PLR0913",
73
+ "PLR0917",
74
+ "PLR2004",
57
75
  ]
58
76
 
59
77
  [tool.ruff.lint.mccabe]
File without changes
File without changes
@@ -3,7 +3,7 @@ from .dependabot import DependabotWorkflow
3
3
  from .validate import CheckCodeWorkflow
4
4
 
5
5
  __all__ = [
6
- "DependabotWorkflow",
7
6
  "BuildCodeWorkflow",
8
7
  "CheckCodeWorkflow",
8
+ "DependabotWorkflow",
9
9
  ]
File without changes