Skip to main content

A tool to inspect, validate, and manage file headers in diverse codebases

Project description

TopMark

TopMark is a command-line tool to inspect, validate, and manage file headers in diverse codebases. It helps maintain consistent header metadata across projects by supporting per-file-type header formats, customizable fields, inclusion/exclusion rules, and dry-run safety.

✨ Features

  • File header detection, insertion, and replacement
  • Supports multiple file types (Python, Makefile, Markdown, .env, ...)
  • Configurable comment styles and header fields
  • Inclusion and exclusion logic (via CLI, globs, stdin, or config)
  • Dry-run by default; safe for CI/CD integration
  • Configuration via pyproject.toml or topmark.toml
  • Shell completion for enum-based options
  • Colorized CLI output (via yachalk)
  • Python ≥3.10
  • Integrated pre-commit hooks for automated checks
  • Formatting and linting support via Makefile targets
  • CI-friendly design for safe automated use
  • Strict static typing with mypy and Pyright, using PEP 604 union syntax
  • Google-style docstrings without redundant type declarations
  • Selective removal
  • Preserves original newline style (LF/CRLF/CR) and BOM
  • Idempotent updates (re-running does not change already-correct files)

🚀 Installation

git clone https://github.com/shutterfreak/topmark.git
cd topmark
make setup  # creates virtualenv, installs dependencies and tools

Or install into an existing virtualenv:

pip install -e .

Or install the latest release from PyPI:

pip install topmark

⚙️ Usage

topmark [OPTIONS] [PATHS]...

TopMark uses Click 8.2 and supports shell completions. The base command performs a dry‑run check by default and applies changes when --apply is provided.

Logging verbosity is controlled globally:

  • -v, --verbose: Increase verbosity (can be repeated)
  • -q, --quiet: Suppress most output (overrides verbosity)

All other options, such as --stdin, --file-type, and path filters, are specific to individual subcommands like check or apply.

Examples

# Check Python files in the src/ directory
topmark --file-type python src/

# Use exclusion patterns, and compute relative paths from src
topmark --file-type python --exclude .venv --relative-to src src/

# Add one verbosity level to topmark, use exclusion patterns from .gitignore
topmark -v --file-type python --exclude-from .gitignore src/

# Read files from stdin, generate summary
find . -name "*.py" | topmark --file-type python --summary --stdin

# Process all files in a Git repo
git ls-files -c -o --exclude-standard | sort -u | topmark --stdin --apply

# Dump the merged configuration (after loading all applicable config layers)
topmark dump-config --file-type python --exclude .venv --exclude-from .gitignore

# Display the default configuration without any merging
topmark show-defaults

# Output a starter configuration to stdout
topmark init-config

# Show TopMark version
topmark version

# Apply changes to files in-place
topmark --apply src/

📐 Header placement rules

TopMark is comment-aware and places the header block according to the file type and its policy.

Pound-style files (e.g., Python, Shell, Ruby, Makefile, YAML, TOML, Dockerfile)

Rules:

  • If a shebang is present (e.g., #!/usr/bin/env python3), place the header after the shebang and ensure exactly one blank line in-between.
  • If a coding/encoding line follows the shebang (PEP 263 style), place the header after shebang and encoding line.
  • Otherwise, place the header at the top of the file.
  • Ensure one trailing blank line after the header block when the next line is not already blank.

Example (Python):

#!/usr/bin/env python3

# topmark:header:start
#
#   file         :
#   file_relpath :
#
# topmark:header:end

print("hello")

XML-style files (XML, HTML/XHTML, SVG, Vue/Svelte/Markdown via HTML comments)

Rules:

  • If present, place the header after the XML declaration and DOCTYPE, with one blank line before the header block.
  • Otherwise, place the header at the top of the file.
  • The header uses the file’s native comment syntax; for XML/HTML it’s a comment block wrapper:
<!--
topmark:header:start

  file         :
  file_relpath :

topmark:header:end
-->

<html>...</html>

General guarantees

  • Newline preservation: The inserted header uses the same newline style as the file (LF/CRLF/CR).
  • BOM preservation: If a UTF‑8 BOM is present, it is preserved.
  • Idempotency: Re-running TopMark on a file with a correct header makes no changes.

Common Options

The following options can be used with most commands.

Option Description
--file-type Specify file type (python, markdown, …)
--relative-to Set base path for relative header fields
--include Include paths or glob patterns
--include-from Read inclusion patterns from file
--exclude Exclude paths or glob patterns
--exclude-from Read exclusion patterns from file
--stdin Read file paths from stdin
--apply Actually modify files instead of dry-run
-v, --verbose Increase verbosity (can be repeated)
-q, --quiet Suppress most output

Subcommands

Command Description
dump-config Show the resolved configuration in TOML format
filetypes List supported file types and their comment styles
version Print TopMark version
show-defaults Show default config (without merging)
init-config Output a starter configuration file

🧩 Supported file types

Processor File types (examples)
PoundHeaderProcessor python, shell, ruby, r, julia, perl, makefile, dockerfile, yaml, toml, env
XmlHeaderProcessor xml, xhtml, html, svg, xsl/xslt, vue, svelte, markdown

🛠 Configuration

You can specify one or more --config files, or rely on local fallback resolution:

  • topmark.toml in the working directory
  • pyproject.toml using the [tool.topmark] table

TopMark reads configuration from one or more TOML files. Configuration is merged from:

  1. Built-in defaults
  2. Local project config (if not disabled via --no-config)
  3. Additional files via --config
  4. CLI overrides

Example configuration snippet (topmark.toml):

[fields]
project = "TopMark"
license = "MIT"
copyright = "(c) 2025 Olivier Biot"

[header]
fields = [ "file", "file_relpath", "project", "license", "copyright",]

[formatting]
align_fields = true
raw_header = false

[files]
file_types = [ "python", "markdown", "env" ]
include = []
include_from = []
exclude = []
exclude_from = [ ".gitignore" ]
relative_to = "."

Notes

  • formatting.align_fields = true vertically aligns the field names within the rendered header lines for readability.
  • File-type specific behavior (shebang handling, XML prolog, blank line policies) is driven by internal FileTypeHeaderPolicy defaults and can be extended to new types.

The EnumParam class enables shell completion for enum-based CLI options.

🧪 Development Setup

For development setup and contribution guidelines, see CONTRIBUTING.md.

To verify compatibility across supported Python versions (3.10–3.13), use tox to run tests and type checks in each environment.

📄 License

MIT License © 2025 Olivier Biot

Markdown formatting is handled by mdformat with the mdformat-tables plugin, and configuration is read from pyproject.toml.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

topmark-0.1.0.tar.gz (70.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

topmark-0.1.0-py3-none-any.whl (86.8 kB view details)

Uploaded Python 3

File details

Details for the file topmark-0.1.0.tar.gz.

File metadata

  • Download URL: topmark-0.1.0.tar.gz
  • Upload date:
  • Size: 70.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for topmark-0.1.0.tar.gz
Algorithm Hash digest
SHA256 357696c127f10371a7a02e0fc39af5a882d5092b19b1ddbb7015803719a16af2
MD5 bc0218c273a99a532476779b3c911e69
BLAKE2b-256 b9f43fc76602e6474e48ee392b4067c9f41198062a989d9475deabb237d0f5a0

See more details on using hashes here.

File details

Details for the file topmark-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: topmark-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 86.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for topmark-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 45d53f0d624bd7773e36328a2615742df72ad20a032453dac16300725576514c
MD5 9054281871ab4d361ad3771e23907410
BLAKE2b-256 cc55ce10c5a165f4433ceddedbd4eb54f01e4ce5ad735ed3eae5b255855728f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page