mquery-toolkit 0.1.0__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.
- mquery_toolkit/THIRD_PARTY_NOTICES.txt +34 -0
- mquery_toolkit/__init__.py +35 -0
- mquery_toolkit/_bridge.cjs +45531 -0
- mquery_toolkit/cli.py +118 -0
- mquery_toolkit/core.py +600 -0
- mquery_toolkit/fabric.py +213 -0
- mquery_toolkit/pqtest.py +93 -0
- mquery_toolkit/py.typed +0 -0
- mquery_toolkit-0.1.0.dist-info/METADATA +189 -0
- mquery_toolkit-0.1.0.dist-info/RECORD +15 -0
- mquery_toolkit-0.1.0.dist-info/WHEEL +5 -0
- mquery_toolkit-0.1.0.dist-info/entry_points.txt +2 -0
- mquery_toolkit-0.1.0.dist-info/licenses/LICENSE +21 -0
- mquery_toolkit-0.1.0.dist-info/licenses/NOTICE +9 -0
- mquery_toolkit-0.1.0.dist-info/top_level.txt +1 -0
mquery_toolkit/cli.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Command line interface with dry-run source edits by default."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from .core import (
|
|
12
|
+
MQueryError,
|
|
13
|
+
check,
|
|
14
|
+
dependencies,
|
|
15
|
+
format_source,
|
|
16
|
+
parse,
|
|
17
|
+
rename,
|
|
18
|
+
replace_source,
|
|
19
|
+
update_file,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _source(path: Path) -> str:
|
|
24
|
+
limit = 10 * 1024 * 1024
|
|
25
|
+
if path.stat().st_size > limit:
|
|
26
|
+
raise MQueryError("input exceeds 10 MiB")
|
|
27
|
+
with path.open("rb") as handle:
|
|
28
|
+
data = handle.read(limit + 1)
|
|
29
|
+
if len(data) > limit:
|
|
30
|
+
raise MQueryError("input exceeds 10 MiB")
|
|
31
|
+
return data.decode("utf-8", "strict")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _print(value: Any, as_json: bool) -> None:
|
|
35
|
+
if as_json or not isinstance(value, str):
|
|
36
|
+
print(json.dumps(value, sort_keys=True, default=lambda item: item.as_dict()))
|
|
37
|
+
else:
|
|
38
|
+
print(value, end="" if value.endswith("\n") else "\n")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def main(argv: list[str] | None = None) -> int:
|
|
42
|
+
parser = argparse.ArgumentParser(prog="mquery")
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"command",
|
|
45
|
+
choices=[
|
|
46
|
+
"parse",
|
|
47
|
+
"format",
|
|
48
|
+
"check",
|
|
49
|
+
"dependencies",
|
|
50
|
+
"rename",
|
|
51
|
+
"replace-source",
|
|
52
|
+
],
|
|
53
|
+
)
|
|
54
|
+
parser.add_argument("file", type=Path)
|
|
55
|
+
parser.add_argument("--json", action="store_true")
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--write",
|
|
58
|
+
action="store_true",
|
|
59
|
+
help="atomically replace source after validation",
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument("--old")
|
|
62
|
+
parser.add_argument("--new")
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"--source", help="complete replacement source for replace-source"
|
|
65
|
+
)
|
|
66
|
+
args = parser.parse_args(argv)
|
|
67
|
+
try:
|
|
68
|
+
if args.command == "parse":
|
|
69
|
+
_print(parse(_source(args.file)), True)
|
|
70
|
+
return 0
|
|
71
|
+
if args.command == "check":
|
|
72
|
+
diagnostics = check(_source(args.file), str(args.file))
|
|
73
|
+
if args.json:
|
|
74
|
+
_print([item.as_dict() for item in diagnostics], True)
|
|
75
|
+
else:
|
|
76
|
+
for item in diagnostics:
|
|
77
|
+
print(
|
|
78
|
+
f"{item.file}:{item.line}:{item.column}: "
|
|
79
|
+
f"{item.severity} {item.code}: {item.message}"
|
|
80
|
+
)
|
|
81
|
+
return 2 if any(item.severity == "error" for item in diagnostics) else 0
|
|
82
|
+
if args.command == "dependencies":
|
|
83
|
+
_print(dependencies(_source(args.file)), True)
|
|
84
|
+
return 0
|
|
85
|
+
transform: Callable[[str], str]
|
|
86
|
+
if args.command == "format":
|
|
87
|
+
transform = format_source
|
|
88
|
+
elif args.command == "rename":
|
|
89
|
+
if args.old is None or args.new is None:
|
|
90
|
+
raise MQueryError("rename requires --old and --new")
|
|
91
|
+
old, new = args.old, args.new
|
|
92
|
+
|
|
93
|
+
def transform(text: str) -> str:
|
|
94
|
+
return rename(text, old, new)
|
|
95
|
+
|
|
96
|
+
else:
|
|
97
|
+
if args.source is None:
|
|
98
|
+
raise MQueryError("replace-source requires --source")
|
|
99
|
+
replacement = args.source
|
|
100
|
+
|
|
101
|
+
def transform(text: str) -> str:
|
|
102
|
+
return replace_source(text, replacement)
|
|
103
|
+
|
|
104
|
+
_print(update_file(args.file, transform, write=args.write), args.json)
|
|
105
|
+
return 0
|
|
106
|
+
except (OSError, UnicodeDecodeError, MQueryError) as error:
|
|
107
|
+
code = getattr(error, "code", "M_IO_ERROR")
|
|
108
|
+
_print(
|
|
109
|
+
{"code": code, "message": str(error)}
|
|
110
|
+
if args.json
|
|
111
|
+
else f"error {code}: {error}",
|
|
112
|
+
args.json,
|
|
113
|
+
)
|
|
114
|
+
return 2
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
raise SystemExit(main())
|