omdev 0.0.0.dev43__py3-none-any.whl → 0.0.0.dev44__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.

Potentially problematic release.


This version of omdev might be problematic. Click here for more details.

omdev/.manifests.json CHANGED
@@ -36,14 +36,14 @@
36
36
  }
37
37
  },
38
38
  {
39
- "module": ".cli.clicmds",
39
+ "module": ".cli.clicli",
40
40
  "attr": "_CLI_MODULE",
41
- "file": "omdev/cli/clicmds.py",
42
- "line": 57,
41
+ "file": "omdev/cli/clicli.py",
42
+ "line": 62,
43
43
  "value": {
44
44
  "$.cli.types.CliModule": {
45
45
  "cmd_name": "cli",
46
- "mod_name": "omdev.cli.clicmds"
46
+ "mod_name": "omdev.cli.clicli"
47
47
  }
48
48
  }
49
49
  },
@@ -135,7 +135,7 @@
135
135
  "module": ".tools.gittools",
136
136
  "attr": "_CLI_MODULE",
137
137
  "file": "omdev/tools/gittools.py",
138
- "line": 22,
138
+ "line": 64,
139
139
  "value": {
140
140
  "$.cli.types.CliModule": {
141
141
  "cmd_name": "git",
omdev/cli/__main__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  if __name__ == '__main__':
2
- from .main import _main
2
+ from .main import _main # noqa
3
3
 
4
4
  _main()
omdev/cli/clicli.py ADDED
@@ -0,0 +1,71 @@
1
+ import inspect
2
+ import os
3
+ import subprocess
4
+ import sys
5
+
6
+ from omlish import __about__
7
+ from omlish import argparse as ap
8
+
9
+ from . import install
10
+ from .types import CliModule
11
+
12
+
13
+ class CliCli(ap.Cli):
14
+
15
+ @ap.command(name='version')
16
+ def print_version(self) -> None:
17
+ print(__about__.__version__)
18
+
19
+ @ap.command(name='revision')
20
+ def print_revision(self) -> None:
21
+ print(__about__.__revision__)
22
+
23
+ @ap.command(
24
+ ap.arg('extra_deps', nargs='*'),
25
+ )
26
+ def reinstall(self) -> None:
27
+ mod_name = globals()['__spec__'].name
28
+ tool_name = '.'.join([mod_name.partition('.')[0], 'tools', 'piptools'])
29
+
30
+ out = subprocess.check_output([
31
+ sys.executable,
32
+ '-m',
33
+ tool_name,
34
+ 'list-root-dists',
35
+ ]).decode()
36
+
37
+ deps = sorted(
38
+ ({s for l in out.splitlines() if (s := l.strip())} | set(self.args.extra_deps or []))
39
+ - {install.DEFAULT_CLI_PKG} # noqa
40
+ )
41
+
42
+ if deps:
43
+ print('Reinstalling with following additional dependencies:')
44
+ print('\n'.join(' ' + d for d in deps))
45
+ else:
46
+ print('No additional dependencies detected.')
47
+ print()
48
+ print('Continue with reinstall? (ctrl-c to cancel)')
49
+ input()
50
+
51
+ install_src = inspect.getsource(install)
52
+
53
+ os.execl(
54
+ sys.executable,
55
+ sys.executable,
56
+ '-c',
57
+ install_src,
58
+ *deps,
59
+ )
60
+
61
+
62
+ # @omlish-manifest
63
+ _CLI_MODULE = CliModule('cli', __name__)
64
+
65
+
66
+ def _main() -> None:
67
+ CliCli()()
68
+
69
+
70
+ if __name__ == '__main__':
71
+ _main()
omdev/cli/install.py CHANGED
@@ -32,7 +32,7 @@ class InstallOpts:
32
32
  extras: ta.Sequence[str] = dc.field(default_factory=list)
33
33
 
34
34
 
35
- class InstallMgr(abc.ABC):
35
+ class InstallManager(abc.ABC):
36
36
  @abc.abstractmethod
37
37
  def is_available(self) -> bool:
38
38
  raise NotImplementedError
@@ -46,7 +46,7 @@ class InstallMgr(abc.ABC):
46
46
  raise NotImplementedError
47
47
 
48
48
 
49
- class UvxInstallMgr(InstallMgr):
49
+ class UvxInstallManager(InstallManager):
50
50
  def is_available(self) -> bool:
51
51
  return bool(shutil.which('uv'))
52
52
 
@@ -80,15 +80,25 @@ class UvxInstallMgr(InstallMgr):
80
80
  *itertools.chain.from_iterable(['--with', e] for e in (opts.extras or [])),
81
81
  ])
82
82
 
83
+ subprocess.check_call([
84
+ 'uv', 'tool',
85
+ 'run',
86
+ '--from', opts.cli_pkg,
87
+ 'om',
88
+ '_post_install',
89
+ ])
83
90
 
84
- class PipxInstallMgr(InstallMgr):
91
+
92
+ class PipxInstallManager(InstallManager):
85
93
  def is_available(self) -> bool:
86
94
  return bool(shutil.which('pipx'))
87
95
 
88
- def uninstall(self, cli_pkg: str) -> None:
96
+ def _list_installed(self) -> ta.Any:
89
97
  out = subprocess.check_output(['pipx', 'list', '--json']).decode()
98
+ return json.loads(out)
90
99
 
91
- dct = json.loads(out)
100
+ def uninstall(self, cli_pkg: str) -> None:
101
+ dct = self._list_installed()
92
102
 
93
103
  if cli_pkg not in dct.get('venvs', {}):
94
104
  return
@@ -108,10 +118,19 @@ class PipxInstallMgr(InstallMgr):
108
118
  *itertools.chain.from_iterable(['--preinstall', e] for e in (opts.extras or [])),
109
119
  ])
110
120
 
121
+ dct = self._list_installed()
122
+
123
+ exe = dct[opts.cli_pkg]['metadata']['main_package']['app_paths'][0]['__Path__']
124
+
125
+ subprocess.check_call([
126
+ exe,
127
+ '_post_install',
128
+ ])
129
+
111
130
 
112
- INSTALL_MGRS = {
113
- 'uvx': UvxInstallMgr(),
114
- 'pipx': PipxInstallMgr(),
131
+ INSTALL_MANAGERS = {
132
+ 'uvx': UvxInstallManager(),
133
+ 'pipx': PipxInstallManager(),
115
134
  }
116
135
 
117
136
 
@@ -133,18 +152,18 @@ def _main() -> None:
133
152
  raise ValueError(f'Must specify py')
134
153
 
135
154
  if mgr := args.mgr:
136
- if (im := INSTALL_MGRS.get(mgr)) is None:
155
+ if (im := INSTALL_MANAGERS.get(mgr)) is None:
137
156
  raise ValueError(f'Unsupported mgr: {mgr}')
138
157
  if not im.is_available():
139
158
  raise ValueError(f'Unavailable mgr: {mgr}')
140
159
  else:
141
- for im in INSTALL_MGRS.values():
160
+ for im in INSTALL_MANAGERS.values():
142
161
  if im.is_available():
143
162
  break
144
163
  else:
145
164
  raise RuntimeError("Can't find install manager")
146
165
 
147
- for m in INSTALL_MGRS.values():
166
+ for m in INSTALL_MANAGERS.values():
148
167
  if m.is_available():
149
168
  m.uninstall(cli)
150
169
 
omdev/cli/main.py CHANGED
@@ -23,7 +23,18 @@ from .types import CliModule
23
23
  ##
24
24
 
25
25
 
26
- _CLI_FUNCS: ta.Sequence[CliFunc] = []
26
+ def _post_install() -> None:
27
+ from .managers import setup_install_manager
28
+
29
+ setup_install_manager()
30
+
31
+
32
+ ##
33
+
34
+
35
+ _CLI_FUNCS: ta.Sequence[CliFunc] = [
36
+ CliFunc('_post_install', _post_install),
37
+ ]
27
38
 
28
39
 
29
40
  ##
omdev/cli/managers.py ADDED
@@ -0,0 +1,77 @@
1
+ import enum
2
+ import os.path
3
+ import site
4
+ import sys
5
+
6
+
7
+ ##
8
+
9
+
10
+ class ManagerType(enum.Enum):
11
+ UVX = 'uvx'
12
+ PIPX = 'pipx'
13
+
14
+
15
+ def _detect_install_manager() -> ManagerType | None:
16
+ if os.path.isfile(fp := os.path.join(sys.prefix, 'uv-receipt.toml')):
17
+ with open(fp) as f:
18
+ if any(l.strip() == '[tool]' for l in f):
19
+ return ManagerType.UVX
20
+
21
+ if os.path.isfile(os.path.join(sys.prefix, 'pipx_metadata.json')):
22
+ return ManagerType.PIPX
23
+
24
+ return None
25
+
26
+
27
+ def detect_install_manager() -> ManagerType | None:
28
+ try:
29
+ return globals()['_DETECTED_MANAGER_TYPE']
30
+ except KeyError:
31
+ pass
32
+ ret = globals()['_DETECTED_MANAGER_TYPE'] = _detect_install_manager()
33
+ return ret
34
+
35
+
36
+ ##
37
+
38
+
39
+ def _ensure_correct_path() -> None:
40
+ sp = site.getsitepackages()[0]
41
+ if sys.path[0] != sp:
42
+ sys.path.insert(0, sp)
43
+
44
+
45
+ class _PathHackMetaFinder:
46
+ def find_spec(self, fullname, path, target=None):
47
+ _ensure_correct_path()
48
+ return None # noqa
49
+
50
+
51
+ def _activate_path_hack() -> None:
52
+ if not any(isinstance(mp, _PathHackMetaFinder) for mp in sys.meta_path):
53
+ sys.meta_path.insert(0, _PathHackMetaFinder())
54
+
55
+
56
+ _PATH_HACK_FILE_NAME = f'{"-".join(__name__.split("."))}-path-hack.pth'
57
+
58
+
59
+ def _install_path_hack_file() -> None:
60
+ sp = site.getsitepackages()[0]
61
+ if os.path.isfile(fp := os.path.join(sp, _PATH_HACK_FILE_NAME)):
62
+ return
63
+
64
+ with open(fp, 'w') as f:
65
+ f.write(f'import {__name__}; {__name__}._activate_path_hack()')
66
+
67
+ _activate_path_hack()
68
+
69
+
70
+ ##
71
+
72
+
73
+ def setup_install_manager() -> None:
74
+ if detect_install_manager() is None:
75
+ return
76
+
77
+ _install_path_hack_file()
omdev/tools/gittools.py CHANGED
@@ -1,3 +1,5 @@
1
+ import os
2
+ import re
1
3
  import subprocess
2
4
 
3
5
  from omlish import argparse as ap
@@ -18,6 +20,46 @@ class Cli(ap.Cli):
18
20
  shell=True,
19
21
  )
20
22
 
23
+ #
24
+
25
+ @ap.command()
26
+ def commits_by_date(self) -> None:
27
+ subprocess.check_call(['git log --date=short --pretty=format:%ad | sort | uniq -c'], shell=True) # noqa
28
+
29
+ #
30
+
31
+ _GITHUB_PAT = re.compile(r'((http(s)?://)?(www\./)?github(\.com)?/)?(?P<user>[^/.]+)/(?P<repo>[^/.]+)(/.*)?')
32
+
33
+ @ap.command(
34
+ ap.arg('repo'),
35
+ ap.arg('args', nargs=ap.REMAINDER),
36
+ accepts_unknown=True,
37
+ )
38
+ def clone(self) -> None:
39
+ if not (m := self._GITHUB_PAT.fullmatch(self.args.repo)):
40
+ subprocess.check_call([
41
+ 'git',
42
+ 'clone',
43
+ *self.unknown_args,
44
+ *self.args.args,
45
+ self.args.repo,
46
+ ])
47
+ return
48
+
49
+ user = m.group('user')
50
+ repo = m.group('repo')
51
+
52
+ os.makedirs(user, 0o755, exist_ok=True)
53
+
54
+ subprocess.check_call([
55
+ 'git',
56
+ 'clone',
57
+ *self.unknown_args,
58
+ *self.args.args,
59
+ f'https://github.com/{user}/{repo}.git',
60
+ os.path.join(user, repo),
61
+ ])
62
+
21
63
 
22
64
  # @omlish-manifest
23
65
  _CLI_MODULE = CliModule('git', __name__)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev43
3
+ Version: 0.0.0.dev44
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ 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: omlish ==0.0.0.dev43
15
+ Requires-Dist: omlish ==0.0.0.dev44
16
16
  Provides-Extra: all
17
17
  Requires-Dist: pycparser ~=2.22 ; extra == 'all'
18
18
  Requires-Dist: cffi ~=1.17 ; extra == 'all'
@@ -1,4 +1,4 @@
1
- omdev/.manifests.json,sha256=c-eZ9NasJYDz6P7LeyEV_-NLPoVpI3ph8LcO8Hg0JNY,3921
1
+ omdev/.manifests.json,sha256=kEgqk5lxYhb_GAnksPc5f0xDcG-5eMUtdcT-v77bCzU,3918
2
2
  omdev/__about__.py,sha256=LqSNNFFcT84xW3W8fIOJ78kPYJKFLIXZyDX-AJREvN0,1005
3
3
  omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  omdev/bracepy.py,sha256=HwBK5XmlOsF_juTel25fRLJK9vHSJCWXuCc-OZlevRQ,2619
@@ -54,10 +54,11 @@ omdev/cexts/_distutils/compilers/ccompiler.py,sha256=cTs88qrvj0hBVXHfemSDE_du_nE
54
54
  omdev/cexts/_distutils/compilers/options.py,sha256=H7r5IcLvga5Fs3jjXWIT-6ap3JBduXRKgtpDmSGCZxs,3818
55
55
  omdev/cexts/_distutils/compilers/unixccompiler.py,sha256=o1h8QuyupLntv4F21_XjzAZmCiwwxJuTmOirvBSL-Qw,15419
56
56
  omdev/cli/__init__.py,sha256=V_l6VP1SZMlJbO-8CJwSuO9TThOy2S_oaPepNYgIrbE,37
57
- omdev/cli/__main__.py,sha256=d23loR_cKfTYZwYiqpt_CmKI7dd5WcYFgIYzqMep75E,68
58
- omdev/cli/clicmds.py,sha256=Qt75JOZ5nnI1OSvKFkNy25Zi1iaNx_hcPlK3PkgWgYY,1923
59
- omdev/cli/install.py,sha256=-pFczwyJn48IeqCswbJzrV15ZslQUNIcREiiOGSjDk0,3933
60
- omdev/cli/main.py,sha256=rGc8SIk-czOS9eILZbzu27nx3ezjc54fn880OWskpYE,1880
57
+ omdev/cli/__main__.py,sha256=5IeIERm-371fSI5ZvPv8eldAJBwgKwpR0R49pTsILNM,76
58
+ omdev/cli/clicli.py,sha256=NY4MF16007Ri31rUsq868u1V9JYDb_2atBALqjjXJK4,1624
59
+ omdev/cli/install.py,sha256=gKqFComs8vk4h3kjXOELBSnJ_nvmzK4SCeJxAaCJCTI,4445
60
+ omdev/cli/main.py,sha256=opoOOc_d4yCfI0_dWkwDV7O2WSnoybIH3YsylGFwqLI,2039
61
+ omdev/cli/managers.py,sha256=FNfJ4G52un6tYGjr41WhRc6OAHlgiUsWejHEzqJPYuw,1669
61
62
  omdev/cli/types.py,sha256=7_Owg0P8C8oOObSuOp6aEYSjkEukVFxTT00SRy1bLHM,250
62
63
  omdev/interp/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
63
64
  omdev/interp/__main__.py,sha256=GMCqeGYltgt5dlJzHxY9gqisa8cRkrPfmZYuZnjg4WI,162
@@ -106,15 +107,15 @@ omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
106
107
  omdev/toml/writer.py,sha256=lk3on3YXVbWuLJa-xsOzOhs1bBAT1vXqw4mBbluZl_w,3040
107
108
  omdev/tools/__init__.py,sha256=iVJAOQ0viGTQOm0DLX4uZLro-9jOioYJGLg9s0kDx1A,78
108
109
  omdev/tools/dockertools.py,sha256=x00GV8j1KReMXwxJ641GlcsVwHoWeuzdIKVBp36BqwU,5298
109
- omdev/tools/gittools.py,sha256=s_-cxh-4Nv2a_bJtHZ6AiKF8kx2IjDrt_GOH8Wjz-3M,669
110
+ omdev/tools/gittools.py,sha256=i2WFM2pX5riDJBchFXMmegOCuLSjvTkKC1ltqShSo7E,1773
110
111
  omdev/tools/importscan.py,sha256=usF35AjdMZacpe8nfP-wfzxelExT5sEQUORNcBKqr5M,3929
111
112
  omdev/tools/piptools.py,sha256=lhwzGXD-v0KFEQNyvzvdO2Kw1OA_2AfGPBs_rIkz8iE,2772
112
113
  omdev/tools/proftools.py,sha256=xKSm_yPoCnfsvS3iT9MblDqFMuZmGfI3_koGj8amMyU,145
113
114
  omdev/tools/rst.py,sha256=6dWk8QZHoGiLSuBw3TKsXZjjFK6wWBEtPi9krdCLKKg,977
114
115
  omdev/tools/sqlrepl.py,sha256=tmFZh80-xsGM62dyQ7_UGLebChrj7IHbIPYBWDJMgVk,5741
115
- omdev-0.0.0.dev43.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
116
- omdev-0.0.0.dev43.dist-info/METADATA,sha256=5Hv8QOnRyAlCu0hmOy2f4I772ceLh29Q1XPQmufh8fw,1252
117
- omdev-0.0.0.dev43.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
118
- omdev-0.0.0.dev43.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
119
- omdev-0.0.0.dev43.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
120
- omdev-0.0.0.dev43.dist-info/RECORD,,
116
+ omdev-0.0.0.dev44.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
117
+ omdev-0.0.0.dev44.dist-info/METADATA,sha256=j1hrMNfOxwMRq2knkUjKyCc6E0cYg1fP3w45COF6KhU,1252
118
+ omdev-0.0.0.dev44.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
119
+ omdev-0.0.0.dev44.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
120
+ omdev-0.0.0.dev44.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
121
+ omdev-0.0.0.dev44.dist-info/RECORD,,
omdev/cli/clicmds.py DELETED
@@ -1,83 +0,0 @@
1
- import argparse
2
- import inspect
3
- import os
4
- import subprocess
5
- import sys
6
-
7
- from omlish import __about__
8
-
9
- from . import install
10
- from .types import CliModule
11
-
12
-
13
- def _print_version(args) -> None:
14
- print(__about__.__version__)
15
-
16
-
17
- def _print_revision(args) -> None:
18
- print(__about__.__revision__)
19
-
20
-
21
- def _reinstall(args) -> None:
22
- mod_name = globals()['__spec__'].name
23
- tool_name = '.'.join([mod_name.partition('.')[0], 'tools', 'piptools'])
24
-
25
- out = subprocess.check_output([
26
- sys.executable,
27
- '-m',
28
- tool_name,
29
- 'list-root-dists',
30
- ]).decode()
31
-
32
- deps = sorted(
33
- ({s for l in out.splitlines() if (s := l.strip())} | set(args.extra_deps or []))
34
- - {install.DEFAULT_CLI_PKG} # noqa
35
- )
36
-
37
- if deps:
38
- print('Reinstalling with following additional dependencies:')
39
- print('\n'.join(' ' + d for d in deps))
40
- else:
41
- print('No additional dependencies detected.')
42
- print()
43
- print('Continue with reinstall? (ctrl-c to cancel)')
44
- input()
45
-
46
- install_src = inspect.getsource(install)
47
-
48
- os.execl(
49
- sys.executable,
50
- sys.executable,
51
- '-c',
52
- install_src,
53
- *deps,
54
- )
55
-
56
-
57
- # @omlish-manifest
58
- _CLI_MODULE = CliModule('cli', __name__)
59
-
60
-
61
- def _main(argv=None) -> None:
62
- parser = argparse.ArgumentParser()
63
- subparsers = parser.add_subparsers()
64
-
65
- parser_version = subparsers.add_parser('version')
66
- parser_version.set_defaults(func=_print_version)
67
-
68
- parser_revision = subparsers.add_parser('revision')
69
- parser_revision.set_defaults(func=_print_revision)
70
-
71
- parser_reinstall = subparsers.add_parser('reinstall')
72
- parser_reinstall.add_argument('extra_deps', nargs='*')
73
- parser_reinstall.set_defaults(func=_reinstall)
74
-
75
- args = parser.parse_args(argv)
76
- if not getattr(args, 'func', None):
77
- parser.print_help()
78
- else:
79
- args.func(args)
80
-
81
-
82
- if __name__ == '__main__':
83
- _main()