Repository navigation
release: v0.3.0 — checker: catch more real bugs; add --fix and CI autofix - #19
Merged
Merged
Conversation
Adds three schema/AST-derived diagnostics with no hand-maintained per-dispatcher data, closing gaps confirmed against real Hyprland issues: - possible_missing_quotes: a bare identifier value (e.g. accel_profile = flat) that's never assigned anywhere in the file would silently evaluate to nil at runtime. Reproduces the exact bug in hyprwm/Hyprland#15727, which broke a user's mouse sensitivity after a .conf migration. - uncalled_dispatcher: a dispatcher factory referenced but not called (hl.dsp.window.close instead of hl.dsp.window.close()), which type-checks under the stub's HL.Dispatcher|function union so nothing else catches it. - duplicate_bind: the same key combo bound more than once, silently shadowing one binding. Caught four genuine, previously-undetected collisions in this project's own vendored real-world test fixture. Both uncalled_dispatcher and duplicate_bind are from hyprwm/Hyprland#15871 ("Improve lua error reporting"); arity-checking dsp.* calls (the issue's third case) is deliberately not implemented since the stub carries no argument-count data for those factories. Also fixes a pre-existing crash: check() grouped Method (a `function T:method() end` definition, no .func attribute) with Call for call-detection; a colon-method definition anywhere in a config raised AttributeError. Invoke is the actual method-call node.
check --fix (hyprvalidate/fixer.py): applies the two corrections that have exactly one right answer - quoting a bare-identifier string value (possible_missing_quotes) and adding () to a referenced-but-uncalled dispatcher factory (uncalled_dispatcher) - as targeted character-offset patches against the original source, never a full AST regenerate-and- reprint, so a user's comments and formatting outside the flagged span survive untouched. Findings with no single correct fix (unknown symbols/keys, type/arity mismatches, duplicate binds) are left reported, never guessed at. Patched output goes through the luac gate and a re-check before being written, same discipline convert already applies to its own output. examples/ci/validate-hyprland-lua.yml: a ready-to-copy GitHub Actions workflow for validating a dotfiles repo's Lua config with no Hyprland installed - pins the hyprvalidate version and its schema.json snapshot to the same git tag so they can't drift apart. Also fixes the README's own CI section, which had gone stale (pipx install git+... from before the PyPI release, and a schema.json reference with no explanation of where it comes from).
checker.py picked up three new checks and a bugfix this PR without a bundle regen - the CI site-bundle-in-sync job caught it.
The validate job only ever flagged problems; closing the loop means the mechanical fixes (missing quotes, uncalled dispatcher factories) get committed automatically instead of waiting on a human to notice and run --fix locally. Split into two jobs by trigger since push and pull_request need different permission/safety postures: - validate (pull_request): unchanged, read-only check. Works the same for a same-repo branch or a fork - no write access, no surprise commits landing mid-review. - validate-and-autofix (push): runs check --fix, commits and pushes any change back onto the branch, still fails the job if something unfixable remains. Guarded against re-triggering itself on its own fix commit via a [hyprvalidate-autofix] marker in the commit message.
Finalizes the Unreleased changelog entries from this PR (checker: three new checks + a crash fix, check --fix, the CI template + autofix wiring) as 0.3.0. Also bumps the CI template's default HYPRVALIDATE_VERSION and the README's inline example to match, and fixes packaging/PKGBUILD, which had been stuck at pkgver=0.1.0 even after the 0.2.0 release. Tagging and pushing v0.3.0 (which triggers the PyPI publish via Trusted Publishing) happens after this merges to main, not on this branch - a release tag should point at what's actually on main.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five commits:
checker.py: three new checks derived from real Hyprland bug reports -possible_missing_quotes— a bare, never-assigned identifier used as a string value (accel_profile = flat) silently evaluates tonil. Reproduces hyprwm/Hyprland#15727, which broke a real user's mouse sensitivity.uncalled_dispatcher— a dispatcher factory referenced but not called.duplicate_bind— the same key combo bound more than once. Caught 4 genuine collisions in this project's own vendored real-world test fixture.uncalled_dispatcherandduplicate_bindare from hyprwm/Hyprland#15871; arity-checkingdsp.*calls (that issue's third case) is deliberately not implemented — no argument-count data exists in the stub to check it against.Methodhas no.func;Invokeis the real method-call node).check --fix(newhyprvalidate/fixer.py): applies the two corrections above that have exactly one right answer, as targeted character-offset patches — never a full AST regenerate-and-reprint, so a hand-written config's comments/formatting survive. Everything else is still reported, never guessed at.examples/ci/validate-hyprland-lua.yml: a ready-to-copy GitHub Actions workflow, split into a read-onlycheckgate on PRs and acheck --fixautofix job on push that commits corrections back onto the branch.site/bundle.jsregenerated (CI's ownsite-bundle-in-syncjob caught the drift).Version bump to 0.3.0, finalizing the changelog and fixing
packaging/PKGBUILD, which had been stuck atpkgver=0.1.0since before this PR.Release plan
This PR does not create or push the
v0.3.0tag — that happens after merge, againstmain, since a release tag should point at what's actually merged rather than a feature-branch commit. After merging, either:git checkout main && git pull && git tag v0.3.0 && git push origin v0.3.0, orv0.3.0onmain— creating the release also creates+pushes the tag, which is allpublish.ymlneeds to trigger the PyPI publish.Test plan
pytest tests/— 195 passed (3 pre-existing/environmental entry-point failures unrelated to this change, deselected)possible_missing_quotesagainst the real bug report in Mouse cursor speed significantly higher after updating Hyprland hyprwm/Hyprland#15727 directly--fixverified end-to-end on a scratch file with a mix of fixable and unfixable findingssite/bundle.jsregenerated and CI'ssite-bundle-in-syncjob confirmed green