Skip to content

feat(init): rust workflow steps, markdownlint migration, idempotence fix#195

Merged
zeitlinger merged 6 commits intodocs/split-and-v2-installfrom
flint-init-rust-workflow-v2
Apr 20, 2026
Merged

feat(init): rust workflow steps, markdownlint migration, idempotence fix#195
zeitlinger merged 6 commits intodocs/split-and-v2-installfrom
flint-init-rust-workflow-v2

Conversation

@zeitlinger
Copy link
Copy Markdown
Member

Summary

Stacked on #187. Three init improvements:

  • Rust workflow steps: generate_lint_workflow takes has_rust param — inserts Swatinem/rust-cache + rustup component add clippy rustfmt when Rust is detected.
  • markdownlint migration: rename config to .markdownlint.yml (from .json), drop line-length rule (deferred to editorconfig-checker). Removes legacy variants.
  • Idempotence fix: normalize_tools_section sorts [tools] and inserts # Linters header once; re-running flint init prints "No changes to apply."

Registry refactor: .toolchain() / .toolchain_components(..) builders replace hardcoded REUSED_RUNTIME_KEYS. Toolchain set is now derived from the registry via toolchain_keys().

Test plan

  • mise exec -- cargo test green
  • new e2e fixture tests/cases/general/init-rust/ asserts rust-aware init
  • init-idempotent fixture verifies re-run prints "No changes to apply."
  • unit test generate_lint_workflow_with_rust covers workflow content (kept out of e2e snapshot to avoid renovate pin-bump flakes)

Stacked on #187.

### Rust workflow steps

`flint init` now adds `Swatinem/rust-cache` and `rustup component add clippy
rustfmt` to `.github/workflows/lint.yml` when a Rust toolchain is detected in
`mise.toml`. The push trigger gets a comment explaining why we run on main
("warms the Rust cache so PR branches get a cache hit").

Also bumps the generated `mise-action` pin to v2026.4.16 to match flint's
own dogfood workflow.

### Markdownlint .yml migration

Switches the generated markdownlint config from `.markdownlint.jsonc` to
`.markdownlint.yml` for uniformity across consumer repos. Legacy variants
(`.markdownlint.{json,jsonc,yaml}` and `.markdownlint-cli2.*`) are replaced
on init. Only generated when editorconfig-checker is also selected, since
the file's comment points to editorconfig-checker for line-length.

### [tools] normalization

New `normalize_tools_section` sorts `mise.toml [tools]` alphabetically and
inserts a `# Linters` header. Toolchain keys (rust/go/dotnet/node) stay
above the header; lint-only binaries go below.

Toolchain detection is registry-driven: a new `Check::toolchain()` /
`Check::toolchain_components()` builder marks a mise_tool as a language
runtime. `toolchain_keys()` collects them at runtime, plus `node` (which
is added by `ensure_node_for_npm` outside the registry).

The old `mise_install_components: Option<&str>` field merges into
`toolchain: Option<Option<&str>>` — None = linter binary, Some(None) =
toolchain without components, Some(Some(c)) = toolchain with components.

### Idempotence fix

Before: first run generates `.github/workflows/lint.yml` but doesn't
detect actionlint (no workflow yaml existed at detect time). Second run
picks up the generated workflow → adds actionlint → non-idempotent.

Fix: when init is about to generate the workflow, synthesize the workflow
patterns into `present_patterns` so actionlint gets selected in the same
run. Covered by new `tests/cases/general/init-idempotent/` e2e case.

### Tests

- New e2e cases: `general/init-rust` (fresh rust project → full init),
  `general/init-idempotent` (fully-initialized repo → "No changes to apply")
- init-rust test uses a fake `mise` shell-script stub to deterministically
  pin tool versions, via the existing `[fake_bins]` harness feature
- Fixes a snapshot-writer bug in `write_test_toml` that was producing
  malformed test.toml (missing newlines, escape-processing strings)
- New unit tests for `normalize_tools_section`, markdownlint migration,
  rust workflow generation
Signed-off-by: Gregor Zeitlinger <[email protected]>
cargo-fmt reformats two over-long lines in generation.rs and reorders
test imports in mod.rs. renovate-tracked-deps.json picks up the new
Swatinem/rust-cache reference added to generate_lint_workflow.
Signed-off-by: Gregor Zeitlinger <[email protected]>
Verifies that `flint init --yes` on a Rust project writes the expected
[tools] section (runtimes above `# Linters` header), toolchain inline
table for rust (version + components), [env], and [tasks] blocks.
Signed-off-by: Gregor Zeitlinger <[email protected]>
- `node` now sorts into the linters group instead of above `# Linters`.
  It's only pinned by `ensure_node_for_npm` as a prereq for `npm:` backend
  linters, not as a first-class toolchain like rust (which runs `cargo`
  directly). Drop the explicit `node` insert from `toolchain_keys()`.

- Mark the `[tasks]` parent table implicit so the empty section header
  is suppressed when only sub-tables (`[tasks.lint]`, `[tasks."lint:fix"]`)
  exist.

- Fake mise in init-rust now requires `--pin` and exits non-zero if it's
  missing — catches regressions that would write soft `latest` pins.
Signed-off-by: Gregor Zeitlinger <[email protected]>
Signed-off-by: Gregor Zeitlinger <[email protected]>
@zeitlinger zeitlinger marked this pull request as ready for review April 18, 2026 12:22
@zeitlinger zeitlinger requested a review from a team as a code owner April 18, 2026 12:22
Adds `github:grafana/flint` at the running binary's CARGO_PKG_VERSION so
all contributors run the same flint release. Skips when the key already
exists (any pin) to respect user's explicit choice.

Signed-off-by: Gregor Zeitlinger <[email protected]>
@zeitlinger zeitlinger merged commit 1a4f421 into docs/split-and-v2-install Apr 20, 2026
11 checks passed
@zeitlinger zeitlinger deleted the flint-init-rust-workflow-v2 branch April 20, 2026 13:43
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.

2 participants