becwright 0.1.0__tar.gz → 0.2.1__tar.gz

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.
Files changed (45) hide show
  1. {becwright-0.1.0/src/becwright.egg-info → becwright-0.2.1}/PKG-INFO +54 -14
  2. {becwright-0.1.0 → becwright-0.2.1}/README.md +48 -13
  3. {becwright-0.1.0 → becwright-0.2.1}/pyproject.toml +6 -2
  4. becwright-0.2.1/src/becwright/__init__.py +1 -0
  5. becwright-0.2.1/src/becwright/__main__.py +6 -0
  6. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/bundle.py +9 -5
  7. becwright-0.2.1/src/becwright/checks/_ignore.py +11 -0
  8. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/dangerous_eval.py +3 -1
  9. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/debug_remnants.py +3 -1
  10. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/forbid.py +3 -1
  11. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/hardcoded_secrets.py +3 -1
  12. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/no_token_in_logs.py +3 -1
  13. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/wildcard_imports.py +3 -1
  14. becwright-0.2.1/src/becwright/cli.py +340 -0
  15. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/git.py +12 -3
  16. becwright-0.2.1/src/becwright/mcp_server.py +45 -0
  17. becwright-0.2.1/src/becwright/report.py +38 -0
  18. {becwright-0.1.0 → becwright-0.2.1/src/becwright.egg-info}/PKG-INFO +54 -14
  19. {becwright-0.1.0 → becwright-0.2.1}/src/becwright.egg-info/SOURCES.txt +10 -1
  20. becwright-0.2.1/src/becwright.egg-info/requires.txt +12 -0
  21. {becwright-0.1.0 → becwright-0.2.1}/tests/test_bundle.py +24 -4
  22. {becwright-0.1.0 → becwright-0.2.1}/tests/test_cli_and_git.py +33 -0
  23. becwright-0.2.1/tests/test_ignore.py +29 -0
  24. becwright-0.2.1/tests/test_init.py +108 -0
  25. becwright-0.2.1/tests/test_list.py +22 -0
  26. becwright-0.2.1/tests/test_mcp.py +55 -0
  27. becwright-0.2.1/tests/test_report_and_json.py +86 -0
  28. becwright-0.1.0/src/becwright/__init__.py +0 -1
  29. becwright-0.1.0/src/becwright/cli.py +0 -179
  30. becwright-0.1.0/src/becwright.egg-info/requires.txt +0 -5
  31. {becwright-0.1.0 → becwright-0.2.1}/LICENSE +0 -0
  32. {becwright-0.1.0 → becwright-0.2.1}/setup.cfg +0 -0
  33. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/__init__.py +0 -0
  34. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/checks/redundant_comments.py +0 -0
  35. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/engine.py +0 -0
  36. {becwright-0.1.0 → becwright-0.2.1}/src/becwright/rules.py +0 -0
  37. {becwright-0.1.0 → becwright-0.2.1}/src/becwright.egg-info/dependency_links.txt +0 -0
  38. {becwright-0.1.0 → becwright-0.2.1}/src/becwright.egg-info/entry_points.txt +0 -0
  39. {becwright-0.1.0 → becwright-0.2.1}/src/becwright.egg-info/top_level.txt +0 -0
  40. {becwright-0.1.0 → becwright-0.2.1}/tests/test_checks.py +0 -0
  41. {becwright-0.1.0 → becwright-0.2.1}/tests/test_engine.py +0 -0
  42. {becwright-0.1.0 → becwright-0.2.1}/tests/test_engine_integration.py +0 -0
  43. {becwright-0.1.0 → becwright-0.2.1}/tests/test_forbid.py +0 -0
  44. {becwright-0.1.0 → becwright-0.2.1}/tests/test_more_checks.py +0 -0
  45. {becwright-0.1.0 → becwright-0.2.1}/tests/test_redundant_comments.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: becwright
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Deterministically enforces constraints (BECs) on your code, blocking commits that violate them.
5
5
  Author: Alonso David De Leon Rodarte
6
6
  License: MIT
@@ -18,6 +18,11 @@ Requires-Dist: pyyaml>=6
18
18
  Provides-Extra: dev
19
19
  Requires-Dist: pytest>=8; extra == "dev"
20
20
  Requires-Dist: pytest-cov>=5; extra == "dev"
21
+ Requires-Dist: mcp>=1.2; extra == "dev"
22
+ Provides-Extra: build
23
+ Requires-Dist: pyinstaller>=6; extra == "build"
24
+ Provides-Extra: mcp
25
+ Requires-Dist: mcp>=1.2; extra == "mcp"
21
26
  Dynamic: license-file
22
27
 
23
28
  > **English** · [Español](README.es.md)
@@ -72,26 +77,53 @@ becwright is installed once as a tool; each repo only contributes its own
72
77
  `.bec/rules.yaml`.
73
78
 
74
79
  ```bash
75
- # 1. Install the engine (once, global)
76
- pipx install git+https://github.com/DataDave-Dev/becwright.git # or local: pipx install .
80
+ # 1. Install the engine. Pick your ecosystem — no Python needed via npm/pnpm,
81
+ # which ship a self-contained binary:
82
+ npm install --save-dev becwright # or global: npm install -g becwright
83
+ pnpm add -D becwright
84
+ pipx install becwright # or: pip install becwright
77
85
 
78
- # 2. In the repo where you want the rules, install the git hook
79
- becwright install # writes .git/hooks/pre-commit
86
+ # 2. In your repo, scaffold rules + install the hook
87
+ becwright init # detects your language, writes .bec/rules.yaml, installs the hook
80
88
 
81
- # 3. Write your rules in .bec/rules.yaml (see examples below)
82
- # 4. Done: each commit runs the checks; if a blocking rule fails, it stops.
89
+ # 3. Done: each commit runs the checks; if a blocking rule fails, it stops.
83
90
  ```
84
91
 
92
+ Installed as a devDependency, the pre-commit hook resolves the local binary from
93
+ `node_modules/.bin`, so it works without a global install. The npm packages cover
94
+ `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64` and `win32-x64`; on any
95
+ other platform use `pipx install becwright`.
96
+
85
97
  Available commands:
86
98
 
87
99
  | Command | What it does |
88
100
  |---|---|
101
+ | `becwright init` | Scaffold a starter `.bec/rules.yaml` and install the hook |
102
+ | `becwright list` | List the built-in checks |
89
103
  | `becwright check` | Runs the rules over the staged files |
90
104
  | `becwright install` | Installs the native `pre-commit` hook |
91
105
  | `becwright uninstall` | Removes the hook |
92
106
  | `becwright export <id>` | Exports a BEC to a `.bec.yaml` file |
93
107
  | `becwright import <file\|URL>` | Imports a BEC from another repo |
94
108
 
109
+ ### Use with AI agents (Claude Code)
110
+
111
+ becwright is the deterministic net for what an AI agent lets slip. There is a
112
+ Claude Code plugin so an agent can install and drive it for you:
113
+
114
+ ```text
115
+ /plugin marketplace add DataDave-Dev/becwright
116
+ /plugin install becwright@becwright
117
+ ```
118
+
119
+ It adds a `becwright` skill and a `/becwright` command. See
120
+ [`integrations/claude-code/`](integrations/claude-code/).
121
+
122
+ For structured results, `becwright check --json` prints a machine-readable
123
+ summary, and `becwright mcp` (install the `mcp` extra: `pipx install
124
+ "becwright[mcp]"`) runs an MCP server exposing `check` and `list_checks` to any
125
+ agent. See [`documentation/mcp.md`](documentation/mcp.md).
126
+
95
127
  A rule in `.bec/rules.yaml`:
96
128
 
97
129
  ```yaml
@@ -103,7 +135,7 @@ rules:
103
135
  If a token shows up in the logs, anyone with access to them can steal a
104
136
  user's session.
105
137
  paths: ["src/**/*.py"]
106
- check: "python3 -m becwright.checks.no_token_in_logs"
138
+ check: "becwright run no_token_in_logs"
107
139
  severity: blocking # blocking = stops the commit | warning = only warns
108
140
  ```
109
141
 
@@ -134,7 +166,7 @@ rules:
134
166
  A secret in the repo stays in git history forever and is visible to
135
167
  anyone with access to the code.
136
168
  paths: ["src/**/*.py"]
137
- check: "python3 -m becwright.checks.hardcoded_secrets"
169
+ check: "becwright run hardcoded_secrets"
138
170
  severity: blocking
139
171
 
140
172
  - id: no-debug-remnants
@@ -143,7 +175,7 @@ rules:
143
175
  why_it_matters: >
144
176
  A forgotten breakpoint hangs the process in production or CI.
145
177
  paths: ["src/**/*.py"]
146
- check: "python3 -m becwright.checks.debug_remnants"
178
+ check: "becwright run debug_remnants"
147
179
  severity: blocking
148
180
 
149
181
  - id: no-dangerous-eval
@@ -152,7 +184,7 @@ rules:
152
184
  why_it_matters: >
153
185
  eval/exec on untrusted input is remote code execution.
154
186
  paths: ["src/**/*.py"]
155
- check: "python3 -m becwright.checks.dangerous_eval"
187
+ check: "becwright run dangerous_eval"
156
188
  severity: blocking
157
189
 
158
190
  - id: no-wildcard-imports
@@ -162,7 +194,7 @@ rules:
162
194
  Wildcard imports hide where each name comes from and break static
163
195
  analysis.
164
196
  paths: ["src/**/*.py"]
165
- check: "python3 -m becwright.checks.wildcard_imports"
197
+ check: "becwright run wildcard_imports"
166
198
  severity: warning
167
199
  ```
168
200
 
@@ -183,7 +215,7 @@ rules:
183
215
  why_it_matters: >
184
216
  A forgotten 'debugger' halts execution and should not reach production.
185
217
  paths: ["**/*.js", "**/*.ts"]
186
- check: "python3 -m becwright.checks.forbid --pattern '\\bdebugger\\b'"
218
+ check: "becwright run forbid --pattern '\\bdebugger\\b'"
187
219
  severity: blocking
188
220
  ```
189
221
 
@@ -214,10 +246,18 @@ Use `--yes` to skip the confirmation in automated environments.
214
246
  There is a **catalog of ready-to-use BECs** in [`becs/`](becs/) that you can
215
247
  import directly from their raw URL.
216
248
 
217
- Built-in checks (`python3 -m becwright.checks.*`) travel with the package, so
249
+ Built-in checks (`becwright run *`) travel with the package, so
218
250
  the bundle only stores their name. A **custom** check (`.bec/checks/foo.py`)
219
251
  travels with its code embedded and lands in `.bec/checks/` of the target repo.
220
252
 
253
+ ## Documentation
254
+
255
+ Technical documentation lives in [`documentation/`](documentation/):
256
+ [architecture & flow](documentation/architecture.md),
257
+ [usage & rules schema](documentation/usage.md),
258
+ [writing checks](documentation/writing-checks.md), and
259
+ [portability](documentation/portability.md).
260
+
221
261
  ## Current status
222
262
 
223
263
  The **installable MVP** is built and verified end-to-end: packaged engine
@@ -50,26 +50,53 @@ becwright is installed once as a tool; each repo only contributes its own
50
50
  `.bec/rules.yaml`.
51
51
 
52
52
  ```bash
53
- # 1. Install the engine (once, global)
54
- pipx install git+https://github.com/DataDave-Dev/becwright.git # or local: pipx install .
53
+ # 1. Install the engine. Pick your ecosystem — no Python needed via npm/pnpm,
54
+ # which ship a self-contained binary:
55
+ npm install --save-dev becwright # or global: npm install -g becwright
56
+ pnpm add -D becwright
57
+ pipx install becwright # or: pip install becwright
55
58
 
56
- # 2. In the repo where you want the rules, install the git hook
57
- becwright install # writes .git/hooks/pre-commit
59
+ # 2. In your repo, scaffold rules + install the hook
60
+ becwright init # detects your language, writes .bec/rules.yaml, installs the hook
58
61
 
59
- # 3. Write your rules in .bec/rules.yaml (see examples below)
60
- # 4. Done: each commit runs the checks; if a blocking rule fails, it stops.
62
+ # 3. Done: each commit runs the checks; if a blocking rule fails, it stops.
61
63
  ```
62
64
 
65
+ Installed as a devDependency, the pre-commit hook resolves the local binary from
66
+ `node_modules/.bin`, so it works without a global install. The npm packages cover
67
+ `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64` and `win32-x64`; on any
68
+ other platform use `pipx install becwright`.
69
+
63
70
  Available commands:
64
71
 
65
72
  | Command | What it does |
66
73
  |---|---|
74
+ | `becwright init` | Scaffold a starter `.bec/rules.yaml` and install the hook |
75
+ | `becwright list` | List the built-in checks |
67
76
  | `becwright check` | Runs the rules over the staged files |
68
77
  | `becwright install` | Installs the native `pre-commit` hook |
69
78
  | `becwright uninstall` | Removes the hook |
70
79
  | `becwright export <id>` | Exports a BEC to a `.bec.yaml` file |
71
80
  | `becwright import <file\|URL>` | Imports a BEC from another repo |
72
81
 
82
+ ### Use with AI agents (Claude Code)
83
+
84
+ becwright is the deterministic net for what an AI agent lets slip. There is a
85
+ Claude Code plugin so an agent can install and drive it for you:
86
+
87
+ ```text
88
+ /plugin marketplace add DataDave-Dev/becwright
89
+ /plugin install becwright@becwright
90
+ ```
91
+
92
+ It adds a `becwright` skill and a `/becwright` command. See
93
+ [`integrations/claude-code/`](integrations/claude-code/).
94
+
95
+ For structured results, `becwright check --json` prints a machine-readable
96
+ summary, and `becwright mcp` (install the `mcp` extra: `pipx install
97
+ "becwright[mcp]"`) runs an MCP server exposing `check` and `list_checks` to any
98
+ agent. See [`documentation/mcp.md`](documentation/mcp.md).
99
+
73
100
  A rule in `.bec/rules.yaml`:
74
101
 
75
102
  ```yaml
@@ -81,7 +108,7 @@ rules:
81
108
  If a token shows up in the logs, anyone with access to them can steal a
82
109
  user's session.
83
110
  paths: ["src/**/*.py"]
84
- check: "python3 -m becwright.checks.no_token_in_logs"
111
+ check: "becwright run no_token_in_logs"
85
112
  severity: blocking # blocking = stops the commit | warning = only warns
86
113
  ```
87
114
 
@@ -112,7 +139,7 @@ rules:
112
139
  A secret in the repo stays in git history forever and is visible to
113
140
  anyone with access to the code.
114
141
  paths: ["src/**/*.py"]
115
- check: "python3 -m becwright.checks.hardcoded_secrets"
142
+ check: "becwright run hardcoded_secrets"
116
143
  severity: blocking
117
144
 
118
145
  - id: no-debug-remnants
@@ -121,7 +148,7 @@ rules:
121
148
  why_it_matters: >
122
149
  A forgotten breakpoint hangs the process in production or CI.
123
150
  paths: ["src/**/*.py"]
124
- check: "python3 -m becwright.checks.debug_remnants"
151
+ check: "becwright run debug_remnants"
125
152
  severity: blocking
126
153
 
127
154
  - id: no-dangerous-eval
@@ -130,7 +157,7 @@ rules:
130
157
  why_it_matters: >
131
158
  eval/exec on untrusted input is remote code execution.
132
159
  paths: ["src/**/*.py"]
133
- check: "python3 -m becwright.checks.dangerous_eval"
160
+ check: "becwright run dangerous_eval"
134
161
  severity: blocking
135
162
 
136
163
  - id: no-wildcard-imports
@@ -140,7 +167,7 @@ rules:
140
167
  Wildcard imports hide where each name comes from and break static
141
168
  analysis.
142
169
  paths: ["src/**/*.py"]
143
- check: "python3 -m becwright.checks.wildcard_imports"
170
+ check: "becwright run wildcard_imports"
144
171
  severity: warning
145
172
  ```
146
173
 
@@ -161,7 +188,7 @@ rules:
161
188
  why_it_matters: >
162
189
  A forgotten 'debugger' halts execution and should not reach production.
163
190
  paths: ["**/*.js", "**/*.ts"]
164
- check: "python3 -m becwright.checks.forbid --pattern '\\bdebugger\\b'"
191
+ check: "becwright run forbid --pattern '\\bdebugger\\b'"
165
192
  severity: blocking
166
193
  ```
167
194
 
@@ -192,10 +219,18 @@ Use `--yes` to skip the confirmation in automated environments.
192
219
  There is a **catalog of ready-to-use BECs** in [`becs/`](becs/) that you can
193
220
  import directly from their raw URL.
194
221
 
195
- Built-in checks (`python3 -m becwright.checks.*`) travel with the package, so
222
+ Built-in checks (`becwright run *`) travel with the package, so
196
223
  the bundle only stores their name. A **custom** check (`.bec/checks/foo.py`)
197
224
  travels with its code embedded and lands in `.bec/checks/` of the target repo.
198
225
 
226
+ ## Documentation
227
+
228
+ Technical documentation lives in [`documentation/`](documentation/):
229
+ [architecture & flow](documentation/architecture.md),
230
+ [usage & rules schema](documentation/usage.md),
231
+ [writing checks](documentation/writing-checks.md), and
232
+ [portability](documentation/portability.md).
233
+
199
234
  ## Current status
200
235
 
201
236
  The **installable MVP** is built and verified end-to-end: packaged engine
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "becwright"
9
- version = "0.1.0"
9
+ version = "0.2.1"
10
10
  description = "Deterministically enforces constraints (BECs) on your code, blocking commits that violate them."
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.12"
@@ -28,7 +28,11 @@ classifiers = [
28
28
  becwright = "becwright.cli:main"
29
29
 
30
30
  [project.optional-dependencies]
31
- dev = ["pytest>=8", "pytest-cov>=5"]
31
+ dev = ["pytest>=8", "pytest-cov>=5", "mcp>=1.2"]
32
+ # Used to freeze the standalone binary distributed via npm (see packaging/).
33
+ build = ["pyinstaller>=6"]
34
+ # MCP server for AI agents: `becwright mcp` (see src/becwright/mcp_server.py).
35
+ mcp = ["mcp>=1.2"]
32
36
 
33
37
  [tool.setuptools.packages.find]
34
38
  where = ["src"]
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"
@@ -0,0 +1,6 @@
1
+ import sys
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ sys.exit(main())
@@ -11,7 +11,11 @@ from .rules import Rule
11
11
 
12
12
  BUNDLE_VERSION = 1
13
13
 
14
- _BUILTIN = re.compile(r"^python3?\s+-m\s+becwright\.checks\.(\w+)(?:\s+(.*))?$")
14
+ # Accept the current `becwright run <module>` form and the legacy
15
+ # `python3 -m becwright.checks.<module>` form so older bundles still import.
16
+ _BUILTIN = re.compile(
17
+ r"^(?:becwright\s+run\s+(\w+)|python3?\s+-m\s+becwright\.checks\.(\w+))(?:\s+(.*))?$"
18
+ )
15
19
  _PY_PATH = re.compile(r"[\w./-]+\.py")
16
20
  _ITEM_INDENT = re.compile(r"^([ \t]+)-\s", re.MULTILINE)
17
21
  _EMPTY_RULES = re.compile(r"^rules:[ \t]*(?:\[[ \t]*\]|\{[ \t]*\})[ \t]*$", re.MULTILINE)
@@ -41,9 +45,9 @@ def classify_check(command: str, root: Path) -> dict:
41
45
  command = command.strip()
42
46
  builtin = _BUILTIN.match(command)
43
47
  if builtin:
44
- out = {"kind": "builtin", "module": builtin.group(1)}
45
- if builtin.group(2):
46
- out["args"] = builtin.group(2).strip()
48
+ out = {"kind": "builtin", "module": builtin.group(1) or builtin.group(2)}
49
+ if builtin.group(3):
50
+ out["args"] = builtin.group(3).strip()
47
51
  return out
48
52
  for token in _PY_PATH.findall(command):
49
53
  candidate = root / token
@@ -108,7 +112,7 @@ def materialize(bundle: dict, root: Path) -> dict:
108
112
  check = bundle["check"]
109
113
  kind = check.get("kind")
110
114
  if kind == "builtin":
111
- command = f"python3 -m becwright.checks.{check['module']}"
115
+ command = f"becwright run {check['module']}"
112
116
  if check.get("args"):
113
117
  command += f" {check['args']}"
114
118
  elif kind == "script":
@@ -0,0 +1,11 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+
5
+ # A line carrying this marker (inside a comment, in any language) is exempt from
6
+ # any check: `# becwright: ignore`, `// becwright: ignore`, etc.
7
+ _MARKER = re.compile(r"becwright:\s*ignore\b", re.IGNORECASE)
8
+
9
+
10
+ def is_ignored(line: str) -> bool:
11
+ return bool(_MARKER.search(line))
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  import sys
5
5
 
6
+ from ._ignore import is_ignored
7
+
6
8
  PATTERN = re.compile(r"\b(?:eval|exec)\s*\(")
7
9
 
8
10
 
@@ -15,7 +17,7 @@ def find_violations(paths: list[str]) -> list[tuple[str, int, str]]:
15
17
  try:
16
18
  with open(path, encoding="utf-8") as f:
17
19
  for lineno, line in enumerate(f, start=1):
18
- if PATTERN.search(line):
20
+ if PATTERN.search(line) and not is_ignored(line):
19
21
  violations.append((path, lineno, line.strip()))
20
22
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
21
23
  continue
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  import sys
5
5
 
6
+ from ._ignore import is_ignored
7
+
6
8
  PATTERN = re.compile(
7
9
  r"\bbreakpoint\s*\(|\b(?:i?pdb)\.set_trace\s*\(|\bimport\s+i?pdb\b"
8
10
  )
@@ -17,7 +19,7 @@ def find_violations(paths: list[str]) -> list[tuple[str, int, str]]:
17
19
  try:
18
20
  with open(path, encoding="utf-8") as f:
19
21
  for lineno, line in enumerate(f, start=1):
20
- if PATTERN.search(line):
22
+ if PATTERN.search(line) and not is_ignored(line):
21
23
  violations.append((path, lineno, line.strip()))
22
24
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
23
25
  continue
@@ -4,6 +4,8 @@ import argparse
4
4
  import re
5
5
  import sys
6
6
 
7
+ from ._ignore import is_ignored
8
+
7
9
 
8
10
  def find_violations(paths: list[str], pattern: str, flags: int = 0) -> list[tuple[str, int, str]]:
9
11
  rx = re.compile(pattern, flags)
@@ -15,7 +17,7 @@ def find_violations(paths: list[str], pattern: str, flags: int = 0) -> list[tupl
15
17
  try:
16
18
  with open(path, encoding="utf-8") as f:
17
19
  for lineno, line in enumerate(f, start=1):
18
- if rx.search(line):
20
+ if rx.search(line) and not is_ignored(line):
19
21
  violations.append((path, lineno, line.strip()))
20
22
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
21
23
  continue
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  import sys
5
5
 
6
+ from ._ignore import is_ignored
7
+
6
8
  _AWS_KEY = r"AKIA[0-9A-Z]{16}"
7
9
  _PRIVATE_KEY = r"-----BEGIN [A-Z ]*PRIVATE KEY-----"
8
10
  _ASSIGNMENT = (
@@ -27,7 +29,7 @@ def find_violations(paths: list[str]) -> list[tuple[str, int, str]]:
27
29
  try:
28
30
  with open(path, encoding="utf-8") as f:
29
31
  for lineno, line in enumerate(f, start=1):
30
- if PATTERN.search(line) and not _PLACEHOLDER.search(line):
32
+ if PATTERN.search(line) and not _PLACEHOLDER.search(line) and not is_ignored(line):
31
33
  violations.append((path, lineno, line.strip()))
32
34
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
33
35
  continue
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  import sys
5
5
 
6
+ from ._ignore import is_ignored
7
+
6
8
  SENSITIVE = r"(token|password|passwd|secret|api[_-]?key|credential|session[_-]?id)"
7
9
  LOG_CALL = r"(log\.|logger\.|logging\.|print\s*\()"
8
10
  # A log call that mentions something sensitive on the same line.
@@ -18,7 +20,7 @@ def find_violations(paths: list[str]) -> list[tuple[str, int, str]]:
18
20
  try:
19
21
  with open(path, encoding="utf-8") as f:
20
22
  for lineno, line in enumerate(f, start=1):
21
- if PATTERN.search(line):
23
+ if PATTERN.search(line) and not is_ignored(line):
22
24
  violations.append((path, lineno, line.strip()))
23
25
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
24
26
  continue
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import re
4
4
  import sys
5
5
 
6
+ from ._ignore import is_ignored
7
+
6
8
  PATTERN = re.compile(r"^\s*from\s+[\w.]+\s+import\s+\*")
7
9
 
8
10
 
@@ -15,7 +17,7 @@ def find_violations(paths: list[str]) -> list[tuple[str, int, str]]:
15
17
  try:
16
18
  with open(path, encoding="utf-8") as f:
17
19
  for lineno, line in enumerate(f, start=1):
18
- if PATTERN.search(line):
20
+ if PATTERN.search(line) and not is_ignored(line):
19
21
  violations.append((path, lineno, line.strip()))
20
22
  except (FileNotFoundError, IsADirectoryError, UnicodeDecodeError):
21
23
  continue