refactor(oxfmt): Resolve options on each path, preparing for .editorconfig support#16991
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
7e40a73 to
5d2aa10
Compare
.editorconfig support
There was a problem hiding this comment.
Pull request overview
This PR refactors the configuration resolution system in oxfmt to prepare for .editorconfig support. The key change is moving from resolving configuration once at the start to resolving it per-file, enabling future per-path overrides from .editorconfig.
Key Changes
- Introduced
ConfigResolverandResolvedOptionstypes to handle configuration resolution per file path - Refactored external formatter callbacks to accept options on each call rather than during initialization
- Updated all formatting entry points to resolve options per-file instead of using cached global options
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/oxfmt/src/core/config.rs | Introduced ConfigResolver and ResolvedOptions for per-file configuration resolution; moved from single load_config() to resolver pattern |
| apps/oxfmt/src/core/format.rs | Updated SourceFormatter::format() to accept ResolvedOptions parameter; formatting methods now receive options per call |
| apps/oxfmt/src/core/external_formatter.rs | Renamed callback from setup_config to init; formatter methods now accept options parameter on each call |
| apps/oxfmt/src/stdin/mod.rs | Updated to use ConfigResolver and resolve options per stdin file entry |
| apps/oxfmt/src/main_napi.rs | Updated NAPI API to use ConfigResolver and resolve options before formatting |
| apps/oxfmt/src/cli/format.rs | Updated CLI runner to create ConfigResolver and pass to FormatService |
| apps/oxfmt/src/cli/service.rs | Updated service to accept ConfigResolver and resolve options per file in parallel formatting |
| apps/oxfmt/src-js/prettier-proxy.ts | Removed config setup from pool initialization; options now passed on each format call |
| apps/oxfmt/src-js/prettier-worker.ts | Removed workerData config; workers now receive options with each task |
| apps/oxfmt/src-js/index.ts | Updated to use initExternalFormatter instead of setupConfig |
| apps/oxfmt/src-js/cli.ts | Updated callback reference to initExternalFormatter |
| apps/oxfmt/src-js/bindings.d.ts | Updated TypeScript type definitions for new callback signatures |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
82edec0 to
95a3d1a
Compare
95a3d1a to
bcff4b6
Compare
Dunqing
left a comment
There was a problem hiding this comment.
Need to take a look at the Copilot review
|
@Dunqing Oh, sorry, I missed that and resolved!
|
Merge activity
|
…config` support (#16991) Refactoring for #15850 ### Before this PR - The config file and its option values were resolved only once at the beginning - They were kept for `OxcFormatter` and also being cached via `setupConfig()` for `ExternalFormatter` - When calling `SourceFormatter.format()`, it always referenced those values ### After this PR - The config file and its option values are resolved only once at the beginning - Those values are still kept as before - But, this is for a fast path when there are no per-path overrides in `.editorconfig` - When calling `SourceFormatter.format()` - If `.editorconfig` exists and has per-path overrides, they are re-resolved per path - Otherwise, it continues to reference the initially cached values We only support the root `.editorconfig`, but since glob-based per-path overrides can be written there, we have to resolve options on each path. Some performance impact is unavoidable. However, in scenarios where `.editorconfig` doesn't exist, or exists but has no per-path overrides, the cost is limited to just cloning the cached values per path.
bcff4b6 to
7b9468b
Compare
…config` support (#16991) Refactoring for #15850 ### Before this PR - The config file and its option values were resolved only once at the beginning - They were kept for `OxcFormatter` and also being cached via `setupConfig()` for `ExternalFormatter` - When calling `SourceFormatter.format()`, it always referenced those values ### After this PR - The config file and its option values are resolved only once at the beginning - Those values are still kept as before - But, this is for a fast path when there are no per-path overrides in `.editorconfig` - When calling `SourceFormatter.format()` - If `.editorconfig` exists and has per-path overrides, they are re-resolved per path - Otherwise, it continues to reference the initially cached values We only support the root `.editorconfig`, but since glob-based per-path overrides can be written there, we have to resolve options on each path. Some performance impact is unavoidable. However, in scenarios where `.editorconfig` doesn't exist, or exists but has no per-path overrides, the cost is limited to just cloning the cached values per path.
7b9468b to
7368d66
Compare

Refactoring for #15850
Before this PR
OxcFormatterand also being cached viasetupConfig()forExternalFormatterSourceFormatter.format(), it always referenced those valuesAfter this PR
.editorconfigSourceFormatter.format().editorconfigexists and has per-path overrides, they are re-resolved per pathWe only support the root
.editorconfig, but since glob-based per-path overrides can be written there, we have to resolve options on each path. Some performance impact is unavoidable.However, in scenarios where
.editorconfigdoesn't exist, or exists but has no per-path overrides, the cost is limited to just cloning the cached values per path.