Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
adb5d2d
feat: add flint Rust binary skeleton (M1)
zeitlinger Apr 2, 2026
b44fd32
feat: add built-in links and renovate-deps special checks (M3)
zeitlinger Apr 2, 2026
5eb5c27
feat: dogfood flint for linting flint itself (M4)
zeitlinger Apr 2, 2026
f822b5d
test: add unit tests for project-scope pattern filtering
zeitlinger Apr 2, 2026
b99606e
chore: update renovate-tracked-deps for Cargo.toml and new mise tools
zeitlinger Apr 2, 2026
b6929da
feat: prefix failed check output with [check-name] header
zeitlinger Apr 2, 2026
bf93290
test: add e2e tests for shellcheck output format
zeitlinger Apr 2, 2026
25f9191
test: add e2e test for cargo-fmt diff output format
zeitlinger Apr 2, 2026
8c87821
chore: exclude cargo manager from renovate-deps linter
zeitlinger Apr 2, 2026
1450848
docs: add FLINT-V2.md — usage guide for the Rust binary
zeitlinger Apr 2, 2026
505b012
chore: remove textlint and super-linter from dogfood config
zeitlinger Apr 2, 2026
aaf1c46
feat: add --short flag for token-efficient AI output
zeitlinger Apr 2, 2026
7a9770b
feat: improve --short summary to emit actionable fix command
zeitlinger Apr 2, 2026
27cde78
chore: fix pre-existing prettier formatting violations
zeitlinger Apr 2, 2026
696af80
Revert "chore: fix pre-existing prettier formatting violations"
zeitlinger Apr 2, 2026
e49f123
fix: remove *.json from prettier scope — biome owns JSON formatting
zeitlinger Apr 2, 2026
e2eb6a9
fix: exclude formatter-owned file types from ec
zeitlinger Apr 2, 2026
934cc7c
fix: make ec exclusions conditional on other formatters being active
zeitlinger Apr 2, 2026
69be30b
fix: narrow ec exclusions to formatters that enforce line length
zeitlinger Apr 2, 2026
e830ba3
docs: document ec deference behavior and --short output format
zeitlinger Apr 2, 2026
1698833
feat: add --auto mode for autonomous agents
zeitlinger Apr 2, 2026
14d2f9e
fix: --auto exits 1 when fixes applied so caller commits before pushing
zeitlinger Apr 2, 2026
b5a90bf
feat: use mise.toml as tool availability source, add version_range su…
zeitlinger Apr 2, 2026
fc540f1
refactor: builder pattern for registry, move linters to src/linters/,…
zeitlinger Apr 2, 2026
f61520e
docs: split AGENTS.md into v1/v2, add v2 architecture guide
zeitlinger Apr 2, 2026
a2d482c
refactor: simplify Rust source — PreparedCheck, async lychee helpers,…
zeitlinger Apr 2, 2026
326f7d4
feat: add FLINT_CONFIG_DIR env var to override config file directory
zeitlinger Apr 3, 2026
9540bc9
test: trigger hook
zeitlinger Apr 3, 2026
9fd286d
refactor: introduce RunOptions struct and CheckResult to avoid fragil…
zeitlinger Apr 3, 2026
6f412ed
feat: route all linter output to stderr, declarative e2e fixtures, ta…
zeitlinger Apr 3, 2026
afe80c5
feat: add exclude_paths setting to filter files by path prefix
zeitlinger Apr 3, 2026
69611a4
feat: env var overrides for any flint.toml setting
zeitlinger Apr 3, 2026
8ddc4bf
feat: inject linter config files from FLINT_CONFIG_DIR
zeitlinger Apr 3, 2026
29415f0
test: add coverage for linter config injection
zeitlinger Apr 3, 2026
50dfbaf
feat: add linters, license-header check, formatter-aware ec exclusion
zeitlinger Apr 3, 2026
b54be4c
docs: restructure README for v2, remove AUTOFIX env var
zeitlinger Apr 3, 2026
35b961d
feat: add env var overrides for all CLI flags
zeitlinger Apr 3, 2026
d0e71de
feat: rewrite renovate-deps check in native Rust
zeitlinger Apr 3, 2026
4627227
refactor: extract constants and fix Windows path compatibility
zeitlinger Apr 4, 2026
12ac0b6
test: add unit tests for renovate-deps native implementation
zeitlinger Apr 4, 2026
97aa613
refactor: replace (bool, Vec<u8>, Vec<u8>) tuple with LinterOutput st…
zeitlinger Apr 4, 2026
b93841b
refactor: extract run_inner to use ? for error propagation in renovat…
zeitlinger Apr 4, 2026
bc70f41
feat: e2e tests for renovate-deps; auto-exclude snapshot from linters
zeitlinger Apr 4, 2026
841fbe7
test: add e2e fixture cases for renovate-deps
zeitlinger Apr 4, 2026
065fc2e
refactor: use [expected] table in test fixtures
zeitlinger Apr 4, 2026
63549b2
refactor: consolidate args/exit into [expected] table
zeitlinger Apr 4, 2026
29b5159
refactor: reorganize test cases into subdirectories by linter
zeitlinger Apr 4, 2026
e5941ea
test: remove programmatic renovate-deps tests superseded by fixture c…
zeitlinger Apr 4, 2026
01c4b0b
docs: split AGENTS-V2.md into .github/agents/knowledge/ files
zeitlinger Apr 4, 2026
3597dd2
style: remove double blank line in e2e.rs
zeitlinger Apr 4, 2026
a85ad73
test: add lychee e2e fixtures and unit tests for lychee/license-header
zeitlinger Apr 4, 2026
9435177
ci: add Rust cache and fix clippy component installation
zeitlinger Apr 4, 2026
4a7f4e5
chore: simplify mise tasks to use cargo run instead of build + exec
zeitlinger Apr 4, 2026
3ddd1ad
refactor: merge --auto into --fix, drop --auto flag
zeitlinger Apr 4, 2026
6b1537a
fix: activate renovate-deps via npm:renovate tool name
zeitlinger Apr 4, 2026
718d238
refactor: redesign CLI to follow golangci-lint conventions (#142)
zeitlinger Apr 4, 2026
c2ff8f6
feat: smoke-test all registry linters are detected and their binaries…
zeitlinger Apr 4, 2026
1b87df6
chore: reformat tables and fix minor whitespace in docs and tests
zeitlinger Apr 4, 2026
6911e57
fix: use args.verbose instead of out-of-scope cli variable in run fn
zeitlinger Apr 4, 2026
c903b5f
docs: generate README linter table from registry with sync test
zeitlinger Apr 5, 2026
353e535
refactor: rename ec check to editorconfig-checker
zeitlinger Apr 5, 2026
41dad73
test: parallel e2e cases, FLINT_CASES filter, and fix stale list snap…
zeitlinger Apr 5, 2026
c2afb1c
fix: dotnet-format is fast, not slow
zeitlinger Apr 5, 2026
26f0d81
test: e2e coverage for all batch-1 linters
zeitlinger Apr 5, 2026
c12f962
chore: remove redundant exclude for renovate-tracked-deps.json
zeitlinger Apr 5, 2026
a26d8cb
test: e2e coverage for batch-2 linters and snapshot format fix
zeitlinger Apr 5, 2026
c85c02a
feat: scope files-linters to changed files, add full_cmd for all-file…
zeitlinger Apr 5, 2026
2ababf4
feat: add release workflow, bump version to 0.20.0-alpha.1, v2 migrat…
zeitlinger Apr 6, 2026
0ecf7d4
docs: add renovate-deps env var migration step
zeitlinger Apr 6, 2026
a63758d
feat: add flint init command for mise.toml setup
zeitlinger Apr 6, 2026
025398f
feat: interactive init selection, renovate detection by config file
zeitlinger Apr 6, 2026
624454b
feat: split Lang into Lang/Style, interactive category selection in init
zeitlinger Apr 6, 2026
c2a5671
feat: redesign flint init with arrow-nav and unified linter table
zeitlinger Apr 6, 2026
58b56c4
feat: allow independent selection of cargo-clippy and cargo-fmt in init
zeitlinger Apr 6, 2026
25428e4
fix(renovate-deps): track snapshot next to config
zeitlinger Apr 6, 2026
d92138a
Merge remote-tracking branch 'origin/main' into feat/flint-v2
zeitlinger Apr 6, 2026
21dd30d
fix(ci): disable rust-cache save in release workflow
zeitlinger Apr 6, 2026
6259b26
docs(rust): explain missing toolchain components
zeitlinger Apr 6, 2026
d427eff
fix(ci): install rust lint components
zeitlinger Apr 6, 2026
63711e3
fix(ci): address rust components and release cache
zeitlinger Apr 6, 2026
6d5f784
feat(init): generate env, tasks, flint.toml, and lint workflow (#145)
zeitlinger Apr 7, 2026
0a19bdb
feat(run): add --time flag to show linter runtimes
zeitlinger Apr 7, 2026
2c1fb34
perf(renovate-deps,cargo-fmt): skip version lookups, fix duplicate ou…
zeitlinger Apr 7, 2026
fb64e9b
chore: regenerate README table
zeitlinger Apr 7, 2026
1d54b0d
refactor(init): split init.rs into init/ module
zeitlinger Apr 7, 2026
cc95b60
test(init): remove has_slow_selected test — no slow checks currently …
zeitlinger Apr 7, 2026
16c0940
feat(init): patch renovate config to add flint preset extends entry
zeitlinger Apr 7, 2026
d29b96a
feat(init): remove outdated linters and v1 HTTP task entries
zeitlinger Apr 7, 2026
aaab364
feat(init): migrate RENOVATE_TRACKED_DEPS_EXCLUDE to flint.toml on init
zeitlinger Apr 7, 2026
0834ac7
fix(init): replace stale lint tasks and fix renovate preset duplication
zeitlinger Apr 7, 2026
c9d1f04
feat(init): add flint itself to mise.toml and pin tools via mise use …
zeitlinger Apr 7, 2026
dad2374
fix(init): use ubi: backend for flint tool key — github: requires lin…
zeitlinger Apr 7, 2026
4343694
chore(init): remove add_flint_tool — no working mise backend for flin…
zeitlinger Apr 7, 2026
1744e95
docs(migration): add step to run flint run --fix renovate-deps after …
zeitlinger Apr 8, 2026
b8cf086
fix(license-header): skip when unconfigured or no matching files changed
zeitlinger Apr 8, 2026
dc3537e
fix(registry): use ubi: backend for google-java-format tool key
zeitlinger Apr 8, 2026
fad51b5
fix(registry): revert google-java-format to github: backend (ubi: dep…
zeitlinger Apr 8, 2026
1a67924
docs: recommend against Spotless for Java projects
zeitlinger Apr 8, 2026
fd71fbd
feat(license-header): support multi-line text matching
zeitlinger Apr 8, 2026
5f8a6aa
feat(init): generate .markdownlint.jsonc when markdownlint-cli2 is se…
zeitlinger Apr 9, 2026
87cf6e6
docs(registry): add per-linter descriptions, rework README linter table
zeitlinger Apr 9, 2026
099853f
refactor(config): replace exclude/exclude_paths with single glob list
zeitlinger Apr 9, 2026
7840e3e
feat(hook): add `flint hook install` command
zeitlinger Apr 9, 2026
f15ab8a
feat(xmllint): add xmllint linter via cargo:xmloxide
zeitlinger Apr 9, 2026
7be7039
fix: address Copilot review comments on robustness and correctness
zeitlinger Apr 9, 2026
4e9f0f1
fix(review): address PR #139 review comments
zeitlinger Apr 9, 2026
19461db
ci: add Windows build and cross-platform unit test workflow
zeitlinger Apr 9, 2026
7e4a43f
fix(review): martincostello follow-up comments
zeitlinger Apr 9, 2026
2d6e467
chore: apply cargo-fmt and update renovate-tracked-deps
zeitlinger Apr 9, 2026
70f2d54
ci: simplify release workflow using taiki-e/upload-rust-binary-action
zeitlinger Apr 9, 2026
dfc60c7
ci: drop manual release creation — release-please handles it
zeitlinger Apr 9, 2026
8304384
ci: add sha256 checksums to release assets
zeitlinger Apr 10, 2026
1c17c80
ci: add GitHub artifact attestations for github: backend compatibility
zeitlinger Apr 10, 2026
0e0caaf
refactor(registry): extract each linter to a named function
zeitlinger Apr 10, 2026
8e92383
test: un-ignore all_registry_binaries_found — CI has mise installed
zeitlinger Apr 10, 2026
038cb07
ci: fix per-platform mise sha256 in test matrix
zeitlinger Apr 10, 2026
a235c1a
test: add missing e2e tools to mise.toml
zeitlinger Apr 10, 2026
2327342
fix(e2e): resolve macOS /private symlink path mismatch
zeitlinger Apr 10, 2026
9793df4
fix(ci): support shellcheck and shfmt on Windows via github backend
zeitlinger Apr 10, 2026
e892478
fix(ci): resolve shfmt binary name when installed via github:mvdan/sh
zeitlinger Apr 10, 2026
d6b5c1f
refactor(registry): simplify tool key fields — drop install_key, add …
zeitlinger Apr 10, 2026
b68c567
fix(ci): remove stale mise_install_key field from runner.rs test struct
zeitlinger Apr 10, 2026
4d6be29
fix(registry): check_active also accepts bare bin_name when mise_tool…
zeitlinger Apr 10, 2026
ea190f3
fix(ci): update shfmt e2e fixtures and check_active to use github:mvd…
zeitlinger Apr 10, 2026
af1dc83
fix(ci): suppress clippy::too_many_arguments on prepare()
zeitlinger Apr 10, 2026
dcaeac6
ci: disable fail-fast on test and release matrices
zeitlinger Apr 10, 2026
f6adda1
ci: pin macos-15 and windows-2025 for consistency with ubuntu-24.04
zeitlinger Apr 10, 2026
26e5b0c
fix(windows): strip \\?\ UNC prefix after canonicalize()
zeitlinger Apr 10, 2026
ae6d5d8
ci: add Windows debug step to inspect mise install dirs
zeitlinger Apr 10, 2026
143a278
fix(windows): route all commands through cmd.exe /C
zeitlinger Apr 10, 2026
5f291b4
ci: remove debug step
zeitlinger Apr 10, 2026
d5b8a1d
ci: add permanent cross-platform tool listing step
zeitlinger Apr 10, 2026
ab470a1
ci: remove redundant mise ls step (already in mise-action output)
zeitlinger Apr 10, 2026
89fae95
fix(windows,ci): normalize paths in e2e output and retry renovate on …
zeitlinger Apr 10, 2026
e24fdd4
fix(windows): handle CRLF line endings and forward-slash paths in e2e…
zeitlinger Apr 10, 2026
c68e74d
fix(windows): apply cmd.exe wrapping to renovate and lychee, fix path…
zeitlinger Apr 10, 2026
e975fec
refactor(windows): centralize Windows spawn and path helpers
zeitlinger Apr 10, 2026
bbeb7b0
fix(windows): detect PE binaries for direct execution, force LF in do…
zeitlinger Apr 10, 2026
4784100
fix(windows): handle self-executing JARs (ktlint) and dotnet LF config
zeitlinger Apr 10, 2026
7f06562
fix(windows): targeted path separator normalization — skip \s in dotn…
zeitlinger Apr 10, 2026
ae14742
fix(windows): normalize \ only within <REPO>-rooted paths
zeitlinger Apr 10, 2026
e53c16f
fix(windows): normalize all path backslashes, skip single-quoted content
zeitlinger Apr 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ max_line_length = 120
[*.py]
indent_size = 4

[*.rs]
indent_size = 4
max_line_length = off

[{CLAUDE.md,.editorconfig,super-linter.env,lychee.toml,renovate.json5,default.json,mise.toml}]
max_line_length = 300
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
14 changes: 14 additions & 0 deletions .github/agents/knowledge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Knowledge Index

Reusable repository guidance for agents working on flint v2.

Load only files relevant to the current scope.

## Topics

| File | Load when |
| ----------------- | --------------------------------------------------------------------------------- |
| `architecture.md` | Navigating the codebase; understanding module roles or check kinds |
| `linters.md` | Adding, modifying, or debugging a linter; `registry.rs` changes; config injection |
| `design.md` | Questioning why something works the way it does; avoiding known pitfalls |
| `testing.md` | Writing or updating tests; adding fixture cases; regenerating snapshots |
38 changes: 38 additions & 0 deletions .github/agents/knowledge/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Architecture

## Module Map

- **`src/registry.rs`**: Static linter registry. Defines
`Check` (builder pattern) and `builtin()` which returns
the full list of built-in checks. This is where new
linters are added.
- **`src/runner.rs`**: Executes checks against a file list.
Handles parallel execution (check mode) and serial
execution (fix mode, to avoid concurrent writes).
- **`src/config.rs`**: Loads `flint.toml` from the project
root. All fields have defaults — the file is optional.
- **`src/files.rs`**: Git-aware file discovery. Returns
changed files relative to the merge base, or all files
with `--full`.
- **`src/linters/`**: Custom logic for special checks that
can't be expressed as a simple command template:
- `lychee.rs`: Link checking orchestration
- `renovate_deps.rs`: Renovate snapshot verification
- **`src/main.rs`**: CLI parsing (clap), orchestration,
output formatting.
- **`tests/e2e.rs`**: End-to-end tests. Spin up a temp git
repo, write files, run the flint binary, assert on
stdout/stderr and exit code.

## Check Kinds

A `Check` is either a `Template` (a command string with
`{FILE}`, `{FILES}`, or `{MERGE_BASE}` placeholders) or a
`Special` (custom Rust logic in `src/linters/`).

Template scopes:

- `File` — invoked once per matched file (`{FILE}`)
- `Files` — invoked once with all matched files (`{FILES}`)
- `Project` — invoked once with no file args; skipped
entirely if no matching files changed
48 changes: 48 additions & 0 deletions .github/agents/knowledge/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Key Design Decisions

1. **Activation via `mise.toml`**: A check is active when
its tool (or `mise_tool_name` override) is declared in
the consuming repo's `mise.toml`. No PATH probing —
mise guarantees declared tools are on PATH.

2. **`editorconfig-checker` deference**: `editorconfig-checker`
(binary: `ec`) runs on all files but skips file types owned
by active line-length-enforcing formatters (`cargo-fmt`,
`ruff-format`, `biome-format`, `prettier`). Implemented
via `.defer_to_formatters()` on the `editorconfig-checker`
entry. This avoids its `max_line_length` check conflicting
with formatter output.

3. **markdownlint + prettier on `*.md`**: Both checkers are
active when their tools are installed. They cover
different concerns (markdownlint: structural rules;
prettier: formatting). To avoid MD013 (line length)
conflicting with prettier's line wrapping, consuming
repos must disable MD013 in `.markdownlint.json`:

```json
{ "MD013": false }
```

4. **Fix mode runs serially**: `runner.rs` runs checks in
parallel in check mode, but serially in fix mode to
avoid concurrent writes to the same file.

5. **Version ranges**: When a `bin_name` has any
`version_range` entries, every entry for that binary
must have one (enforced by a registry unit test). This
prevents ambiguous activation when ranges don't cover
all versions.

6. **Special checks**: `links` and `renovate-deps` have
custom orchestration logic that doesn't fit the command
template model. Their implementations live in
`src/linters/`.

7. **Built-in file exclusions**: `src/files.rs` has a
`BUILTIN_EXCLUDES` slice of paths that are always removed
from the file list before any linter sees it. Currently
contains `.github/renovate-tracked-deps.json` (a
generated file that should never be linted by prettier,
ec, etc.). Add entries here — not in user-facing `exclude`
docs — when a file is managed by flint itself.
80 changes: 80 additions & 0 deletions .github/agents/knowledge/linters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Adding a New Linter

Add an entry to `builtin()` in `src/registry.rs` using the
builder pattern:

```rust
// File scope — invoked per file
Check::file("mytool", "mytool --check {FILE}", &["*.ext"])
.fix("mytool --fix {FILE}"),

// Files scope — invoked once with all matched files (absolute paths)
Check::files("mytool", "mytool {FILES}", &["*.ext"])
.fix("mytool --fix {FILES}"),

// Files scope — invoked once with all matched files (relative to project root)
// Use {RELFILES} when the tool requires paths relative to the project root
// (e.g. dotnet format --include).
Check::files("mytool", "mytool --include {RELFILES}", &["*.ext"])
.fix("mytool --fix --include {RELFILES}"),

// Project scope — invoked once, skipped if no *.ext changed
Check::project("mytool", "mytool run", &["*.ext"]),
```

Available builder modifiers:

| Method | Purpose |
| ---------------------------- | ----------------------------------------------------------------------------- |
| `.fix(cmd)` | Enable `--fix` mode with this command |
| `.bin(name)` | Override binary name (when check name ≠ binary) |
| `.mise_tool(name)` | Look up availability under a different mise key (e.g. `rust` for `cargo-fmt`) |
| `.version_req(range)` | Restrict to a semver range (e.g. `">=1.0.0"`) |
| `.excludes(names)` | Skip files already owned by these active checks |
| `.slow()` | Mark as slow — skipped by `--fast-only` |
| `.linter_config(file, flag)` | Inject a config flag when `FLINT_CONFIG_DIR/<file>` exists (see below) |

## Config File Injection (`.linter_config`)

Use `.linter_config(filename, flag)` when the tool supports an explicit config
file path via a CLI flag. At runtime, if `FLINT_CONFIG_DIR/<filename>` exists,
flint injects `flag <abs-path>` right after the binary name in the command.
If the file is absent the flag is silently omitted — native config discovery
remains in effect.

```rust
// Example: markdownlint accepts --config <path>
Check::file("markdownlint", "markdownlint {FILE}", &["*.md"])
.fix("markdownlint --fix {FILE}")
.linter_config(".markdownlint.json", "--config"),
// → markdownlint --config /repo/.github/config/.markdownlint.json <file>
```

**When NOT to use it:**

- The tool has no explicit `--config`/`--rcfile`/equivalent flag (e.g. `shfmt`)
- The flag accepts a **directory** rather than a file (e.g. biome's
`--config-path <dir>`) — a different injection shape is needed. For biome,
check for `biome.json` existence but pass `config_dir` itself as the arg:
`biome --config-path <config_dir> check <file>`. This requires a variant of
`.linter_config` that injects the directory rather than the full file path
(not yet implemented)
- The tool is project-scoped and its config must live at the project root to
function (no explicit `--config` flag exists)

Look up the tool's `--help` or man page for the config flag name and expected
argument type before adding `.linter_config`.

For checks that need custom logic (not a simple command template), add a module
under `src/linters/` and use `CheckKind::Special`.

## Changed-files scoping

Most linters use `file` or `files` scope, so they naturally receive only changed
files as arguments. `golangci-lint` uses `project` scope but scopes internally via
`--new-from-rev={MERGE_BASE}`.

**`cargo-clippy` cannot scope to changed files.** Cargo has no git-aware flag
equivalent to `--new-from-rev`. It still skips entirely when no `*.rs` files
changed, but when it does run it checks the whole project. Workspace support
(`-p <pkg> --no-deps` per changed package) would be a future improvement.
60 changes: 60 additions & 0 deletions .github/agents/knowledge/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Testing

Run all tests with:

```bash
cargo test
```

## Unit Tests

In-module `#[cfg(test)]` blocks in `src/`. Notable:

- `src/registry.rs`: enforces version-range consistency
- `src/runner.rs`: config injection, scope filtering
- `src/linters/renovate_deps.rs`: log parsing, snapshot
read/write, diff output

## Fixture-based E2E Tests

`tests/cases/` holds one directory per scenario. Each
contains:

- `files/` — files copied verbatim into a temp git repo
and staged before the run
- `test.toml` — test spec:

```toml
[expected]
args = "--full shellcheck"
exit = 1 # optional, default 0
stderr = """
...golden output...
"""

[expected.files] # optional: assert files written by --fix
".github/renovate-tracked-deps.json" = """
{...}
"""

[env] # optional extra env vars
FOO = "bar"

[fake_bins] # optional fake binaries (Unix only)
renovate = '''
#!/bin/sh
echo '...'
'''
```

The `cases` test in `tests/e2e.rs` runs all of them.
Set `UPDATE_SNAPSHOTS=1` to regenerate `[expected].exit`/
`stderr`/`stdout` in place. `[expected.files]` and `[fake_bins]`
are always preserved by the snapshot writer.

Use fixture cases for any check — including ones that require
fake external binaries (via `[fake_bins]`). The fixture runner
writes each binary into a tempdir and prepends it to `PATH`.

When adding a new check, cover at least: clean pass, failure
with correct diff/output, and fix mode if supported.
5 changes: 5 additions & 0 deletions .github/config/flint.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[settings]
exclude = ["CHANGELOG.md", "tests/cases/**"]

[checks.renovate-deps]
exclude_managers = ["github-actions", "github-runners", "cargo"]
31 changes: 26 additions & 5 deletions .github/renovate-tracked-deps.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,40 @@
"mise"
]
},
"README.md": {
".github/workflows/test.yml": {
"regex": [
"grafana/flint"
"mise"
]
},
"mise.toml": {
"mise": [
"actionlint",
"cargo:xmloxide",
"dotnet",
"editorconfig-checker",
"github:google/google-java-format",
"github:koalaman/shellcheck",
"github:mvdan/sh",
"github:pinterest/ktlint",
"go",
"golangci-lint",
"hadolint",
"lychee",
"node",
"npm:renovate"
],
"npm:@biomejs/biome",
"npm:markdownlint-cli2",
"npm:prettier",
"npm:renovate",
"pipx:codespell",
"pipx:ruff",
"rust"
]
},
"src/init/generation.rs": {
"regex": [
"ghcr.io/super-linter/super-linter"
"actions/checkout",
"jdx/mise-action",
"mise"
]
}
}
29 changes: 28 additions & 1 deletion .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
dependencyDashboard: true,
platformCommit: "enabled",
automerge: true,
ignorePaths: [],
ignorePaths: ["tests/"],
ignorePresets: [":ignoreModulesAndTests"],
ignoreUnstable: true,
vulnerabilityAlerts: {
Expand Down Expand Up @@ -38,6 +38,33 @@
depNameTemplate: "mise",
matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?<currentValue>v[.\\d]+)[\"']?\\s*\\n\\s*sha256: [\"']?(?<currentDigest>\\w+)[\"']?"],
},
{
customType: "regex",
description: "Update GitHub Action SHA pins embedded in the generated workflow template (src/init/generation.rs)",
managerFilePatterns: ["/^src/init/generation\\.rs$/"],
matchStrings: ["uses: (?<depName>[^@\\\\]+)@(?<currentDigest>[a-f0-9]{40})\\s*#\\s*(?<currentValue>v[^\\s'\"\\\\]+)"],
datasourceTemplate: "github-tags",
},
{
customType: "regex",
description: "Update mise per-platform sha256 hashes in test.yml matrix",
managerFilePatterns: ["/.github/workflows/test.yml/"],
datasourceTemplate: "github-release-attachments",
packageNameTemplate: "jdx/mise",
depNameTemplate: "mise",
matchStrings: [
"mise_version: [\"']?(?<currentValue>v[.\\d]+)[\"']?\\s*\\n\\s*mise_sha256: [\"']?(?<currentDigest>[a-f0-9]{64})[\"']?",
],
},
{
customType: "regex",
description: "Update mise version embedded in the generated workflow template (src/init/generation.rs)",
managerFilePatterns: ["/^src/init/generation\\.rs$/"],
datasourceTemplate: "github-release-attachments",
packageNameTemplate: "jdx/mise",
depNameTemplate: "mise",
matchStrings: ["jdx/mise-action.*\\n\\s*with:\\s*\\n\\s*version: [\"']?(?<currentValue>v[.\\d]+)[\"']?\\s*\\n\\s*sha256: [\"']?(?<currentDigest>\\w+)[\"']?"],
},
],
packageRules: [
{
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
name: Lint

on:
push:
branches: [main] # warms the Rust cache so PR branches get a cache hit
pull_request:

permissions: {}
Expand All @@ -26,6 +28,13 @@ jobs:
version: v2026.4.1
sha256: c597fa1e4da76d1ea1967111d150a6a655ca51a72f4cd17fdc584be2b9eaa8bd

# mise may activate an existing Rust toolchain without adding missing components.
- name: Install Rust lint components
run: rustup component add clippy rustfmt

- name: Restore cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1

- name: Lint
env:
GITHUB_TOKEN: ${{ github.token }}
Expand Down
Loading
Loading