ominfra 0.0.0.dev181__tar.gz → 0.0.0.dev182__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {ominfra-0.0.0.dev181/ominfra.egg-info → ominfra-0.0.0.dev182}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/scripts/manage.py +251 -249
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182/ominfra.egg-info}/PKG-INFO +3 -3
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra.egg-info/requires.txt +2 -2
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/pyproject.toml +3 -3
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/LICENSE +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/MANIFEST.in +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/README.rst +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/.manifests.json +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/__about__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/__main__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/auth.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/cli.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/dataclasses.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/__main__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/cursor.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/driver.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/main.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/journald2aws/poster.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/logs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/aws/metadata.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/gcp/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/clouds/gcp/auth.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/cmds.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/configs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/journald/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/journald/fields.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/journald/genmessages.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/journald/messages.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/journald/tailer.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/__main__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/bootstrap.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/bootstrap_.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/base.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/local.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/marshal.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/ping.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/subprocess.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/commands/types.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/config.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/apps.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/commands.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/conf.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/config.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/deploy.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/driver.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/git.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/interp.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/manager.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/owners.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/paths.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/paths/types.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/specs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/tags.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/tmp.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/types.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/deploy/venvs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/main.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/marshal.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/_main.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/channel.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/config.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/connection.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/execution.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/payload.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/remote/spawning.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/commands.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/config.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/packages.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/system/platforms.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/bestpython.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/bestpython.sh +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/connection.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/manage/targets/targets.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/pyremote.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/scripts/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/scripts/journald2aws.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/scripts/supervisor.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/ssh.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/LICENSE.txt +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/__main__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/configs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/dispatchers.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/dispatchersimpl.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/events.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/exceptions.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/groups.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/groupsimpl.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/http.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/inject.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/io.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/main.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/pipes.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/privileges.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/process.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/processimpl.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/setup.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/setupimpl.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/signals.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/spawning.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/spawningimpl.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/states.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/supervisor.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/types.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/collections.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/diag.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/fds.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/fs.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/os.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/ostypes.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/signals.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/strings.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/supervisor/utils/users.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/systemd.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/tailscale/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/tailscale/api.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/tailscale/cli.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/threadworkers.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/tools/__init__.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra/tools/listresources.py +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra.egg-info/SOURCES.txt +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra.egg-info/dependency_links.txt +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra.egg-info/entry_points.txt +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/ominfra.egg-info/top_level.txt +0 -0
- {ominfra-0.0.0.dev181 → ominfra-0.0.0.dev182}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev182
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev182
|
16
|
+
Requires-Dist: omlish==0.0.0.dev182
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -8914,6 +8914,88 @@ class InterpInspector:
|
|
8914
8914
|
return ret
|
8915
8915
|
|
8916
8916
|
|
8917
|
+
########################################
|
8918
|
+
# ../../../omdev/interp/pyenv/pyenv.py
|
8919
|
+
"""
|
8920
|
+
TODO:
|
8921
|
+
- custom tags
|
8922
|
+
- 'aliases'
|
8923
|
+
- https://github.com/pyenv/pyenv/pull/2966
|
8924
|
+
- https://github.com/pyenv/pyenv/issues/218 (lol)
|
8925
|
+
- probably need custom (temp?) definition file
|
8926
|
+
- *or* python-build directly just into the versions dir?
|
8927
|
+
- optionally install / upgrade pyenv itself
|
8928
|
+
- new vers dont need these custom mac opts, only run on old vers
|
8929
|
+
"""
|
8930
|
+
|
8931
|
+
|
8932
|
+
class Pyenv:
|
8933
|
+
def __init__(
|
8934
|
+
self,
|
8935
|
+
*,
|
8936
|
+
root: ta.Optional[str] = None,
|
8937
|
+
) -> None:
|
8938
|
+
if root is not None and not (isinstance(root, str) and root):
|
8939
|
+
raise ValueError(f'pyenv_root: {root!r}')
|
8940
|
+
|
8941
|
+
super().__init__()
|
8942
|
+
|
8943
|
+
self._root_kw = root
|
8944
|
+
|
8945
|
+
@async_cached_nullary
|
8946
|
+
async def root(self) -> ta.Optional[str]:
|
8947
|
+
if self._root_kw is not None:
|
8948
|
+
return self._root_kw
|
8949
|
+
|
8950
|
+
if shutil.which('pyenv'):
|
8951
|
+
return await asyncio_subprocesses.check_output_str('pyenv', 'root')
|
8952
|
+
|
8953
|
+
d = os.path.expanduser('~/.pyenv')
|
8954
|
+
if os.path.isdir(d) and os.path.isfile(os.path.join(d, 'bin', 'pyenv')):
|
8955
|
+
return d
|
8956
|
+
|
8957
|
+
return None
|
8958
|
+
|
8959
|
+
@async_cached_nullary
|
8960
|
+
async def exe(self) -> str:
|
8961
|
+
return os.path.join(check.not_none(await self.root()), 'bin', 'pyenv')
|
8962
|
+
|
8963
|
+
async def version_exes(self) -> ta.List[ta.Tuple[str, str]]:
|
8964
|
+
if (root := await self.root()) is None:
|
8965
|
+
return []
|
8966
|
+
ret = []
|
8967
|
+
vp = os.path.join(root, 'versions')
|
8968
|
+
if os.path.isdir(vp):
|
8969
|
+
for dn in os.listdir(vp):
|
8970
|
+
ep = os.path.join(vp, dn, 'bin', 'python')
|
8971
|
+
if not os.path.isfile(ep):
|
8972
|
+
continue
|
8973
|
+
ret.append((dn, ep))
|
8974
|
+
return ret
|
8975
|
+
|
8976
|
+
async def installable_versions(self) -> ta.List[str]:
|
8977
|
+
if await self.root() is None:
|
8978
|
+
return []
|
8979
|
+
ret = []
|
8980
|
+
s = await asyncio_subprocesses.check_output_str(await self.exe(), 'install', '--list')
|
8981
|
+
for l in s.splitlines():
|
8982
|
+
if not l.startswith(' '):
|
8983
|
+
continue
|
8984
|
+
l = l.strip()
|
8985
|
+
if not l:
|
8986
|
+
continue
|
8987
|
+
ret.append(l)
|
8988
|
+
return ret
|
8989
|
+
|
8990
|
+
async def update(self) -> bool:
|
8991
|
+
if (root := await self.root()) is None:
|
8992
|
+
return False
|
8993
|
+
if not os.path.isdir(os.path.join(root, '.git')):
|
8994
|
+
return False
|
8995
|
+
await asyncio_subprocesses.check_call('git', 'pull', cwd=root)
|
8996
|
+
return True
|
8997
|
+
|
8998
|
+
|
8917
8999
|
########################################
|
8918
9000
|
# ../../../omdev/interp/resolvers.py
|
8919
9001
|
|
@@ -9802,88 +9884,7 @@ class SystemInterpProvider(InterpProvider):
|
|
9802
9884
|
|
9803
9885
|
|
9804
9886
|
########################################
|
9805
|
-
# ../../../omdev/interp/pyenv/
|
9806
|
-
"""
|
9807
|
-
TODO:
|
9808
|
-
- custom tags
|
9809
|
-
- 'aliases'
|
9810
|
-
- https://github.com/pyenv/pyenv/pull/2966
|
9811
|
-
- https://github.com/pyenv/pyenv/issues/218 (lol)
|
9812
|
-
- probably need custom (temp?) definition file
|
9813
|
-
- *or* python-build directly just into the versions dir?
|
9814
|
-
- optionally install / upgrade pyenv itself
|
9815
|
-
- new vers dont need these custom mac opts, only run on old vers
|
9816
|
-
"""
|
9817
|
-
|
9818
|
-
|
9819
|
-
##
|
9820
|
-
|
9821
|
-
|
9822
|
-
class Pyenv:
|
9823
|
-
def __init__(
|
9824
|
-
self,
|
9825
|
-
*,
|
9826
|
-
root: ta.Optional[str] = None,
|
9827
|
-
) -> None:
|
9828
|
-
if root is not None and not (isinstance(root, str) and root):
|
9829
|
-
raise ValueError(f'pyenv_root: {root!r}')
|
9830
|
-
|
9831
|
-
super().__init__()
|
9832
|
-
|
9833
|
-
self._root_kw = root
|
9834
|
-
|
9835
|
-
@async_cached_nullary
|
9836
|
-
async def root(self) -> ta.Optional[str]:
|
9837
|
-
if self._root_kw is not None:
|
9838
|
-
return self._root_kw
|
9839
|
-
|
9840
|
-
if shutil.which('pyenv'):
|
9841
|
-
return await asyncio_subprocesses.check_output_str('pyenv', 'root')
|
9842
|
-
|
9843
|
-
d = os.path.expanduser('~/.pyenv')
|
9844
|
-
if os.path.isdir(d) and os.path.isfile(os.path.join(d, 'bin', 'pyenv')):
|
9845
|
-
return d
|
9846
|
-
|
9847
|
-
return None
|
9848
|
-
|
9849
|
-
@async_cached_nullary
|
9850
|
-
async def exe(self) -> str:
|
9851
|
-
return os.path.join(check.not_none(await self.root()), 'bin', 'pyenv')
|
9852
|
-
|
9853
|
-
async def version_exes(self) -> ta.List[ta.Tuple[str, str]]:
|
9854
|
-
if (root := await self.root()) is None:
|
9855
|
-
return []
|
9856
|
-
ret = []
|
9857
|
-
vp = os.path.join(root, 'versions')
|
9858
|
-
if os.path.isdir(vp):
|
9859
|
-
for dn in os.listdir(vp):
|
9860
|
-
ep = os.path.join(vp, dn, 'bin', 'python')
|
9861
|
-
if not os.path.isfile(ep):
|
9862
|
-
continue
|
9863
|
-
ret.append((dn, ep))
|
9864
|
-
return ret
|
9865
|
-
|
9866
|
-
async def installable_versions(self) -> ta.List[str]:
|
9867
|
-
if await self.root() is None:
|
9868
|
-
return []
|
9869
|
-
ret = []
|
9870
|
-
s = await asyncio_subprocesses.check_output_str(await self.exe(), 'install', '--list')
|
9871
|
-
for l in s.splitlines():
|
9872
|
-
if not l.startswith(' '):
|
9873
|
-
continue
|
9874
|
-
l = l.strip()
|
9875
|
-
if not l:
|
9876
|
-
continue
|
9877
|
-
ret.append(l)
|
9878
|
-
return ret
|
9879
|
-
|
9880
|
-
async def update(self) -> bool:
|
9881
|
-
if (root := await self.root()) is None:
|
9882
|
-
return False
|
9883
|
-
if not os.path.isdir(os.path.join(root, '.git')):
|
9884
|
-
return False
|
9885
|
-
await asyncio_subprocesses.check_call('git', 'pull', cwd=root)
|
9886
|
-
return True
|
9887
|
+
# ../../../omdev/interp/pyenv/install.py
|
9887
9888
|
|
9888
9889
|
|
9889
9890
|
##
|
@@ -10121,136 +10122,6 @@ class PyenvVersionInstaller:
|
|
10121
10122
|
return exe
|
10122
10123
|
|
10123
10124
|
|
10124
|
-
##
|
10125
|
-
|
10126
|
-
|
10127
|
-
class PyenvInterpProvider(InterpProvider):
|
10128
|
-
@dc.dataclass(frozen=True)
|
10129
|
-
class Options:
|
10130
|
-
inspect: bool = False
|
10131
|
-
|
10132
|
-
try_update: bool = False
|
10133
|
-
|
10134
|
-
def __init__(
|
10135
|
-
self,
|
10136
|
-
options: Options = Options(),
|
10137
|
-
*,
|
10138
|
-
pyenv: Pyenv,
|
10139
|
-
inspector: InterpInspector,
|
10140
|
-
log: ta.Optional[logging.Logger] = None,
|
10141
|
-
) -> None:
|
10142
|
-
super().__init__()
|
10143
|
-
|
10144
|
-
self._options = options
|
10145
|
-
|
10146
|
-
self._pyenv = pyenv
|
10147
|
-
self._inspector = inspector
|
10148
|
-
self._log = log
|
10149
|
-
|
10150
|
-
#
|
10151
|
-
|
10152
|
-
@staticmethod
|
10153
|
-
def guess_version(s: str) -> ta.Optional[InterpVersion]:
|
10154
|
-
def strip_sfx(s: str, sfx: str) -> ta.Tuple[str, bool]:
|
10155
|
-
if s.endswith(sfx):
|
10156
|
-
return s[:-len(sfx)], True
|
10157
|
-
return s, False
|
10158
|
-
ok = {}
|
10159
|
-
s, ok['debug'] = strip_sfx(s, '-debug')
|
10160
|
-
s, ok['threaded'] = strip_sfx(s, 't')
|
10161
|
-
try:
|
10162
|
-
v = Version(s)
|
10163
|
-
except InvalidVersion:
|
10164
|
-
return None
|
10165
|
-
return InterpVersion(v, InterpOpts(**ok))
|
10166
|
-
|
10167
|
-
class Installed(ta.NamedTuple):
|
10168
|
-
name: str
|
10169
|
-
exe: str
|
10170
|
-
version: InterpVersion
|
10171
|
-
|
10172
|
-
async def _make_installed(self, vn: str, ep: str) -> ta.Optional[Installed]:
|
10173
|
-
iv: ta.Optional[InterpVersion]
|
10174
|
-
if self._options.inspect:
|
10175
|
-
try:
|
10176
|
-
iv = check.not_none(await self._inspector.inspect(ep)).iv
|
10177
|
-
except Exception as e: # noqa
|
10178
|
-
return None
|
10179
|
-
else:
|
10180
|
-
iv = self.guess_version(vn)
|
10181
|
-
if iv is None:
|
10182
|
-
return None
|
10183
|
-
return PyenvInterpProvider.Installed(
|
10184
|
-
name=vn,
|
10185
|
-
exe=ep,
|
10186
|
-
version=iv,
|
10187
|
-
)
|
10188
|
-
|
10189
|
-
async def installed(self) -> ta.Sequence[Installed]:
|
10190
|
-
ret: ta.List[PyenvInterpProvider.Installed] = []
|
10191
|
-
for vn, ep in await self._pyenv.version_exes():
|
10192
|
-
if (i := await self._make_installed(vn, ep)) is None:
|
10193
|
-
if self._log is not None:
|
10194
|
-
self._log.debug('Invalid pyenv version: %s', vn)
|
10195
|
-
continue
|
10196
|
-
ret.append(i)
|
10197
|
-
return ret
|
10198
|
-
|
10199
|
-
#
|
10200
|
-
|
10201
|
-
async def get_installed_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10202
|
-
return [i.version for i in await self.installed()]
|
10203
|
-
|
10204
|
-
async def get_installed_version(self, version: InterpVersion) -> Interp:
|
10205
|
-
for i in await self.installed():
|
10206
|
-
if i.version == version:
|
10207
|
-
return Interp(
|
10208
|
-
exe=i.exe,
|
10209
|
-
version=i.version,
|
10210
|
-
)
|
10211
|
-
raise KeyError(version)
|
10212
|
-
|
10213
|
-
#
|
10214
|
-
|
10215
|
-
async def _get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10216
|
-
lst = []
|
10217
|
-
|
10218
|
-
for vs in await self._pyenv.installable_versions():
|
10219
|
-
if (iv := self.guess_version(vs)) is None:
|
10220
|
-
continue
|
10221
|
-
if iv.opts.debug:
|
10222
|
-
raise Exception('Pyenv installable versions not expected to have debug suffix')
|
10223
|
-
for d in [False, True]:
|
10224
|
-
lst.append(dc.replace(iv, opts=dc.replace(iv.opts, debug=d)))
|
10225
|
-
|
10226
|
-
return lst
|
10227
|
-
|
10228
|
-
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10229
|
-
lst = await self._get_installable_versions(spec)
|
10230
|
-
|
10231
|
-
if self._options.try_update and not any(v in spec for v in lst):
|
10232
|
-
if self._pyenv.update():
|
10233
|
-
lst = await self._get_installable_versions(spec)
|
10234
|
-
|
10235
|
-
return lst
|
10236
|
-
|
10237
|
-
async def install_version(self, version: InterpVersion) -> Interp:
|
10238
|
-
inst_version = str(version.version)
|
10239
|
-
inst_opts = version.opts
|
10240
|
-
if inst_opts.threaded:
|
10241
|
-
inst_version += 't'
|
10242
|
-
inst_opts = dc.replace(inst_opts, threaded=False)
|
10243
|
-
|
10244
|
-
installer = PyenvVersionInstaller(
|
10245
|
-
inst_version,
|
10246
|
-
interp_opts=inst_opts,
|
10247
|
-
pyenv=self._pyenv,
|
10248
|
-
)
|
10249
|
-
|
10250
|
-
exe = await installer.install()
|
10251
|
-
return Interp(exe, version)
|
10252
|
-
|
10253
|
-
|
10254
10125
|
########################################
|
10255
10126
|
# ../commands/inject.py
|
10256
10127
|
|
@@ -10578,18 +10449,134 @@ def bind_interp_providers() -> InjectorBindings:
|
|
10578
10449
|
|
10579
10450
|
|
10580
10451
|
########################################
|
10581
|
-
# ../../../omdev/interp/pyenv/
|
10452
|
+
# ../../../omdev/interp/pyenv/provider.py
|
10582
10453
|
|
10583
10454
|
|
10584
|
-
|
10585
|
-
|
10586
|
-
|
10455
|
+
class PyenvInterpProvider(InterpProvider):
|
10456
|
+
@dc.dataclass(frozen=True)
|
10457
|
+
class Options:
|
10458
|
+
inspect: bool = False
|
10587
10459
|
|
10588
|
-
|
10589
|
-
inj.bind(InterpProvider, to_key=PyenvInterpProvider, array=True),
|
10590
|
-
]
|
10460
|
+
try_update: bool = False
|
10591
10461
|
|
10592
|
-
|
10462
|
+
def __init__(
|
10463
|
+
self,
|
10464
|
+
options: Options = Options(),
|
10465
|
+
*,
|
10466
|
+
pyenv: Pyenv,
|
10467
|
+
inspector: InterpInspector,
|
10468
|
+
log: ta.Optional[logging.Logger] = None,
|
10469
|
+
) -> None:
|
10470
|
+
super().__init__()
|
10471
|
+
|
10472
|
+
self._options = options
|
10473
|
+
|
10474
|
+
self._pyenv = pyenv
|
10475
|
+
self._inspector = inspector
|
10476
|
+
self._log = log
|
10477
|
+
|
10478
|
+
#
|
10479
|
+
|
10480
|
+
@staticmethod
|
10481
|
+
def guess_version(s: str) -> ta.Optional[InterpVersion]:
|
10482
|
+
def strip_sfx(s: str, sfx: str) -> ta.Tuple[str, bool]:
|
10483
|
+
if s.endswith(sfx):
|
10484
|
+
return s[:-len(sfx)], True
|
10485
|
+
return s, False
|
10486
|
+
ok = {}
|
10487
|
+
s, ok['debug'] = strip_sfx(s, '-debug')
|
10488
|
+
s, ok['threaded'] = strip_sfx(s, 't')
|
10489
|
+
try:
|
10490
|
+
v = Version(s)
|
10491
|
+
except InvalidVersion:
|
10492
|
+
return None
|
10493
|
+
return InterpVersion(v, InterpOpts(**ok))
|
10494
|
+
|
10495
|
+
class Installed(ta.NamedTuple):
|
10496
|
+
name: str
|
10497
|
+
exe: str
|
10498
|
+
version: InterpVersion
|
10499
|
+
|
10500
|
+
async def _make_installed(self, vn: str, ep: str) -> ta.Optional[Installed]:
|
10501
|
+
iv: ta.Optional[InterpVersion]
|
10502
|
+
if self._options.inspect:
|
10503
|
+
try:
|
10504
|
+
iv = check.not_none(await self._inspector.inspect(ep)).iv
|
10505
|
+
except Exception as e: # noqa
|
10506
|
+
return None
|
10507
|
+
else:
|
10508
|
+
iv = self.guess_version(vn)
|
10509
|
+
if iv is None:
|
10510
|
+
return None
|
10511
|
+
return PyenvInterpProvider.Installed(
|
10512
|
+
name=vn,
|
10513
|
+
exe=ep,
|
10514
|
+
version=iv,
|
10515
|
+
)
|
10516
|
+
|
10517
|
+
async def installed(self) -> ta.Sequence[Installed]:
|
10518
|
+
ret: ta.List[PyenvInterpProvider.Installed] = []
|
10519
|
+
for vn, ep in await self._pyenv.version_exes():
|
10520
|
+
if (i := await self._make_installed(vn, ep)) is None:
|
10521
|
+
if self._log is not None:
|
10522
|
+
self._log.debug('Invalid pyenv version: %s', vn)
|
10523
|
+
continue
|
10524
|
+
ret.append(i)
|
10525
|
+
return ret
|
10526
|
+
|
10527
|
+
#
|
10528
|
+
|
10529
|
+
async def get_installed_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10530
|
+
return [i.version for i in await self.installed()]
|
10531
|
+
|
10532
|
+
async def get_installed_version(self, version: InterpVersion) -> Interp:
|
10533
|
+
for i in await self.installed():
|
10534
|
+
if i.version == version:
|
10535
|
+
return Interp(
|
10536
|
+
exe=i.exe,
|
10537
|
+
version=i.version,
|
10538
|
+
)
|
10539
|
+
raise KeyError(version)
|
10540
|
+
|
10541
|
+
#
|
10542
|
+
|
10543
|
+
async def _get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10544
|
+
lst = []
|
10545
|
+
|
10546
|
+
for vs in await self._pyenv.installable_versions():
|
10547
|
+
if (iv := self.guess_version(vs)) is None:
|
10548
|
+
continue
|
10549
|
+
if iv.opts.debug:
|
10550
|
+
raise Exception('Pyenv installable versions not expected to have debug suffix')
|
10551
|
+
for d in [False, True]:
|
10552
|
+
lst.append(dc.replace(iv, opts=dc.replace(iv.opts, debug=d)))
|
10553
|
+
|
10554
|
+
return lst
|
10555
|
+
|
10556
|
+
async def get_installable_versions(self, spec: InterpSpecifier) -> ta.Sequence[InterpVersion]:
|
10557
|
+
lst = await self._get_installable_versions(spec)
|
10558
|
+
|
10559
|
+
if self._options.try_update and not any(v in spec for v in lst):
|
10560
|
+
if self._pyenv.update():
|
10561
|
+
lst = await self._get_installable_versions(spec)
|
10562
|
+
|
10563
|
+
return lst
|
10564
|
+
|
10565
|
+
async def install_version(self, version: InterpVersion) -> Interp:
|
10566
|
+
inst_version = str(version.version)
|
10567
|
+
inst_opts = version.opts
|
10568
|
+
if inst_opts.threaded:
|
10569
|
+
inst_version += 't'
|
10570
|
+
inst_opts = dc.replace(inst_opts, threaded=False)
|
10571
|
+
|
10572
|
+
installer = PyenvVersionInstaller(
|
10573
|
+
inst_version,
|
10574
|
+
interp_opts=inst_opts,
|
10575
|
+
pyenv=self._pyenv,
|
10576
|
+
)
|
10577
|
+
|
10578
|
+
exe = await installer.install()
|
10579
|
+
return Interp(exe, version)
|
10593
10580
|
|
10594
10581
|
|
10595
10582
|
########################################
|
@@ -10955,6 +10942,50 @@ class SshManageTargetConnector(ManageTargetConnector):
|
|
10955
10942
|
yield rce
|
10956
10943
|
|
10957
10944
|
|
10945
|
+
########################################
|
10946
|
+
# ../../../omdev/interp/pyenv/inject.py
|
10947
|
+
|
10948
|
+
|
10949
|
+
def bind_interp_pyenv() -> InjectorBindings:
|
10950
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
10951
|
+
inj.bind(Pyenv, singleton=True),
|
10952
|
+
|
10953
|
+
inj.bind(PyenvInterpProvider, singleton=True),
|
10954
|
+
inj.bind(InterpProvider, to_key=PyenvInterpProvider, array=True),
|
10955
|
+
]
|
10956
|
+
|
10957
|
+
return inj.as_bindings(*lst)
|
10958
|
+
|
10959
|
+
|
10960
|
+
########################################
|
10961
|
+
# ../targets/inject.py
|
10962
|
+
|
10963
|
+
|
10964
|
+
def bind_targets() -> InjectorBindings:
|
10965
|
+
lst: ta.List[InjectorBindingOrBindings] = [
|
10966
|
+
inj.bind(LocalManageTargetConnector, singleton=True),
|
10967
|
+
inj.bind(DockerManageTargetConnector, singleton=True),
|
10968
|
+
inj.bind(SshManageTargetConnector, singleton=True),
|
10969
|
+
|
10970
|
+
inj.bind(TypeSwitchedManageTargetConnector, singleton=True),
|
10971
|
+
inj.bind(ManageTargetConnector, to_key=TypeSwitchedManageTargetConnector),
|
10972
|
+
]
|
10973
|
+
|
10974
|
+
#
|
10975
|
+
|
10976
|
+
def provide_manage_target_connector_map(injector: Injector) -> ManageTargetConnectorMap:
|
10977
|
+
return ManageTargetConnectorMap({
|
10978
|
+
LocalManageTarget: injector[LocalManageTargetConnector],
|
10979
|
+
DockerManageTarget: injector[DockerManageTargetConnector],
|
10980
|
+
SshManageTarget: injector[SshManageTargetConnector],
|
10981
|
+
})
|
10982
|
+
lst.append(inj.bind(provide_manage_target_connector_map, singleton=True))
|
10983
|
+
|
10984
|
+
#
|
10985
|
+
|
10986
|
+
return inj.as_bindings(*lst)
|
10987
|
+
|
10988
|
+
|
10958
10989
|
########################################
|
10959
10990
|
# ../../../omdev/interp/inject.py
|
10960
10991
|
|
@@ -10996,35 +11027,6 @@ def bind_interp() -> InjectorBindings:
|
|
10996
11027
|
return inj.as_bindings(*lst)
|
10997
11028
|
|
10998
11029
|
|
10999
|
-
########################################
|
11000
|
-
# ../targets/inject.py
|
11001
|
-
|
11002
|
-
|
11003
|
-
def bind_targets() -> InjectorBindings:
|
11004
|
-
lst: ta.List[InjectorBindingOrBindings] = [
|
11005
|
-
inj.bind(LocalManageTargetConnector, singleton=True),
|
11006
|
-
inj.bind(DockerManageTargetConnector, singleton=True),
|
11007
|
-
inj.bind(SshManageTargetConnector, singleton=True),
|
11008
|
-
|
11009
|
-
inj.bind(TypeSwitchedManageTargetConnector, singleton=True),
|
11010
|
-
inj.bind(ManageTargetConnector, to_key=TypeSwitchedManageTargetConnector),
|
11011
|
-
]
|
11012
|
-
|
11013
|
-
#
|
11014
|
-
|
11015
|
-
def provide_manage_target_connector_map(injector: Injector) -> ManageTargetConnectorMap:
|
11016
|
-
return ManageTargetConnectorMap({
|
11017
|
-
LocalManageTarget: injector[LocalManageTargetConnector],
|
11018
|
-
DockerManageTarget: injector[DockerManageTargetConnector],
|
11019
|
-
SshManageTarget: injector[SshManageTargetConnector],
|
11020
|
-
})
|
11021
|
-
lst.append(inj.bind(provide_manage_target_connector_map, singleton=True))
|
11022
|
-
|
11023
|
-
#
|
11024
|
-
|
11025
|
-
return inj.as_bindings(*lst)
|
11026
|
-
|
11027
|
-
|
11028
11030
|
########################################
|
11029
11031
|
# ../../../omdev/interp/default.py
|
11030
11032
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev182
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev182
|
16
|
+
Requires-Dist: omlish==0.0.0.dev182
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|
@@ -12,7 +12,7 @@ authors = [
|
|
12
12
|
urls = {source = 'https://github.com/wrmsr/omlish'}
|
13
13
|
license = {text = 'BSD-3-Clause'}
|
14
14
|
requires-python = '>=3.12'
|
15
|
-
version = '0.0.0.
|
15
|
+
version = '0.0.0.dev182'
|
16
16
|
classifiers = [
|
17
17
|
'License :: OSI Approved :: BSD License',
|
18
18
|
'Development Status :: 2 - Pre-Alpha',
|
@@ -22,8 +22,8 @@ classifiers = [
|
|
22
22
|
]
|
23
23
|
description = 'ominfra'
|
24
24
|
dependencies = [
|
25
|
-
'omdev == 0.0.0.
|
26
|
-
'omlish == 0.0.0.
|
25
|
+
'omdev == 0.0.0.dev182',
|
26
|
+
'omlish == 0.0.0.dev182',
|
27
27
|
]
|
28
28
|
|
29
29
|
[project.optional-dependencies]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|