Skip to content

feat: flint update command, explicit JAR flag, v0.20.0#146

Merged
zeitlinger merged 21 commits intomainfrom
cleanup-pre-commit
Apr 13, 2026
Merged

feat: flint update command, explicit JAR flag, v0.20.0#146
zeitlinger merged 21 commits intomainfrom
cleanup-pre-commit

Conversation

@zeitlinger
Copy link
Copy Markdown
Member

@zeitlinger zeitlinger commented Apr 10, 2026

Summary

  • Add flint update command: non-interactively replaces obsolete mise.toml tool keys (e.g. npm:markdownlint-clinpm:markdownlint-cli2), preserving the declared version.
  • Bail on obsolete keys during flint run: exits with a migration hint pointing to flint update.
  • Replace ktlint self-executing JAR heuristic: explicit .windows_java_jar() registry flag instead of the fragile #! + >1 MB size guess.
  • Remove lint:pre-commit mise task: pre-push hooks should use FLINT_FAST_ONLY=true with the existing lint:fix task — no dedicated task needed.
  • Bump to v0.20.0: fix release-please config (release-type: rust) and manifest (was tracking old bash v1 version 0.9.2).
  • Update mise to v2026.4.10 in CI: first version with a published Windows SHA256.
  • Add 'Why not Husky?' to README.

Changes

  • src/registry.rs: windows_java_jar field + builder, OBSOLETE_KEYS + find_obsolete_key(), versioned_bin_fmt for shfmt (ubi keeps version suffix in binary name on all platforms)
  • src/linters/mod.rs: find_pe_binary (MZ-only), find_file_in_path for JARs, spawn_command takes explicit windows_java_jar
  • src/runner.rs: thread windows_java_jar through to spawn_command
  • src/main.rs: flint update subcommand, obsolete key check in flint run
  • src/init/generation.rs: replace_obsolete_keys() — only silences NotFound, propagates other IO errors
  • src/init/mod.rs: pub(crate) visibility for generation module
  • mise.toml: remove lint:pre-commit task
  • .github/config/release-please-config.json: release-type: rust
  • .github/config/.release-please-manifest.json: 0.19.0 (so next release is 0.20.0)
  • .github/workflows/test.yml: mise v2026.4.10 with Windows SHA256; cache_key_prefix: mise-v2
  • README.md: document flint update, add 'Why not Husky?' section
  • tests/cases/general/: e2e cases for version, hook-install, update-no-op, update-obsolete-key

Test plan

  • CI passes (ubuntu, macos, windows)
  • Unit tests for find_obsolete_key and replace_obsolete_keys
  • e2e cases for all new/updated commands

@zeitlinger zeitlinger marked this pull request as ready for review April 10, 2026 18:05
@zeitlinger zeitlinger requested a review from a team as a code owner April 10, 2026 18:05
Base automatically changed from feat/flint-v2 to main April 10, 2026 18:06
Pre-push hooks wanting fast-only mode should set FLINT_FAST_ONLY=1 when
calling lint:fix rather than relying on a dedicated task.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
…stry flag

The previous code detected ktlint's self-executing JAR by checking for a
'#!' header and file size >1MB. Replace with an explicit .java_jar() flag
in the Check registry: when set, the binary is located in PATH and invoked
as 'java -jar <path>' rather than via cmd.exe.

This removes the size-based heuristic and makes the intent clear at the
registry level. find_executable_in_path collapses back into the original
find_pe_binary (MZ-only detection) plus a new find_file_in_path helper
used only for the JAR case.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
…test helper

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Add find_obsolete_key() that checks mise_tools for superseded keys and
returns the first violation. Called at the start of flint run — fails
fast with a migration hint before any linters are executed.

Complements the existing flint init migration path: init auto-fixes
obsolete keys; run catches them if init hasn't been run yet.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
flint update replaces obsolete tool keys with their modern equivalents,
preserving the existing version. Non-interactive counterpart to flint init's
migration path. flint run now suggests running it when an obsolete key is found.

Updated README to document the new command and the error/fix flow.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
…ines

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger changed the title chore: remove lint:pre-commit task; replace ktlint JAR heuristic with explicit flag chore: remove lint:pre-commit task; replace ktlint JAR heuristic; add flint update command Apr 10, 2026
Drops the -alpha.1 pre-release suffix now that v2 is ready to ship.
Updates release-please-config to release-type: rust so future releases
automatically update Cargo.toml, and resets the manifest from the old
bash v1 version (0.9.2) to 0.20.0.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Copilot AI review requested due to automatic review settings April 10, 2026 18:40
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR streamlines lint task usage, improves Windows execution behavior for self-executing JAR linters by switching to an explicit registry flag, and introduces a flint update migration command to rewrite obsolete mise.toml tool keys. It also updates docs and adds new e2e coverage for the new/adjusted CLI behavior.

Changes:

  • Remove the lint:pre-commit mise task and rely on lint:fix + FLINT_FAST_ONLY=true/--fast-only.
  • Replace ktlint “JAR detection” heuristics with an explicit windows_java_jar registry flag, threaded through runner spawning.
  • Add flint update, fail flint run on obsolete tool keys with a migration hint, and add README + e2e tests.

Reviewed changes

Copilot reviewed 19 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/cases/general/version/test.toml Adds e2e coverage for flint version output
tests/cases/general/version/files/.gitkeep Test fixture placeholder
tests/cases/general/update-obsolete-key/test.toml Adds e2e coverage for flint update replacing an obsolete key
tests/cases/general/update-obsolete-key/files/mise.toml Input fixture containing an obsolete tool key
tests/cases/general/update-no-op/test.toml Adds e2e coverage for flint update no-op behavior
tests/cases/general/update-no-op/files/mise.toml Input fixture already using modern keys
tests/cases/general/hook-install/test.toml Adds e2e coverage for flint hook install output and script content
tests/cases/general/hook-install/files/.gitkeep Test fixture placeholder
src/runner.rs Threads windows_java_jar through prepared checks to command spawning
src/registry.rs Adds windows_java_jar flag/builder; marks ktlint; introduces obsolete-key detection helper + tests
src/main.rs Adds flint update subcommand; fails flint run when obsolete keys are present
src/linters/mod.rs Updates spawn_command API; restores PE-header detection; adds PATH file resolver
src/linters/lychee.rs Updates call site for new spawn_command signature
src/linters/renovate_deps.rs Updates call site for new spawn_command signature
src/init/mod.rs Exposes generation module for update command wiring
src/init/generation.rs Implements replace_obsolete_keys migration helper + unit tests
README.md Documents flint update and adds “Why not Husky?” rationale
mise.toml Removes lint:pre-commit task
Cargo.toml Updates package version
Cargo.lock Updates locked package version
.github/config/release-please-config.json Changes Release Please release type
.github/config/.release-please-manifest.json Updates Release Please manifest version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/cases/general/version/test.toml Outdated
Comment thread src/init/generation.rs Outdated
Comment thread src/init/mod.rs Outdated
Comment thread Cargo.toml
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
On Linux/macOS, ubi renames the downloaded binary to the plain tool name
(e.g. shfmt, not shfmt_v3.12.0), so resolve_bin_name was looking for a
binary that doesn't exist. The versioned filename is a Windows-only ubi
behaviour.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
When mise-shim.exe is absent, mise falls back to 'file' mode: each shim
is an extensionless bash script (#!/bin/bash) that calls 'mise exec'.
cmd.exe cannot execute these (no .cmd/.exe extension), so detect them via
the #! magic bytes and invoke via bash instead.

Also increments cache_key_prefix to force a fresh tool installation and
clear the stale 3.13.1 entry that Renovate left behind.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
ubi (mise's github: backend) preserves the version suffix in the binary
name on all platforms, not just Windows. Reverting the #[cfg(windows)]
gate that caused Linux to look for 'shfmt' instead of 'shfmt_v3.12.0'.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Cargo-installed tools (e.g. xmllint from cargo:xmloxide) use the .exe
extension. Without this, find_pe_binary missed them and find_bash_shim
picked up a stray xmllint bash/WSL wrapper instead, causing WSL errors.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
The bash shim workaround is the wrong layer: it's fragile (picks up stray
WSL wrappers), and the root cause is that mise-action doesn't install
mise-shim.exe, causing mise to fall back to extensionless bash scripts.
Filed upstream: jdx/mise-action should provide mise-shim.exe so shims
are proper .exe files that cmd.exe handles natively.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Only difference from main: windows_java_jar explicit flag instead of the
size-based JAR heuristic. No .exe check, no bash shim — cmd.exe handles
those cases correctly on its own.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger changed the title chore: remove lint:pre-commit task; replace ktlint JAR heuristic; add flint update command feat: flint update command, explicit JAR flag, v0.20.0 Apr 13, 2026
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger merged commit b43bf52 into main Apr 13, 2026
13 checks passed
@zeitlinger zeitlinger deleted the cleanup-pre-commit branch April 13, 2026 14:19
zeitlinger pushed a commit that referenced this pull request Apr 13, 2026
## flint v0.20.0 — Rust rewrite

flint has been rewritten from scratch in Rust. The bash + Docker stack
is replaced by a fast, cross-platform native binary with no container
dependency.

### Highlights

- **Native binary** — no Docker, no bash wrappers; runs anywhere mise
can install a Rust crate
- **Parallel linting** — all checks run concurrently
- **Diff-aware** — only checks files changed since the merge base by
default (`--full` for everything)
- **`flint update`** — migrates obsolete `mise.toml` tool keys
automatically (e.g. `ubi:` → `github:`, `npm:markdownlint-cli` →
`npm:markdownlint-cli2`)
- **`flint hook install`** — installs a pre-commit hook without any mise
task knowledge
- **New linters**: `gofmt`, `google-java-format`, `ktlint`,
`dotnet-format`, `markdownlint-cli2`, `xmllint` (via `cargo:xmloxide`),
`license-header` (pure-Rust, no binary)
- **Windows support** — ktlint self-executing JAR handled via explicit
`java -jar` invocation

### Migration

See
[AGENTS-V2.md](https://github.com/grafana/flint/blob/main/AGENTS-V2.md)
and [README.md](https://github.com/grafana/flint/blob/main/README.md)
for full setup instructions.

Quick reference for existing consumers:

```toml
[tools]
# While installing from source (pre-crates.io release):
"cargo:https://github.com/grafana/flint" = "branch:main"

[env]
FLINT_CONFIG_DIR = ".github/config"

[tasks.lint]
run = "flint run"

[tasks."lint:fix"]
run = "flint run --fix"
```

Remove: `lint:super-linter`, `lint:links`, `lint:renovate-deps`,
`setup:native-lint-tools`, `setup:pre-commit-hook` tasks. Run `flint
update` to auto-migrate any obsolete tool keys.

> [!NOTE]
> The changelog below includes entries from the legacy v1 bash era — see
[README-V1.md](https://github.com/grafana/flint/blob/main/README-V1.md)
for v1 docs.

---

##
[0.20.0](flint-v0.19.0...flint-v0.20.0)
(2026-04-13)


### Features

* add flint v2 Rust binary
([#139](#139))
([19f2b25](19f2b25))
* add native linting mode and version mapping infrastructure
([#93](#93))
([24b06da](24b06da))
* add Renovate shareable preset for consuming repos
([#17](#17))
([8a06590](8a06590))
* consolidate link checking and add autofix flags
([#7](#7))
([086a5e9](086a5e9))
* flint update command, explicit JAR flag, v0.20.0
([#146](#146))
([b43bf52](b43bf52))
* handle line-number anchors and issue comments globally
([#56](#56))
([cf751df](cf751df))
* **links:** add GitHub URL remaps for line-number and fragment anchors
([#28](#28))
([5b59065](5b59065))
* **links:** auto-remap base-branch GitHub URLs to PR branch
([#18](#18))
([dd6cc61](dd6cc61))
* **renovate:** support SHA-pinned URLs in Renovate preset
([#21](#21))
([4fd1f28](4fd1f28))
* **super-linter:** default to slim image
([#24](#24))
([c8eeab8](c8eeab8))
* support NATIVE env var for container-free linting
([#107](#107))
([0a8193d](0a8193d))


### Bug Fixes

* activate mise environment in native lint mode
([#123](#123))
([d0fec45](d0fec45))
* add 'mise run fix' hint to lint failure output
([#90](#90))
([5b4ad5d](5b4ad5d))
* decouple version mapping generation from pinned super-linter version
([#112](#112))
([5370e77](5370e77))
* **deps:** update rust crate crossterm to 0.29
([#156](#156))
([c59ae3e](c59ae3e))
* **deps:** update rust crate similar to v3
([#160](#160))
([684be4e](684be4e))
* **deps:** update rust crate toml to v1
([#161](#161))
([3aae614](3aae614))
* **deps:** update rust crate toml_edit to 0.25
([#158](#158))
([42d9efd](42d9efd))
* exclude GitHub compare links from lychee checks
([#10](#10))
([e714608](e714608))
* fail native lint when enabled tools are missing
([#111](#111))
([163bb6b](163bb6b))
* improve link checker reliability against GitHub rate limiting
([#95](#95))
([7a5282d](7a5282d))
* include staged files in native lint file list
([#135](#135))
([34412d6](34412d6))
* **links:** add regex anchors to remap patterns
([#19](#19))
([2e17348](2e17348))
* native lint in worktrees, trust toml, use ec binary, drop isort
([#134](#134))
([8594bba](8594bba))
* **release-please:** fix footer not appearing on release PRs
([#40](#40))
([d7a55e4](d7a55e4))
* remap same-repo GitHub URLs to local file paths
([#100](#100))
([b4feadd](b4feadd))
* **renovate-deps:** forward GITHUB_TOKEN as GITHUB_COM_TOKEN
([#132](#132))
([4d6510b](4d6510b))
* replace broken release-please PR comment with docs
([#12](#12))
([817b37d](817b37d))
* run shellcheck on .bats files in native mode
([#137](#137))
([a4fd3f8](a4fd3f8))
* strip Scroll to Text Fragment anchors in link checks
([#86](#86))
([b630cdf](b630cdf))
* tighten markdownlint config for native mode
([#106](#106))
([6ef25b2](6ef25b2))
* use remap instead of exclude for issue comment anchors
([#58](#58))
([656f355](656f355))

---
> [!IMPORTANT]
> Close and reopen this PR to trigger CI checks.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This was referenced Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants