testscan 0.1.0__py3-none-win_amd64.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.
- testscan-0.1.0.dist-info/METADATA +107 -0
- testscan-0.1.0.dist-info/RECORD +9 -0
- testscan-0.1.0.dist-info/WHEEL +5 -0
- testscan-0.1.0.dist-info/entry_points.txt +2 -0
- testscan_py/__init__.py +6 -0
- testscan_py/_version.py +24 -0
- testscan_py/bin/.gitkeep +4 -0
- testscan_py/bin/testscan.exe +0 -0
- testscan_py/cli.py +51 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: testscan
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Static analysis for AI-generated Python tests — thin launcher for the Go testscan CLI
|
|
5
|
+
Project-URL: Homepage, https://github.com/Nikita527/testscan
|
|
6
|
+
Project-URL: Repository, https://github.com/Nikita527/testscan
|
|
7
|
+
Project-URL: Issues, https://github.com/Nikita527/testscan/issues
|
|
8
|
+
Author: Nikita527
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: ai,linter,pytest,static-analysis,test-smells,testing
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
|
+
Classifier: Topic :: Software Development :: Testing
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# testscan (Python launcher)
|
|
30
|
+
|
|
31
|
+
English | [Русский](README.ru.md)
|
|
32
|
+
|
|
33
|
+
Thin wrapper: finds the Go binary and forwards `argv` / exit code.
|
|
34
|
+
**Source of truth is the Go CLI** (`cmd/testscan`). Python has no rules, parsing, or flag handling.
|
|
35
|
+
|
|
36
|
+
Package name on PyPI: **`testscan`**. Version comes from git tags (`v*`) via hatch-vcs.
|
|
37
|
+
|
|
38
|
+
## Install (PyPI)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uvx testscan@latest tests/
|
|
42
|
+
# or: pipx run testscan tests/
|
|
43
|
+
# or: pip install testscan && testscan tests/
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Release CI builds platform wheels (`linux/amd64`, `darwin/arm64`, `windows/amd64`) with the Go binary under `testscan_py/bin/`.
|
|
47
|
+
|
|
48
|
+
## Local embed (contributors)
|
|
49
|
+
|
|
50
|
+
Binaries under `src/testscan_py/bin/` are **not committed** (`.gitignore`). Embed before `uvx --from ./python`. `pyproject.toml` sets `ignore-vcs = true` and `force-include` for `bin/*`, otherwise hatchling can drop the binary because of gitignore.
|
|
51
|
+
|
|
52
|
+
```powershell
|
|
53
|
+
powershell -ExecutionPolicy Bypass -File python/scripts/embed_bin.ps1
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bash python/scripts/embed_bin.sh
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Manual equivalent:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
go build -o python/src/testscan_py/bin/testscan ./cmd/testscan
|
|
64
|
+
# Windows: .../bin/testscan.exe
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uvx --from ./python testscan --help
|
|
71
|
+
uvx --from ./python testscan rules/testdata/empty --fail-on never
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Without embed — via env (handy for debugging the wrapper):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
go build -o /tmp/testscan ./cmd/testscan
|
|
78
|
+
TESTSCAN_BIN=/tmp/testscan uvx --from ./python testscan --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Platform wheel (release / maintainers)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# from repo root; needs git tag history for hatch-vcs
|
|
85
|
+
bash python/scripts/build_platform_wheel.sh linux-amd64 manylinux_2_17_x86_64
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Tag a release (`v0.1.0`) to trigger `.github/workflows/release.yml` → multi-OS wheels → PyPI + GitHub Release.
|
|
89
|
+
|
|
90
|
+
Before the first publish: create a PyPI project + [Trusted Publisher](https://docs.pypi.org/trusted-publishers/) for this repo (workflow `Release`, environment `pypi`), or the publish job will fail on OIDC.
|
|
91
|
+
|
|
92
|
+
## Binary lookup (priority)
|
|
93
|
+
|
|
94
|
+
1. `TESTSCAN_BIN`
|
|
95
|
+
2. bundled: `testscan_py/bin/testscan.exe` (Windows) / `testscan` (unix)
|
|
96
|
+
3. `PATH` (`shutil.which("testscan")`)
|
|
97
|
+
|
|
98
|
+
If not found → message on stderr, exit `2`.
|
|
99
|
+
|
|
100
|
+
## Manual check list
|
|
101
|
+
|
|
102
|
+
- [x] `uvx testscan@latest --help` (after PyPI publish) → usage (exit 0)
|
|
103
|
+
- [x] `uvx --from ./python testscan --help` after embed → usage (exit 0)
|
|
104
|
+
- [x] `uvx --from ./python testscan rules/testdata/empty/hit --rule empty-test --fail-on error` → exit 1
|
|
105
|
+
- [x] `uvx --from ./python testscan rules/testdata/empty/clean --fail-on error` → exit 0
|
|
106
|
+
- [x] bundled binary in wheel after embed + `ignore-vcs` / `force-include`
|
|
107
|
+
- [x] `go test ./...` green
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
testscan_py/__init__.py,sha256=JmfAvCrIymZlazY3cDkZBtkCxb1FgUd4dpvIVyCo_O0,208
|
|
2
|
+
testscan_py/_version.py,sha256=ptILGutmCA6QX4OPt03bkYZX2VUTr2ovOOy8vb2k2ZU,544
|
|
3
|
+
testscan_py/cli.py,sha256=8q1-JprvPWDTeAEfhCxCOm-jZPnpqnEYd3_6fBcLBvM,1478
|
|
4
|
+
testscan_py/bin/.gitkeep,sha256=Zou8IZ3GE4d1_ImZSH2x9-hiGPsg6bg2TcMsL9Sl4XY,178
|
|
5
|
+
testscan_py/bin/testscan.exe,sha256=_WJCtW1MIz9mt0lxzLqsYldNO7mySG_EIrDfQOq4ld4,2958848
|
|
6
|
+
testscan-0.1.0.dist-info/METADATA,sha256=thduCBOfCOnhpUw-xQDU_cAjWiammBbI2eMM86cDwsY,3878
|
|
7
|
+
testscan-0.1.0.dist-info/WHEEL,sha256=DqRKTdcjqcnA9JhnVHem7iyI7zn0B1vfHx5zVCEXDZY,95
|
|
8
|
+
testscan-0.1.0.dist-info/entry_points.txt,sha256=ORpinBgXEk20x8X-dzXLTyeF66kD2f0OCCV2rFPdjTU,50
|
|
9
|
+
testscan-0.1.0.dist-info/RECORD,,
|
testscan_py/__init__.py
ADDED
testscan_py/_version.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '0.1.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 0)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
testscan_py/bin/.gitkeep
ADDED
|
Binary file
|
testscan_py/cli.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Thin launcher for the Go testscan binary. No parsing or rules here."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def resolve_bin() -> Path:
|
|
13
|
+
if env := os.environ.get("TESTSCAN_BIN"):
|
|
14
|
+
p = Path(env)
|
|
15
|
+
if not p.is_file():
|
|
16
|
+
raise FileNotFoundError(f"TESTSCAN_BIN not a file: {env}")
|
|
17
|
+
return p
|
|
18
|
+
|
|
19
|
+
name = "testscan.exe" if os.name == "nt" else "testscan"
|
|
20
|
+
bundled = Path(__file__).resolve().parent / "bin" / name
|
|
21
|
+
if bundled.is_file():
|
|
22
|
+
return bundled
|
|
23
|
+
|
|
24
|
+
which = shutil.which("testscan")
|
|
25
|
+
if which:
|
|
26
|
+
p = Path(which).resolve()
|
|
27
|
+
# не выбирать сам uvx/pip entry-point (рекурсия)
|
|
28
|
+
argv0 = Path(sys.argv[0]).resolve()
|
|
29
|
+
if p != argv0 and p.is_file():
|
|
30
|
+
return p
|
|
31
|
+
|
|
32
|
+
raise FileNotFoundError(
|
|
33
|
+
"testscan binary not found. Install from PyPI (uvx testscan@latest), "
|
|
34
|
+
"set TESTSCAN_BIN, run python/scripts/embed_bin.ps1 (or .sh), "
|
|
35
|
+
"or put the Go binary on PATH."
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def main() -> None:
|
|
40
|
+
try:
|
|
41
|
+
bin_path = resolve_bin()
|
|
42
|
+
except FileNotFoundError as exc:
|
|
43
|
+
print(f"testscan: {exc}", file=sys.stderr)
|
|
44
|
+
raise SystemExit(2) from exc
|
|
45
|
+
|
|
46
|
+
# Windows + uvx: subprocess надёжнее os.execv
|
|
47
|
+
raise SystemExit(subprocess.call([str(bin_path), *sys.argv[1:]]))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|