Repository navigation
Adopt Ultracite's Oxlint and Oxfmt presets - #1141
Merged
Merged
Conversation
Replace the formatter defaults with the "ultracite/oxfmt" preset and reformat every file it covers. The preset wraps code at 80 columns, sorts imports and package.json keys, and never wraps prose, so the folded descriptions in the action manifests now sit on one line. Their parsed YAML is unchanged, as are the bundles.
Run "vp check --fix" with the "ultracite/oxlint/core" and "ultracite/oxlint/vitest" presets and keep what it changed: sorted object keys, explicit join separators, merged push calls, "utf-8" encoding names, test() instead of it(), and resolves matchers. The lint configuration itself switches in a later commit, once the rest of the code base passes. Two fixes needed help. The test() rename left the it imports behind, and mocking modules through import() made the mocks follow the real module types. The Actions cache mock now takes its parameter types from @actions/cache, and the systeminformation mock is gone. The action reads the real OS release, which the transcripts normalise like the platform and architecture.
Ultracite's Oxlint preset sets func-style to "expression" with arrow functions allowed, so turn each of the 80 function declarations into a const bound to an arrow function. A codemod rewrote the head of each declaration from the parsed source and left the bodies untouched. No code calls a function before its new definition. The tests, the action transcripts and the lint action bundles behave as before.
Extend "ultracite/oxlint/core" and "ultracite/oxlint/vitest" in the lint configuration and fix what the automatic fixes left behind. Functions that return a value on some paths now return null on the others instead of falling off the end, so restoreCache, matchVersion and the .ocamlformat reader say "nothing found" explicitly. Conditions on optional strings compare against undefined and the empty string, which keeps the empty string treated as absent, as before. The supported architectures and platforms move from switch statements into lookup tables, and the error messages list them from there. The exhaustiveness check would otherwise want a case for every value that Node.js defines. Loops that must run in order, such as adding repositories by priority, keep their await and say why in a disable comment. So does the Actions cache mock, which mirrors an asynchronous API without awaiting anything. Tests sit in describe blocks, regular expressions use the Unicode flag and named groups, and node:path is a default import.
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.
Why
Use a maintained lint and format preset instead of a growing set of project-specific rules.
What changed
vite.config.tsextendsultracite/oxlint/coreandultracite/oxlint/vitest, and formats withultracite/oxfmt.vp checkstill runs both.nullfor "nothing found", lookup tables for the supported architectures and platforms, and tests indescribeblocks.Scope
ultracite init, so there are no editor settings, agent rules, or separate Oxlint and Oxfmt config files.Tradeoffs
The presets live in
vite.config.tsrather than inoxlint.config.tsandoxfmt.config.ts. The project already runs lint and formatting through vite-plus, and Ultracite's documentation does not cover vite-plus, so a second config would have split the source of truth.Blast radius
Almost every file changes, but only through formatting and lint fixes. The action manifests parse to the same YAML.
yarn.lockgrows by about 700 lines for Ultracite's dependencies.Verification
yarn lint,yarn knip,yarn typecheck,CI=true yarn test, and a cleanyarn build.