Skip to content

Commit 9c62c26

Browse files
committed
6. add scripts entry to pyproject.toml for morebuiltins command line tool.
1 parent 5db89e2 commit 9c62c26

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
2. `LoggerStream.replace_print_ctx`: A context manager to temporarily replace the print function within a block of code.
1010
1. add time prefix to each print line.
1111
5. add `nofmt` extra field support to `morebuiltins.cmd.log_server` to skip formatting for high-frequency/thinking logs.
12+
6. add `scripts` entry to `pyproject.toml` for `morebuiltins` command line tool.
13+
1. now you can run `uvx morebuiltins morebuiltins.cmd.log_server` to start log server with uvx.
1214

1315
### 1.3.4 (2025-10-15)
1416
1. fix `morebuiltins.utils.gen_id` wrong length issue.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ ibution.
3939
4040
- Use `pyz`(downloaded from [releases](https://github.com/ClericPy/morebuiltins/releases))
4141

42+
- Use `uvx morebuiltins morebuiltins.cmd.xxx`
43+
4244
```python
4345
import sys
4446
sys.path.insert(0, 'morebuiltins.pyz')

morebuiltins/cmd/bin/_runner.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import sys
2+
import runpy
3+
4+
# Usage:
5+
# python runner.py <module> [args...]
6+
# Example:
7+
# python runner.py morebuiltins.cmd.log_server
8+
# uvx:
9+
# uvx morebuiltins morebuiltins.cmd.log_server
10+
11+
12+
import importlib.util
13+
14+
15+
def runner(mod_name: str | None = None, argv: list[str] | None = None) -> None:
16+
# Read module name and args from command line if not provided
17+
if mod_name is None:
18+
if len(sys.argv) < 2:
19+
print("Usage: python runner.py <module> [args...]")
20+
raise SystemExit(2)
21+
mod_name = sys.argv[1]
22+
argv = sys.argv[2:]
23+
if argv is None:
24+
argv = []
25+
26+
# Mimic `python -m <module>` by setting sys.argv
27+
orig_argv = sys.argv[:]
28+
sys.argv = [mod_name] + argv
29+
try:
30+
# Prefer private API to replicate `python -m` semantics (incl. package __main__)
31+
run_as_main = getattr(runpy, "_run_module_as_main", None)
32+
if run_as_main is not None:
33+
# We already set sys.argv above; prevent _run_module_as_main from altering it again
34+
run_as_main(mod_name, alter_argv=False)
35+
return
36+
37+
# Fallback: manually handle package __main__
38+
spec = importlib.util.find_spec(mod_name)
39+
if spec is None:
40+
raise ModuleNotFoundError(f"No module named '{mod_name}'")
41+
42+
target = mod_name
43+
if spec.submodule_search_locations is not None:
44+
# Package: run <pkg>.__main__
45+
main_name = f"{mod_name}.__main__"
46+
if importlib.util.find_spec(main_name) is None:
47+
raise ModuleNotFoundError(f"No module named '{main_name}'")
48+
target = main_name
49+
50+
# Run target module as __main__
51+
runpy.run_module(target, run_name="__main__", alter_sys=True)
52+
finally:
53+
# Restore original argv to avoid side effects
54+
sys.argv = orig_argv
55+
56+
57+
if __name__ == "__main__":
58+
runner()

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ classifiers = ["License :: OSI Approved :: MIT License"]
1111
dynamic = ["version"]
1212
description = "Expanding Python's built-in functionalities to enable richer and more versatile work scenarios."
1313
requires-python = ">=3.8"
14+
scripts = {morebuiltins = "morebuiltins.cmd.bin._runner:runner"}
1415

1516
[project.urls]
1617
Home = "https://github.com/ClericPy/morebuiltins"

0 commit comments

Comments
 (0)