omdev 0.0.0.dev224__py3-none-any.whl → 0.0.0.dev225__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/amalg/typing.py +7 -1
- omdev/ci/requirements.py +1 -1
- omdev/git/revisions.py +2 -2
- omdev/git/shallow.py +1 -1
- omdev/git/status.py +1 -1
- omdev/precheck/lite.py +1 -1
- omdev/pyproject/pkg.py +1 -1
- omdev/scripts/ci.py +324 -271
- omdev/scripts/interp.py +230 -318
- omdev/scripts/pyproject.py +349 -296
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/RECORD +16 -16
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev225.dist-info}/top_level.txt +0 -0
omdev/scripts/ci.py
CHANGED
@@ -89,7 +89,7 @@ InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
89
89
|
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
90
90
|
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
91
91
|
|
92
|
-
# ../../omlish/subprocesses.py
|
92
|
+
# ../../omlish/subprocesses/base.py
|
93
93
|
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
|
94
94
|
|
95
95
|
|
@@ -3123,6 +3123,98 @@ def temp_named_file_context(
|
|
3123
3123
|
shutil.rmtree(f.name, ignore_errors=True)
|
3124
3124
|
|
3125
3125
|
|
3126
|
+
########################################
|
3127
|
+
# ../../../omlish/subprocesses/run.py
|
3128
|
+
|
3129
|
+
|
3130
|
+
##
|
3131
|
+
|
3132
|
+
|
3133
|
+
@dc.dataclass(frozen=True)
|
3134
|
+
class SubprocessRunOutput(ta.Generic[T]):
|
3135
|
+
proc: T
|
3136
|
+
|
3137
|
+
returncode: int # noqa
|
3138
|
+
|
3139
|
+
stdout: ta.Optional[bytes] = None
|
3140
|
+
stderr: ta.Optional[bytes] = None
|
3141
|
+
|
3142
|
+
|
3143
|
+
##
|
3144
|
+
|
3145
|
+
|
3146
|
+
@dc.dataclass(frozen=True)
|
3147
|
+
class SubprocessRun:
|
3148
|
+
cmd: ta.Sequence[str]
|
3149
|
+
input: ta.Any = None
|
3150
|
+
timeout: ta.Optional[float] = None
|
3151
|
+
check: bool = False
|
3152
|
+
capture_output: ta.Optional[bool] = None
|
3153
|
+
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
3154
|
+
|
3155
|
+
@classmethod
|
3156
|
+
def of(
|
3157
|
+
cls,
|
3158
|
+
*cmd: str,
|
3159
|
+
input: ta.Any = None, # noqa
|
3160
|
+
timeout: ta.Optional[float] = None,
|
3161
|
+
check: bool = False, # noqa
|
3162
|
+
capture_output: ta.Optional[bool] = None,
|
3163
|
+
**kwargs: ta.Any,
|
3164
|
+
) -> 'SubprocessRun':
|
3165
|
+
return cls(
|
3166
|
+
cmd=cmd,
|
3167
|
+
input=input,
|
3168
|
+
timeout=timeout,
|
3169
|
+
check=check,
|
3170
|
+
capture_output=capture_output,
|
3171
|
+
kwargs=kwargs,
|
3172
|
+
)
|
3173
|
+
|
3174
|
+
#
|
3175
|
+
|
3176
|
+
_DEFAULT_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractSubprocesses
|
3177
|
+
|
3178
|
+
def run(
|
3179
|
+
self,
|
3180
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
3181
|
+
) -> SubprocessRunOutput:
|
3182
|
+
if subprocesses is None:
|
3183
|
+
subprocesses = self._DEFAULT_SUBPROCESSES
|
3184
|
+
return check.not_none(subprocesses).run_(self) # type: ignore[attr-defined]
|
3185
|
+
|
3186
|
+
_DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
|
3187
|
+
|
3188
|
+
async def async_run(
|
3189
|
+
self,
|
3190
|
+
async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
|
3191
|
+
) -> SubprocessRunOutput:
|
3192
|
+
if async_subprocesses is None:
|
3193
|
+
async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
|
3194
|
+
return await check.not_none(async_subprocesses).run_(self) # type: ignore[attr-defined]
|
3195
|
+
|
3196
|
+
|
3197
|
+
##
|
3198
|
+
|
3199
|
+
|
3200
|
+
class SubprocessRunnable(abc.ABC, ta.Generic[T]):
|
3201
|
+
@abc.abstractmethod
|
3202
|
+
def make_run(self) -> SubprocessRun:
|
3203
|
+
raise NotImplementedError
|
3204
|
+
|
3205
|
+
@abc.abstractmethod
|
3206
|
+
def handle_run_output(self, output: SubprocessRunOutput) -> T:
|
3207
|
+
raise NotImplementedError
|
3208
|
+
|
3209
|
+
#
|
3210
|
+
|
3211
|
+
def run(self, subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractSubprocesses
|
3212
|
+
return self.handle_run_output(self.make_run().run(subprocesses))
|
3213
|
+
|
3214
|
+
async def async_run(self, async_subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractAsyncSubprocesses
|
3215
|
+
return self.handle_run_output(await self.make_run().async_run(async_subprocesses))
|
3216
|
+
|
3217
|
+
|
3126
3218
|
########################################
|
3127
3219
|
# ../cache.py
|
3128
3220
|
|
@@ -3989,23 +4081,7 @@ def configure_standard_logging(
|
|
3989
4081
|
|
3990
4082
|
|
3991
4083
|
########################################
|
3992
|
-
# ../../../omlish/subprocesses.py
|
3993
|
-
|
3994
|
-
|
3995
|
-
##
|
3996
|
-
|
3997
|
-
|
3998
|
-
# Valid channel type kwarg values:
|
3999
|
-
# - A special flag negative int
|
4000
|
-
# - A positive fd int
|
4001
|
-
# - A file-like object
|
4002
|
-
# - None
|
4003
|
-
|
4004
|
-
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
4005
|
-
'pipe': subprocess.PIPE,
|
4006
|
-
'stdout': subprocess.STDOUT,
|
4007
|
-
'devnull': subprocess.DEVNULL,
|
4008
|
-
}
|
4084
|
+
# ../../../omlish/subprocesses/wrap.py
|
4009
4085
|
|
4010
4086
|
|
4011
4087
|
##
|
@@ -4025,22 +4101,143 @@ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
|
|
4025
4101
|
return cmd
|
4026
4102
|
|
4027
4103
|
|
4104
|
+
########################################
|
4105
|
+
# ../github/cache.py
|
4106
|
+
|
4107
|
+
|
4028
4108
|
##
|
4029
4109
|
|
4030
4110
|
|
4031
|
-
|
4032
|
-
|
4033
|
-
|
4034
|
-
|
4035
|
-
|
4036
|
-
|
4037
|
-
|
4038
|
-
|
4039
|
-
|
4040
|
-
|
4041
|
-
|
4111
|
+
class GithubCache(FileCache, DataCache):
|
4112
|
+
@dc.dataclass(frozen=True)
|
4113
|
+
class Config:
|
4114
|
+
dir: str
|
4115
|
+
|
4116
|
+
def __init__(
|
4117
|
+
self,
|
4118
|
+
config: Config,
|
4119
|
+
*,
|
4120
|
+
client: ta.Optional[GithubCacheClient] = None,
|
4121
|
+
version: ta.Optional[CacheVersion] = None,
|
4122
|
+
) -> None:
|
4123
|
+
super().__init__(
|
4124
|
+
version=version,
|
4125
|
+
)
|
4126
|
+
|
4127
|
+
self._config = config
|
4128
|
+
|
4129
|
+
if client is None:
|
4130
|
+
client = GithubCacheServiceV1Client(
|
4131
|
+
cache_version=self._version,
|
4132
|
+
)
|
4133
|
+
self._client: GithubCacheClient = client
|
4134
|
+
|
4135
|
+
self._local = DirectoryFileCache(
|
4136
|
+
DirectoryFileCache.Config(
|
4137
|
+
dir=check.non_empty_str(config.dir),
|
4138
|
+
),
|
4139
|
+
version=self._version,
|
4140
|
+
)
|
4141
|
+
|
4142
|
+
#
|
4143
|
+
|
4144
|
+
async def get_file(self, key: str) -> ta.Optional[str]:
|
4145
|
+
local_file = self._local.get_cache_file_path(key)
|
4146
|
+
if os.path.exists(local_file):
|
4147
|
+
return local_file
|
4148
|
+
|
4149
|
+
if (entry := await self._client.get_entry(key)) is None:
|
4150
|
+
return None
|
4151
|
+
|
4152
|
+
tmp_file = self._local.format_incomplete_file(local_file)
|
4153
|
+
with unlinking_if_exists(tmp_file):
|
4154
|
+
await self._client.download_file(entry, tmp_file)
|
4155
|
+
|
4156
|
+
os.replace(tmp_file, local_file)
|
4157
|
+
|
4158
|
+
return local_file
|
4159
|
+
|
4160
|
+
async def put_file(
|
4161
|
+
self,
|
4162
|
+
key: str,
|
4163
|
+
file_path: str,
|
4164
|
+
*,
|
4165
|
+
steal: bool = False,
|
4166
|
+
) -> str:
|
4167
|
+
cache_file_path = await self._local.put_file(
|
4168
|
+
key,
|
4169
|
+
file_path,
|
4170
|
+
steal=steal,
|
4171
|
+
)
|
4172
|
+
|
4173
|
+
await self._client.upload_file(key, cache_file_path)
|
4174
|
+
|
4175
|
+
return cache_file_path
|
4176
|
+
|
4177
|
+
#
|
4178
|
+
|
4179
|
+
async def get_data(self, key: str) -> ta.Optional[DataCache.Data]:
|
4180
|
+
local_file = self._local.get_cache_file_path(key)
|
4181
|
+
if os.path.exists(local_file):
|
4182
|
+
return DataCache.FileData(local_file)
|
4183
|
+
|
4184
|
+
if (entry := await self._client.get_entry(key)) is None:
|
4185
|
+
return None
|
4186
|
+
|
4187
|
+
return DataCache.UrlData(check.non_empty_str(self._client.get_entry_url(entry)))
|
4188
|
+
|
4189
|
+
async def put_data(self, key: str, data: DataCache.Data) -> None:
|
4190
|
+
await FileCacheDataCache(self).put_data(key, data)
|
4191
|
+
|
4192
|
+
|
4193
|
+
########################################
|
4194
|
+
# ../github/cli.py
|
4195
|
+
"""
|
4196
|
+
See:
|
4197
|
+
- https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28
|
4198
|
+
"""
|
4199
|
+
|
4200
|
+
|
4201
|
+
class GithubCli(ArgparseCli):
|
4202
|
+
@argparse_cmd()
|
4203
|
+
def list_referenced_env_vars(self) -> None:
|
4204
|
+
print('\n'.join(sorted(ev.k for ev in GITHUB_ENV_VARS)))
|
4205
|
+
|
4206
|
+
@argparse_cmd(
|
4207
|
+
argparse_arg('key'),
|
4208
|
+
)
|
4209
|
+
async def get_cache_entry(self) -> None:
|
4210
|
+
client = GithubCacheServiceV1Client()
|
4211
|
+
entry = await client.get_entry(self.args.key)
|
4212
|
+
if entry is None:
|
4213
|
+
return
|
4214
|
+
print(json_dumps_pretty(dc.asdict(entry))) # noqa
|
4215
|
+
|
4216
|
+
@argparse_cmd(
|
4217
|
+
argparse_arg('repository-id'),
|
4218
|
+
)
|
4219
|
+
def list_cache_entries(self) -> None:
|
4220
|
+
raise NotImplementedError
|
4221
|
+
|
4222
|
+
|
4223
|
+
########################################
|
4224
|
+
# ../../../omlish/subprocesses/base.py
|
4225
|
+
|
4042
4226
|
|
4043
|
-
|
4227
|
+
##
|
4228
|
+
|
4229
|
+
|
4230
|
+
# Valid channel type kwarg values:
|
4231
|
+
# - A special flag negative int
|
4232
|
+
# - A positive fd int
|
4233
|
+
# - A file-like object
|
4234
|
+
# - None
|
4235
|
+
|
4236
|
+
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
4237
|
+
'pipe': subprocess.PIPE,
|
4238
|
+
'stdout': subprocess.STDOUT,
|
4239
|
+
'devnull': subprocess.DEVNULL,
|
4240
|
+
}
|
4044
4241
|
|
4045
4242
|
|
4046
4243
|
##
|
@@ -4227,51 +4424,41 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
4227
4424
|
return e
|
4228
4425
|
|
4229
4426
|
|
4230
|
-
|
4231
|
-
|
4427
|
+
########################################
|
4428
|
+
# ../github/inject.py
|
4232
4429
|
|
4233
|
-
@dc.dataclass(frozen=True)
|
4234
|
-
class SubprocessRun:
|
4235
|
-
cmd: ta.Sequence[str]
|
4236
|
-
input: ta.Any = None
|
4237
|
-
timeout: ta.Optional[float] = None
|
4238
|
-
check: bool = False
|
4239
|
-
capture_output: ta.Optional[bool] = None
|
4240
|
-
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
4241
4430
|
|
4242
|
-
|
4243
|
-
def of(
|
4244
|
-
cls,
|
4245
|
-
*cmd: str,
|
4246
|
-
input: ta.Any = None, # noqa
|
4247
|
-
timeout: ta.Optional[float] = None,
|
4248
|
-
check: bool = False,
|
4249
|
-
capture_output: ta.Optional[bool] = None,
|
4250
|
-
**kwargs: ta.Any,
|
4251
|
-
) -> 'SubprocessRun':
|
4252
|
-
return cls(
|
4253
|
-
cmd=cmd,
|
4254
|
-
input=input,
|
4255
|
-
timeout=timeout,
|
4256
|
-
check=check,
|
4257
|
-
capture_output=capture_output,
|
4258
|
-
kwargs=kwargs,
|
4259
|
-
)
|
4431
|
+
##
|
4260
4432
|
|
4261
4433
|
|
4262
|
-
|
4263
|
-
|
4264
|
-
|
4434
|
+
def bind_github(
|
4435
|
+
*,
|
4436
|
+
cache_dir: ta.Optional[str] = None,
|
4437
|
+
) -> InjectorBindings:
|
4438
|
+
lst: ta.List[InjectorBindingOrBindings] = []
|
4265
4439
|
|
4266
|
-
|
4440
|
+
if cache_dir is not None:
|
4441
|
+
lst.extend([
|
4442
|
+
inj.bind(GithubCache.Config(
|
4443
|
+
dir=cache_dir,
|
4444
|
+
)),
|
4445
|
+
inj.bind(GithubCache, singleton=True),
|
4446
|
+
inj.bind(FileCache, to_key=GithubCache),
|
4447
|
+
])
|
4267
4448
|
|
4268
|
-
|
4269
|
-
stderr: ta.Optional[bytes] = None
|
4449
|
+
return inj.as_bindings(*lst)
|
4270
4450
|
|
4271
4451
|
|
4272
|
-
|
4452
|
+
########################################
|
4453
|
+
# ../../../omlish/subprocesses/async_.py
|
4454
|
+
|
4455
|
+
|
4456
|
+
##
|
4457
|
+
|
4458
|
+
|
4459
|
+
class AbstractAsyncSubprocesses(BaseSubprocesses):
|
4273
4460
|
@abc.abstractmethod
|
4274
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4461
|
+
async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4275
4462
|
raise NotImplementedError
|
4276
4463
|
|
4277
4464
|
def run(
|
@@ -4282,7 +4469,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4282
4469
|
check: bool = False,
|
4283
4470
|
capture_output: ta.Optional[bool] = None,
|
4284
4471
|
**kwargs: ta.Any,
|
4285
|
-
) -> SubprocessRunOutput:
|
4472
|
+
) -> ta.Awaitable[SubprocessRunOutput]:
|
4286
4473
|
return self.run_(SubprocessRun(
|
4287
4474
|
cmd=cmd,
|
4288
4475
|
input=input,
|
@@ -4295,7 +4482,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4295
4482
|
#
|
4296
4483
|
|
4297
4484
|
@abc.abstractmethod
|
4298
|
-
def check_call(
|
4485
|
+
async def check_call(
|
4299
4486
|
self,
|
4300
4487
|
*cmd: str,
|
4301
4488
|
stdout: ta.Any = sys.stderr,
|
@@ -4304,7 +4491,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4304
4491
|
raise NotImplementedError
|
4305
4492
|
|
4306
4493
|
@abc.abstractmethod
|
4307
|
-
def check_output(
|
4494
|
+
async def check_output(
|
4308
4495
|
self,
|
4309
4496
|
*cmd: str,
|
4310
4497
|
**kwargs: ta.Any,
|
@@ -4313,96 +4500,56 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4313
4500
|
|
4314
4501
|
#
|
4315
4502
|
|
4316
|
-
def check_output_str(
|
4503
|
+
async def check_output_str(
|
4317
4504
|
self,
|
4318
4505
|
*cmd: str,
|
4319
4506
|
**kwargs: ta.Any,
|
4320
4507
|
) -> str:
|
4321
|
-
return self.check_output(*cmd, **kwargs).decode().strip()
|
4508
|
+
return (await self.check_output(*cmd, **kwargs)).decode().strip()
|
4322
4509
|
|
4323
4510
|
#
|
4324
4511
|
|
4325
|
-
def try_call(
|
4512
|
+
async def try_call(
|
4326
4513
|
self,
|
4327
4514
|
*cmd: str,
|
4328
4515
|
**kwargs: ta.Any,
|
4329
4516
|
) -> bool:
|
4330
|
-
if isinstance(self.
|
4517
|
+
if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
|
4331
4518
|
return False
|
4332
4519
|
else:
|
4333
4520
|
return True
|
4334
4521
|
|
4335
|
-
def try_output(
|
4522
|
+
async def try_output(
|
4336
4523
|
self,
|
4337
4524
|
*cmd: str,
|
4338
4525
|
**kwargs: ta.Any,
|
4339
4526
|
) -> ta.Optional[bytes]:
|
4340
|
-
if isinstance(ret := self.
|
4527
|
+
if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
|
4341
4528
|
return None
|
4342
4529
|
else:
|
4343
4530
|
return ret
|
4344
4531
|
|
4345
|
-
def try_output_str(
|
4532
|
+
async def try_output_str(
|
4346
4533
|
self,
|
4347
4534
|
*cmd: str,
|
4348
4535
|
**kwargs: ta.Any,
|
4349
4536
|
) -> ta.Optional[str]:
|
4350
|
-
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
4537
|
+
if (ret := await self.try_output(*cmd, **kwargs)) is None:
|
4351
4538
|
return None
|
4352
4539
|
else:
|
4353
4540
|
return ret.decode().strip()
|
4354
4541
|
|
4355
4542
|
|
4356
|
-
|
4357
|
-
|
4358
|
-
|
4359
|
-
class Subprocesses(AbstractSubprocesses):
|
4360
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
|
4361
|
-
proc = subprocess.run(
|
4362
|
-
run.cmd,
|
4363
|
-
input=run.input,
|
4364
|
-
timeout=run.timeout,
|
4365
|
-
check=run.check,
|
4366
|
-
capture_output=run.capture_output or False,
|
4367
|
-
**(run.kwargs or {}),
|
4368
|
-
)
|
4369
|
-
|
4370
|
-
return SubprocessRunOutput(
|
4371
|
-
proc=proc,
|
4372
|
-
|
4373
|
-
returncode=proc.returncode,
|
4374
|
-
|
4375
|
-
stdout=proc.stdout, # noqa
|
4376
|
-
stderr=proc.stderr, # noqa
|
4377
|
-
)
|
4378
|
-
|
4379
|
-
def check_call(
|
4380
|
-
self,
|
4381
|
-
*cmd: str,
|
4382
|
-
stdout: ta.Any = sys.stderr,
|
4383
|
-
**kwargs: ta.Any,
|
4384
|
-
) -> None:
|
4385
|
-
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
4386
|
-
subprocess.check_call(cmd, **kwargs)
|
4387
|
-
|
4388
|
-
def check_output(
|
4389
|
-
self,
|
4390
|
-
*cmd: str,
|
4391
|
-
**kwargs: ta.Any,
|
4392
|
-
) -> bytes:
|
4393
|
-
with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
|
4394
|
-
return subprocess.check_output(cmd, **kwargs)
|
4395
|
-
|
4396
|
-
|
4397
|
-
subprocesses = Subprocesses()
|
4543
|
+
########################################
|
4544
|
+
# ../../../omlish/subprocesses/sync.py
|
4398
4545
|
|
4399
4546
|
|
4400
4547
|
##
|
4401
4548
|
|
4402
4549
|
|
4403
|
-
class
|
4550
|
+
class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
4404
4551
|
@abc.abstractmethod
|
4405
|
-
|
4552
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4406
4553
|
raise NotImplementedError
|
4407
4554
|
|
4408
4555
|
def run(
|
@@ -4413,7 +4560,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4413
4560
|
check: bool = False,
|
4414
4561
|
capture_output: ta.Optional[bool] = None,
|
4415
4562
|
**kwargs: ta.Any,
|
4416
|
-
) ->
|
4563
|
+
) -> SubprocessRunOutput:
|
4417
4564
|
return self.run_(SubprocessRun(
|
4418
4565
|
cmd=cmd,
|
4419
4566
|
input=input,
|
@@ -4426,7 +4573,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4426
4573
|
#
|
4427
4574
|
|
4428
4575
|
@abc.abstractmethod
|
4429
|
-
|
4576
|
+
def check_call(
|
4430
4577
|
self,
|
4431
4578
|
*cmd: str,
|
4432
4579
|
stdout: ta.Any = sys.stderr,
|
@@ -4435,7 +4582,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4435
4582
|
raise NotImplementedError
|
4436
4583
|
|
4437
4584
|
@abc.abstractmethod
|
4438
|
-
|
4585
|
+
def check_output(
|
4439
4586
|
self,
|
4440
4587
|
*cmd: str,
|
4441
4588
|
**kwargs: ta.Any,
|
@@ -4444,163 +4591,94 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4444
4591
|
|
4445
4592
|
#
|
4446
4593
|
|
4447
|
-
|
4594
|
+
def check_output_str(
|
4448
4595
|
self,
|
4449
4596
|
*cmd: str,
|
4450
4597
|
**kwargs: ta.Any,
|
4451
4598
|
) -> str:
|
4452
|
-
return
|
4599
|
+
return self.check_output(*cmd, **kwargs).decode().strip()
|
4453
4600
|
|
4454
4601
|
#
|
4455
4602
|
|
4456
|
-
|
4603
|
+
def try_call(
|
4457
4604
|
self,
|
4458
4605
|
*cmd: str,
|
4459
4606
|
**kwargs: ta.Any,
|
4460
4607
|
) -> bool:
|
4461
|
-
if isinstance(
|
4608
|
+
if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
|
4462
4609
|
return False
|
4463
4610
|
else:
|
4464
4611
|
return True
|
4465
4612
|
|
4466
|
-
|
4613
|
+
def try_output(
|
4467
4614
|
self,
|
4468
4615
|
*cmd: str,
|
4469
4616
|
**kwargs: ta.Any,
|
4470
4617
|
) -> ta.Optional[bytes]:
|
4471
|
-
if isinstance(ret :=
|
4618
|
+
if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
|
4472
4619
|
return None
|
4473
4620
|
else:
|
4474
4621
|
return ret
|
4475
4622
|
|
4476
|
-
|
4623
|
+
def try_output_str(
|
4477
4624
|
self,
|
4478
4625
|
*cmd: str,
|
4479
4626
|
**kwargs: ta.Any,
|
4480
4627
|
) -> ta.Optional[str]:
|
4481
|
-
if (ret :=
|
4628
|
+
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
4482
4629
|
return None
|
4483
4630
|
else:
|
4484
4631
|
return ret.decode().strip()
|
4485
4632
|
|
4486
4633
|
|
4487
|
-
########################################
|
4488
|
-
# ../github/cache.py
|
4489
|
-
|
4490
|
-
|
4491
4634
|
##
|
4492
4635
|
|
4493
4636
|
|
4494
|
-
class
|
4495
|
-
|
4496
|
-
|
4497
|
-
|
4498
|
-
|
4499
|
-
|
4500
|
-
|
4501
|
-
|
4502
|
-
|
4503
|
-
|
4504
|
-
|
4505
|
-
) -> None:
|
4506
|
-
super().__init__(
|
4507
|
-
version=version,
|
4508
|
-
)
|
4637
|
+
class Subprocesses(AbstractSubprocesses):
|
4638
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
|
4639
|
+
with self.prepare_and_wrap(
|
4640
|
+
*run.cmd,
|
4641
|
+
input=run.input,
|
4642
|
+
timeout=run.timeout,
|
4643
|
+
check=run.check,
|
4644
|
+
capture_output=run.capture_output or False,
|
4645
|
+
**(run.kwargs or {}),
|
4646
|
+
) as (cmd, kwargs):
|
4647
|
+
proc = subprocess.run(cmd, **kwargs) # noqa
|
4509
4648
|
|
4510
|
-
|
4649
|
+
return SubprocessRunOutput(
|
4650
|
+
proc=proc,
|
4511
4651
|
|
4512
|
-
|
4513
|
-
client = GithubCacheServiceV1Client(
|
4514
|
-
cache_version=self._version,
|
4515
|
-
)
|
4516
|
-
self._client: GithubCacheClient = client
|
4652
|
+
returncode=proc.returncode,
|
4517
4653
|
|
4518
|
-
|
4519
|
-
|
4520
|
-
dir=check.non_empty_str(config.dir),
|
4521
|
-
),
|
4522
|
-
version=self._version,
|
4654
|
+
stdout=proc.stdout, # noqa
|
4655
|
+
stderr=proc.stderr, # noqa
|
4523
4656
|
)
|
4524
4657
|
|
4525
|
-
|
4526
|
-
|
4527
|
-
async def get_file(self, key: str) -> ta.Optional[str]:
|
4528
|
-
local_file = self._local.get_cache_file_path(key)
|
4529
|
-
if os.path.exists(local_file):
|
4530
|
-
return local_file
|
4531
|
-
|
4532
|
-
if (entry := await self._client.get_entry(key)) is None:
|
4533
|
-
return None
|
4534
|
-
|
4535
|
-
tmp_file = self._local.format_incomplete_file(local_file)
|
4536
|
-
with unlinking_if_exists(tmp_file):
|
4537
|
-
await self._client.download_file(entry, tmp_file)
|
4538
|
-
|
4539
|
-
os.replace(tmp_file, local_file)
|
4540
|
-
|
4541
|
-
return local_file
|
4542
|
-
|
4543
|
-
async def put_file(
|
4658
|
+
def check_call(
|
4544
4659
|
self,
|
4545
|
-
|
4546
|
-
|
4547
|
-
|
4548
|
-
|
4549
|
-
|
4550
|
-
|
4551
|
-
key,
|
4552
|
-
file_path,
|
4553
|
-
steal=steal,
|
4554
|
-
)
|
4555
|
-
|
4556
|
-
await self._client.upload_file(key, cache_file_path)
|
4557
|
-
|
4558
|
-
return cache_file_path
|
4559
|
-
|
4560
|
-
#
|
4561
|
-
|
4562
|
-
async def get_data(self, key: str) -> ta.Optional[DataCache.Data]:
|
4563
|
-
local_file = self._local.get_cache_file_path(key)
|
4564
|
-
if os.path.exists(local_file):
|
4565
|
-
return DataCache.FileData(local_file)
|
4566
|
-
|
4567
|
-
if (entry := await self._client.get_entry(key)) is None:
|
4568
|
-
return None
|
4569
|
-
|
4570
|
-
return DataCache.UrlData(check.non_empty_str(self._client.get_entry_url(entry)))
|
4571
|
-
|
4572
|
-
async def put_data(self, key: str, data: DataCache.Data) -> None:
|
4573
|
-
await FileCacheDataCache(self).put_data(key, data)
|
4660
|
+
*cmd: str,
|
4661
|
+
stdout: ta.Any = sys.stderr,
|
4662
|
+
**kwargs: ta.Any,
|
4663
|
+
) -> None:
|
4664
|
+
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
4665
|
+
subprocess.check_call(cmd, **kwargs)
|
4574
4666
|
|
4667
|
+
def check_output(
|
4668
|
+
self,
|
4669
|
+
*cmd: str,
|
4670
|
+
**kwargs: ta.Any,
|
4671
|
+
) -> bytes:
|
4672
|
+
with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
|
4673
|
+
return subprocess.check_output(cmd, **kwargs)
|
4575
4674
|
|
4576
|
-
########################################
|
4577
|
-
# ../github/cli.py
|
4578
|
-
"""
|
4579
|
-
See:
|
4580
|
-
- https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28
|
4581
|
-
"""
|
4582
4675
|
|
4676
|
+
##
|
4583
4677
|
|
4584
|
-
class GithubCli(ArgparseCli):
|
4585
|
-
@argparse_cmd()
|
4586
|
-
def list_referenced_env_vars(self) -> None:
|
4587
|
-
print('\n'.join(sorted(ev.k for ev in GITHUB_ENV_VARS)))
|
4588
4678
|
|
4589
|
-
|
4590
|
-
argparse_arg('key'),
|
4591
|
-
)
|
4592
|
-
async def get_cache_entry(self) -> None:
|
4593
|
-
client = GithubCacheServiceV1Client()
|
4594
|
-
entry = await client.get_entry(self.args.key)
|
4595
|
-
if entry is None:
|
4596
|
-
return
|
4597
|
-
print(json_dumps_pretty(dc.asdict(entry))) # noqa
|
4679
|
+
subprocesses = Subprocesses()
|
4598
4680
|
|
4599
|
-
|
4600
|
-
argparse_arg('repository-id'),
|
4601
|
-
)
|
4602
|
-
def list_cache_entries(self) -> None:
|
4603
|
-
raise NotImplementedError
|
4681
|
+
SubprocessRun._DEFAULT_SUBPROCESSES = subprocesses # noqa
|
4604
4682
|
|
4605
4683
|
|
4606
4684
|
########################################
|
@@ -4816,19 +4894,19 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
|
|
4816
4894
|
timeout: ta.Optional[float] = None,
|
4817
4895
|
**kwargs: ta.Any,
|
4818
4896
|
) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
|
4819
|
-
fac: ta.Any
|
4820
|
-
if shell:
|
4821
|
-
fac = functools.partial(
|
4822
|
-
asyncio.create_subprocess_shell,
|
4823
|
-
check.single(cmd),
|
4824
|
-
)
|
4825
|
-
else:
|
4826
|
-
fac = functools.partial(
|
4827
|
-
asyncio.create_subprocess_exec,
|
4828
|
-
*cmd,
|
4829
|
-
)
|
4830
|
-
|
4831
4897
|
with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
|
4898
|
+
fac: ta.Any
|
4899
|
+
if shell:
|
4900
|
+
fac = functools.partial(
|
4901
|
+
asyncio.create_subprocess_shell,
|
4902
|
+
check.single(cmd),
|
4903
|
+
)
|
4904
|
+
else:
|
4905
|
+
fac = functools.partial(
|
4906
|
+
asyncio.create_subprocess_exec,
|
4907
|
+
*cmd,
|
4908
|
+
)
|
4909
|
+
|
4832
4910
|
proc: asyncio.subprocess.Process = await fac(**kwargs)
|
4833
4911
|
try:
|
4834
4912
|
yield proc
|
@@ -5172,31 +5250,6 @@ async def load_docker_tar(
|
|
5172
5250
|
return await load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
|
5173
5251
|
|
5174
5252
|
|
5175
|
-
########################################
|
5176
|
-
# ../github/inject.py
|
5177
|
-
|
5178
|
-
|
5179
|
-
##
|
5180
|
-
|
5181
|
-
|
5182
|
-
def bind_github(
|
5183
|
-
*,
|
5184
|
-
cache_dir: ta.Optional[str] = None,
|
5185
|
-
) -> InjectorBindings:
|
5186
|
-
lst: ta.List[InjectorBindingOrBindings] = []
|
5187
|
-
|
5188
|
-
if cache_dir is not None:
|
5189
|
-
lst.extend([
|
5190
|
-
inj.bind(GithubCache.Config(
|
5191
|
-
dir=cache_dir,
|
5192
|
-
)),
|
5193
|
-
inj.bind(GithubCache, singleton=True),
|
5194
|
-
inj.bind(FileCache, to_key=GithubCache),
|
5195
|
-
])
|
5196
|
-
|
5197
|
-
return inj.as_bindings(*lst)
|
5198
|
-
|
5199
|
-
|
5200
5253
|
########################################
|
5201
5254
|
# ../docker/cache.py
|
5202
5255
|
|