Skip to content
shutterfreakPublic

About

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.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1,029 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TopMark

PyPI version GitHub release Python Versions CI Coverage Documentation Status License: MIT Development Status Downloads

TopMark is a dry-run-first Python CLI for keeping license, copyright, project, and file metadata headers consistent across polyglot repositories.

It was built for real-world codebases where file headers must be safe to inspect, update, remove, and automate across different languages, comment styles, documentation files, and CI workflows.

It helps teams avoid fragile one-off scripts by providing:

  • comment-aware header rendering;
  • layered configuration and policy controls;
  • dry-run-by-default safety;
  • stable CI-friendly exit codes;
  • machine-readable output with stable cross-platform path serialization;
  • transparent file-type resolution diagnostics;
  • deterministic configuration discovery and filesystem processing;
  • configuration, registry, and file-resolution introspection commands;
  • and a public Python API for automation and integration.

Quick start

Install TopMark from PyPI:

pip install topmark

Create a starter configuration:

topmark config init --root > topmark.toml

Preview whether TopMark would insert or update headers:

topmark check .

Preview the changes TopMark would insert or update as unified diffs:

topmark check --diff .

--diff is a dry-run preview mode and is therefore mutually exclusive with --apply.

Apply the changes once the preview looks right:

topmark check --apply .

Remove TopMark-managed headers when needed:

topmark strip .
topmark strip --apply .

TopMark also provides diagnostics for understanding how files, configuration, and processors are resolved:

topmark probe README.md
topmark config dump --show-layers
topmark registry filetypes
topmark registry processors
topmark registry bindings

TopMark never mutates files unless --apply is passed.

For a guided first setup, see:


Why TopMark?

TopMark started from a simple need: manage consistent file headers in multi-language codebases without relying on brittle custom scripts. It began with Python files, expanded to Markdown documentation, and matured into a general-purpose CLI for polyglot repositories.

TopMark is useful when you need to:

  • keep license and copyright headers consistent across source and documentation files;
  • preview repository-wide changes before anything is written;
  • preserve shebangs, BOMs, newline style, and file-specific comment syntax, with explicit BOM-before-shebang remediation when requested;
  • configure behavior differently across nested projects or file types;
  • inspect why a file was included, excluded, or matched to a specific processor;
  • integrate header checks into CI, pre-commit, Git hooks, or custom automation;
  • consume deterministic JSON or NDJSON output from scripts and tooling, with stable machine-readable path serialization, processing-path semantics, configuration provenance, and canonical cross-platform registry metadata.

The goal is not to replace formatters, linters, or license scanners. TopMark focuses on one job: safe, deterministic, comment-aware file header management.


Documentation

Full documentation is hosted on Read the Docs:
👉 https://topmark.readthedocs.io/en/latest/

This README provides a compact overview for GitHub and PyPI. Detailed usage, configuration, command-reference, API, CI/CD, and contributor documentation live in the generated documentation site.


Example headers

TopMark adapts headers to the comment syntax of each supported file type.

Dry-run diff preview

A dry-run preview makes the intended change explicit before files are modified:

--- src/example.py (current)    2026-05-23 09:37:03 +0000
+++ src/example.py (updated)    2026-05-23 09:37:18 +0000
@@ -1 +1,11 @@
+# topmark:header:start
+#
+#   project      : ACME Project
+#   file         : example.py
+#   file_relpath : src/example.py
+#   license      : MIT
+#   copyright    : (C) 2025 John Doe
+#
+# topmark:header:end
+
 print("Hello, World!")

The same retained diff information is also available to machine-readable consumers through JSON and NDJSON output, using structured diff payloads instead of terminal-oriented unified diff rendering.

Header rendering and placement rules for supported file types are documented in:


Installation

From PyPI

TopMark stable releases are published on PyPI:

pip install topmark

TopMark currently supports Python 3.10-3.15. See the Python support policy (hosted docs) for lifecycle and EOL compatibility details.

[!NOTE] Upgrading an existing repository

Review the applicable major-version migration guide before changing existing configuration, CI jobs, or pre-commit hooks:

From source

For development setup from source, see:

Verify CLI

topmark version
topmark --help

For development builds between release tags, topmark version may report SCM-derived development versions that include commit-based metadata.


Usage

topmark [COMMAND] [OPTIONS] [PATHS]...

The most common workflow is:

topmark check .           # preview which files would change
topmark check --diff .    # preview unified diffs
topmark check --apply .   # add/update headers

topmark strip .           # preview which files would change
topmark strip --diff .    # preview unified diffs
topmark strip --apply .   # remove headers

--diff previews retained changes without mutating files. Human TEXT and Markdown output render unified diffs, while JSON detail embeds structured per-file diff payloads and NDJSON detail emits adjacent standalone diff records. --apply and --diff are mutually exclusive.

Common commands:

Command Purpose
topmark check Validate, preview, and optionally apply TopMark headers
topmark strip Preview and remove TopMark-managed headers
topmark probe Explain file-type and processor resolution
topmark config Inspect, validate, and generate configuration
topmark registry Inspect file types, processors, and bindings
topmark version Print version and environment information

Useful diagnostics while adopting TopMark:

topmark probe README.md
topmark config dump --show-layers
topmark registry filetypes

All available commands, shared options, output formats, machine-readable payload contracts, STDIN behavior, and exit codes are documented in the hosted documentation:

Exit codes (CI / scripting)

TopMark uses a small, stable set of exit codes for automation:

  • SUCCESS (0) - success (no changes needed or changes applied)
  • WOULD_CHANGE (3) - dry-run indicates changes would be made (check, strip)
  • CONFIG_ERROR (78) - configuration validation failed (check, strip, probe, config check)
  • USAGE_ERROR (64) - CLI usage error
  • invalid command/option combinations, positional paths on file-agnostic commands, and unsupported STDIN modes are reported as usage errors

Exit code 2 is reserved for Click-owned parser-level usage errors, such as unknown commands, unknown options or invalid option values.

Other codes (for example UNSUPPORTED_FILE_TYPE (69), PIPELINE_ERROR (70), IO_ERROR (74), PERMISSION_DENIED (77)) are used for more specific runtime conditions after CLI usage has been accepted.

For the complete, stable contract, see:


Configuration and Policy

TopMark supports layered configuration discovery and policy-based control over header mutation.

Common configuration sources include:

  • topmark.toml
  • pyproject.toml under [tool.topmark]
  • user configuration
  • explicit --config files
  • CLI options

Project-chain discovery starts from the resolved discovery anchor before layered configuration is built. Loaded file-backed configuration sources then use configuration-source identity based on resolved configuration-file targets. Layered configuration provenance, applicability evaluation, and precedence therefore behave consistently when working directories, input anchors, or configuration files are accessed through symlinks.

A minimal project configuration looks like this:

[config]
root = true

[fields]
project = "ACME Project"
license = "MIT"

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

[policy]
bom_before_shebang = "reject"
mixed_line_endings = "reject"

Generate a documented starter configuration:

topmark config init --root > topmark.toml

Use the CLI to inspect the effective configuration:

topmark config dump --show-layers
topmark config dump --show-layers --output-format json

Detailed configuration, policy, and filtering behavior is documented in:


Pre-commit and CI Integration

Add TopMark to .pre-commit-config.yaml:

repos:
  - repo: https://github.com/shutterfreak/topmark
    rev: v1.0.0
    hooks:
      - id: topmark-check

Install hooks:

pre-commit install
pre-commit run --all-files

For CI validation, run TopMark without --apply:

topmark config check --strict
topmark check .

Exit code 3 means files would require header updates.

Detailed integration guidance is documented in:


Public API

TopMark exposes a public Python API for programmatic checks, stripping, probing, and registry discovery.

Public API callers should use the functions and DTOs exposed from topmark.api. Runtime helpers, resolver internals, and pipeline contexts are implementation details.

Public API operations follow the same configuration-discovery, filesystem-identity evaluation, processing-path, and configuration-source identity contracts as the CLI.

Example dry-run check:

from pathlib import Path

from topmark import api

result = api.check(
    [Path("src")],
    apply=False,
    report="actionable",
)

print(result.summary)
print(result.had_errors)

For read-only resolution diagnostics, use api.probe():

from pathlib import Path

from topmark import api

result = api.probe([Path("README.md")])

for file_result in result.files:
    print(file_result.path, file_result.status, file_result.reason)

For API details, see:


Packaging and Versioning

TopMark uses Git-tag-driven package versions via setuptools-scm. Versions are derived from Git tags at build time rather than maintained manually in pyproject.toml.

Stable releases are published to PyPI, and pre-releases are validated through TestPyPI before promotion.

For detailed release architecture and maintainer guidance, see:


Development

For day-to-day development, use the local .venv for editor integration and interactive work. Automated testing, typing, documentation, and validation run in isolated environments managed by nox.

Common validation commands:

make pytest
make test
make docs-build
make verify

For contributor setup and validation details, see:


License

MIT License © 2025 Olivier Biot

See LICENSE


TopMark - consistent headers for consistent projects.

About

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.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages