Skip to main content

rumk

A fast Makefile linter written in Rust, built as the Makefile sibling of Rumdl.

Rumk is currently alpha software. Its CLI, configuration model, diagnostics, fixing behavior, and exit codes intentionally follow Rumdl so existing Rumdl users can reuse their workflow.

Features

  • Lints individual Makefiles or entire directory trees
  • Safely fixes recipe indentation, style-aware .PHONY declarations, and recursive Make invocations
  • Parses continued logical statements and nested $(...)/${...} expressions
  • Models GNU Make assignment flavors, static patterns, target-specific variables, includes, conditionals, define blocks, custom recipe prefixes, and .ONESHELL
  • Builds semantic indexes for variables, references, targets, dependencies, and includes
  • Safely evaluates statically knowable variables and conditionals without running recipes, shell commands, or side-effecting Make functions
  • Supports GNU substitution references plus common word, path, list, and lazy logical functions
  • Resolves expanded include graphs and reports cross-file findings at their real source paths
  • Preserves LF/CRLF line endings and final newlines during fixes
  • Uses Rumdl-style check, fmt, rule, config, init, and explain commands
  • Discovers .rumk.toml upward through the project tree
  • Respects .gitignore by default
  • Supports rule selection, file globs, per-file ignores, severities, and fix allowlists
  • Emits text, flat JSON, and GitHub Actions annotations

Installation

cargo install rumk --locked --version 0.0.5

Or install the native executable from PyPI with a Python tool manager:

uv tool install rumk==0.0.5
# or
pipx install rumk==0.0.5

Rumk is alpha-stage 0.0.x software, so installation names the version explicitly. Release archives and Python wheels cover Linux, macOS, and Windows. GitHub release assets include SHA-256 checksums and build-provenance attestations.

Quick start

# Check Makefiles below the current directory
rumk check

# Check specific files or directories
rumk check Makefile build/

# Apply safe fixes, then fail only if violations remain
rumk check --fix

# Format files with formatter-style exit behavior
rumk fmt

# Preview formatting changes
rumk fmt --diff

# Fail when formatting changes are required
rumk fmt --check

# Inspect rules and effective configuration
rumk rule
rumk rule MK101
rumk config
rumk config get MK101.line-length
rumk config file

Run rumk --help or rumk <command> --help for all options.

Configuration

Create a .rumk.toml file manually or run rumk init:

[global]
dialect = "gnu"
respect-gitignore = true
exclude = ["vendor/**", "generated/**"]
disable = ["MK101"]
fixable = ["MK001"]
include-paths = ["mk"]
predefined-variables = { FROM_CLI = "yes" }
entry-targets = ["all"]

[MK101]
enabled = true
severity = "warning"
line-length = 100
ignore-comments = true
ignore-recipes = true

[MK102]
enabled = true
style = "upper-case"

[MK201]
placement = "auto"

[per-file-ignores]
"vendor/**/*.mk" = ["MK202"]

Configuration discovery checks .rumk.toml, rumk.toml, and .config/rumk.toml while walking upward, stopping at a Git project boundary. Use --config <PATH> for an explicit file or --no-config/--isolated for built-in defaults.

Configurations can inherit another file with extends = "../.rumk.toml"; nested tables are merged, child values win, relative paths resolve from the extending file, and cycles are rejected.

Rules can be suppressed in Make comments without changing project configuration:

# rumk-disable MK202
INSTALL_PREFIX := /usr/local
# rumk-enable MK202

# rumk-disable-next-line MK201
clean:
	rm -rf build

rumk-disable, rumk-enable, rumk-disable-line, and rumk-disable-next-line are supported. Recipe shell comments are not interpreted as Rumk directives.

The original Rumk [rules] and [ignore] configuration sections remain accepted for migration.

include-paths models GNU Make's -I search directories and resolves relative entries from the configuration directory. predefined-variables supplies command-line-style values to safe evaluation and names expected by opt-in rule MK208. That rule intentionally ignores references inside recipes and deferred macro bodies, where command-line parameters and shell values are normal. entry-targets supplies the roots for opt-in reachability rule MK209; the rule stays silent without explicit roots because any Make target may be invoked directly from the command line.

Rule and file selection

Rumk follows Rumdl's selection vocabulary:

rumk check --enable MK001,MK002 .
rumk check --disable MK101 .
rumk check --extend-enable MK202 .
rumk check --exclude "vendor/**,generated/**" .
rumk check --include "src/**" .
rumk check --respect-gitignore=false .
rumk fmt --fixable MK001 .

Exit codes

  • 0: success, or all selected violations were fixed
  • 1: lint violations, or fmt --check found required changes
  • 2: configuration, file access, or other tool error

rumk check fails on any diagnostic by default. Use --fail-on warning, --fail-on error, or --fail-on never to change that policy. rumk fmt exits successfully after formatting even if non-fixable lint diagnostics remain.

Output

Text diagnostics follow Rumdl's familiar form:

Makefile:2:1: [MK001] Recipe must be indented with tab, not spaces [*]

JSON output is a flat array collected across all files:

rumk check --output-format json .
[
  {
    "file": "Makefile",
    "line": 2,
    "column": 1,
    "end_line": 2,
    "end_column": 1,
    "rule": "MK001",
    "message": "Recipe must be indented with tab, not spaces",
    "severity": "error",
    "fixable": true,
    "fix": {
      "range": { "start": 7, "end": 11 },
      "replacement": "\t"
    }
  }
]

The legacy --format spelling remains an alias for --output-format.

Rules

Rules marked default run without configuration. Each rule page documents its behavior, configuration, fixes, edge cases, and the GNU Make, POSIX, or Rumk convention on which it is based.

Syntax

  • MK001 — Recipes must use tab indentation (default, fixable)
  • MK002 — Invalid variable syntax (default)
  • MK003 — Malformed conditional structure (default)
  • MK004 — Targets must not mix single- and double-colon declarations (default)
  • MK005 — GNU Make special targets must stand alone (default)

Style

  • MK101 — Declarative line exceeds the configured maximum length; comments and recipes are ignored by default (default)
  • MK102 — Variable naming convention
  • MK103 — Target naming convention

Best practices

  • MK201 — Conventional non-file targets should be .PHONY; fixes consolidate canonical groups, preserve per-section style, and wrap long declarations (default, fixable)
  • MK202 — Avoid hardcoded absolute paths (opt-in)
  • MK203 — Recursive Make invocations should use $(MAKE) (default, fixable)
  • MK204 — Concrete targets should not declare multiple single-colon recipes (default)
  • MK205 — Explicit target dependencies must not form cycles (default)
  • MK206 — Required static includes must resolve (default)
  • MK207 — Static Makefile includes must not form cycles (default)
  • MK208 — Static graph-level variable references must resolve (opt-in)
  • MK209 — Targets must be reachable from explicitly configured entries (opt-in)
  • MK210 — Explain include expressions blocked by safe evaluation (opt-in)

Development

cargo test --all-targets --all-features
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --check
cargo build --release
make check-gnu-fixtures

The product-level compatibility contract is documented in docs/rumdl-compatibility.md.

Contributing

See CONTRIBUTING.md.

License

MIT. See LICENSE.

Download files

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

Source Distribution

rumk-0.0.5.tar.gz (89.9 kB view details)

Uploaded Source

Built Distributions

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

rumk-0.0.5-py3-none-win_amd64.whl (1.5 MB view details)

Uploaded Python 3Windows x86-64

rumk-0.0.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

rumk-0.0.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

rumk-0.0.5-py3-none-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

rumk-0.0.5-py3-none-macosx_10_12_x86_64.whl (1.5 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file rumk-0.0.5.tar.gz.

File metadata

  • Download URL: rumk-0.0.5.tar.gz
  • Upload date:
  • Size: 89.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.5

File hashes

Hashes for rumk-0.0.5.tar.gz
Algorithm Hash digest
SHA256 9b4d7d92b1244043fec4a3384962e7eb300c4b3c95ec41dc98bb79d53510cf5c
MD5 36a0b277bdcadde5aa83732be8a29752
BLAKE2b-256 a3917cfedc6cdbf4cd1784d65b7ce0c24e9488291928db8ea1bd465bfe347da3

See more details on using hashes here.

File details

Details for the file rumk-0.0.5-py3-none-win_amd64.whl.

File metadata

  • Download URL: rumk-0.0.5-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.5

File hashes

Hashes for rumk-0.0.5-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a32cde9ca9989fe6a2b1460e4189b4ee5f13e8cb62a69df8b32d3ef60afa375a
MD5 b27806a3b4ffb6ad9f3564a00a21b358
BLAKE2b-256 19fef1efef4e6af46cb1b3994bcf5f4291190d6a1ddf87d3d5f0442e3eacce01

See more details on using hashes here.

File details

Details for the file rumk-0.0.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rumk-0.0.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 94175a373e4803ed3decebf457d97477f9e8da0af1411b080b46f7a5068a154b
MD5 0efdb190e3aa5ba14bfa63606416b904
BLAKE2b-256 6480394af0c4a3931bb22b8900bdca07f00e5c94d06da78276521df76807c54a

See more details on using hashes here.

File details

Details for the file rumk-0.0.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rumk-0.0.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 58e3b7e470cf8e46296b49e04cbc87022b816e648c1710e23440e9fd12731645
MD5 2acde7df35165bf8410dc55975e19361
BLAKE2b-256 5d85ceb7e80b745fb0f6cbc76b55920390a3935f27b19fbdc843d0619f42b6be

See more details on using hashes here.

File details

Details for the file rumk-0.0.5-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: rumk-0.0.5-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.5

File hashes

Hashes for rumk-0.0.5-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c77c817c4ea5f323b6991c2cb595714acd7a4e7babf9531820b6fe44e713f64a
MD5 a480cc96046a9f5a6814520369c8dd78
BLAKE2b-256 62ca5b98f0438d6bdc80cbe54f26339a3287064af9b0ddd551e8ec34d2b15a63

See more details on using hashes here.

File details

Details for the file rumk-0.0.5-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rumk-0.0.5-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0d4a3000be96d5f5129ea28198cde687ddb8c6559a79efd4ee004a435313178d
MD5 fd711d6954e3f9fb4b0e110c60180d17
BLAKE2b-256 1165fbcd6b2e5be0f1c666dad98015a7f631b781c9fcc3d7817e369233e7a86f

See more details on using hashes here.

Release history Release notifications | RSS feed

0.0.7

6 files

0.0.6

6 files

This release

0.0.5 This release

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page