omdev 0.0.0.dev212__py3-none-any.whl → 0.0.0.dev214__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.
- omdev/.manifests.json +1 -1
- omdev/cc/cdeps.py +34 -1
- omdev/cc/cdeps.toml +19 -2
- omdev/cc/cli.py +13 -1
- omdev/ci/__init__.py +1 -0
- omdev/ci/cache.py +100 -121
- omdev/ci/ci.py +161 -136
- omdev/ci/cli.py +62 -30
- omdev/ci/compose.py +26 -62
- omdev/ci/consts.py +1 -0
- omdev/ci/docker.py +39 -22
- omdev/ci/github/{cacheapi.py → api.py} +1 -2
- omdev/ci/github/bootstrap.py +8 -1
- omdev/ci/github/cache.py +36 -320
- omdev/ci/github/cli.py +9 -5
- omdev/ci/github/client.py +492 -0
- omdev/ci/github/env.py +21 -0
- omdev/ci/requirements.py +0 -1
- omdev/ci/shell.py +0 -1
- omdev/ci/utils.py +2 -14
- omdev/git/shallow.py +1 -1
- omdev/scripts/ci.py +1602 -887
- omdev/scripts/interp.py +23 -0
- omdev/scripts/pyproject.py +23 -0
- omdev/tokens/tokenizert.py +1 -3
- omdev/tools/docker.py +6 -0
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/RECORD +32 -29
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev212.dist-info → omdev-0.0.0.dev214.dist-info}/top_level.txt +0 -0
omdev/ci/compose.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
# @omlish-lite
|
3
2
|
"""
|
4
3
|
TODO:
|
5
4
|
- fix rmi - only when not referenced anymore
|
@@ -11,15 +10,16 @@ import os.path
|
|
11
10
|
import shlex
|
12
11
|
import typing as ta
|
13
12
|
|
13
|
+
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
14
14
|
from omlish.lite.cached import cached_nullary
|
15
15
|
from omlish.lite.check import check
|
16
|
-
from omlish.lite.contextmanagers import
|
16
|
+
from omlish.lite.contextmanagers import AsyncExitStacked
|
17
|
+
from omlish.lite.contextmanagers import adefer
|
17
18
|
from omlish.lite.contextmanagers import defer
|
18
19
|
from omlish.lite.json import json_dumps_pretty
|
19
|
-
from omlish.
|
20
|
+
from omlish.os.temp import make_temp_file
|
20
21
|
|
21
22
|
from .shell import ShellCmd
|
22
|
-
from .utils import make_temp_file
|
23
23
|
from .utils import read_yaml_file
|
24
24
|
|
25
25
|
|
@@ -46,7 +46,7 @@ def get_compose_service_dependencies(
|
|
46
46
|
##
|
47
47
|
|
48
48
|
|
49
|
-
class DockerComposeRun(
|
49
|
+
class DockerComposeRun(AsyncExitStacked):
|
50
50
|
@dc.dataclass(frozen=True)
|
51
51
|
class Config:
|
52
52
|
compose_file: str
|
@@ -64,6 +64,7 @@ class DockerComposeRun(ExitStacked):
|
|
64
64
|
|
65
65
|
#
|
66
66
|
|
67
|
+
no_dependencies: bool = False
|
67
68
|
no_dependency_cleanup: bool = False
|
68
69
|
|
69
70
|
#
|
@@ -82,40 +83,6 @@ class DockerComposeRun(ExitStacked):
|
|
82
83
|
|
83
84
|
#
|
84
85
|
|
85
|
-
@property
|
86
|
-
def image_tag(self) -> str:
|
87
|
-
pfx = 'sha256:'
|
88
|
-
if (image := self._cfg.image).startswith(pfx):
|
89
|
-
image = image[len(pfx):]
|
90
|
-
|
91
|
-
return f'{self._cfg.service}:{image}'
|
92
|
-
|
93
|
-
@cached_nullary
|
94
|
-
def tag_image(self) -> str:
|
95
|
-
image_tag = self.image_tag
|
96
|
-
|
97
|
-
subprocesses.check_call(
|
98
|
-
'docker',
|
99
|
-
'tag',
|
100
|
-
self._cfg.image,
|
101
|
-
image_tag,
|
102
|
-
**self._subprocess_kwargs,
|
103
|
-
)
|
104
|
-
|
105
|
-
def delete_tag() -> None:
|
106
|
-
subprocesses.check_call(
|
107
|
-
'docker',
|
108
|
-
'rmi',
|
109
|
-
image_tag,
|
110
|
-
**self._subprocess_kwargs,
|
111
|
-
)
|
112
|
-
|
113
|
-
self._enter_context(defer(delete_tag)) # noqa
|
114
|
-
|
115
|
-
return image_tag
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
86
|
def _rewrite_compose_dct(self, in_dct: ta.Dict[str, ta.Any]) -> ta.Dict[str, ta.Any]:
|
120
87
|
out = dict(in_dct)
|
121
88
|
|
@@ -129,29 +96,28 @@ class DockerComposeRun(ExitStacked):
|
|
129
96
|
in_service: dict = in_services[self._cfg.service]
|
130
97
|
out_services[self._cfg.service] = out_service = dict(in_service)
|
131
98
|
|
132
|
-
out_service['image'] = self.
|
99
|
+
out_service['image'] = self._cfg.image
|
133
100
|
|
134
101
|
for k in ['build', 'platform']:
|
135
102
|
if k in out_service:
|
136
103
|
del out_service[k]
|
137
104
|
|
138
|
-
out_service['links'] = [
|
139
|
-
f'{l}:{l}' if ':' not in l else l
|
140
|
-
for l in out_service.get('links', [])
|
141
|
-
]
|
142
|
-
|
143
105
|
#
|
144
106
|
|
145
|
-
|
107
|
+
if not self._cfg.no_dependencies:
|
108
|
+
depends_on = in_service.get('depends_on', [])
|
146
109
|
|
147
|
-
|
148
|
-
|
149
|
-
|
110
|
+
for dep_service, in_dep_service_dct in list(in_services.items()):
|
111
|
+
if dep_service not in depends_on:
|
112
|
+
continue
|
150
113
|
|
151
|
-
|
152
|
-
|
114
|
+
out_dep_service: dict = dict(in_dep_service_dct)
|
115
|
+
out_services[dep_service] = out_dep_service
|
153
116
|
|
154
|
-
|
117
|
+
out_dep_service['ports'] = []
|
118
|
+
|
119
|
+
else:
|
120
|
+
out_service['depends_on'] = []
|
155
121
|
|
156
122
|
#
|
157
123
|
|
@@ -177,22 +143,20 @@ class DockerComposeRun(ExitStacked):
|
|
177
143
|
|
178
144
|
#
|
179
145
|
|
180
|
-
def _cleanup_dependencies(self) -> None:
|
181
|
-
|
146
|
+
async def _cleanup_dependencies(self) -> None:
|
147
|
+
await asyncio_subprocesses.check_call(
|
182
148
|
'docker',
|
183
149
|
'compose',
|
184
150
|
'-f', self.rewrite_compose_file(),
|
185
151
|
'down',
|
186
152
|
)
|
187
153
|
|
188
|
-
def run(self) -> None:
|
189
|
-
self.tag_image()
|
190
|
-
|
154
|
+
async def run(self) -> None:
|
191
155
|
compose_file = self.rewrite_compose_file()
|
192
156
|
|
193
|
-
with contextlib.
|
194
|
-
if not self._cfg.no_dependency_cleanup:
|
195
|
-
es.
|
157
|
+
async with contextlib.AsyncExitStack() as es:
|
158
|
+
if not (self._cfg.no_dependencies or self._cfg.no_dependency_cleanup):
|
159
|
+
await es.enter_async_context(adefer(self._cleanup_dependencies)) # noqa
|
196
160
|
|
197
161
|
sh_cmd = ' '.join([
|
198
162
|
'docker',
|
@@ -211,7 +175,7 @@ class DockerComposeRun(ExitStacked):
|
|
211
175
|
|
212
176
|
run_cmd = dc.replace(self._cfg.cmd, s=sh_cmd)
|
213
177
|
|
214
|
-
run_cmd.run(
|
215
|
-
|
178
|
+
await run_cmd.run(
|
179
|
+
asyncio_subprocesses.check_call,
|
216
180
|
**self._subprocess_kwargs,
|
217
181
|
)
|
omdev/ci/consts.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
CI_CACHE_VERSION = 1
|
omdev/ci/docker.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
# @omlish-lite
|
3
2
|
"""
|
4
3
|
TODO:
|
5
4
|
- some less stupid Dockerfile hash
|
@@ -13,12 +12,11 @@ import shlex
|
|
13
12
|
import tarfile
|
14
13
|
import typing as ta
|
15
14
|
|
15
|
+
from omlish.asyncs.asyncio.subprocesses import asyncio_subprocesses
|
16
16
|
from omlish.lite.check import check
|
17
|
-
from omlish.
|
18
|
-
from omlish.subprocesses import subprocesses
|
17
|
+
from omlish.os.temp import temp_file_context
|
19
18
|
|
20
19
|
from .shell import ShellCmd
|
21
|
-
from .utils import make_temp_file
|
22
20
|
from .utils import sha256_str
|
23
21
|
|
24
22
|
|
@@ -60,8 +58,8 @@ def read_docker_tar_image_id(tar_file: str) -> str:
|
|
60
58
|
##
|
61
59
|
|
62
60
|
|
63
|
-
def is_docker_image_present(image: str) -> bool:
|
64
|
-
out =
|
61
|
+
async def is_docker_image_present(image: str) -> bool:
|
62
|
+
out = await asyncio_subprocesses.check_output(
|
65
63
|
'docker',
|
66
64
|
'images',
|
67
65
|
'--format', 'json',
|
@@ -76,55 +74,74 @@ def is_docker_image_present(image: str) -> bool:
|
|
76
74
|
return True
|
77
75
|
|
78
76
|
|
79
|
-
def pull_docker_image(
|
77
|
+
async def pull_docker_image(
|
80
78
|
image: str,
|
81
79
|
) -> None:
|
82
|
-
|
80
|
+
await asyncio_subprocesses.check_call(
|
83
81
|
'docker',
|
84
82
|
'pull',
|
85
83
|
image,
|
86
84
|
)
|
87
85
|
|
88
86
|
|
89
|
-
def build_docker_image(
|
87
|
+
async def build_docker_image(
|
90
88
|
docker_file: str,
|
91
89
|
*,
|
90
|
+
tag: ta.Optional[str] = None,
|
92
91
|
cwd: ta.Optional[str] = None,
|
92
|
+
run_options: ta.Optional[ta.Sequence[str]] = None,
|
93
93
|
) -> str:
|
94
|
-
|
95
|
-
|
96
|
-
subprocesses.check_call(
|
94
|
+
with temp_file_context() as id_file:
|
95
|
+
await asyncio_subprocesses.check_call(
|
97
96
|
'docker',
|
98
97
|
'build',
|
99
98
|
'-f', os.path.abspath(docker_file),
|
100
99
|
'--iidfile', id_file,
|
101
|
-
'--
|
100
|
+
*(['--tag', tag] if tag is not None else []),
|
101
|
+
*(run_options or []),
|
102
102
|
'.',
|
103
103
|
**(dict(cwd=cwd) if cwd is not None else {}),
|
104
104
|
)
|
105
105
|
|
106
|
-
with open(id_file) as f:
|
106
|
+
with open(id_file) as f: # noqa
|
107
107
|
image_id = check.single(f.read().strip().splitlines()).strip()
|
108
108
|
|
109
109
|
return image_id
|
110
110
|
|
111
111
|
|
112
|
+
async def tag_docker_image(image: str, tag: str) -> None:
|
113
|
+
await asyncio_subprocesses.check_call(
|
114
|
+
'docker',
|
115
|
+
'tag',
|
116
|
+
image,
|
117
|
+
tag,
|
118
|
+
)
|
119
|
+
|
120
|
+
|
121
|
+
async def delete_docker_tag(tag: str) -> None:
|
122
|
+
await asyncio_subprocesses.check_call(
|
123
|
+
'docker',
|
124
|
+
'rmi',
|
125
|
+
tag,
|
126
|
+
)
|
127
|
+
|
128
|
+
|
112
129
|
##
|
113
130
|
|
114
131
|
|
115
|
-
def save_docker_tar_cmd(
|
132
|
+
async def save_docker_tar_cmd(
|
116
133
|
image: str,
|
117
134
|
output_cmd: ShellCmd,
|
118
135
|
) -> None:
|
119
136
|
cmd = dc.replace(output_cmd, s=f'docker save {image} | {output_cmd.s}')
|
120
|
-
cmd.run(
|
137
|
+
await cmd.run(asyncio_subprocesses.check_call)
|
121
138
|
|
122
139
|
|
123
|
-
def save_docker_tar(
|
140
|
+
async def save_docker_tar(
|
124
141
|
image: str,
|
125
142
|
tar_file: str,
|
126
143
|
) -> None:
|
127
|
-
return save_docker_tar_cmd(
|
144
|
+
return await save_docker_tar_cmd(
|
128
145
|
image,
|
129
146
|
ShellCmd(f'cat > {shlex.quote(tar_file)}'),
|
130
147
|
)
|
@@ -133,19 +150,19 @@ def save_docker_tar(
|
|
133
150
|
#
|
134
151
|
|
135
152
|
|
136
|
-
def load_docker_tar_cmd(
|
153
|
+
async def load_docker_tar_cmd(
|
137
154
|
input_cmd: ShellCmd,
|
138
155
|
) -> str:
|
139
156
|
cmd = dc.replace(input_cmd, s=f'{input_cmd.s} | docker load')
|
140
157
|
|
141
|
-
out = cmd.run(
|
158
|
+
out = (await cmd.run(asyncio_subprocesses.check_output)).decode()
|
142
159
|
|
143
160
|
line = check.single(out.strip().splitlines())
|
144
161
|
loaded = line.partition(':')[2].strip()
|
145
162
|
return loaded
|
146
163
|
|
147
164
|
|
148
|
-
def load_docker_tar(
|
165
|
+
async def load_docker_tar(
|
149
166
|
tar_file: str,
|
150
167
|
) -> str:
|
151
|
-
return load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
|
168
|
+
return await load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
# @omlish-lite
|
3
2
|
"""
|
4
3
|
export FILE_SIZE=$(stat --format="%s" $FILE)
|
5
4
|
|
@@ -93,7 +92,7 @@ class GithubCacheServiceV1:
|
|
93
92
|
@dc.dataclass(frozen=True)
|
94
93
|
class ReserveCacheRequest:
|
95
94
|
key: str
|
96
|
-
cache_size: ta.Optional[int]
|
95
|
+
cache_size: ta.Optional[int] = None
|
97
96
|
version: ta.Optional[str] = None
|
98
97
|
|
99
98
|
@dc.dataclass(frozen=True)
|
omdev/ci/github/bootstrap.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
# @omlish-lite
|
3
2
|
"""
|
4
3
|
sudo rm -rf \
|
5
4
|
/usr/local/.ghcup \
|
@@ -9,3 +8,11 @@ sudo rm -rf \
|
|
9
8
|
/opt/hostedtoolcache 8.0G, 14843980 files
|
10
9
|
/usr/local/lib/android 6.4G, 17251667 files
|
11
10
|
"""
|
11
|
+
from .env import register_github_env_var
|
12
|
+
|
13
|
+
|
14
|
+
GITHUB_ACTIONS_ENV_VAR = register_github_env_var('GITHUB_ACTIONS')
|
15
|
+
|
16
|
+
|
17
|
+
def is_in_github_actions() -> bool:
|
18
|
+
return GITHUB_ACTIONS_ENV_VAR() is not None
|