falsegreen 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.
falsegreen/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """falsegreen: find unit tests that give false positives."""
2
+ from .scanner import run, main, CASES, Finding
3
+
4
+ __version__ = "0.1.0"
5
+ __all__ = ["run", "main", "CASES", "Finding", "__version__"]
falsegreen/__main__.py ADDED
@@ -0,0 +1,6 @@
1
+ import sys
2
+
3
+ from .scanner import main
4
+
5
+ if __name__ == "__main__":
6
+ sys.exit(main())
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Install the falsegreen scanner as a repo git pre-commit hook.
5
+
6
+ This is the no-framework path, for people who do not use the pre-commit tool.
7
+ If you already use https://pre-commit.com, prefer the .pre-commit-hooks.yaml
8
+ entry instead (versioned, shared across clones).
9
+
10
+ The hook runs the scanner against staged test files on every commit.
11
+ - HIGH-confidence findings block the commit (override once with
12
+ `git commit --no-verify`, or globally by exporting FALSEGREEN_BLOCK=0).
13
+ - LOW-confidence findings only warn.
14
+
15
+ Usage:
16
+ python -m falsegreen.hook_install [--repo PATH]
17
+ python -m falsegreen.hook_install --uninstall [--repo PATH]
18
+ """
19
+
20
+ import argparse
21
+ import os
22
+ import sys
23
+
24
+ MARKER = "# >>> falsegreen pre-commit hook >>>"
25
+ MARKER_END = "# <<< falsegreen pre-commit hook <<<"
26
+
27
+ HOOK = """#!/bin/sh
28
+ {marker}
29
+ PY="$(command -v python3 || command -v python || command -v py)"
30
+ if [ -z "$PY" ]; then
31
+ echo "[falsegreen] python not found on PATH, skipping test scan"
32
+ exit 0
33
+ fi
34
+ "$PY" -m falsegreen --staged
35
+ CODE=$?
36
+ if [ "$CODE" -eq 20 ] && [ "${{FALSEGREEN_BLOCK:-1}}" != "0" ]; then
37
+ echo ""
38
+ echo "[falsegreen] high-confidence false positives above. Commit blocked."
39
+ echo " - fix them, or bypass this once with: git commit --no-verify"
40
+ echo " - deep semantic audit (expected vs intended): run /falsegreen"
41
+ exit 1
42
+ fi
43
+ exit 0
44
+ {marker_end}
45
+ """.format(marker=MARKER, marker_end=MARKER_END)
46
+
47
+
48
+ def find_git_dir(repo):
49
+ git = os.path.join(repo, ".git")
50
+ if os.path.isdir(git):
51
+ return git
52
+ if os.path.isfile(git):
53
+ with open(git, "r", encoding="utf-8") as fh:
54
+ for line in fh:
55
+ if line.startswith("gitdir:"):
56
+ return line.split(":", 1)[1].strip()
57
+ return None
58
+
59
+
60
+ def install(repo):
61
+ git_dir = find_git_dir(repo)
62
+ if not git_dir:
63
+ print("error: %s is not a git repository (no .git found)." % repo)
64
+ return 1
65
+ hooks_dir = os.path.join(git_dir, "hooks")
66
+ os.makedirs(hooks_dir, exist_ok=True)
67
+ hook_path = os.path.join(hooks_dir, "pre-commit")
68
+
69
+ if os.path.exists(hook_path):
70
+ with open(hook_path, "r", encoding="utf-8", errors="replace") as fh:
71
+ existing = fh.read()
72
+ if MARKER not in existing:
73
+ backup = hook_path + ".bak"
74
+ with open(backup, "w", encoding="utf-8") as fh:
75
+ fh.write(existing)
76
+ print("note: existing pre-commit backed up to %s" % backup)
77
+
78
+ with open(hook_path, "w", encoding="utf-8", newline="\n") as fh:
79
+ fh.write(HOOK)
80
+ try:
81
+ os.chmod(hook_path, 0o755)
82
+ except Exception:
83
+ pass
84
+
85
+ print("installed pre-commit hook -> %s" % hook_path)
86
+ print("it runs `python -m falsegreen --staged` (install the package first: pip install falsegreen).")
87
+ print("HIGH-confidence findings block the commit. Set FALSEGREEN_BLOCK=0 to warn only.")
88
+ return 0
89
+
90
+
91
+ def uninstall(repo):
92
+ git_dir = find_git_dir(repo)
93
+ if not git_dir:
94
+ print("error: %s is not a git repository." % repo)
95
+ return 1
96
+ hook_path = os.path.join(git_dir, "hooks", "pre-commit")
97
+ if not os.path.exists(hook_path):
98
+ print("no pre-commit hook to remove.")
99
+ return 0
100
+ with open(hook_path, "r", encoding="utf-8", errors="replace") as fh:
101
+ content = fh.read()
102
+ if MARKER not in content:
103
+ print("pre-commit hook was not installed by falsegreen, leaving it alone.")
104
+ return 0
105
+ backup = hook_path + ".bak"
106
+ if os.path.exists(backup):
107
+ with open(backup, "r", encoding="utf-8") as fh:
108
+ prev = fh.read()
109
+ with open(hook_path, "w", encoding="utf-8", newline="\n") as fh:
110
+ fh.write(prev)
111
+ os.remove(backup)
112
+ print("restored previous pre-commit hook from backup.")
113
+ else:
114
+ os.remove(hook_path)
115
+ print("removed pre-commit hook.")
116
+ return 0
117
+
118
+
119
+ def main(argv=None):
120
+ ap = argparse.ArgumentParser(description="Install the falsegreen pre-commit hook.")
121
+ ap.add_argument("--repo", default=".", help="path to the target repo (default: cwd)")
122
+ ap.add_argument("--uninstall", action="store_true", help="remove the hook")
123
+ args = ap.parse_args(argv)
124
+ repo = os.path.abspath(args.repo)
125
+ if args.uninstall:
126
+ return uninstall(repo)
127
+ return install(repo)
128
+
129
+
130
+ if __name__ == "__main__":
131
+ sys.exit(main())