omdev 0.0.0.dev224__py3-none-any.whl → 0.0.0.dev226__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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 +600 -296
- omdev/scripts/interp.py +501 -343
- omdev/scripts/pyproject.py +603 -299
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/RECORD +16 -16
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev224.dist-info → omdev-0.0.0.dev226.dist-info}/top_level.txt +0 -0
omdev/scripts/ci.py
CHANGED
@@ -64,9 +64,6 @@ T = ta.TypeVar('T')
|
|
64
64
|
# ../../omlish/asyncs/asyncio/asyncio.py
|
65
65
|
CallableT = ta.TypeVar('CallableT', bound=ta.Callable)
|
66
66
|
|
67
|
-
# ../../omlish/asyncs/asyncio/timeouts.py
|
68
|
-
AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
|
69
|
-
|
70
67
|
# ../../omlish/lite/check.py
|
71
68
|
SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
|
72
69
|
CheckMessage = ta.Union[str, ta.Callable[..., ta.Optional[str]], None] # ta.TypeAlias
|
@@ -75,9 +72,15 @@ CheckOnRaiseFn = ta.Callable[[Exception], None] # ta.TypeAlias
|
|
75
72
|
CheckExceptionFactory = ta.Callable[..., Exception] # ta.TypeAlias
|
76
73
|
CheckArgsRenderer = ta.Callable[..., ta.Optional[str]] # ta.TypeAlias
|
77
74
|
|
75
|
+
# ../../omlish/lite/timeouts.py
|
76
|
+
TimeoutLike = ta.Union['Timeout', 'Timeout.Default', ta.Iterable['TimeoutLike'], float] # ta.TypeAlias
|
77
|
+
|
78
78
|
# ../../omlish/argparse/cli.py
|
79
79
|
ArgparseCmdFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
|
80
80
|
|
81
|
+
# ../../omlish/asyncs/asyncio/timeouts.py
|
82
|
+
AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
|
83
|
+
|
81
84
|
# ../../omlish/lite/contextmanagers.py
|
82
85
|
ExitStackedT = ta.TypeVar('ExitStackedT', bound='ExitStacked')
|
83
86
|
AsyncExitStackedT = ta.TypeVar('AsyncExitStackedT', bound='AsyncExitStacked')
|
@@ -89,7 +92,7 @@ InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
89
92
|
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
90
93
|
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
91
94
|
|
92
|
-
# ../../omlish/subprocesses.py
|
95
|
+
# ../../omlish/subprocesses/base.py
|
93
96
|
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
|
94
97
|
|
95
98
|
|
@@ -245,19 +248,6 @@ async def asyncio_wait_concurrent(
|
|
245
248
|
return [task.result() for task in done]
|
246
249
|
|
247
250
|
|
248
|
-
########################################
|
249
|
-
# ../../../omlish/asyncs/asyncio/timeouts.py
|
250
|
-
|
251
|
-
|
252
|
-
def asyncio_maybe_timeout(
|
253
|
-
fut: AwaitableT,
|
254
|
-
timeout: ta.Optional[float] = None,
|
255
|
-
) -> AwaitableT:
|
256
|
-
if timeout is not None:
|
257
|
-
fut = asyncio.wait_for(fut, timeout) # type: ignore
|
258
|
-
return fut
|
259
|
-
|
260
|
-
|
261
251
|
########################################
|
262
252
|
# ../../../omlish/lite/cached.py
|
263
253
|
|
@@ -1057,6 +1047,205 @@ def format_num_bytes(num_bytes: int) -> str:
|
|
1057
1047
|
return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
|
1058
1048
|
|
1059
1049
|
|
1050
|
+
########################################
|
1051
|
+
# ../../../omlish/lite/timeouts.py
|
1052
|
+
"""
|
1053
|
+
TODO:
|
1054
|
+
- Event (/ Predicate)
|
1055
|
+
"""
|
1056
|
+
|
1057
|
+
|
1058
|
+
##
|
1059
|
+
|
1060
|
+
|
1061
|
+
class Timeout(abc.ABC):
|
1062
|
+
@property
|
1063
|
+
@abc.abstractmethod
|
1064
|
+
def can_expire(self) -> bool:
|
1065
|
+
"""Indicates whether or not this timeout will ever expire."""
|
1066
|
+
|
1067
|
+
raise NotImplementedError
|
1068
|
+
|
1069
|
+
@abc.abstractmethod
|
1070
|
+
def expired(self) -> bool:
|
1071
|
+
"""Return whether or not this timeout has expired."""
|
1072
|
+
|
1073
|
+
raise NotImplementedError
|
1074
|
+
|
1075
|
+
@abc.abstractmethod
|
1076
|
+
def remaining(self) -> float:
|
1077
|
+
"""Returns the time (in seconds) remaining until the timeout expires. May be negative and/or infinite."""
|
1078
|
+
|
1079
|
+
raise NotImplementedError
|
1080
|
+
|
1081
|
+
@abc.abstractmethod
|
1082
|
+
def __call__(self) -> float:
|
1083
|
+
"""Returns the time (in seconds) remaining until the timeout expires, or raises if the timeout has expired."""
|
1084
|
+
|
1085
|
+
raise NotImplementedError
|
1086
|
+
|
1087
|
+
@abc.abstractmethod
|
1088
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
1089
|
+
"""Evaluates time remaining via remaining() if this timeout can expire, otherwise returns `o`."""
|
1090
|
+
|
1091
|
+
raise NotImplementedError
|
1092
|
+
|
1093
|
+
#
|
1094
|
+
|
1095
|
+
@classmethod
|
1096
|
+
def _now(cls) -> float:
|
1097
|
+
return time.time()
|
1098
|
+
|
1099
|
+
#
|
1100
|
+
|
1101
|
+
class Default:
|
1102
|
+
def __new__(cls, *args, **kwargs): # noqa
|
1103
|
+
raise TypeError
|
1104
|
+
|
1105
|
+
class _NOT_SPECIFIED: # noqa
|
1106
|
+
def __new__(cls, *args, **kwargs): # noqa
|
1107
|
+
raise TypeError
|
1108
|
+
|
1109
|
+
@classmethod
|
1110
|
+
def of(
|
1111
|
+
cls,
|
1112
|
+
obj: ta.Optional[TimeoutLike],
|
1113
|
+
default: ta.Union[TimeoutLike, ta.Type[_NOT_SPECIFIED]] = _NOT_SPECIFIED,
|
1114
|
+
) -> 'Timeout':
|
1115
|
+
if obj is None:
|
1116
|
+
return InfiniteTimeout()
|
1117
|
+
|
1118
|
+
elif isinstance(obj, Timeout):
|
1119
|
+
return obj
|
1120
|
+
|
1121
|
+
elif isinstance(obj, (float, int)):
|
1122
|
+
return DeadlineTimeout(cls._now() + obj)
|
1123
|
+
|
1124
|
+
elif isinstance(obj, ta.Iterable):
|
1125
|
+
return CompositeTimeout(*[Timeout.of(c) for c in obj])
|
1126
|
+
|
1127
|
+
elif obj is Timeout.Default:
|
1128
|
+
if default is Timeout._NOT_SPECIFIED or default is Timeout.Default:
|
1129
|
+
raise RuntimeError('Must specify a default timeout')
|
1130
|
+
|
1131
|
+
else:
|
1132
|
+
return Timeout.of(default) # type: ignore[arg-type]
|
1133
|
+
|
1134
|
+
else:
|
1135
|
+
raise TypeError(obj)
|
1136
|
+
|
1137
|
+
@classmethod
|
1138
|
+
def of_deadline(cls, deadline: float) -> 'DeadlineTimeout':
|
1139
|
+
return DeadlineTimeout(deadline)
|
1140
|
+
|
1141
|
+
@classmethod
|
1142
|
+
def of_predicate(cls, expired_fn: ta.Callable[[], bool]) -> 'PredicateTimeout':
|
1143
|
+
return PredicateTimeout(expired_fn)
|
1144
|
+
|
1145
|
+
|
1146
|
+
class DeadlineTimeout(Timeout):
|
1147
|
+
def __init__(
|
1148
|
+
self,
|
1149
|
+
deadline: float,
|
1150
|
+
exc: ta.Union[ta.Type[BaseException], BaseException] = TimeoutError,
|
1151
|
+
) -> None:
|
1152
|
+
super().__init__()
|
1153
|
+
|
1154
|
+
self.deadline = deadline
|
1155
|
+
self.exc = exc
|
1156
|
+
|
1157
|
+
@property
|
1158
|
+
def can_expire(self) -> bool:
|
1159
|
+
return True
|
1160
|
+
|
1161
|
+
def expired(self) -> bool:
|
1162
|
+
return not (self.remaining() > 0)
|
1163
|
+
|
1164
|
+
def remaining(self) -> float:
|
1165
|
+
return self.deadline - self._now()
|
1166
|
+
|
1167
|
+
def __call__(self) -> float:
|
1168
|
+
if (rem := self.remaining()) > 0:
|
1169
|
+
return rem
|
1170
|
+
raise self.exc
|
1171
|
+
|
1172
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
1173
|
+
return self()
|
1174
|
+
|
1175
|
+
|
1176
|
+
class InfiniteTimeout(Timeout):
|
1177
|
+
@property
|
1178
|
+
def can_expire(self) -> bool:
|
1179
|
+
return False
|
1180
|
+
|
1181
|
+
def expired(self) -> bool:
|
1182
|
+
return False
|
1183
|
+
|
1184
|
+
def remaining(self) -> float:
|
1185
|
+
return float('inf')
|
1186
|
+
|
1187
|
+
def __call__(self) -> float:
|
1188
|
+
return float('inf')
|
1189
|
+
|
1190
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
1191
|
+
return o
|
1192
|
+
|
1193
|
+
|
1194
|
+
class CompositeTimeout(Timeout):
|
1195
|
+
def __init__(self, *children: Timeout) -> None:
|
1196
|
+
super().__init__()
|
1197
|
+
|
1198
|
+
self.children = children
|
1199
|
+
|
1200
|
+
@property
|
1201
|
+
def can_expire(self) -> bool:
|
1202
|
+
return any(c.can_expire for c in self.children)
|
1203
|
+
|
1204
|
+
def expired(self) -> bool:
|
1205
|
+
return any(c.expired() for c in self.children)
|
1206
|
+
|
1207
|
+
def remaining(self) -> float:
|
1208
|
+
return min(c.remaining() for c in self.children)
|
1209
|
+
|
1210
|
+
def __call__(self) -> float:
|
1211
|
+
return min(c() for c in self.children)
|
1212
|
+
|
1213
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
1214
|
+
if self.can_expire:
|
1215
|
+
return self()
|
1216
|
+
return o
|
1217
|
+
|
1218
|
+
|
1219
|
+
class PredicateTimeout(Timeout):
|
1220
|
+
def __init__(
|
1221
|
+
self,
|
1222
|
+
expired_fn: ta.Callable[[], bool],
|
1223
|
+
exc: ta.Union[ta.Type[BaseException], BaseException] = TimeoutError,
|
1224
|
+
) -> None:
|
1225
|
+
super().__init__()
|
1226
|
+
|
1227
|
+
self.expired_fn = expired_fn
|
1228
|
+
self.exc = exc
|
1229
|
+
|
1230
|
+
@property
|
1231
|
+
def can_expire(self) -> bool:
|
1232
|
+
return True
|
1233
|
+
|
1234
|
+
def expired(self) -> bool:
|
1235
|
+
return self.expired_fn()
|
1236
|
+
|
1237
|
+
def remaining(self) -> float:
|
1238
|
+
return float('inf')
|
1239
|
+
|
1240
|
+
def __call__(self) -> float:
|
1241
|
+
if not self.expired_fn():
|
1242
|
+
return float('inf')
|
1243
|
+
raise self.exc
|
1244
|
+
|
1245
|
+
def or_(self, o: ta.Any) -> ta.Any:
|
1246
|
+
return self()
|
1247
|
+
|
1248
|
+
|
1060
1249
|
########################################
|
1061
1250
|
# ../../../omlish/logs/filters.py
|
1062
1251
|
|
@@ -1814,6 +2003,19 @@ class ArgparseCli:
|
|
1814
2003
|
return fn()
|
1815
2004
|
|
1816
2005
|
|
2006
|
+
########################################
|
2007
|
+
# ../../../omlish/asyncs/asyncio/timeouts.py
|
2008
|
+
|
2009
|
+
|
2010
|
+
def asyncio_maybe_timeout(
|
2011
|
+
fut: AwaitableT,
|
2012
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
2013
|
+
) -> AwaitableT:
|
2014
|
+
if timeout is not None:
|
2015
|
+
fut = asyncio.wait_for(fut, Timeout.of(timeout)()) # type: ignore
|
2016
|
+
return fut
|
2017
|
+
|
2018
|
+
|
1817
2019
|
########################################
|
1818
2020
|
# ../../../omlish/lite/contextmanagers.py
|
1819
2021
|
|
@@ -3123,6 +3325,137 @@ def temp_named_file_context(
|
|
3123
3325
|
shutil.rmtree(f.name, ignore_errors=True)
|
3124
3326
|
|
3125
3327
|
|
3328
|
+
########################################
|
3329
|
+
# ../../../omlish/subprocesses/run.py
|
3330
|
+
|
3331
|
+
|
3332
|
+
##
|
3333
|
+
|
3334
|
+
|
3335
|
+
@dc.dataclass(frozen=True)
|
3336
|
+
class SubprocessRunOutput(ta.Generic[T]):
|
3337
|
+
proc: T
|
3338
|
+
|
3339
|
+
returncode: int # noqa
|
3340
|
+
|
3341
|
+
stdout: ta.Optional[bytes] = None
|
3342
|
+
stderr: ta.Optional[bytes] = None
|
3343
|
+
|
3344
|
+
|
3345
|
+
##
|
3346
|
+
|
3347
|
+
|
3348
|
+
@dc.dataclass(frozen=True)
|
3349
|
+
class SubprocessRun:
|
3350
|
+
cmd: ta.Sequence[str]
|
3351
|
+
input: ta.Any = None
|
3352
|
+
timeout: ta.Optional[TimeoutLike] = None
|
3353
|
+
check: bool = False
|
3354
|
+
capture_output: ta.Optional[bool] = None
|
3355
|
+
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
3356
|
+
|
3357
|
+
#
|
3358
|
+
|
3359
|
+
_FIELD_NAMES: ta.ClassVar[ta.FrozenSet[str]]
|
3360
|
+
|
3361
|
+
def replace(self, **kwargs: ta.Any) -> 'SubprocessRun':
|
3362
|
+
if not kwargs:
|
3363
|
+
return self
|
3364
|
+
|
3365
|
+
field_kws = {}
|
3366
|
+
extra_kws = {}
|
3367
|
+
for k, v in kwargs.items():
|
3368
|
+
if k in self._FIELD_NAMES:
|
3369
|
+
field_kws[k] = v
|
3370
|
+
else:
|
3371
|
+
extra_kws[k] = v
|
3372
|
+
|
3373
|
+
return dc.replace(self, **{
|
3374
|
+
**dict(kwargs={
|
3375
|
+
**(self.kwargs or {}),
|
3376
|
+
**extra_kws,
|
3377
|
+
}),
|
3378
|
+
**field_kws, # passing a kwarg named 'kwargs' intentionally clobbers
|
3379
|
+
})
|
3380
|
+
|
3381
|
+
#
|
3382
|
+
|
3383
|
+
@classmethod
|
3384
|
+
def of(
|
3385
|
+
cls,
|
3386
|
+
*cmd: str,
|
3387
|
+
input: ta.Any = None, # noqa
|
3388
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
3389
|
+
check: bool = False, # noqa
|
3390
|
+
capture_output: ta.Optional[bool] = None,
|
3391
|
+
**kwargs: ta.Any,
|
3392
|
+
) -> 'SubprocessRun':
|
3393
|
+
return cls(
|
3394
|
+
cmd=cmd,
|
3395
|
+
input=input,
|
3396
|
+
timeout=timeout,
|
3397
|
+
check=check,
|
3398
|
+
capture_output=capture_output,
|
3399
|
+
kwargs=kwargs,
|
3400
|
+
)
|
3401
|
+
|
3402
|
+
#
|
3403
|
+
|
3404
|
+
_DEFAULT_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractSubprocesses
|
3405
|
+
|
3406
|
+
def run(
|
3407
|
+
self,
|
3408
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
3409
|
+
**kwargs: ta.Any,
|
3410
|
+
) -> SubprocessRunOutput:
|
3411
|
+
if subprocesses is None:
|
3412
|
+
subprocesses = self._DEFAULT_SUBPROCESSES
|
3413
|
+
return check.not_none(subprocesses).run_(self.replace(**kwargs)) # type: ignore[attr-defined]
|
3414
|
+
|
3415
|
+
_DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
|
3416
|
+
|
3417
|
+
async def async_run(
|
3418
|
+
self,
|
3419
|
+
async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
|
3420
|
+
**kwargs: ta.Any,
|
3421
|
+
) -> SubprocessRunOutput:
|
3422
|
+
if async_subprocesses is None:
|
3423
|
+
async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
|
3424
|
+
return await check.not_none(async_subprocesses).run_(self.replace(**kwargs)) # type: ignore[attr-defined]
|
3425
|
+
|
3426
|
+
|
3427
|
+
SubprocessRun._FIELD_NAMES = frozenset(fld.name for fld in dc.fields(SubprocessRun)) # noqa
|
3428
|
+
|
3429
|
+
|
3430
|
+
##
|
3431
|
+
|
3432
|
+
|
3433
|
+
class SubprocessRunnable(abc.ABC, ta.Generic[T]):
|
3434
|
+
@abc.abstractmethod
|
3435
|
+
def make_run(self) -> SubprocessRun:
|
3436
|
+
raise NotImplementedError
|
3437
|
+
|
3438
|
+
@abc.abstractmethod
|
3439
|
+
def handle_run_output(self, output: SubprocessRunOutput) -> T:
|
3440
|
+
raise NotImplementedError
|
3441
|
+
|
3442
|
+
#
|
3443
|
+
|
3444
|
+
def run(
|
3445
|
+
self,
|
3446
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
3447
|
+
**kwargs: ta.Any,
|
3448
|
+
) -> T:
|
3449
|
+
return self.handle_run_output(self.make_run().run(subprocesses, **kwargs))
|
3450
|
+
|
3451
|
+
async def async_run(
|
3452
|
+
self,
|
3453
|
+
async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
|
3454
|
+
**kwargs: ta.Any,
|
3455
|
+
) -> T:
|
3456
|
+
return self.handle_run_output(await self.make_run().async_run(async_subprocesses, **kwargs))
|
3457
|
+
|
3458
|
+
|
3126
3459
|
########################################
|
3127
3460
|
# ../cache.py
|
3128
3461
|
|
@@ -3989,23 +4322,7 @@ def configure_standard_logging(
|
|
3989
4322
|
|
3990
4323
|
|
3991
4324
|
########################################
|
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
|
-
}
|
4325
|
+
# ../../../omlish/subprocesses/wrap.py
|
4009
4326
|
|
4010
4327
|
|
4011
4328
|
##
|
@@ -4025,29 +4342,150 @@ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
|
|
4025
4342
|
return cmd
|
4026
4343
|
|
4027
4344
|
|
4028
|
-
|
4029
|
-
|
4030
|
-
|
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()
|
4042
|
-
|
4043
|
-
proc.wait(timeout)
|
4345
|
+
########################################
|
4346
|
+
# ../github/cache.py
|
4044
4347
|
|
4045
4348
|
|
4046
4349
|
##
|
4047
4350
|
|
4048
4351
|
|
4049
|
-
class
|
4050
|
-
@
|
4352
|
+
class GithubCache(FileCache, DataCache):
|
4353
|
+
@dc.dataclass(frozen=True)
|
4354
|
+
class Config:
|
4355
|
+
dir: str
|
4356
|
+
|
4357
|
+
def __init__(
|
4358
|
+
self,
|
4359
|
+
config: Config,
|
4360
|
+
*,
|
4361
|
+
client: ta.Optional[GithubCacheClient] = None,
|
4362
|
+
version: ta.Optional[CacheVersion] = None,
|
4363
|
+
) -> None:
|
4364
|
+
super().__init__(
|
4365
|
+
version=version,
|
4366
|
+
)
|
4367
|
+
|
4368
|
+
self._config = config
|
4369
|
+
|
4370
|
+
if client is None:
|
4371
|
+
client = GithubCacheServiceV1Client(
|
4372
|
+
cache_version=self._version,
|
4373
|
+
)
|
4374
|
+
self._client: GithubCacheClient = client
|
4375
|
+
|
4376
|
+
self._local = DirectoryFileCache(
|
4377
|
+
DirectoryFileCache.Config(
|
4378
|
+
dir=check.non_empty_str(config.dir),
|
4379
|
+
),
|
4380
|
+
version=self._version,
|
4381
|
+
)
|
4382
|
+
|
4383
|
+
#
|
4384
|
+
|
4385
|
+
async def get_file(self, key: str) -> ta.Optional[str]:
|
4386
|
+
local_file = self._local.get_cache_file_path(key)
|
4387
|
+
if os.path.exists(local_file):
|
4388
|
+
return local_file
|
4389
|
+
|
4390
|
+
if (entry := await self._client.get_entry(key)) is None:
|
4391
|
+
return None
|
4392
|
+
|
4393
|
+
tmp_file = self._local.format_incomplete_file(local_file)
|
4394
|
+
with unlinking_if_exists(tmp_file):
|
4395
|
+
await self._client.download_file(entry, tmp_file)
|
4396
|
+
|
4397
|
+
os.replace(tmp_file, local_file)
|
4398
|
+
|
4399
|
+
return local_file
|
4400
|
+
|
4401
|
+
async def put_file(
|
4402
|
+
self,
|
4403
|
+
key: str,
|
4404
|
+
file_path: str,
|
4405
|
+
*,
|
4406
|
+
steal: bool = False,
|
4407
|
+
) -> str:
|
4408
|
+
cache_file_path = await self._local.put_file(
|
4409
|
+
key,
|
4410
|
+
file_path,
|
4411
|
+
steal=steal,
|
4412
|
+
)
|
4413
|
+
|
4414
|
+
await self._client.upload_file(key, cache_file_path)
|
4415
|
+
|
4416
|
+
return cache_file_path
|
4417
|
+
|
4418
|
+
#
|
4419
|
+
|
4420
|
+
async def get_data(self, key: str) -> ta.Optional[DataCache.Data]:
|
4421
|
+
local_file = self._local.get_cache_file_path(key)
|
4422
|
+
if os.path.exists(local_file):
|
4423
|
+
return DataCache.FileData(local_file)
|
4424
|
+
|
4425
|
+
if (entry := await self._client.get_entry(key)) is None:
|
4426
|
+
return None
|
4427
|
+
|
4428
|
+
return DataCache.UrlData(check.non_empty_str(self._client.get_entry_url(entry)))
|
4429
|
+
|
4430
|
+
async def put_data(self, key: str, data: DataCache.Data) -> None:
|
4431
|
+
await FileCacheDataCache(self).put_data(key, data)
|
4432
|
+
|
4433
|
+
|
4434
|
+
########################################
|
4435
|
+
# ../github/cli.py
|
4436
|
+
"""
|
4437
|
+
See:
|
4438
|
+
- https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28
|
4439
|
+
"""
|
4440
|
+
|
4441
|
+
|
4442
|
+
class GithubCli(ArgparseCli):
|
4443
|
+
@argparse_cmd()
|
4444
|
+
def list_referenced_env_vars(self) -> None:
|
4445
|
+
print('\n'.join(sorted(ev.k for ev in GITHUB_ENV_VARS)))
|
4446
|
+
|
4447
|
+
@argparse_cmd(
|
4448
|
+
argparse_arg('key'),
|
4449
|
+
)
|
4450
|
+
async def get_cache_entry(self) -> None:
|
4451
|
+
client = GithubCacheServiceV1Client()
|
4452
|
+
entry = await client.get_entry(self.args.key)
|
4453
|
+
if entry is None:
|
4454
|
+
return
|
4455
|
+
print(json_dumps_pretty(dc.asdict(entry))) # noqa
|
4456
|
+
|
4457
|
+
@argparse_cmd(
|
4458
|
+
argparse_arg('repository-id'),
|
4459
|
+
)
|
4460
|
+
def list_cache_entries(self) -> None:
|
4461
|
+
raise NotImplementedError
|
4462
|
+
|
4463
|
+
|
4464
|
+
########################################
|
4465
|
+
# ../../../omlish/subprocesses/base.py
|
4466
|
+
|
4467
|
+
|
4468
|
+
##
|
4469
|
+
|
4470
|
+
|
4471
|
+
# Valid channel type kwarg values:
|
4472
|
+
# - A special flag negative int
|
4473
|
+
# - A positive fd int
|
4474
|
+
# - A file-like object
|
4475
|
+
# - None
|
4476
|
+
|
4477
|
+
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
4478
|
+
'pipe': subprocess.PIPE,
|
4479
|
+
'stdout': subprocess.STDOUT,
|
4480
|
+
'devnull': subprocess.DEVNULL,
|
4481
|
+
}
|
4482
|
+
|
4483
|
+
|
4484
|
+
##
|
4485
|
+
|
4486
|
+
|
4487
|
+
class VerboseCalledProcessError(subprocess.CalledProcessError):
|
4488
|
+
@classmethod
|
4051
4489
|
def from_std(cls, e: subprocess.CalledProcessError) -> 'VerboseCalledProcessError':
|
4052
4490
|
return cls(
|
4053
4491
|
e.returncode,
|
@@ -4123,6 +4561,11 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
4123
4561
|
|
4124
4562
|
#
|
4125
4563
|
|
4564
|
+
if 'timeout' in kwargs:
|
4565
|
+
kwargs['timeout'] = Timeout.of(kwargs['timeout']).or_(None)
|
4566
|
+
|
4567
|
+
#
|
4568
|
+
|
4126
4569
|
return cmd, dict(
|
4127
4570
|
env=env,
|
4128
4571
|
shell=shell,
|
@@ -4227,62 +4670,52 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
4227
4670
|
return e
|
4228
4671
|
|
4229
4672
|
|
4673
|
+
########################################
|
4674
|
+
# ../github/inject.py
|
4675
|
+
|
4676
|
+
|
4230
4677
|
##
|
4231
4678
|
|
4232
4679
|
|
4233
|
-
|
4234
|
-
|
4235
|
-
|
4236
|
-
|
4237
|
-
|
4238
|
-
check: bool = False
|
4239
|
-
capture_output: ta.Optional[bool] = None
|
4240
|
-
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
4680
|
+
def bind_github(
|
4681
|
+
*,
|
4682
|
+
cache_dir: ta.Optional[str] = None,
|
4683
|
+
) -> InjectorBindings:
|
4684
|
+
lst: ta.List[InjectorBindingOrBindings] = []
|
4241
4685
|
|
4242
|
-
|
4243
|
-
|
4244
|
-
|
4245
|
-
|
4246
|
-
|
4247
|
-
|
4248
|
-
|
4249
|
-
|
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
|
-
)
|
4686
|
+
if cache_dir is not None:
|
4687
|
+
lst.extend([
|
4688
|
+
inj.bind(GithubCache.Config(
|
4689
|
+
dir=cache_dir,
|
4690
|
+
)),
|
4691
|
+
inj.bind(GithubCache, singleton=True),
|
4692
|
+
inj.bind(FileCache, to_key=GithubCache),
|
4693
|
+
])
|
4260
4694
|
|
4695
|
+
return inj.as_bindings(*lst)
|
4261
4696
|
|
4262
|
-
@dc.dataclass(frozen=True)
|
4263
|
-
class SubprocessRunOutput(ta.Generic[T]):
|
4264
|
-
proc: T
|
4265
4697
|
|
4266
|
-
|
4698
|
+
########################################
|
4699
|
+
# ../../../omlish/subprocesses/async_.py
|
4267
4700
|
|
4268
|
-
stdout: ta.Optional[bytes] = None
|
4269
|
-
stderr: ta.Optional[bytes] = None
|
4270
4701
|
|
4702
|
+
##
|
4271
4703
|
|
4272
|
-
|
4704
|
+
|
4705
|
+
class AbstractAsyncSubprocesses(BaseSubprocesses):
|
4273
4706
|
@abc.abstractmethod
|
4274
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4707
|
+
async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4275
4708
|
raise NotImplementedError
|
4276
4709
|
|
4277
4710
|
def run(
|
4278
4711
|
self,
|
4279
4712
|
*cmd: str,
|
4280
4713
|
input: ta.Any = None, # noqa
|
4281
|
-
timeout: ta.Optional[
|
4714
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
4282
4715
|
check: bool = False,
|
4283
4716
|
capture_output: ta.Optional[bool] = None,
|
4284
4717
|
**kwargs: ta.Any,
|
4285
|
-
) -> SubprocessRunOutput:
|
4718
|
+
) -> ta.Awaitable[SubprocessRunOutput]:
|
4286
4719
|
return self.run_(SubprocessRun(
|
4287
4720
|
cmd=cmd,
|
4288
4721
|
input=input,
|
@@ -4295,7 +4728,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4295
4728
|
#
|
4296
4729
|
|
4297
4730
|
@abc.abstractmethod
|
4298
|
-
def check_call(
|
4731
|
+
async def check_call(
|
4299
4732
|
self,
|
4300
4733
|
*cmd: str,
|
4301
4734
|
stdout: ta.Any = sys.stderr,
|
@@ -4304,7 +4737,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4304
4737
|
raise NotImplementedError
|
4305
4738
|
|
4306
4739
|
@abc.abstractmethod
|
4307
|
-
def check_output(
|
4740
|
+
async def check_output(
|
4308
4741
|
self,
|
4309
4742
|
*cmd: str,
|
4310
4743
|
**kwargs: ta.Any,
|
@@ -4313,107 +4746,72 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
4313
4746
|
|
4314
4747
|
#
|
4315
4748
|
|
4316
|
-
def check_output_str(
|
4749
|
+
async def check_output_str(
|
4317
4750
|
self,
|
4318
4751
|
*cmd: str,
|
4319
4752
|
**kwargs: ta.Any,
|
4320
4753
|
) -> str:
|
4321
|
-
return self.check_output(*cmd, **kwargs).decode().strip()
|
4754
|
+
return (await self.check_output(*cmd, **kwargs)).decode().strip()
|
4322
4755
|
|
4323
4756
|
#
|
4324
4757
|
|
4325
|
-
def try_call(
|
4758
|
+
async def try_call(
|
4326
4759
|
self,
|
4327
4760
|
*cmd: str,
|
4328
4761
|
**kwargs: ta.Any,
|
4329
4762
|
) -> bool:
|
4330
|
-
if isinstance(self.
|
4763
|
+
if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
|
4331
4764
|
return False
|
4332
4765
|
else:
|
4333
4766
|
return True
|
4334
4767
|
|
4335
|
-
def try_output(
|
4768
|
+
async def try_output(
|
4336
4769
|
self,
|
4337
4770
|
*cmd: str,
|
4338
4771
|
**kwargs: ta.Any,
|
4339
4772
|
) -> ta.Optional[bytes]:
|
4340
|
-
if isinstance(ret := self.
|
4773
|
+
if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
|
4341
4774
|
return None
|
4342
4775
|
else:
|
4343
4776
|
return ret
|
4344
4777
|
|
4345
|
-
def try_output_str(
|
4778
|
+
async def try_output_str(
|
4346
4779
|
self,
|
4347
4780
|
*cmd: str,
|
4348
4781
|
**kwargs: ta.Any,
|
4349
4782
|
) -> ta.Optional[str]:
|
4350
|
-
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
4783
|
+
if (ret := await self.try_output(*cmd, **kwargs)) is None:
|
4351
4784
|
return None
|
4352
4785
|
else:
|
4353
4786
|
return ret.decode().strip()
|
4354
4787
|
|
4355
4788
|
|
4356
|
-
|
4357
|
-
|
4358
|
-
|
4359
|
-
|
4360
|
-
|
4361
|
-
|
4362
|
-
|
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()
|
4789
|
+
########################################
|
4790
|
+
# ../../../omlish/subprocesses/sync.py
|
4791
|
+
"""
|
4792
|
+
TODO:
|
4793
|
+
- popen
|
4794
|
+
- route check_calls through run_?
|
4795
|
+
"""
|
4398
4796
|
|
4399
4797
|
|
4400
4798
|
##
|
4401
4799
|
|
4402
4800
|
|
4403
|
-
class
|
4801
|
+
class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
4404
4802
|
@abc.abstractmethod
|
4405
|
-
|
4803
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
4406
4804
|
raise NotImplementedError
|
4407
4805
|
|
4408
4806
|
def run(
|
4409
4807
|
self,
|
4410
4808
|
*cmd: str,
|
4411
4809
|
input: ta.Any = None, # noqa
|
4412
|
-
timeout: ta.Optional[
|
4810
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
4413
4811
|
check: bool = False,
|
4414
4812
|
capture_output: ta.Optional[bool] = None,
|
4415
4813
|
**kwargs: ta.Any,
|
4416
|
-
) ->
|
4814
|
+
) -> SubprocessRunOutput:
|
4417
4815
|
return self.run_(SubprocessRun(
|
4418
4816
|
cmd=cmd,
|
4419
4817
|
input=input,
|
@@ -4426,7 +4824,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4426
4824
|
#
|
4427
4825
|
|
4428
4826
|
@abc.abstractmethod
|
4429
|
-
|
4827
|
+
def check_call(
|
4430
4828
|
self,
|
4431
4829
|
*cmd: str,
|
4432
4830
|
stdout: ta.Any = sys.stderr,
|
@@ -4435,7 +4833,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4435
4833
|
raise NotImplementedError
|
4436
4834
|
|
4437
4835
|
@abc.abstractmethod
|
4438
|
-
|
4836
|
+
def check_output(
|
4439
4837
|
self,
|
4440
4838
|
*cmd: str,
|
4441
4839
|
**kwargs: ta.Any,
|
@@ -4444,163 +4842,94 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
4444
4842
|
|
4445
4843
|
#
|
4446
4844
|
|
4447
|
-
|
4845
|
+
def check_output_str(
|
4448
4846
|
self,
|
4449
4847
|
*cmd: str,
|
4450
4848
|
**kwargs: ta.Any,
|
4451
4849
|
) -> str:
|
4452
|
-
return
|
4850
|
+
return self.check_output(*cmd, **kwargs).decode().strip()
|
4453
4851
|
|
4454
4852
|
#
|
4455
4853
|
|
4456
|
-
|
4854
|
+
def try_call(
|
4457
4855
|
self,
|
4458
4856
|
*cmd: str,
|
4459
4857
|
**kwargs: ta.Any,
|
4460
4858
|
) -> bool:
|
4461
|
-
if isinstance(
|
4859
|
+
if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
|
4462
4860
|
return False
|
4463
4861
|
else:
|
4464
4862
|
return True
|
4465
4863
|
|
4466
|
-
|
4864
|
+
def try_output(
|
4467
4865
|
self,
|
4468
4866
|
*cmd: str,
|
4469
4867
|
**kwargs: ta.Any,
|
4470
4868
|
) -> ta.Optional[bytes]:
|
4471
|
-
if isinstance(ret :=
|
4869
|
+
if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
|
4472
4870
|
return None
|
4473
4871
|
else:
|
4474
4872
|
return ret
|
4475
4873
|
|
4476
|
-
|
4874
|
+
def try_output_str(
|
4477
4875
|
self,
|
4478
4876
|
*cmd: str,
|
4479
4877
|
**kwargs: ta.Any,
|
4480
4878
|
) -> ta.Optional[str]:
|
4481
|
-
if (ret :=
|
4879
|
+
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
4482
4880
|
return None
|
4483
4881
|
else:
|
4484
4882
|
return ret.decode().strip()
|
4485
4883
|
|
4486
4884
|
|
4487
|
-
########################################
|
4488
|
-
# ../github/cache.py
|
4489
|
-
|
4490
|
-
|
4491
4885
|
##
|
4492
4886
|
|
4493
4887
|
|
4494
|
-
class
|
4495
|
-
|
4496
|
-
|
4497
|
-
|
4498
|
-
|
4499
|
-
|
4500
|
-
|
4501
|
-
|
4502
|
-
|
4503
|
-
|
4504
|
-
|
4505
|
-
) -> None:
|
4506
|
-
super().__init__(
|
4507
|
-
version=version,
|
4508
|
-
)
|
4888
|
+
class Subprocesses(AbstractSubprocesses):
|
4889
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
|
4890
|
+
with self.prepare_and_wrap(
|
4891
|
+
*run.cmd,
|
4892
|
+
input=run.input,
|
4893
|
+
timeout=run.timeout,
|
4894
|
+
check=run.check,
|
4895
|
+
capture_output=run.capture_output or False,
|
4896
|
+
**(run.kwargs or {}),
|
4897
|
+
) as (cmd, kwargs):
|
4898
|
+
proc = subprocess.run(cmd, **kwargs) # noqa
|
4509
4899
|
|
4510
|
-
|
4900
|
+
return SubprocessRunOutput(
|
4901
|
+
proc=proc,
|
4511
4902
|
|
4512
|
-
|
4513
|
-
client = GithubCacheServiceV1Client(
|
4514
|
-
cache_version=self._version,
|
4515
|
-
)
|
4516
|
-
self._client: GithubCacheClient = client
|
4903
|
+
returncode=proc.returncode,
|
4517
4904
|
|
4518
|
-
|
4519
|
-
|
4520
|
-
dir=check.non_empty_str(config.dir),
|
4521
|
-
),
|
4522
|
-
version=self._version,
|
4905
|
+
stdout=proc.stdout, # noqa
|
4906
|
+
stderr=proc.stderr, # noqa
|
4523
4907
|
)
|
4524
4908
|
|
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(
|
4909
|
+
def check_call(
|
4544
4910
|
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)
|
4911
|
+
*cmd: str,
|
4912
|
+
stdout: ta.Any = sys.stderr,
|
4913
|
+
**kwargs: ta.Any,
|
4914
|
+
) -> None:
|
4915
|
+
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
4916
|
+
subprocess.check_call(cmd, **kwargs)
|
4574
4917
|
|
4918
|
+
def check_output(
|
4919
|
+
self,
|
4920
|
+
*cmd: str,
|
4921
|
+
**kwargs: ta.Any,
|
4922
|
+
) -> bytes:
|
4923
|
+
with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
|
4924
|
+
return subprocess.check_output(cmd, **kwargs)
|
4575
4925
|
|
4576
|
-
########################################
|
4577
|
-
# ../github/cli.py
|
4578
|
-
"""
|
4579
|
-
See:
|
4580
|
-
- https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28
|
4581
|
-
"""
|
4582
4926
|
|
4927
|
+
##
|
4583
4928
|
|
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
4929
|
|
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
|
4930
|
+
subprocesses = Subprocesses()
|
4598
4931
|
|
4599
|
-
|
4600
|
-
argparse_arg('repository-id'),
|
4601
|
-
)
|
4602
|
-
def list_cache_entries(self) -> None:
|
4603
|
-
raise NotImplementedError
|
4932
|
+
SubprocessRun._DEFAULT_SUBPROCESSES = subprocesses # noqa
|
4604
4933
|
|
4605
4934
|
|
4606
4935
|
########################################
|
@@ -4789,7 +5118,7 @@ class AsyncioProcessCommunicator:
|
|
4789
5118
|
async def communicate(
|
4790
5119
|
self,
|
4791
5120
|
input: ta.Any = None, # noqa
|
4792
|
-
timeout: ta.Optional[
|
5121
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
4793
5122
|
) -> Communication:
|
4794
5123
|
return await asyncio_maybe_timeout(self._communicate(input), timeout)
|
4795
5124
|
|
@@ -4802,7 +5131,7 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
|
|
4802
5131
|
self,
|
4803
5132
|
proc: asyncio.subprocess.Process,
|
4804
5133
|
input: ta.Any = None, # noqa
|
4805
|
-
timeout: ta.Optional[
|
5134
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
4806
5135
|
) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
|
4807
5136
|
return await AsyncioProcessCommunicator(proc).communicate(input, timeout) # noqa
|
4808
5137
|
|
@@ -4813,22 +5142,22 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
|
|
4813
5142
|
self,
|
4814
5143
|
*cmd: str,
|
4815
5144
|
shell: bool = False,
|
4816
|
-
timeout: ta.Optional[
|
5145
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
4817
5146
|
**kwargs: ta.Any,
|
4818
5147
|
) -> 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
5148
|
with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
|
5149
|
+
fac: ta.Any
|
5150
|
+
if shell:
|
5151
|
+
fac = functools.partial(
|
5152
|
+
asyncio.create_subprocess_shell,
|
5153
|
+
check.single(cmd),
|
5154
|
+
)
|
5155
|
+
else:
|
5156
|
+
fac = functools.partial(
|
5157
|
+
asyncio.create_subprocess_exec,
|
5158
|
+
*cmd,
|
5159
|
+
)
|
5160
|
+
|
4832
5161
|
proc: asyncio.subprocess.Process = await fac(**kwargs)
|
4833
5162
|
try:
|
4834
5163
|
yield proc
|
@@ -5172,31 +5501,6 @@ async def load_docker_tar(
|
|
5172
5501
|
return await load_docker_tar_cmd(ShellCmd(f'cat {shlex.quote(tar_file)}'))
|
5173
5502
|
|
5174
5503
|
|
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
5504
|
########################################
|
5201
5505
|
# ../docker/cache.py
|
5202
5506
|
|