filefilter 0.2.4__tar.gz → 0.2.6__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 (22) hide show
  1. {filefilter-0.2.4/src/filefilter.egg-info → filefilter-0.2.6}/PKG-INFO +58 -40
  2. {filefilter-0.2.4 → filefilter-0.2.6}/README.md +57 -39
  3. {filefilter-0.2.4 → filefilter-0.2.6}/pyproject.toml +1 -1
  4. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter/__init__.py +14 -52
  5. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter/collector.py +158 -55
  6. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter/ruleset.py +3 -3
  7. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter/utilities.py +21 -37
  8. {filefilter-0.2.4 → filefilter-0.2.6/src/filefilter.egg-info}/PKG-INFO +58 -40
  9. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter.egg-info/SOURCES.txt +2 -0
  10. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_comprehensive.py +5 -5
  11. filefilter-0.2.6/tests/test_dry_run.py +136 -0
  12. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_inclusion_logic.py +2 -2
  13. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_matcher.py +3 -3
  14. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_ruleset.py +3 -6
  15. filefilter-0.2.6/tests/test_three_pass.py +436 -0
  16. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_utilities.py +28 -32
  17. {filefilter-0.2.4 → filefilter-0.2.6}/LICENSE +0 -0
  18. {filefilter-0.2.4 → filefilter-0.2.6}/setup.cfg +0 -0
  19. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter.egg-info/dependency_links.txt +0 -0
  20. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter.egg-info/requires.txt +0 -0
  21. {filefilter-0.2.4 → filefilter-0.2.6}/src/filefilter.egg-info/top_level.txt +0 -0
  22. {filefilter-0.2.4 → filefilter-0.2.6}/tests/test_readme_verification.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: filefilter
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Filter files in a directory tree based on configurable glob rules.
5
5
  Author-email: "Ioannis D (devcoons)" <support@devcoons.com>
6
6
  License-Expression: MIT
@@ -159,40 +159,55 @@ When scanning files, the library applies filters in this exact sequence:
159
159
 
160
160
  1️⃣ **Extension excludes (hard)**
161
161
  - If the file extension matches `exclude.extensions` → **excluded immediately**.
162
- - This step is not overridden by include patterns.
163
-
164
- 2️⃣ **Path excludes vs. override patterns (`include.odirs`, `include.ofiles`)**
165
- - If the file path matches `exclude.files`, or its parent directory matches `exclude.dirs`, the file is a candidate for exclusion.
166
- - **`include.dirs` and `include.files` do not override excludes** — they only gate inclusion later.
167
- - If a matching pattern in `include.odirs` or `include.ofiles` is **more specific** than the best matching exclude pattern → the exclude is **ignored** for this file.
168
- - Otherwise → **excluded**.
169
-
170
- | Pattern | Relative specificity |
171
- |---------|---------------------|
172
- | `**` | very low (broad) |
173
- | `**/KLM/**` | higher |
174
- | `**/KLM/ABC/**` | highest |
175
- | `**/test_*.py` vs `**/test_keep.py` | ofile wins (more specific) |
176
-
177
- > Use `include.dirs` for normal scoping (e.g. `**`, `src/**`).
178
- > Use `include.odirs` for directory carve-outs under `exclude.dirs` / `exclude.files`.
179
- > Use `include.ofiles` for file carve-outs under `exclude.files` / `exclude.dirs`.
180
-
181
- 3️⃣ **Include-file fast path**
162
+ - Not overridden by `odirs`, `ofiles`, or any other include rule.
163
+
164
+ 2️⃣ **Pass 1 — Scope (`include.dirs`, `include.files`)**
165
+ - If any `include.dirs` or `include.files` patterns are set, the file must match **at least one** of them.
166
+ - Otherwise → **excluded** (excludes are not evaluated).
167
+ - `include.odirs` and `include.ofiles` do **not** define scope.
168
+
169
+ 3️⃣ **Pass 2 — Path excludes (`exclude.dirs`, `exclude.files`)**
170
+ - If the file path matches `exclude.files`, or its parent directory matches `exclude.dirs` → **marked excluded**.
171
+
172
+ 4️⃣ **Pass 3 — Overrides (`include.odirs`, `include.ofiles`)**
173
+ - If pass 2 excluded the file, a matching `include.odirs` or `include.ofiles` pattern → **exclude is undone**.
174
+ - If no override matches → **excluded**.
175
+ - Any matching override wins (no specificity scoring).
176
+
177
+ > Use `include.dirs` / `include.files` for normal scoping.
178
+ > Use `include.odirs` / `include.ofiles` only to carve exceptions out of pass-2 excludes.
179
+
180
+ 5️⃣ **Include-file fast path**
182
181
  - If the file matches any `include.files` pattern → **included immediately**,
183
182
  even if its extension isn’t in `include.extensions`.
184
183
 
185
- 4️⃣ **Inclusion gating**
186
- - If there are *any* include patterns (dirs or files), the file must match
187
- at least one of them.
188
- Otherwise, it’s excluded.
189
-
190
- 5️⃣ **Extension whitelist**
184
+ 6️⃣ **Extension whitelist**
191
185
  - If `include.extensions` is not empty, only matching extensions are included.
192
186
 
193
- 6️⃣ **Everything else**
187
+ 7️⃣ **Everything else**
194
188
  - Included by default.
195
189
 
190
+ ### Dry-run / rule hit report
191
+
192
+ `dry_run(rules)` walks the tree like `scan`, but also records how many files each rule pattern matched. Rule keys use the form `category:pattern`, e.g. `include.dirs:**`, `exclude.files:**/test_*.py`.
193
+
194
+ ```python
195
+ from filefilter import dry_run, load
196
+
197
+ rules = load(cfg_json, base="cwd")
198
+ report = dry_run(rules)
199
+
200
+ report.scanned # files walked
201
+ report.included # paths that would be selected
202
+ report.excluded # scanned - included
203
+ report.hits # {"include.dirs:**": 42, ...}
204
+ report.was_hit("exclude.dirs:**/build/**")
205
+ report.has_rule("include.extensions:.py") # configured (may be 0)
206
+ report.count("include.extensions:.py")
207
+ ```
208
+
209
+ Hits count **pattern matches per file** during the walk. Path rules (`dirs`, `files`, …) match on every scanned file. `include.extensions` only counts files that **reach the extension whitelist** (not skipped by `include.files` fast path or earlier excludes). `exclude.extensions` matches on any scanned file. Configured extension patterns always appear in `report.hits` (with count `0` when unused). Keys use parsed form, e.g. `include.extensions:.py` for JSON `"py"`.
210
+
196
211
  ---
197
212
 
198
213
  ## Configuration Schema
@@ -220,10 +235,10 @@ When scanning files, the library applies filters in this exact sequence:
220
235
  | Field | Description |
221
236
  |-------|--------------|
222
237
  | `root_dir` | Base directory (absolute or relative). |
223
- | `filters.include.dirs` | Directory inclusion patterns for gating (must match when any include filters are set). Never overrides excludes. |
224
- | `filters.include.odirs` | Optional. Override directory patterns (defaults to `[]` when omitted). When more specific than a matching exclude, the exclude is ignored for that path. Also satisfies dir gating. |
225
- | `filters.include.ofiles` | Optional. Override file patterns (defaults to `[]` when omitted). When more specific than a matching exclude, the exclude is ignored for that path. Also satisfies file gating (does not skip extension whitelist). |
226
- | `filters.include.files` | File inclusion patterns (glob-like). Forces inclusion (skips extension whitelist) once path excludes are resolved. Does not override excludes. |
238
+ | `filters.include.dirs` | Directory scope patterns. When set, files must live under a matching directory. Never overrides excludes. |
239
+ | `filters.include.files` | File scope patterns. When set (alone or with dirs), matching files pass pass 1. Also forces inclusion (skips extension whitelist) once later passes succeed. Does not override excludes. |
240
+ | `filters.include.odirs` | Optional override directory patterns (defaults to `[]`). Undo pass-2 `exclude.dirs` / `exclude.files` when matched. Do not define scope. |
241
+ | `filters.include.ofiles` | Optional override file patterns (defaults to `[]`). Undo pass-2 excludes when matched. Do not define scope or skip extension whitelist. |
227
242
  | `filters.include.extensions` | Extension whitelist. |
228
243
  | `filters.exclude.*` | Same structure, but acts as exclusion filters. |
229
244
 
@@ -466,7 +481,7 @@ Use `include.dirs` for the broad scope and `include.odirs` for the exception:
466
481
  |------------|---------|--------|
467
482
  | `src/foo.c` | ✅ | broad `**` include + `.c` extension |
468
483
  | `src/KLM/skip.c` | ❌ | `**/KLM/**` exclude; no matching `odirs` |
469
- | `src/KLM/ABC/keep.c` | ✅ | `**/KLM/ABC/**` odir beats `**/KLM/**` exclude |
484
+ | `src/KLM/ABC/keep.c` | ✅ | `**/KLM/ABC/**` odir undoes `**/KLM/**` exclude |
470
485
  | `src/x/KLM/ABC/deep/keep.c` | ✅ | odir exception works at any depth |
471
486
  | `src/KLM/ABC/keep.txt` | ❌ | wrong extension (still inside the allowed dir) |
472
487
 
@@ -501,7 +516,7 @@ Exclude all `test_*.py` files, but keep `test_keep.py`:
501
516
  |------------|---------|--------|
502
517
  | `src/app.py` | ✅ | broad include + `.py` extension |
503
518
  | `src/test_foo.py` | ❌ | `**/test_*.py` exclude; no matching `ofiles` |
504
- | `src/test_keep.py` | ✅ | `**/test_keep.py` ofile beats `**/test_*.py` exclude |
519
+ | `src/test_keep.py` | ✅ | `**/test_keep.py` ofile undoes `**/test_*.py` exclude |
505
520
  | `nested/test_keep.py` | ✅ | ofile exception works at any depth |
506
521
 
507
522
  ---
@@ -509,9 +524,11 @@ Exclude all `test_*.py` files, but keep `test_keep.py`:
509
524
  ## Summary of Behavior
510
525
 
511
526
  - `exclude.extensions` are always applied first (hard exclude).
512
- - `include.dirs` and `include.files` **never** override path excludes — they only gate inclusion.
513
- - Only `include.odirs` and `include.ofiles` can override a matching exclude, and only when the override pattern is **more specific**.
514
- - A matching `include.files` pattern forces inclusion (skips extension whitelist), once path excludes are resolved.
527
+ - **Pass 1:** `include.dirs` / `include.files` define scope (when set).
528
+ - **Pass 2:** `exclude.dirs` / `exclude.files` remove files.
529
+ - **Pass 3:** `include.odirs` / `include.ofiles` undo pass-2 excludes when matched.
530
+ - `include.dirs` and `include.files` **never** override excludes — use `odirs` / `ofiles`.
531
+ - A matching `include.files` pattern forces inclusion (skips extension whitelist) after passes 1–3.
515
532
  - If any include filters exist, at least one must match (inclusion gating).
516
533
  - Extensions act as a **final whitelist** when not bypassed by `include.files`.
517
534
  - Matching is **case-insensitive** and normalized.
@@ -532,9 +549,6 @@ cfg_json = """{
532
549
  }
533
550
  }"""
534
551
 
535
- # Deprecated option
536
- files = filter_paths(cfg_json)
537
-
538
552
  # Option 1: one-liner convenience
539
553
  matched_files = select(cfg_json)
540
554
 
@@ -542,6 +556,10 @@ matched_files = select(cfg_json)
542
556
  rules = load(cfg_json, base="cwd")
543
557
  matched_files = scan(rules)
544
558
 
559
+ # Dry-run: same selection plus per-rule hit counts
560
+ report = dry_run(rules)
561
+ print(report.scanned, report.excluded, report.count("include.dirs:**"))
562
+
545
563
  # Print any matched file
546
564
  for f in matched_files:
547
565
  print(f)
@@ -126,40 +126,55 @@ When scanning files, the library applies filters in this exact sequence:
126
126
 
127
127
  1️⃣ **Extension excludes (hard)**
128
128
  - If the file extension matches `exclude.extensions` → **excluded immediately**.
129
- - This step is not overridden by include patterns.
130
-
131
- 2️⃣ **Path excludes vs. override patterns (`include.odirs`, `include.ofiles`)**
132
- - If the file path matches `exclude.files`, or its parent directory matches `exclude.dirs`, the file is a candidate for exclusion.
133
- - **`include.dirs` and `include.files` do not override excludes** — they only gate inclusion later.
134
- - If a matching pattern in `include.odirs` or `include.ofiles` is **more specific** than the best matching exclude pattern → the exclude is **ignored** for this file.
135
- - Otherwise → **excluded**.
136
-
137
- | Pattern | Relative specificity |
138
- |---------|---------------------|
139
- | `**` | very low (broad) |
140
- | `**/KLM/**` | higher |
141
- | `**/KLM/ABC/**` | highest |
142
- | `**/test_*.py` vs `**/test_keep.py` | ofile wins (more specific) |
143
-
144
- > Use `include.dirs` for normal scoping (e.g. `**`, `src/**`).
145
- > Use `include.odirs` for directory carve-outs under `exclude.dirs` / `exclude.files`.
146
- > Use `include.ofiles` for file carve-outs under `exclude.files` / `exclude.dirs`.
147
-
148
- 3️⃣ **Include-file fast path**
129
+ - Not overridden by `odirs`, `ofiles`, or any other include rule.
130
+
131
+ 2️⃣ **Pass 1 — Scope (`include.dirs`, `include.files`)**
132
+ - If any `include.dirs` or `include.files` patterns are set, the file must match **at least one** of them.
133
+ - Otherwise → **excluded** (excludes are not evaluated).
134
+ - `include.odirs` and `include.ofiles` do **not** define scope.
135
+
136
+ 3️⃣ **Pass 2 — Path excludes (`exclude.dirs`, `exclude.files`)**
137
+ - If the file path matches `exclude.files`, or its parent directory matches `exclude.dirs` → **marked excluded**.
138
+
139
+ 4️⃣ **Pass 3 — Overrides (`include.odirs`, `include.ofiles`)**
140
+ - If pass 2 excluded the file, a matching `include.odirs` or `include.ofiles` pattern → **exclude is undone**.
141
+ - If no override matches → **excluded**.
142
+ - Any matching override wins (no specificity scoring).
143
+
144
+ > Use `include.dirs` / `include.files` for normal scoping.
145
+ > Use `include.odirs` / `include.ofiles` only to carve exceptions out of pass-2 excludes.
146
+
147
+ 5️⃣ **Include-file fast path**
149
148
  - If the file matches any `include.files` pattern → **included immediately**,
150
149
  even if its extension isn’t in `include.extensions`.
151
150
 
152
- 4️⃣ **Inclusion gating**
153
- - If there are *any* include patterns (dirs or files), the file must match
154
- at least one of them.
155
- Otherwise, it’s excluded.
156
-
157
- 5️⃣ **Extension whitelist**
151
+ 6️⃣ **Extension whitelist**
158
152
  - If `include.extensions` is not empty, only matching extensions are included.
159
153
 
160
- 6️⃣ **Everything else**
154
+ 7️⃣ **Everything else**
161
155
  - Included by default.
162
156
 
157
+ ### Dry-run / rule hit report
158
+
159
+ `dry_run(rules)` walks the tree like `scan`, but also records how many files each rule pattern matched. Rule keys use the form `category:pattern`, e.g. `include.dirs:**`, `exclude.files:**/test_*.py`.
160
+
161
+ ```python
162
+ from filefilter import dry_run, load
163
+
164
+ rules = load(cfg_json, base="cwd")
165
+ report = dry_run(rules)
166
+
167
+ report.scanned # files walked
168
+ report.included # paths that would be selected
169
+ report.excluded # scanned - included
170
+ report.hits # {"include.dirs:**": 42, ...}
171
+ report.was_hit("exclude.dirs:**/build/**")
172
+ report.has_rule("include.extensions:.py") # configured (may be 0)
173
+ report.count("include.extensions:.py")
174
+ ```
175
+
176
+ Hits count **pattern matches per file** during the walk. Path rules (`dirs`, `files`, …) match on every scanned file. `include.extensions` only counts files that **reach the extension whitelist** (not skipped by `include.files` fast path or earlier excludes). `exclude.extensions` matches on any scanned file. Configured extension patterns always appear in `report.hits` (with count `0` when unused). Keys use parsed form, e.g. `include.extensions:.py` for JSON `"py"`.
177
+
163
178
  ---
164
179
 
165
180
  ## Configuration Schema
@@ -187,10 +202,10 @@ When scanning files, the library applies filters in this exact sequence:
187
202
  | Field | Description |
188
203
  |-------|--------------|
189
204
  | `root_dir` | Base directory (absolute or relative). |
190
- | `filters.include.dirs` | Directory inclusion patterns for gating (must match when any include filters are set). Never overrides excludes. |
191
- | `filters.include.odirs` | Optional. Override directory patterns (defaults to `[]` when omitted). When more specific than a matching exclude, the exclude is ignored for that path. Also satisfies dir gating. |
192
- | `filters.include.ofiles` | Optional. Override file patterns (defaults to `[]` when omitted). When more specific than a matching exclude, the exclude is ignored for that path. Also satisfies file gating (does not skip extension whitelist). |
193
- | `filters.include.files` | File inclusion patterns (glob-like). Forces inclusion (skips extension whitelist) once path excludes are resolved. Does not override excludes. |
205
+ | `filters.include.dirs` | Directory scope patterns. When set, files must live under a matching directory. Never overrides excludes. |
206
+ | `filters.include.files` | File scope patterns. When set (alone or with dirs), matching files pass pass 1. Also forces inclusion (skips extension whitelist) once later passes succeed. Does not override excludes. |
207
+ | `filters.include.odirs` | Optional override directory patterns (defaults to `[]`). Undo pass-2 `exclude.dirs` / `exclude.files` when matched. Do not define scope. |
208
+ | `filters.include.ofiles` | Optional override file patterns (defaults to `[]`). Undo pass-2 excludes when matched. Do not define scope or skip extension whitelist. |
194
209
  | `filters.include.extensions` | Extension whitelist. |
195
210
  | `filters.exclude.*` | Same structure, but acts as exclusion filters. |
196
211
 
@@ -433,7 +448,7 @@ Use `include.dirs` for the broad scope and `include.odirs` for the exception:
433
448
  |------------|---------|--------|
434
449
  | `src/foo.c` | ✅ | broad `**` include + `.c` extension |
435
450
  | `src/KLM/skip.c` | ❌ | `**/KLM/**` exclude; no matching `odirs` |
436
- | `src/KLM/ABC/keep.c` | ✅ | `**/KLM/ABC/**` odir beats `**/KLM/**` exclude |
451
+ | `src/KLM/ABC/keep.c` | ✅ | `**/KLM/ABC/**` odir undoes `**/KLM/**` exclude |
437
452
  | `src/x/KLM/ABC/deep/keep.c` | ✅ | odir exception works at any depth |
438
453
  | `src/KLM/ABC/keep.txt` | ❌ | wrong extension (still inside the allowed dir) |
439
454
 
@@ -468,7 +483,7 @@ Exclude all `test_*.py` files, but keep `test_keep.py`:
468
483
  |------------|---------|--------|
469
484
  | `src/app.py` | ✅ | broad include + `.py` extension |
470
485
  | `src/test_foo.py` | ❌ | `**/test_*.py` exclude; no matching `ofiles` |
471
- | `src/test_keep.py` | ✅ | `**/test_keep.py` ofile beats `**/test_*.py` exclude |
486
+ | `src/test_keep.py` | ✅ | `**/test_keep.py` ofile undoes `**/test_*.py` exclude |
472
487
  | `nested/test_keep.py` | ✅ | ofile exception works at any depth |
473
488
 
474
489
  ---
@@ -476,9 +491,11 @@ Exclude all `test_*.py` files, but keep `test_keep.py`:
476
491
  ## Summary of Behavior
477
492
 
478
493
  - `exclude.extensions` are always applied first (hard exclude).
479
- - `include.dirs` and `include.files` **never** override path excludes — they only gate inclusion.
480
- - Only `include.odirs` and `include.ofiles` can override a matching exclude, and only when the override pattern is **more specific**.
481
- - A matching `include.files` pattern forces inclusion (skips extension whitelist), once path excludes are resolved.
494
+ - **Pass 1:** `include.dirs` / `include.files` define scope (when set).
495
+ - **Pass 2:** `exclude.dirs` / `exclude.files` remove files.
496
+ - **Pass 3:** `include.odirs` / `include.ofiles` undo pass-2 excludes when matched.
497
+ - `include.dirs` and `include.files` **never** override excludes — use `odirs` / `ofiles`.
498
+ - A matching `include.files` pattern forces inclusion (skips extension whitelist) after passes 1–3.
482
499
  - If any include filters exist, at least one must match (inclusion gating).
483
500
  - Extensions act as a **final whitelist** when not bypassed by `include.files`.
484
501
  - Matching is **case-insensitive** and normalized.
@@ -499,9 +516,6 @@ cfg_json = """{
499
516
  }
500
517
  }"""
501
518
 
502
- # Deprecated option
503
- files = filter_paths(cfg_json)
504
-
505
519
  # Option 1: one-liner convenience
506
520
  matched_files = select(cfg_json)
507
521
 
@@ -509,6 +523,10 @@ matched_files = select(cfg_json)
509
523
  rules = load(cfg_json, base="cwd")
510
524
  matched_files = scan(rules)
511
525
 
526
+ # Dry-run: same selection plus per-rule hit counts
527
+ report = dry_run(rules)
528
+ print(report.scanned, report.excluded, report.count("include.dirs:**"))
529
+
512
530
  # Print any matched file
513
531
  for f in matched_files:
514
532
  print(f)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "filefilter"
7
- version = "0.2.4"
7
+ version = "0.2.6"
8
8
  description = "Filter files in a directory tree based on configurable glob rules."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Ioannis D (devcoons)", email = "support@devcoons.com" }]
@@ -24,78 +24,40 @@
24
24
  # #
25
25
  #########################################################################################
26
26
 
27
- __version__ = '0.2.4'
27
+ __version__ = '0.2.6'
28
28
 
29
29
  #########################################################################################
30
30
  # IMPORTS #
31
31
  #########################################################################################
32
32
 
33
33
  import json
34
- import warnings
35
- from .utilities import *
36
- from .ruleset import *
37
- from .collector import *
34
+ from .ruleset import Ruleset
35
+ from .collector import (
36
+ DryRunResult,
37
+ dry_run,
38
+ match_dir,
39
+ match_file,
40
+ matches,
41
+ scan,
42
+ )
38
43
 
39
44
  __all__ = [
40
- # Preferred API
41
- "Ruleset", "load", "scan", "matches", "select", "match_dir", "match_file",
42
- # Legacy API (still supported)
43
- "filter_paths"
45
+ "Ruleset", "load", "scan", "matches", "select", "dry_run",
46
+ "DryRunResult", "match_dir", "match_file",
44
47
  ]
45
- #########################################################################################
46
-
47
- def _warn(old: str, new: str):
48
- warnings.warn(
49
- f"'filefilter.{old}' is deprecated and will be removed in 0.2.0; "
50
- f"use 'filefilter.{new}'",
51
- DeprecationWarning,
52
- stacklevel=2,
53
- )
54
48
 
55
49
  #########################################################################################
56
50
 
57
51
  def load(config_json: str, base: str = "cwd") -> Ruleset:
58
- """
59
- Parse the config JSON and return a RuleSet resolved against `base`.
60
- Equivalent to: RuleSet(json.loads(config_json), resolve_base=base)
61
- """
52
+ """Parse config JSON and return a Ruleset resolved against `base`."""
62
53
  data = json.loads(config_json)
63
54
  return Ruleset(data, resolve_base=base)
64
55
 
65
56
  #########################################################################################
66
57
 
67
- def scan(rules: Ruleset) -> list[str]:
68
- """
69
- Walk rules.root_dir and return files accepted by the rules.
70
- Equivalent to: collect_files(rules)
71
- """
72
- return collect_files(rules)
73
-
74
- #########################################################################################
75
-
76
- def matches(path: str, rules: Ruleset) -> bool:
77
- """
78
- Return True if `path` would be included by `rules`.
79
- Equivalent to: should_include(path, rules)
80
- """
81
- return should_include(path, rules)
82
-
83
- #########################################################################################
84
-
85
58
  def select(config_json: str, base: str = "cwd") -> list[str]:
86
- """
87
- Convenience: load(...) + scan(...).
88
- """
59
+ """Convenience: load(...) + scan(...)."""
89
60
  return scan(load(config_json, base=base))
90
61
 
91
62
  #########################################################################################
92
-
93
- def filter_paths(config_json: str, resolve_base: str = 'cwd'):
94
- """Load config JSON, build Config, and return collected files."""
95
- _warn("filter_paths", "select")
96
- data = json.loads(config_json)
97
- cfg = Ruleset(data, resolve_base=resolve_base)
98
- return collect_files(cfg)
99
-
100
63
  #########################################################################################
101
- #########################################################################################