Skip to main content

A Python CLI to inspect, validate, and manage license and copyright headers.

Project description

TopMark

PyPI version Documentation Status Downloads GitHub release

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.1.tar.gz (72.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.1-py3-none-any.whl (89.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: topmark-0.1.1.tar.gz
  • Upload date:
  • Size: 72.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for topmark-0.1.1.tar.gz
Algorithm Hash digest
SHA256 95cfc905ab5d5b9faf717dbdb6069deb72628d6cc7a5cedc240e41f6c7e96848
MD5 18065fbcd0b4c5bddb28bb89c90da7ee
BLAKE2b-256 1f1543069061a98653ef1eaf994a8fc894bc7d57e68fe2301f4d3e0d73e1f1dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for topmark-0.1.1.tar.gz:

Publisher: release.yml on shutterfreak/topmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: topmark-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 89.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for topmark-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 428f118bf3a55fe49a0276180079dc0273971494399fc85f697f7259e36b0d57
MD5 e01f7122e0b4f502ffc6f5c60da50481
BLAKE2b-256 205807c5852df4375ae77f3c7f907948695a5ec836f27a7e349f2f7ae1664f65

See more details on using hashes here.

Provenance

The following attestation bundles were made for topmark-0.1.1-py3-none-any.whl:

Publisher: release.yml on shutterfreak/topmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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