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.
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/PKG-INFO +1 -1
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/program.py +12 -3
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/service.py +4 -1
- apexcodexpy-0.6.4/codex/infra/workflows/base.py +56 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/ci.py +12 -4
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/validate.py +3 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/pyproject.toml +1 -1
- apexcodexpy-0.6.2/codex/infra/workflows/base.py +0 -53
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/LICENSE +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/README.md +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/__init__.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/__init__.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/pyproject.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/reporters.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/result.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/tools.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/__init__.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/device.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/root.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/typer/testing.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/__init__.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/build.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/workflows/dependabot.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/infra/yamler.py +0 -0
- {apexcodexpy-0.6.2 → apexcodexpy-0.6.4}/codex/runner.py +0 -0
|
@@ -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
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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
|
-
"
|
|
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,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
|
|
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
|