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/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
- def subprocess_close(
4032
- proc: subprocess.Popen,
4033
- timeout: ta.Optional[float] = None,
4034
- ) -> None:
4035
- # TODO: terminate, sleep, kill
4036
- if proc.stdout:
4037
- proc.stdout.close()
4038
- if proc.stderr:
4039
- proc.stderr.close()
4040
- if proc.stdin:
4041
- proc.stdin.close()
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
- proc.wait(timeout)
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
- @classmethod
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
- @dc.dataclass(frozen=True)
4263
- class SubprocessRunOutput(ta.Generic[T]):
4264
- proc: T
4434
+ def bind_github(
4435
+ *,
4436
+ cache_dir: ta.Optional[str] = None,
4437
+ ) -> InjectorBindings:
4438
+ lst: ta.List[InjectorBindingOrBindings] = []
4265
4439
 
4266
- returncode: int # noqa
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
- stdout: ta.Optional[bytes] = None
4269
- stderr: ta.Optional[bytes] = None
4449
+ return inj.as_bindings(*lst)
4270
4450
 
4271
4451
 
4272
- class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
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.try_fn(self.check_call, *cmd, **kwargs), Exception):
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.try_fn(self.check_output, *cmd, **kwargs), Exception):
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 AbstractAsyncSubprocesses(BaseSubprocesses):
4550
+ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
4404
4551
  @abc.abstractmethod
4405
- async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
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
- ) -> ta.Awaitable[SubprocessRunOutput]:
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
- async def check_call(
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
- async def check_output(
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
- async def check_output_str(
4594
+ def check_output_str(
4448
4595
  self,
4449
4596
  *cmd: str,
4450
4597
  **kwargs: ta.Any,
4451
4598
  ) -> str:
4452
- return (await self.check_output(*cmd, **kwargs)).decode().strip()
4599
+ return self.check_output(*cmd, **kwargs).decode().strip()
4453
4600
 
4454
4601
  #
4455
4602
 
4456
- async def try_call(
4603
+ def try_call(
4457
4604
  self,
4458
4605
  *cmd: str,
4459
4606
  **kwargs: ta.Any,
4460
4607
  ) -> bool:
4461
- if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
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
- async def try_output(
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 := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
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
- async def try_output_str(
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 := await self.try_output(*cmd, **kwargs)) is None:
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 GithubCache(FileCache, DataCache):
4495
- @dc.dataclass(frozen=True)
4496
- class Config:
4497
- dir: str
4498
-
4499
- def __init__(
4500
- self,
4501
- config: Config,
4502
- *,
4503
- client: ta.Optional[GithubCacheClient] = None,
4504
- version: ta.Optional[CacheVersion] = None,
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
- self._config = config
4649
+ return SubprocessRunOutput(
4650
+ proc=proc,
4511
4651
 
4512
- if client is None:
4513
- client = GithubCacheServiceV1Client(
4514
- cache_version=self._version,
4515
- )
4516
- self._client: GithubCacheClient = client
4652
+ returncode=proc.returncode,
4517
4653
 
4518
- self._local = DirectoryFileCache(
4519
- DirectoryFileCache.Config(
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
- key: str,
4546
- file_path: str,
4547
- *,
4548
- steal: bool = False,
4549
- ) -> str:
4550
- cache_file_path = await self._local.put_file(
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
- @argparse_cmd(
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
- @argparse_cmd(
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