omdev 0.0.0.dev224__py3-none-any.whl → 0.0.0.dev226__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 +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
|
|