topmark 0.2.1__tar.gz → 0.3.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 (88) hide show
  1. {topmark-0.2.1/src/topmark.egg-info → topmark-0.3.1}/PKG-INFO +166 -148
  2. topmark-0.3.1/README.md +377 -0
  3. {topmark-0.2.1 → topmark-0.3.1}/pyproject.toml +21 -15
  4. topmark-0.3.1/src/topmark/api/__init__.py +536 -0
  5. topmark-0.3.1/src/topmark/api/public_types.py +98 -0
  6. topmark-0.3.1/src/topmark/api/types.py +149 -0
  7. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/__init__.py +5 -1
  8. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/cli_types.py +10 -9
  9. topmark-0.3.1/src/topmark/cli/cmd_common.py +228 -0
  10. topmark-0.3.1/src/topmark/cli/commands/check.py +399 -0
  11. topmark-0.3.1/src/topmark/cli/commands/dump_config.py +175 -0
  12. topmark-0.3.1/src/topmark/cli/commands/filetypes.py +236 -0
  13. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/commands/init_config.py +13 -10
  14. topmark-0.3.1/src/topmark/cli/commands/processors.py +194 -0
  15. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/commands/show_defaults.py +12 -8
  16. topmark-0.3.1/src/topmark/cli/commands/strip.py +347 -0
  17. topmark-0.3.1/src/topmark/cli/commands/version.py +63 -0
  18. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/config_resolver.py +3 -0
  19. topmark-0.3.1/src/topmark/cli/errors.py +100 -0
  20. topmark-0.3.1/src/topmark/cli/io.py +295 -0
  21. topmark-0.3.1/src/topmark/cli/main.py +121 -0
  22. topmark-0.3.1/src/topmark/cli/options.py +542 -0
  23. topmark-0.3.1/src/topmark/cli/utils.py +148 -0
  24. topmark-0.3.1/src/topmark/cli_shared/__init__.py +11 -0
  25. topmark-0.3.1/src/topmark/cli_shared/exit_codes.py +72 -0
  26. {topmark-0.2.1/src/topmark/cli → topmark-0.3.1/src/topmark/cli_shared}/utils.py +175 -14
  27. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/config/__init__.py +78 -57
  28. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/config/logging.py +1 -1
  29. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/constants.py +1 -1
  30. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/file_resolver.py +102 -80
  31. topmark-0.3.1/src/topmark/filetypes/base.py +190 -0
  32. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/filetypes/instances.py +137 -24
  33. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/filetypes/registry.py +3 -7
  34. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/context.py +12 -10
  35. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/pipelines.py +6 -3
  36. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/processors/__init__.py +7 -5
  37. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/processors/base.py +214 -114
  38. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/processors/pound.py +2 -4
  39. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/processors/slash.py +3 -4
  40. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/processors/xml.py +91 -4
  41. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/runner.py +1 -2
  42. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/builder.py +4 -1
  43. topmark-0.3.1/src/topmark/pipeline/steps/comparer.py +129 -0
  44. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/patcher.py +2 -2
  45. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/reader.py +29 -2
  46. topmark-0.3.1/src/topmark/pipeline/steps/renderer.py +113 -0
  47. topmark-0.3.1/src/topmark/pipeline/steps/resolver.py +295 -0
  48. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/updater.py +89 -38
  49. topmark-0.3.1/src/topmark/registry/__init__.py +50 -0
  50. topmark-0.3.1/src/topmark/registry/filetypes.py +196 -0
  51. topmark-0.3.1/src/topmark/registry/processors.py +193 -0
  52. topmark-0.3.1/src/topmark/registry/registry.py +177 -0
  53. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/utils/diff.py +2 -1
  54. {topmark-0.2.1 → topmark-0.3.1/src/topmark.egg-info}/PKG-INFO +166 -148
  55. {topmark-0.2.1 → topmark-0.3.1}/src/topmark.egg-info/SOURCES.txt +15 -1
  56. {topmark-0.2.1 → topmark-0.3.1}/src/topmark.egg-info/requires.txt +3 -2
  57. topmark-0.2.1/README.md +0 -360
  58. topmark-0.2.1/src/topmark/cli/commands/default.py +0 -328
  59. topmark-0.2.1/src/topmark/cli/commands/dump_config.py +0 -108
  60. topmark-0.2.1/src/topmark/cli/commands/filetypes.py +0 -39
  61. topmark-0.2.1/src/topmark/cli/commands/strip.py +0 -331
  62. topmark-0.2.1/src/topmark/cli/commands/version.py +0 -32
  63. topmark-0.2.1/src/topmark/cli/main.py +0 -502
  64. topmark-0.2.1/src/topmark/cli/options.py +0 -276
  65. topmark-0.2.1/src/topmark/filetypes/base.py +0 -97
  66. topmark-0.2.1/src/topmark/pipeline/steps/comparer.py +0 -105
  67. topmark-0.2.1/src/topmark/pipeline/steps/renderer.py +0 -64
  68. topmark-0.2.1/src/topmark/pipeline/steps/resolver.py +0 -142
  69. {topmark-0.2.1 → topmark-0.3.1}/LICENSE +0 -0
  70. {topmark-0.2.1 → topmark-0.3.1}/setup.cfg +0 -0
  71. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/__init__.py +0 -0
  72. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/cli/commands/__init__.py +0 -0
  73. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/config/topmark-default.toml +0 -0
  74. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/filetypes/__init__.py +0 -0
  75. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/filetypes/policy.py +0 -0
  76. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/__init__.py +0 -0
  77. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/contracts.py +0 -0
  78. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/__init__.py +0 -0
  79. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/scanner.py +0 -0
  80. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/pipeline/steps/stripper.py +0 -0
  81. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/py.typed +0 -0
  82. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/rendering/api.py +0 -0
  83. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/rendering/formats.py +0 -0
  84. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/utils/__init__.py +0 -0
  85. {topmark-0.2.1 → topmark-0.3.1}/src/topmark/utils/file.py +0 -0
  86. {topmark-0.2.1 → topmark-0.3.1}/src/topmark.egg-info/dependency_links.txt +0 -0
  87. {topmark-0.2.1 → topmark-0.3.1}/src/topmark.egg-info/entry_points.txt +0 -0
  88. {topmark-0.2.1 → topmark-0.3.1}/src/topmark.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topmark
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: A Python CLI to inspect, validate, and manage license and copyright headers.
5
5
  Author-email: Olivier Biot <olivier.biot@gmail.com>
6
6
  License-Expression: MIT
@@ -24,7 +24,6 @@ Requires-Dist: click
24
24
  Provides-Extra: dev
25
25
  Requires-Dist: ruff; extra == "dev"
26
26
  Requires-Dist: pylint; extra == "dev"
27
- Requires-Dist: mypy; extra == "dev"
28
27
  Requires-Dist: pyright; extra == "dev"
29
28
  Requires-Dist: mdformat; extra == "dev"
30
29
  Requires-Dist: mdformat-tables; extra == "dev"
@@ -38,12 +37,14 @@ Provides-Extra: docs
38
37
  Requires-Dist: mkdocs>=1.6; extra == "docs"
39
38
  Requires-Dist: mkdocs-material>=9.5; extra == "docs"
40
39
  Requires-Dist: mkdocstrings[python]>=0.25; extra == "docs"
40
+ Requires-Dist: mkdocs-autorefs>=0.5; extra == "docs"
41
41
  Requires-Dist: pymdown-extensions>=10.8; extra == "docs"
42
+ Requires-Dist: mkdocs-gen-files<0.6,>=0.5; extra == "docs"
43
+ Requires-Dist: ruff; extra == "docs"
42
44
  Provides-Extra: test
43
45
  Requires-Dist: pytest; extra == "test"
44
46
  Requires-Dist: pytest-xdist; extra == "test"
45
47
  Provides-Extra: typing
46
- Requires-Dist: mypy; extra == "typing"
47
48
  Requires-Dist: types-toml; extra == "typing"
48
49
  Dynamic: license-file
49
50
 
@@ -70,6 +71,13 @@ topmark:header:end
70
71
  codebases. It helps maintain consistent header metadata across projects by supporting per-file-type
71
72
  header formats, customizable fields, inclusion/exclusion rules, and dry-run safety.
72
73
 
74
+ ## 📚 Documentation
75
+
76
+ Full documentation is available on Read the Docs: <https://topmark.readthedocs.io>
77
+
78
+ This README is the canonical, complete introduction for GitHub/PyPI. The docs site provides a
79
+ concise landing page and deep links into topics (install, usage, CI, API, etc.).
80
+
73
81
  ## ✨ Features
74
82
 
75
83
  - File header detection, insertion, and replacement
@@ -113,7 +121,7 @@ pip install topmark
113
121
  ## ⚙️ Usage
114
122
 
115
123
  ```bash
116
- topmark [OPTIONS] [PATHS]...
124
+ topmark [SUBCOMMAND] [OPTIONS] [PATHS]...
117
125
  ```
118
126
 
119
127
  TopMark uses Click 8.2 and supports shell completions. The base command performs a dry‑run *check*
@@ -126,35 +134,47 @@ Logging verbosity is controlled globally:
126
134
  - `-v`, `--verbose`: Increase verbosity (can be repeated)
127
135
  - `-q`, `--quiet`: Suppress most output (overrides verbosity)
128
136
 
129
- All other options, such as `--stdin`, `--file-type`, and path filters, are specific to individual
130
- subcommands like `check` or `apply`.
137
+ All other options are specific to individual subcommands.
138
+
139
+ ______________________________________________________________________
131
140
 
132
- ### Skipping and filtering helpers
141
+ ### Subcommands
133
142
 
134
- These switches help keep CI output meaningful and fast:
143
+ | Command | Description |
144
+ | --------------- | -------------------------------------------------- |
145
+ | `dump-config` | Show the resolved configuration in TOML format |
146
+ | `filetypes` | List supported file types and their comment styles |
147
+ | `processors` | List registered header processors and file types |
148
+ | `strip` | Remove TopMark headers from files (destructive) |
149
+ | `version` | Print TopMark version |
150
+ | `show-defaults` | Show default config (without merging) |
151
+ | `init-config` | Output a starter configuration file |
135
152
 
136
- - `--skip-compliant` — hide files that are already compliant; only show items that need attention.
137
- - `--skip-unsupported` — hide unsupported file types and files matched by known types that
138
- intentionally **do not** support headers (e.g., strict JSON). They remain **recognized** but are
139
- not listed in results.
153
+ ______________________________________________________________________
140
154
 
141
155
  ### Examples
142
156
 
143
157
  ```bash
144
158
  # Check Python files in the src/ directory
145
- topmark --file-type python src/
159
+ topmark check --file-type python src/
146
160
 
147
161
  # Use exclusion patterns, and compute relative paths from src
148
- topmark --file-type python --exclude .venv --relative-to src src/
162
+ topmark check --file-type python --exclude .venv --relative-to src src/
149
163
 
150
164
  # Add one verbosity level to topmark, use exclusion patterns from .gitignore
151
- topmark -v --file-type python --exclude-from .gitignore src/
165
+ topmark -v check --file-type python --exclude-from .gitignore src/
166
+
167
+ # Read a list of files from STDIN, generate summary
168
+ find . -name "*.py" | topmark check --file-type python --files-from - --summary
152
169
 
153
- # Read files from stdin, generate summary
154
- find . -name "*.py" | topmark --file-type python --summary --stdin
170
+ # Process all files that are either staged, or untracked but not ignored in a Git repo (needs dedulication with `sort -u`)
171
+ git ls-files -c -o --exclude-standard | sort -u | topmark check --files-from - --apply
155
172
 
156
- # Process all files in a Git repo
157
- git ls-files -c -o --exclude-standard | sort -u | topmark --stdin --apply
173
+ # Read a single file's *content* from STDIN and render the resultng unified diff
174
+ cat README.md | topmark - --stdin-filename README.md --diff
175
+
176
+ # Read a single file's *content* from STDIN and print the updated content to stdout
177
+ cat README.md | topmark - --stdin-filename README.md --apply
158
178
 
159
179
  # Dump the merged configuration (after loading all applicable config layers)
160
180
  topmark dump-config --file-type python --exclude .venv --exclude-from .gitignore
@@ -165,11 +185,11 @@ topmark show-defaults
165
185
  # Output a starter configuration to stdout
166
186
  topmark init-config
167
187
 
168
- # Show TopMark version
169
- topmark version
188
+ # Show TopMark version in JSON format
189
+ topmark version --format json
170
190
 
171
191
  # Apply changes to files in-place
172
- topmark --apply src/
192
+ topmark check --apply src/
173
193
 
174
194
  # Remove headers from files (dry-run)
175
195
  topmark strip src/
@@ -178,174 +198,173 @@ topmark strip src/
178
198
  topmark strip --apply src/
179
199
 
180
200
  # CI-friendly summary: only show issues; ignore unsupported types
181
- topmark --skip-compliant --skip-unsupported src/
201
+ topmark check --skip-compliant --skip-unsupported src/
202
+
203
+ # Apply fixes, don't report unsupported files, muted output (useful for pre-commit)
204
+ topmark check --apply --skip-unsupported --quiet
182
205
 
183
- # Apply fixes for only the changed files passed by pre-commit
184
- topmark --apply --apply --skip-unsupported --quiet
206
+ # Show supported file types in MarkDown format, providing detailed output:
207
+ topmark filetypes --format markdown --long
208
+
209
+ # Show registered header processors (brief)
210
+ topmark processors
211
+
212
+ # Detailed Markdown listing of processors and their file types
213
+ topmark processors --format markdown --long
185
214
  ```
186
215
 
187
- ## 📐 Header placement rules
216
+ ______________________________________________________________________
188
217
 
189
- TopMark is comment-aware and places the header block according to the file type and its policy.
218
+ ## 🔌 Public API (stable)
219
+
220
+ TopMark exposes a small, stable Python API for integrations. Import from `topmark.api` for core
221
+ operations, and use the registry facade for read-only discovery.
222
+
223
+ ### Quickstart
224
+
225
+ ```python
226
+ from pathlib import Path
227
+ from topmark import api
228
+
229
+ # Check (dry-run by default)
230
+ result = api.check([Path("src")])
231
+ print(result.summary) # {"unchanged": N, "error": M, ...}
232
+ print(result.had_errors) # True/False
190
233
 
191
- ### Pound-style files (e.g., Python, Shell, Ruby, Makefile, YAML, TOML, Dockerfile)
234
+ # Apply changes explicitly
235
+ applied = api.check([Path("src")], apply=True)
192
236
 
193
- Rules:
237
+ # Remove headers
238
+ stripped = api.strip([Path("src")], apply=False)
239
+ ```
240
+
241
+ ### Registry facade (read-only)
194
242
 
195
- - If a **shebang** is present (e.g., `#!/usr/bin/env python3`), place the header **after** the
196
- shebang and ensure **exactly one** blank line in-between.
197
- - If a **coding/encoding line** follows the shebang (PEP 263 style), place the header **after**
198
- shebang **and** encoding line.
199
- - Otherwise, place the header **at the top of the file**.
200
- - Ensure **one trailing blank line** after the header block when the next line is not already blank.
243
+ ```python
244
+ from topmark.registry import Registry
201
245
 
202
- Example (Python):
246
+ fts = Registry.filetypes() # Mapping[str, FileType]
247
+ procs = Registry.processors() # Mapping[str, HeaderProcessor]
248
+ for b in Registry.bindings(): # (filetype, optional processor)
249
+ print(b.filetype.name, bool(b.processor))
250
+ ```
203
251
 
204
- ```py
205
- #!/usr/bin/env python3
252
+ > **Note:** `Registry` is **not** re-exported from `topmark.api`; import it from `topmark.registry`.
206
253
 
207
- # topmark:header:start
208
- #
209
- # file :
210
- # file_relpath :
211
- #
212
- # topmark:header:end
254
+ ### Version helper
213
255
 
214
- print("hello")
256
+ ```python
257
+ from topmark import api
258
+ print(api.version()) # e.g. "0.3.1"
215
259
  ```
216
260
 
217
- ### XML-style files (XML, HTML/XHTML, SVG, Vue/Svelte/Markdown via HTML comments)
261
+ ### Stability
218
262
 
219
- Rules:
263
+ - `topmark.api` and the `Registry` facade are covered by semantic versioning.
264
+ - Low-level registries (`FileTypeRegistry`, `HeaderProcessorRegistry`) remain available for
265
+ plugins/tests but are **advanced** and may change between minor versions.
220
266
 
221
- - If present, place the header **after the XML declaration** and **DOCTYPE**, with **one blank
222
- line** before the header block.
223
- - Otherwise, place the header **at the top of the file**.
224
- - The header uses the file’s native comment syntax; for XML/HTML it’s a comment block wrapper:
267
+ ### Adding & updating headers
225
268
 
226
- ```html
227
- <!--
228
- topmark:header:start
269
+ Use the `topmark check` command to insert or update headers. It’s **dry‑run by default**; add
270
+ `--apply` to write changes. Placement follows file‑type policy (shebang/encoding for Python, XML
271
+ declaration for XML/HTML, etc.). Newline style and BOM are preserved; runs are idempotent.
229
272
 
230
- file :
231
- file_relpath :
273
+ #### Quick examples
232
274
 
233
- topmark:header:end
234
- -->
275
+ ```bash
276
+ # Preview (exit code 2 when changes are pending)
277
+ topmark src/
235
278
 
236
- <html>...</html>
279
+ # Apply in place
280
+ topmark check --apply src/
237
281
  ```
238
282
 
239
- ### General guarantees
283
+ > For full details, options, examples, and exit codes, see the dedicated guide:
284
+ > **[Adding & updating headers with `topmark`](docs/usage/commands/topmark.md)**
240
285
 
241
- - **Newline preservation:** The inserted header uses the same newline style as the file
242
- (LF/CRLF/CR).
243
- - **BOM preservation:** If a UTF‑8 BOM is present, it is preserved.
244
- - **Idempotency:** Re-running TopMark on a file with a correct header makes **no changes**.
286
+ ### Removing headers with `strip`
245
287
 
246
- ### Common Options
288
+ Use `topmark strip` to remove the entire TopMark header block. The command is **dry-run by
289
+ default**; add `--apply` to write changes. It preserves newline style and BOM, and keeps XML
290
+ declarations and Markdown code fences intact.
247
291
 
248
- The following options can be used with most commands.
292
+ #### Quick examples
249
293
 
250
- | Option | Description |
251
- | ---------------- | ---------------------------------------- |
252
- | `--file-type` | Specify file type (python, markdown, …) |
253
- | `--relative-to` | Set base path for relative header fields |
254
- | `--include` | Include paths or glob patterns |
255
- | `--include-from` | Read inclusion patterns from file |
256
- | `--exclude` | Exclude paths or glob patterns |
257
- | `--exclude-from` | Read exclusion patterns from file |
258
- | `--stdin` | Read file paths from stdin |
259
- | `--apply` | Actually modify files instead of dry-run |
260
- | `-v, --verbose` | Increase verbosity (can be repeated) |
261
- | `-q, --quiet` | Suppress most output |
294
+ ```bash
295
+ # Preview (exit code 2 when removals are pending)
296
+ topmark strip src/
262
297
 
263
- ### Subcommands
298
+ # Apply in place
299
+ topmark strip --apply src/
300
+ ```
264
301
 
265
- | Command | Description |
266
- | --------------- | -------------------------------------------------- |
267
- | `dump-config` | Show the resolved configuration in TOML format |
268
- | `filetypes` | List supported file types and their comment styles |
269
- | `strip` | Remove TopMark headers from files (destructive) |
270
- | `version` | Print TopMark version |
271
- | `show-defaults` | Show default config (without merging) |
272
- | `init-config` | Output a starter configuration file |
302
+ > For full details, options, examples, and exit codes, see the dedicated guide:
303
+ > **[Removing headers with `topmark strip`](docs/usage/commands/strip.md)**
273
304
 
274
- ## 🧩 Supported file types
305
+ ### Dumping the merged configuration
275
306
 
276
- | Processor | File types (examples) |
277
- | -------------------- | -------------------------------------------------------------------------------------------------------------- |
278
- | PoundHeaderProcessor | dockerfile, env, git-meta, ini, julia, makefile, perl, python, python-requirements, r, ruby, shell, toml, yaml |
279
- | SlashHeaderProcessor | c, cpp, cs, go, java, javascript, kotlin, rust, swift, typescript, vscode-jsonc |
280
- | XmlHeaderProcessor | html, markdown, svelte, svg, vue, xhtml, xml, xsl, xslt, yaml |
307
+ Use `topmark dump-config` to print the **effective** configuration (defaults → discovered config →
308
+ `--config` files → CLI flags) as TOML. This command is **file‑agnostic**: positional paths and
309
+ `--files-from` are ignored; filter flags (`--include/--exclude`, `--include-from/--exclude-from`)
310
+ are honored.
281
311
 
282
- Some formats (e.g., strict JSON) are **recognized but intentionally skipped** because they lack a
283
- safe comment syntax. Use `--skip-unsupported` to hide them from the report while keeping safety.
312
+ ```bash
313
+ # Dump merged configuration
314
+ topmark dump-config
284
315
 
285
- For a complete list, please run:
316
+ # Include/exclude filters still apply
317
+ topmark dump-config --exclude .venv --exclude-from .gitignore
286
318
 
287
- ```sh
288
- topmark filetypes
319
+ # Read patterns from STDIN
320
+ printf "*.py\n" | topmark dump-config --include-from -
289
321
  ```
290
322
 
291
- ### How TopMark resolves file types (specificity & safety)
323
+ > For details and notes, see:
324
+ > **[Dumping the merged configuration with `dump-config`](docs/usage/commands/dump_config.md)**
292
325
 
293
- TopMark may have multiple `FileType` definitions that **match** a given path. The resolver now:
326
+ ### Listing supported file types
294
327
 
295
- - evaluates **all** matching file types and scores them by **specificity**,
296
- - prefers **explicit filenames / tail subpaths** (e.g., `.vscode/settings.json`) over patterns, and
297
- **patterns** over simple **extensions**,
298
- - breaks ties in favor of **headerable** types (those without `skip_processing=True`).
328
+ Use `topmark filetypes` to see the identifiers you can pass to `--file-type` and the associated
329
+ comment styles TopMark will use when rendering headers.
299
330
 
300
- **Tail subpath matching.** `FileType.filenames` entries that contain a path separator (e.g.,
301
- `".vscode/settings.json"`) are matched as **path suffixes** against `path.as_posix()`; plain names
302
- still match the **basename** only.
331
+ ```bash
332
+ # Show available file type identifiers
333
+ topmark filetypes
303
334
 
304
- **JSON vs JSONC.** Generic `json` is recognized but marked `skip_processing=True` (no comments in
305
- strict JSON), while `vscode-jsonc` is a safe, **narrow** opt‑in that uses `//` headers. If you need
306
- more JSON-with-comments files, add them via a dedicated `FileType` or an explicit allow‑list in
307
- config.
335
+ # Then restrict processing to one or more types
336
+ topmark check --file-type python src/
337
+ topmark check --file-type markdown --file-type env docs/ config/
338
+ ```
308
339
 
309
- **Shebang‑aware insertion.** The default insertion logic is policy‑driven and shebang‑aware (insert
310
- after `#!` and optional encoding line). For formats like XML that need character‑precise placement,
311
- processors provide a text‑offset path; `XmlHeaderProcessor` uses this and signals **no line
312
- anchor**.
340
+ > For details, see:
341
+ > **[Listing supported file types with `filetypes`](docs/usage/commands/filetypes.md)**
313
342
 
314
- ## 🪝 Pre-commit integration
343
+ ## 📐 Header placement rules
315
344
 
316
- TopMark provides first-class pre-commit hooks. A minimal consumer configuration:
317
-
318
- ```yaml
319
- # .pre-commit-config.yaml (in a consuming repository)
320
- repos:
321
- - repo: https://github.com/shutterfreak/topmark
322
- rev: v0.2.0 # pin to a released tag
323
- hooks:
324
- - id: topmark-check
325
- # Optional: limit scope to supported text types
326
- # files: '\\.(py|md|toml|ya?ml|sh|Makefile)$'
327
- ```
345
+ TopMark is comment-aware and places the header block according to the file type and its policy.
328
346
 
329
- Hooks shipped by this repo:
347
+ The complete header placement rules are documented in the usage guide:
330
348
 
331
- - **`topmark-check`** — non-destructive validation. Recommended on `pre-commit` / `pre-push`.
332
- - **`topmark-apply`** — destructive, requires `--apply`. Marked `manual` so it only runs when you
333
- call it explicitly.
349
+ - [Header placement rules](docs/usage/header-placement.md)
334
350
 
335
- **Run the manual hook locally:**
351
+ ## 🧩 Supported file types
336
352
 
337
- ```bash
338
- # On the whole repo
339
- pre-commit run topmark-apply --all-files --hook-stage manual
353
+ See the full list and resolver behavior in the dedicated guide:
340
354
 
341
- # On specific files
342
- pre-commit run topmark-apply --files path/to/file1 path/to/file2 --hook-stage manual
343
- ```
355
+ - [Supported file types](docs/usage/filetypes.md)
356
+
357
+ ## 🪝 Pre-commit integration
358
+
359
+ TopMark ships with pre-commit hooks to validate or update file headers.
360
+
361
+ - **`topmark-check`** — runs automatically at `pre-commit` / `pre-push`, fails if headers need
362
+ changes.
363
+ - **`topmark-apply`** — manual only; applies fixes and may modify files.
364
+
365
+ For configuration examples, hook policies, and troubleshooting, see the dedicated guide:
344
366
 
345
- **Why does the hook seem to run multiple times?** Pre-commit batches filenames to avoid OS
346
- argument-length limits. You may see repeated banners (e.g., “Processing N file(s)”) as the hook runs
347
- once per batch. To run **once** per repo, set `pass_filenames: false` in the hook manifest and let
348
- TopMark discover files itself.
367
+ - [Using TopMark with pre-commit](docs/usage/pre-commit.md)
349
368
 
350
369
  ## 🛠 Configuration
351
370
 
@@ -357,9 +376,9 @@ You can specify one or more `--config` files, or rely on local fallback resoluti
357
376
  TopMark reads configuration from one or more TOML files. Configuration is merged from:
358
377
 
359
378
  1. Built-in defaults
360
- 2. Local project config (if not disabled via `--no-config`)
361
- 3. Additional files via `--config`
362
- 4. CLI overrides
379
+ 1. Local project config (if not disabled via `--no-config`)
380
+ 1. Additional files via `--config`
381
+ 1. CLI overrides
363
382
 
364
383
  Example configuration snippet (`topmark.toml`):
365
384
 
@@ -405,5 +424,4 @@ type checks in each environment.
405
424
 
406
425
  MIT License © 2025 Olivier Biot
407
426
 
408
- Markdown formatting is handled by `mdformat` with the `mdformat-tables` plugin, and configuration is
409
- read from `pyproject.toml`.
427
+ > **[LICENSE (MIT)](LICENSE)**