apexcodexpy 0.6.2__tar.gz → 0.6.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 (25) hide show
  1. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/PKG-INFO +1 -1
  2. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/program.py +12 -3
  3. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/service.py +4 -1
  4. apexcodexpy-0.6.4/codex/infra/workflows/base.py +56 -0
  5. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/ci.py +12 -4
  6. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/validate.py +3 -0
  7. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/pyproject.toml +1 -1
  8. apexcodexpy-0.6.2/codex/infra/workflows/base.py +0 -53
  9. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/LICENSE +0 -0
  10. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/README.md +0 -0
  11. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/__init__.py +0 -0
  12. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/__init__.py +0 -0
  13. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/pyproject.py +0 -0
  14. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/reporters.py +0 -0
  15. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/result.py +0 -0
  16. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/tools.py +0 -0
  17. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/__init__.py +0 -0
  18. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/device.py +0 -0
  19. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/root.py +0 -0
  20. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/testing.py +0 -0
  21. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/__init__.py +0 -0
  22. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/build.py +0 -0
  23. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/dependabot.py +0 -0
  24. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/yamler.py +0 -0
  25. {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexcodexpy
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: The Non-Destructive Configuration Steward for Python Projects.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import subprocess
4
- from collections.abc import Iterable, Iterator, MutableSequence
4
+ from collections.abc import Callable, Iterable, Iterator, MutableSequence
5
5
  from dataclasses import dataclass, field, replace
6
6
  from typing import Any, Protocol
7
7
 
@@ -85,12 +85,21 @@ class Executable(Protocol):
85
85
  pass
86
86
 
87
87
 
88
+ @dataclass(frozen=True)
89
+ class LazyExecutable:
90
+ inner: Callable[[], TaskResult]
91
+
92
+ def execute(self) -> TaskResult:
93
+ return self.inner()
94
+
95
+
88
96
  @dataclass(frozen=True)
89
97
  class MultiProgram:
90
98
  sub_programs: MutableSequence[Executable] = field(default_factory=list)
91
99
 
92
- def attach(self, program: Executable) -> MultiProgram:
93
- self.sub_programs.append(program)
100
+ def attach(self, program: Executable, when: bool = True) -> MultiProgram:
101
+ if when:
102
+ self.sub_programs.append(program)
94
103
 
95
104
  return self
96
105
 
@@ -136,7 +136,10 @@ class CodexTools:
136
136
  .attach(PyProjectToml().sync(self.target))
137
137
  .attach(DependabotWorkflow().sync(self.target, force=force))
138
138
  .attach(CheckCodeWorkflow().sync(self.target, force=force))
139
- .attach(BuildCodeWorkflow(disclaimer=False).sync(self.target, force=force))
139
+ .attach(
140
+ BuildCodeWorkflow(disclaimer=False).sync(self.target, force=force),
141
+ when=self.target.joinpath("Dockerfile").exists(),
142
+ )
140
143
  )
141
144
 
142
145
  def lock(self) -> Executable:
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from dataclasses import dataclass
5
+ from datetime import UTC, datetime
6
+ from pathlib import Path
7
+
8
+ from codex.infra.program import Executable, LazyExecutable
9
+ from codex.infra.result import ProgramResult
10
+ from codex.infra.tools import Version
11
+ from codex.infra.yamler import Yamler
12
+
13
+
14
+ @dataclass(frozen=True, kw_only=True)
15
+ class YamlWorkflow(ABC):
16
+ name: str
17
+ path: Path
18
+
19
+ disclaimer: bool = True
20
+
21
+ @property
22
+ @abstractmethod
23
+ def standards(self) -> Yamler:
24
+ pass
25
+
26
+ def sync(self, target: Path, force: bool = False) -> Executable:
27
+ def _() -> ProgramResult:
28
+ path = target / self.path
29
+ path.parent.mkdir(parents=True, exist_ok=True)
30
+ path.touch(exist_ok=True)
31
+
32
+ standards = self.standards
33
+ if not force and Yamler.read(path) == standards:
34
+ return ProgramResult(name=self.name).no_changes()
35
+
36
+ if self.disclaimer:
37
+ standards = standards.comment(
38
+ "Auto Generated",
39
+ f"By: Apex Codex {Version()}",
40
+ f"At: {self._utcnow()}",
41
+ "Do not edit this file manually!\n\n",
42
+ )
43
+
44
+ standards.dump_to(path)
45
+
46
+ return self.success()
47
+
48
+ return LazyExecutable(_)
49
+
50
+ def _utcnow(self) -> str:
51
+ return datetime.now(tz=UTC).replace(microsecond=0).isoformat(sep=" ")
52
+
53
+ def success(self) -> ProgramResult:
54
+ return ProgramResult(name=self.name).success(
55
+ message=f"{self.name} workflow succeeded.\n"
56
+ )
@@ -33,12 +33,19 @@ class CiWorkflow:
33
33
  class CiJob:
34
34
  name: str
35
35
 
36
- is_enabled: bool = True
37
36
  platform: str = "ubuntu-latest"
38
- steps: MutableSequence[Yamler] = field(default_factory=list)
37
+ is_enabled: bool = True
38
+
39
+ _steps: MutableSequence[Yamler] = field(default_factory=list)
40
+ _needs: MutableSequence[str] = field(default_factory=list)
41
+
42
+ def needs(self, *names: str) -> CiJob:
43
+ self._needs.extend(names)
44
+
45
+ return self
39
46
 
40
47
  def with_step(self, step: Yamler) -> CiJob:
41
- self.steps.append(step)
48
+ self._steps.append(step)
42
49
 
43
50
  return self
44
51
 
@@ -52,6 +59,7 @@ class CiJob:
52
59
  return Yamler.parse(
53
60
  {
54
61
  "runs-on": self.platform,
55
- "steps": [step.as_mapping() for step in self.steps],
62
+ **({"needs": self._needs} if self._needs else {}),
63
+ "steps": [step.as_mapping() for step in self._steps],
56
64
  }
57
65
  )
@@ -49,6 +49,7 @@ class CheckCodeWorkflow(YamlWorkflow):
49
49
  )
50
50
  .with_job(
51
51
  CiJob(name="test-unit")
52
+ .needs("lint")
52
53
  .with_step(self.CHECKOUT)
53
54
  .with_step(self.SETUP)
54
55
  .run(
@@ -59,6 +60,7 @@ class CheckCodeWorkflow(YamlWorkflow):
59
60
  )
60
61
  .with_job(
61
62
  CiJob(name="test-integration")
63
+ .needs("lint", "test-unit")
62
64
  .with_step(self.CHECKOUT)
63
65
  .with_step(self.SETUP)
64
66
  .run(
@@ -69,6 +71,7 @@ class CheckCodeWorkflow(YamlWorkflow):
69
71
  )
70
72
  .with_job(
71
73
  CiJob(name="test-behaviour")
74
+ .needs("lint", "test-unit")
72
75
  .with_step(self.CHECKOUT)
73
76
  .with_step(self.SETUP)
74
77
  .run(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexcodexpy"
3
- version = "0.6.2"
3
+ version = "0.6.4"
4
4
  description = "The Non-Destructive Configuration Steward for Python Projects."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,53 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from abc import ABC, abstractmethod
4
- from dataclasses import dataclass
5
- from datetime import UTC, datetime
6
- from pathlib import Path
7
-
8
- from codex.infra.program import Executable
9
- from codex.infra.result import ProgramResult
10
- from codex.infra.tools import Version
11
- from codex.infra.yamler import Yamler
12
-
13
-
14
- @dataclass(frozen=True, kw_only=True)
15
- class YamlWorkflow(ABC):
16
- name: str
17
- path: Path
18
-
19
- disclaimer: bool = True
20
-
21
- @property
22
- @abstractmethod
23
- def standards(self) -> Yamler:
24
- pass
25
-
26
- def sync(self, target: Path, force: bool = False) -> Executable:
27
- path = target / self.path
28
- path.parent.mkdir(parents=True, exist_ok=True)
29
- path.touch(exist_ok=True)
30
-
31
- standards = self.standards
32
- if not force and Yamler.read(path) == standards:
33
- return ProgramResult(name=self.name).no_changes()
34
-
35
- if self.disclaimer:
36
- standards = standards.comment(
37
- "Auto Generated",
38
- f"By: Apex Codex {Version()}",
39
- f"At: {self._utcnow()}",
40
- "Do not edit this file manually!\n\n",
41
- )
42
-
43
- standards.dump_to(path)
44
-
45
- return self.success()
46
-
47
- def _utcnow(self) -> str:
48
- return datetime.now(tz=UTC).replace(microsecond=0).isoformat(sep=" ")
49
-
50
- def success(self) -> ProgramResult:
51
- return ProgramResult(name=self.name).success(
52
- message=f"{self.name} workflow succeeded.\n"
53
- )
File without changes
File without changes
File without changes