omdev 0.0.0.dev223__py3-none-any.whl → 0.0.0.dev225__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/cache.py +108 -0
- omdev/ci/ci.py +1 -1
- omdev/ci/docker/cacheserved.py +262 -0
- omdev/ci/docker/dataserver.py +204 -0
- omdev/ci/docker/imagepulling.py +2 -1
- omdev/ci/docker/packing.py +72 -0
- omdev/ci/docker/repositories.py +40 -0
- omdev/ci/github/cache.py +20 -1
- omdev/ci/github/client.py +9 -2
- omdev/ci/github/inject.py +4 -4
- omdev/ci/requirements.py +1 -1
- omdev/ci/utils.py +0 -49
- omdev/dataserver/targets.py +32 -0
- omdev/git/revisions.py +2 -2
- omdev/git/shallow.py +1 -1
- omdev/git/status.py +1 -1
- omdev/oci/data.py +19 -0
- omdev/oci/dataserver.py +4 -1
- omdev/oci/pack/__init__.py +0 -0
- omdev/oci/pack/packing.py +185 -0
- omdev/oci/pack/repositories.py +162 -0
- omdev/oci/{packing.py → pack/unpacking.py} +0 -177
- omdev/oci/repositories.py +6 -0
- omdev/precheck/lite.py +1 -1
- omdev/pyproject/pkg.py +1 -1
- omdev/scripts/ci.py +773 -552
- omdev/scripts/interp.py +230 -299
- omdev/scripts/pyproject.py +328 -256
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/RECORD +35 -28
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev223.dist-info → omdev-0.0.0.dev225.dist-info}/top_level.txt +0 -0
omdev/scripts/pyproject.py
CHANGED
@@ -128,7 +128,7 @@ InjectorProviderFn = ta.Callable[['Injector'], ta.Any]
|
|
128
128
|
InjectorProviderFnMap = ta.Mapping['InjectorKey', 'InjectorProviderFn']
|
129
129
|
InjectorBindingOrBindings = ta.Union['InjectorBinding', 'InjectorBindings']
|
130
130
|
|
131
|
-
# ../../omlish/subprocesses.py
|
131
|
+
# ../../omlish/subprocesses/base.py
|
132
132
|
SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
|
133
133
|
|
134
134
|
|
@@ -5625,6 +5625,98 @@ class JsonLogFormatter(logging.Formatter):
|
|
5625
5625
|
return self._json_dumps(dct)
|
5626
5626
|
|
5627
5627
|
|
5628
|
+
########################################
|
5629
|
+
# ../../../omlish/subprocesses/run.py
|
5630
|
+
|
5631
|
+
|
5632
|
+
##
|
5633
|
+
|
5634
|
+
|
5635
|
+
@dc.dataclass(frozen=True)
|
5636
|
+
class SubprocessRunOutput(ta.Generic[T]):
|
5637
|
+
proc: T
|
5638
|
+
|
5639
|
+
returncode: int # noqa
|
5640
|
+
|
5641
|
+
stdout: ta.Optional[bytes] = None
|
5642
|
+
stderr: ta.Optional[bytes] = None
|
5643
|
+
|
5644
|
+
|
5645
|
+
##
|
5646
|
+
|
5647
|
+
|
5648
|
+
@dc.dataclass(frozen=True)
|
5649
|
+
class SubprocessRun:
|
5650
|
+
cmd: ta.Sequence[str]
|
5651
|
+
input: ta.Any = None
|
5652
|
+
timeout: ta.Optional[float] = None
|
5653
|
+
check: bool = False
|
5654
|
+
capture_output: ta.Optional[bool] = None
|
5655
|
+
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
5656
|
+
|
5657
|
+
@classmethod
|
5658
|
+
def of(
|
5659
|
+
cls,
|
5660
|
+
*cmd: str,
|
5661
|
+
input: ta.Any = None, # noqa
|
5662
|
+
timeout: ta.Optional[float] = None,
|
5663
|
+
check: bool = False, # noqa
|
5664
|
+
capture_output: ta.Optional[bool] = None,
|
5665
|
+
**kwargs: ta.Any,
|
5666
|
+
) -> 'SubprocessRun':
|
5667
|
+
return cls(
|
5668
|
+
cmd=cmd,
|
5669
|
+
input=input,
|
5670
|
+
timeout=timeout,
|
5671
|
+
check=check,
|
5672
|
+
capture_output=capture_output,
|
5673
|
+
kwargs=kwargs,
|
5674
|
+
)
|
5675
|
+
|
5676
|
+
#
|
5677
|
+
|
5678
|
+
_DEFAULT_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractSubprocesses
|
5679
|
+
|
5680
|
+
def run(
|
5681
|
+
self,
|
5682
|
+
subprocesses: ta.Optional[ta.Any] = None, # AbstractSubprocesses
|
5683
|
+
) -> SubprocessRunOutput:
|
5684
|
+
if subprocesses is None:
|
5685
|
+
subprocesses = self._DEFAULT_SUBPROCESSES
|
5686
|
+
return check.not_none(subprocesses).run_(self) # type: ignore[attr-defined]
|
5687
|
+
|
5688
|
+
_DEFAULT_ASYNC_SUBPROCESSES: ta.ClassVar[ta.Optional[ta.Any]] = None # AbstractAsyncSubprocesses
|
5689
|
+
|
5690
|
+
async def async_run(
|
5691
|
+
self,
|
5692
|
+
async_subprocesses: ta.Optional[ta.Any] = None, # AbstractAsyncSubprocesses
|
5693
|
+
) -> SubprocessRunOutput:
|
5694
|
+
if async_subprocesses is None:
|
5695
|
+
async_subprocesses = self._DEFAULT_ASYNC_SUBPROCESSES
|
5696
|
+
return await check.not_none(async_subprocesses).run_(self) # type: ignore[attr-defined]
|
5697
|
+
|
5698
|
+
|
5699
|
+
##
|
5700
|
+
|
5701
|
+
|
5702
|
+
class SubprocessRunnable(abc.ABC, ta.Generic[T]):
|
5703
|
+
@abc.abstractmethod
|
5704
|
+
def make_run(self) -> SubprocessRun:
|
5705
|
+
raise NotImplementedError
|
5706
|
+
|
5707
|
+
@abc.abstractmethod
|
5708
|
+
def handle_run_output(self, output: SubprocessRunOutput) -> T:
|
5709
|
+
raise NotImplementedError
|
5710
|
+
|
5711
|
+
#
|
5712
|
+
|
5713
|
+
def run(self, subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractSubprocesses
|
5714
|
+
return self.handle_run_output(self.make_run().run(subprocesses))
|
5715
|
+
|
5716
|
+
async def async_run(self, async_subprocesses: ta.Optional[ta.Any] = None) -> T: # AbstractAsyncSubprocesses
|
5717
|
+
return self.handle_run_output(await self.make_run().async_run(async_subprocesses))
|
5718
|
+
|
5719
|
+
|
5628
5720
|
########################################
|
5629
5721
|
# ../../interp/types.py
|
5630
5722
|
|
@@ -5863,23 +5955,7 @@ def configure_standard_logging(
|
|
5863
5955
|
|
5864
5956
|
|
5865
5957
|
########################################
|
5866
|
-
# ../../../omlish/subprocesses.py
|
5867
|
-
|
5868
|
-
|
5869
|
-
##
|
5870
|
-
|
5871
|
-
|
5872
|
-
# Valid channel type kwarg values:
|
5873
|
-
# - A special flag negative int
|
5874
|
-
# - A positive fd int
|
5875
|
-
# - A file-like object
|
5876
|
-
# - None
|
5877
|
-
|
5878
|
-
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
5879
|
-
'pipe': subprocess.PIPE,
|
5880
|
-
'stdout': subprocess.STDOUT,
|
5881
|
-
'devnull': subprocess.DEVNULL,
|
5882
|
-
}
|
5958
|
+
# ../../../omlish/subprocesses/wrap.py
|
5883
5959
|
|
5884
5960
|
|
5885
5961
|
##
|
@@ -5899,22 +5975,68 @@ def subprocess_maybe_shell_wrap_exec(*cmd: str) -> ta.Tuple[str, ...]:
|
|
5899
5975
|
return cmd
|
5900
5976
|
|
5901
5977
|
|
5978
|
+
########################################
|
5979
|
+
# ../../interp/providers/base.py
|
5980
|
+
"""
|
5981
|
+
TODO:
|
5982
|
+
- backends
|
5983
|
+
- local builds
|
5984
|
+
- deadsnakes?
|
5985
|
+
- uv
|
5986
|
+
- loose versions
|
5987
|
+
"""
|
5988
|
+
|
5989
|
+
|
5902
5990
|
##
|
5903
5991
|
|
5904
5992
|
|
5905
|
-
|
5906
|
-
|
5907
|
-
|
5908
|
-
) -> None:
|
5909
|
-
|
5910
|
-
|
5911
|
-
|
5912
|
-
|
5913
|
-
|
5914
|
-
|
5915
|
-
|
5993
|
+
class InterpProvider(abc.ABC):
|
5994
|
+
name: ta.ClassVar[str]
|
5995
|
+
|
5996
|
+
def __init_subclass__(cls, **kwargs: ta.Any) -> None:
|
5997
|
+
super().__init_subclass__(**kwargs)
|
5998
|
+
if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
|
5999
|
+
sfx = 'InterpProvider'
|
6000
|
+
if not cls.__name__.endswith(sfx):
|
6001
|
+
raise NameError(cls)
|
6002
|
+
setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
|
6003
|
+
|
6004
|
+
@abc.abstractmethod
|
6005
|
+
def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
|
6006
|
+
raise NotImplementedError
|
6007
|
+
|
6008
|
+
@abc.abstractmethod
|
6009
|
+
def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
|
6010
|
+
raise NotImplementedError
|
6011
|
+
|
6012
|
+
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
6013
|
+
return []
|
6014
|
+
|
6015
|
+
async def install_version(self, version: InterpVersion) -> Interp:
|
6016
|
+
raise TypeError
|
6017
|
+
|
6018
|
+
|
6019
|
+
InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
|
6020
|
+
|
6021
|
+
|
6022
|
+
########################################
|
6023
|
+
# ../../../omlish/subprocesses/base.py
|
6024
|
+
|
6025
|
+
|
6026
|
+
##
|
6027
|
+
|
6028
|
+
|
6029
|
+
# Valid channel type kwarg values:
|
6030
|
+
# - A special flag negative int
|
6031
|
+
# - A positive fd int
|
6032
|
+
# - A file-like object
|
6033
|
+
# - None
|
5916
6034
|
|
5917
|
-
|
6035
|
+
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
6036
|
+
'pipe': subprocess.PIPE,
|
6037
|
+
'stdout': subprocess.STDOUT,
|
6038
|
+
'devnull': subprocess.DEVNULL,
|
6039
|
+
}
|
5918
6040
|
|
5919
6041
|
|
5920
6042
|
##
|
@@ -6101,32 +6223,104 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
6101
6223
|
return e
|
6102
6224
|
|
6103
6225
|
|
6104
|
-
|
6226
|
+
########################################
|
6227
|
+
# ../../interp/resolvers.py
|
6105
6228
|
|
6106
6229
|
|
6107
6230
|
@dc.dataclass(frozen=True)
|
6108
|
-
class
|
6109
|
-
|
6110
|
-
input: ta.Any = None
|
6111
|
-
timeout: ta.Optional[float] = None
|
6112
|
-
check: bool = False
|
6113
|
-
capture_output: ta.Optional[bool] = None
|
6114
|
-
kwargs: ta.Optional[ta.Mapping[str, ta.Any]] = None
|
6231
|
+
class InterpResolverProviders:
|
6232
|
+
providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
|
6115
6233
|
|
6116
6234
|
|
6117
|
-
|
6118
|
-
|
6119
|
-
|
6235
|
+
class InterpResolver:
|
6236
|
+
def __init__(
|
6237
|
+
self,
|
6238
|
+
providers: InterpResolverProviders,
|
6239
|
+
) -> None:
|
6240
|
+
super().__init__()
|
6120
6241
|
|
6121
|
-
|
6242
|
+
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
|
6122
6243
|
|
6123
|
-
|
6124
|
-
|
6244
|
+
async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
6245
|
+
lst = [
|
6246
|
+
(i, si)
|
6247
|
+
for i, p in enumerate(self._providers.values())
|
6248
|
+
for si in await p.get_installed_versions(spec)
|
6249
|
+
if spec.contains(si)
|
6250
|
+
]
|
6125
6251
|
|
6252
|
+
slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
|
6253
|
+
if not slst:
|
6254
|
+
return None
|
6126
6255
|
|
6127
|
-
|
6256
|
+
bi, bv = slst[-1]
|
6257
|
+
bp = list(self._providers.values())[bi]
|
6258
|
+
return (bp, bv)
|
6259
|
+
|
6260
|
+
async def resolve(
|
6261
|
+
self,
|
6262
|
+
spec: InterpSpecifier,
|
6263
|
+
*,
|
6264
|
+
install: bool = False,
|
6265
|
+
) -> ta.Optional[Interp]:
|
6266
|
+
tup = await self._resolve_installed(spec)
|
6267
|
+
if tup is not None:
|
6268
|
+
bp, bv = tup
|
6269
|
+
return await bp.get_installed_version(bv)
|
6270
|
+
|
6271
|
+
if not install:
|
6272
|
+
return None
|
6273
|
+
|
6274
|
+
tp = list(self._providers.values())[0] # noqa
|
6275
|
+
|
6276
|
+
sv = sorted(
|
6277
|
+
[s for s in await tp.get_installable_versions(spec) if s in spec],
|
6278
|
+
key=lambda s: s.version,
|
6279
|
+
)
|
6280
|
+
if not sv:
|
6281
|
+
return None
|
6282
|
+
|
6283
|
+
bv = sv[-1]
|
6284
|
+
return await tp.install_version(bv)
|
6285
|
+
|
6286
|
+
async def list(self, spec: InterpSpecifier) -> None:
|
6287
|
+
print('installed:')
|
6288
|
+
for n, p in self._providers.items():
|
6289
|
+
lst = [
|
6290
|
+
si
|
6291
|
+
for si in await p.get_installed_versions(spec)
|
6292
|
+
if spec.contains(si)
|
6293
|
+
]
|
6294
|
+
if lst:
|
6295
|
+
print(f' {n}')
|
6296
|
+
for si in lst:
|
6297
|
+
print(f' {si}')
|
6298
|
+
|
6299
|
+
print()
|
6300
|
+
|
6301
|
+
print('installable:')
|
6302
|
+
for n, p in self._providers.items():
|
6303
|
+
lst = [
|
6304
|
+
si
|
6305
|
+
for si in await p.get_installable_versions(spec)
|
6306
|
+
if spec.contains(si)
|
6307
|
+
]
|
6308
|
+
if lst:
|
6309
|
+
print(f' {n}')
|
6310
|
+
for si in lst:
|
6311
|
+
print(f' {si}')
|
6312
|
+
|
6313
|
+
|
6314
|
+
########################################
|
6315
|
+
# ../../../omlish/subprocesses/async_.py
|
6316
|
+
|
6317
|
+
|
6318
|
+
##
|
6319
|
+
|
6320
|
+
|
6321
|
+
class AbstractAsyncSubprocesses(BaseSubprocesses):
|
6128
6322
|
@abc.abstractmethod
|
6129
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
6323
|
+
async def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
6130
6324
|
raise NotImplementedError
|
6131
6325
|
|
6132
6326
|
def run(
|
@@ -6137,7 +6331,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
6137
6331
|
check: bool = False,
|
6138
6332
|
capture_output: ta.Optional[bool] = None,
|
6139
6333
|
**kwargs: ta.Any,
|
6140
|
-
) -> SubprocessRunOutput:
|
6334
|
+
) -> ta.Awaitable[SubprocessRunOutput]:
|
6141
6335
|
return self.run_(SubprocessRun(
|
6142
6336
|
cmd=cmd,
|
6143
6337
|
input=input,
|
@@ -6150,7 +6344,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
6150
6344
|
#
|
6151
6345
|
|
6152
6346
|
@abc.abstractmethod
|
6153
|
-
def check_call(
|
6347
|
+
async def check_call(
|
6154
6348
|
self,
|
6155
6349
|
*cmd: str,
|
6156
6350
|
stdout: ta.Any = sys.stderr,
|
@@ -6159,7 +6353,7 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
6159
6353
|
raise NotImplementedError
|
6160
6354
|
|
6161
6355
|
@abc.abstractmethod
|
6162
|
-
def check_output(
|
6356
|
+
async def check_output(
|
6163
6357
|
self,
|
6164
6358
|
*cmd: str,
|
6165
6359
|
**kwargs: ta.Any,
|
@@ -6168,96 +6362,56 @@ class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
|
6168
6362
|
|
6169
6363
|
#
|
6170
6364
|
|
6171
|
-
def check_output_str(
|
6365
|
+
async def check_output_str(
|
6172
6366
|
self,
|
6173
6367
|
*cmd: str,
|
6174
6368
|
**kwargs: ta.Any,
|
6175
6369
|
) -> str:
|
6176
|
-
return self.check_output(*cmd, **kwargs).decode().strip()
|
6370
|
+
return (await self.check_output(*cmd, **kwargs)).decode().strip()
|
6177
6371
|
|
6178
6372
|
#
|
6179
6373
|
|
6180
|
-
def try_call(
|
6374
|
+
async def try_call(
|
6181
6375
|
self,
|
6182
6376
|
*cmd: str,
|
6183
6377
|
**kwargs: ta.Any,
|
6184
6378
|
) -> bool:
|
6185
|
-
if isinstance(self.
|
6379
|
+
if isinstance(await self.async_try_fn(self.check_call, *cmd, **kwargs), Exception):
|
6186
6380
|
return False
|
6187
6381
|
else:
|
6188
6382
|
return True
|
6189
6383
|
|
6190
|
-
def try_output(
|
6384
|
+
async def try_output(
|
6191
6385
|
self,
|
6192
6386
|
*cmd: str,
|
6193
6387
|
**kwargs: ta.Any,
|
6194
6388
|
) -> ta.Optional[bytes]:
|
6195
|
-
if isinstance(ret := self.
|
6389
|
+
if isinstance(ret := await self.async_try_fn(self.check_output, *cmd, **kwargs), Exception):
|
6196
6390
|
return None
|
6197
6391
|
else:
|
6198
6392
|
return ret
|
6199
6393
|
|
6200
|
-
def try_output_str(
|
6394
|
+
async def try_output_str(
|
6201
6395
|
self,
|
6202
6396
|
*cmd: str,
|
6203
6397
|
**kwargs: ta.Any,
|
6204
6398
|
) -> ta.Optional[str]:
|
6205
|
-
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
6399
|
+
if (ret := await self.try_output(*cmd, **kwargs)) is None:
|
6206
6400
|
return None
|
6207
6401
|
else:
|
6208
6402
|
return ret.decode().strip()
|
6209
6403
|
|
6210
6404
|
|
6211
|
-
|
6212
|
-
|
6213
|
-
|
6214
|
-
class Subprocesses(AbstractSubprocesses):
|
6215
|
-
def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
|
6216
|
-
proc = subprocess.run(
|
6217
|
-
run.cmd,
|
6218
|
-
input=run.input,
|
6219
|
-
timeout=run.timeout,
|
6220
|
-
check=run.check,
|
6221
|
-
capture_output=run.capture_output or False,
|
6222
|
-
**(run.kwargs or {}),
|
6223
|
-
)
|
6224
|
-
|
6225
|
-
return SubprocessRunOutput(
|
6226
|
-
proc=proc,
|
6227
|
-
|
6228
|
-
returncode=proc.returncode,
|
6229
|
-
|
6230
|
-
stdout=proc.stdout, # noqa
|
6231
|
-
stderr=proc.stderr, # noqa
|
6232
|
-
)
|
6233
|
-
|
6234
|
-
def check_call(
|
6235
|
-
self,
|
6236
|
-
*cmd: str,
|
6237
|
-
stdout: ta.Any = sys.stderr,
|
6238
|
-
**kwargs: ta.Any,
|
6239
|
-
) -> None:
|
6240
|
-
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
6241
|
-
subprocess.check_call(cmd, **kwargs)
|
6242
|
-
|
6243
|
-
def check_output(
|
6244
|
-
self,
|
6245
|
-
*cmd: str,
|
6246
|
-
**kwargs: ta.Any,
|
6247
|
-
) -> bytes:
|
6248
|
-
with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
|
6249
|
-
return subprocess.check_output(cmd, **kwargs)
|
6250
|
-
|
6251
|
-
|
6252
|
-
subprocesses = Subprocesses()
|
6405
|
+
########################################
|
6406
|
+
# ../../../omlish/subprocesses/sync.py
|
6253
6407
|
|
6254
6408
|
|
6255
6409
|
##
|
6256
6410
|
|
6257
6411
|
|
6258
|
-
class
|
6412
|
+
class AbstractSubprocesses(BaseSubprocesses, abc.ABC):
|
6259
6413
|
@abc.abstractmethod
|
6260
|
-
|
6414
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput:
|
6261
6415
|
raise NotImplementedError
|
6262
6416
|
|
6263
6417
|
def run(
|
@@ -6268,7 +6422,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
6268
6422
|
check: bool = False,
|
6269
6423
|
capture_output: ta.Optional[bool] = None,
|
6270
6424
|
**kwargs: ta.Any,
|
6271
|
-
) ->
|
6425
|
+
) -> SubprocessRunOutput:
|
6272
6426
|
return self.run_(SubprocessRun(
|
6273
6427
|
cmd=cmd,
|
6274
6428
|
input=input,
|
@@ -6281,7 +6435,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
6281
6435
|
#
|
6282
6436
|
|
6283
6437
|
@abc.abstractmethod
|
6284
|
-
|
6438
|
+
def check_call(
|
6285
6439
|
self,
|
6286
6440
|
*cmd: str,
|
6287
6441
|
stdout: ta.Any = sys.stderr,
|
@@ -6290,7 +6444,7 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
6290
6444
|
raise NotImplementedError
|
6291
6445
|
|
6292
6446
|
@abc.abstractmethod
|
6293
|
-
|
6447
|
+
def check_output(
|
6294
6448
|
self,
|
6295
6449
|
*cmd: str,
|
6296
6450
|
**kwargs: ta.Any,
|
@@ -6299,46 +6453,96 @@ class AbstractAsyncSubprocesses(BaseSubprocesses):
|
|
6299
6453
|
|
6300
6454
|
#
|
6301
6455
|
|
6302
|
-
|
6456
|
+
def check_output_str(
|
6303
6457
|
self,
|
6304
6458
|
*cmd: str,
|
6305
6459
|
**kwargs: ta.Any,
|
6306
6460
|
) -> str:
|
6307
|
-
return
|
6461
|
+
return self.check_output(*cmd, **kwargs).decode().strip()
|
6308
6462
|
|
6309
6463
|
#
|
6310
6464
|
|
6311
|
-
|
6465
|
+
def try_call(
|
6312
6466
|
self,
|
6313
6467
|
*cmd: str,
|
6314
6468
|
**kwargs: ta.Any,
|
6315
6469
|
) -> bool:
|
6316
|
-
if isinstance(
|
6470
|
+
if isinstance(self.try_fn(self.check_call, *cmd, **kwargs), Exception):
|
6317
6471
|
return False
|
6318
6472
|
else:
|
6319
6473
|
return True
|
6320
6474
|
|
6321
|
-
|
6475
|
+
def try_output(
|
6322
6476
|
self,
|
6323
6477
|
*cmd: str,
|
6324
6478
|
**kwargs: ta.Any,
|
6325
6479
|
) -> ta.Optional[bytes]:
|
6326
|
-
if isinstance(ret :=
|
6480
|
+
if isinstance(ret := self.try_fn(self.check_output, *cmd, **kwargs), Exception):
|
6327
6481
|
return None
|
6328
6482
|
else:
|
6329
6483
|
return ret
|
6330
6484
|
|
6331
|
-
|
6485
|
+
def try_output_str(
|
6332
6486
|
self,
|
6333
6487
|
*cmd: str,
|
6334
6488
|
**kwargs: ta.Any,
|
6335
6489
|
) -> ta.Optional[str]:
|
6336
|
-
if (ret :=
|
6490
|
+
if (ret := self.try_output(*cmd, **kwargs)) is None:
|
6337
6491
|
return None
|
6338
6492
|
else:
|
6339
6493
|
return ret.decode().strip()
|
6340
6494
|
|
6341
6495
|
|
6496
|
+
##
|
6497
|
+
|
6498
|
+
|
6499
|
+
class Subprocesses(AbstractSubprocesses):
|
6500
|
+
def run_(self, run: SubprocessRun) -> SubprocessRunOutput[subprocess.CompletedProcess]:
|
6501
|
+
with self.prepare_and_wrap(
|
6502
|
+
*run.cmd,
|
6503
|
+
input=run.input,
|
6504
|
+
timeout=run.timeout,
|
6505
|
+
check=run.check,
|
6506
|
+
capture_output=run.capture_output or False,
|
6507
|
+
**(run.kwargs or {}),
|
6508
|
+
) as (cmd, kwargs):
|
6509
|
+
proc = subprocess.run(cmd, **kwargs) # noqa
|
6510
|
+
|
6511
|
+
return SubprocessRunOutput(
|
6512
|
+
proc=proc,
|
6513
|
+
|
6514
|
+
returncode=proc.returncode,
|
6515
|
+
|
6516
|
+
stdout=proc.stdout, # noqa
|
6517
|
+
stderr=proc.stderr, # noqa
|
6518
|
+
)
|
6519
|
+
|
6520
|
+
def check_call(
|
6521
|
+
self,
|
6522
|
+
*cmd: str,
|
6523
|
+
stdout: ta.Any = sys.stderr,
|
6524
|
+
**kwargs: ta.Any,
|
6525
|
+
) -> None:
|
6526
|
+
with self.prepare_and_wrap(*cmd, stdout=stdout, **kwargs) as (cmd, kwargs): # noqa
|
6527
|
+
subprocess.check_call(cmd, **kwargs)
|
6528
|
+
|
6529
|
+
def check_output(
|
6530
|
+
self,
|
6531
|
+
*cmd: str,
|
6532
|
+
**kwargs: ta.Any,
|
6533
|
+
) -> bytes:
|
6534
|
+
with self.prepare_and_wrap(*cmd, **kwargs) as (cmd, kwargs): # noqa
|
6535
|
+
return subprocess.check_output(cmd, **kwargs)
|
6536
|
+
|
6537
|
+
|
6538
|
+
##
|
6539
|
+
|
6540
|
+
|
6541
|
+
subprocesses = Subprocesses()
|
6542
|
+
|
6543
|
+
SubprocessRun._DEFAULT_SUBPROCESSES = subprocesses # noqa
|
6544
|
+
|
6545
|
+
|
6342
6546
|
########################################
|
6343
6547
|
# ../../git/revisions.py
|
6344
6548
|
|
@@ -6385,50 +6589,6 @@ def get_git_revision(
|
|
6385
6589
|
return dirty_rev + ('-untracked' if has_untracked else '')
|
6386
6590
|
|
6387
6591
|
|
6388
|
-
########################################
|
6389
|
-
# ../../interp/providers/base.py
|
6390
|
-
"""
|
6391
|
-
TODO:
|
6392
|
-
- backends
|
6393
|
-
- local builds
|
6394
|
-
- deadsnakes?
|
6395
|
-
- uv
|
6396
|
-
- loose versions
|
6397
|
-
"""
|
6398
|
-
|
6399
|
-
|
6400
|
-
##
|
6401
|
-
|
6402
|
-
|
6403
|
-
class InterpProvider(abc.ABC):
|
6404
|
-
name: ta.ClassVar[str]
|
6405
|
-
|
6406
|
-
def __init_subclass__(cls, **kwargs: ta.Any) -> None:
|
6407
|
-
super().__init_subclass__(**kwargs)
|
6408
|
-
if abc.ABC not in cls.__bases__ and 'name' not in cls.__dict__:
|
6409
|
-
sfx = 'InterpProvider'
|
6410
|
-
if not cls.__name__.endswith(sfx):
|
6411
|
-
raise NameError(cls)
|
6412
|
-
setattr(cls, 'name', snake_case(cls.__name__[:-len(sfx)]))
|
6413
|
-
|
6414
|
-
@abc.abstractmethod
|
6415
|
-
def get_installed_versions(self, spec: InterpSpecifier) -> ta.Awaitable[ta.Sequence[InterpVersion]]:
|
6416
|
-
raise NotImplementedError
|
6417
|
-
|
6418
|
-
@abc.abstractmethod
|
6419
|
-
def get_installed_version(self, version: InterpVersion) -> ta.Awaitable[Interp]:
|
6420
|
-
raise NotImplementedError
|
6421
|
-
|
6422
|
-
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
6423
|
-
return []
|
6424
|
-
|
6425
|
-
async def install_version(self, version: InterpVersion) -> Interp:
|
6426
|
-
raise TypeError
|
6427
|
-
|
6428
|
-
|
6429
|
-
InterpProviders = ta.NewType('InterpProviders', ta.Sequence[InterpProvider])
|
6430
|
-
|
6431
|
-
|
6432
6592
|
########################################
|
6433
6593
|
# ../../../omlish/asyncs/asyncio/subprocesses.py
|
6434
6594
|
|
@@ -6571,19 +6731,19 @@ class AsyncioSubprocesses(AbstractAsyncSubprocesses):
|
|
6571
6731
|
timeout: ta.Optional[float] = None,
|
6572
6732
|
**kwargs: ta.Any,
|
6573
6733
|
) -> ta.AsyncGenerator[asyncio.subprocess.Process, None]:
|
6574
|
-
fac: ta.Any
|
6575
|
-
if shell:
|
6576
|
-
fac = functools.partial(
|
6577
|
-
asyncio.create_subprocess_shell,
|
6578
|
-
check.single(cmd),
|
6579
|
-
)
|
6580
|
-
else:
|
6581
|
-
fac = functools.partial(
|
6582
|
-
asyncio.create_subprocess_exec,
|
6583
|
-
*cmd,
|
6584
|
-
)
|
6585
|
-
|
6586
6734
|
with self.prepare_and_wrap( *cmd, shell=shell, **kwargs) as (cmd, kwargs): # noqa
|
6735
|
+
fac: ta.Any
|
6736
|
+
if shell:
|
6737
|
+
fac = functools.partial(
|
6738
|
+
asyncio.create_subprocess_shell,
|
6739
|
+
check.single(cmd),
|
6740
|
+
)
|
6741
|
+
else:
|
6742
|
+
fac = functools.partial(
|
6743
|
+
asyncio.create_subprocess_exec,
|
6744
|
+
*cmd,
|
6745
|
+
)
|
6746
|
+
|
6587
6747
|
proc: asyncio.subprocess.Process = await fac(**kwargs)
|
6588
6748
|
try:
|
6589
6749
|
yield proc
|
@@ -6824,94 +6984,6 @@ class Pyenv:
|
|
6824
6984
|
return True
|
6825
6985
|
|
6826
6986
|
|
6827
|
-
########################################
|
6828
|
-
# ../../interp/resolvers.py
|
6829
|
-
|
6830
|
-
|
6831
|
-
@dc.dataclass(frozen=True)
|
6832
|
-
class InterpResolverProviders:
|
6833
|
-
providers: ta.Sequence[ta.Tuple[str, InterpProvider]]
|
6834
|
-
|
6835
|
-
|
6836
|
-
class InterpResolver:
|
6837
|
-
def __init__(
|
6838
|
-
self,
|
6839
|
-
providers: InterpResolverProviders,
|
6840
|
-
) -> None:
|
6841
|
-
super().__init__()
|
6842
|
-
|
6843
|
-
self._providers: ta.Mapping[str, InterpProvider] = collections.OrderedDict(providers.providers)
|
6844
|
-
|
6845
|
-
async def _resolve_installed(self, spec: InterpSpecifier) -> ta.Optional[ta.Tuple[InterpProvider, InterpVersion]]:
|
6846
|
-
lst = [
|
6847
|
-
(i, si)
|
6848
|
-
for i, p in enumerate(self._providers.values())
|
6849
|
-
for si in await p.get_installed_versions(spec)
|
6850
|
-
if spec.contains(si)
|
6851
|
-
]
|
6852
|
-
|
6853
|
-
slst = sorted(lst, key=lambda t: (-t[0], t[1].version))
|
6854
|
-
if not slst:
|
6855
|
-
return None
|
6856
|
-
|
6857
|
-
bi, bv = slst[-1]
|
6858
|
-
bp = list(self._providers.values())[bi]
|
6859
|
-
return (bp, bv)
|
6860
|
-
|
6861
|
-
async def resolve(
|
6862
|
-
self,
|
6863
|
-
spec: InterpSpecifier,
|
6864
|
-
*,
|
6865
|
-
install: bool = False,
|
6866
|
-
) -> ta.Optional[Interp]:
|
6867
|
-
tup = await self._resolve_installed(spec)
|
6868
|
-
if tup is not None:
|
6869
|
-
bp, bv = tup
|
6870
|
-
return await bp.get_installed_version(bv)
|
6871
|
-
|
6872
|
-
if not install:
|
6873
|
-
return None
|
6874
|
-
|
6875
|
-
tp = list(self._providers.values())[0] # noqa
|
6876
|
-
|
6877
|
-
sv = sorted(
|
6878
|
-
[s for s in await tp.get_installable_versions(spec) if s in spec],
|
6879
|
-
key=lambda s: s.version,
|
6880
|
-
)
|
6881
|
-
if not sv:
|
6882
|
-
return None
|
6883
|
-
|
6884
|
-
bv = sv[-1]
|
6885
|
-
return await tp.install_version(bv)
|
6886
|
-
|
6887
|
-
async def list(self, spec: InterpSpecifier) -> None:
|
6888
|
-
print('installed:')
|
6889
|
-
for n, p in self._providers.items():
|
6890
|
-
lst = [
|
6891
|
-
si
|
6892
|
-
for si in await p.get_installed_versions(spec)
|
6893
|
-
if spec.contains(si)
|
6894
|
-
]
|
6895
|
-
if lst:
|
6896
|
-
print(f' {n}')
|
6897
|
-
for si in lst:
|
6898
|
-
print(f' {si}')
|
6899
|
-
|
6900
|
-
print()
|
6901
|
-
|
6902
|
-
print('installable:')
|
6903
|
-
for n, p in self._providers.items():
|
6904
|
-
lst = [
|
6905
|
-
si
|
6906
|
-
for si in await p.get_installable_versions(spec)
|
6907
|
-
if spec.contains(si)
|
6908
|
-
]
|
6909
|
-
if lst:
|
6910
|
-
print(f' {n}')
|
6911
|
-
for si in lst:
|
6912
|
-
print(f' {si}')
|
6913
|
-
|
6914
|
-
|
6915
6987
|
########################################
|
6916
6988
|
# ../../revisions.py
|
6917
6989
|
"""
|