omdev 0.0.0.dev223__py3-none-any.whl → 0.0.0.dev225__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omdev/amalg/typing.py +7 -1
- omdev/ci/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
|
"""
|