Skip to content

Separate output planning from writing#1164

Merged
christianhelle merged 10 commits into
mainfrom
refactor-output-planning-and-writing
Jun 20, 2026
Merged

Separate output planning from writing#1164
christianhelle merged 10 commits into
mainfrom
refactor-output-planning-and-writing

Conversation

@christianhelle

@christianhelle christianhelle commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

Implements PRD-003: separates output planning from writing by introducing two narrow interfaces in Refitter.Core, each with distribution-form-specific adapters.

Changes

New interfaces (Refitter.Core)

  • IOutputPlanner — resolves GeneratorOutput into a list of PlannedFile (path + content). Pure logic, no I/O.
  • IFileWriter — accepts a PlannedFile and writes it to disk, creating directories as needed.

Adapters

  • OutputPlannerAdapter (Refitter.Core) — wraps static OutputPlanner methods behind IOutputPlanner
  • CliFileWriter (Refitter) — writes files and reports progress via IGenerationReporter
  • MsBuildFileWriter (Refitter.MSBuild) — writes files synchronously (netstandard2.0)
  • SourceGeneratorFileWriter (Refitter.Core) — writes files with content-equality check (skips when content unchanged)

Refactored distribution forms

  • GenerationOrchestrator (CLI) — delegates planning to IOutputPlanner and writing to IFileWriter; no longer creates directories or calls File.WriteAllTextAsync directly
  • RefitterGenerateTask (MSBuild) — delegates to OutputPlannerAdapter and MsBuildFileWriter
  • RefitterSourceGenerator (Source Generator) — delegates writing to SourceGeneratorFileWriter

Tests

  • OutputPlannerAdapterTests — 6 tests covering single/multi-file planning through IOutputPlanner
  • CliFileWriterTests — 3 tests for directory creation and content preservation
  • MsBuildFileWriterTests — 2 tests for synchronous file writing
  • SourceGeneratorFileWriterTests — 3 tests including content-equality skip logic
  • All existing 2290+ tests continue to pass unchanged

Commit history (9 micro-commits)

Each change is small, logical, and independently reviewed:

  1. Add IOutputPlanner and IFileWriter interfaces
  2. Add OutputPlannerAdapter implementing IOutputPlanner
  3. Add CliFileWriter implementing IFileWriter
  4. Add MsBuildFileWriter implementing IFileWriter
  5. Add SourceGeneratorFileWriter implementing IFileWriter
  6. Refactor GenerationOrchestrator to use interfaces
  7. Refactor RefitterGenerateTask to use interfaces
  8. Refactor RefitterSourceGenerator to use interfaces
  9. Remove unused imports from source generator

Closes PRD-003

Summary by CodeRabbit

  • New Features
    • Added a unified output planning/writing pipeline, improving single-file and multi-file generation behavior and output-path handling.
    • Introduced dedicated file writers for CLI, MSBuild, and source generation, including “write only when content differs” to reduce unnecessary overwrites and improve performance.
  • Refactor
    • Updated generation orchestration to route output through the planner and writers, standardizing progress/reporting and metadata.
  • Tests
    • Added/expanded test suites covering CLI, MSBuild, source generator writing behavior, and output-path planning scenarios.

Introduce two narrow interfaces that separate output planning from writing:
- IOutputPlanner resolves GeneratorOutput into PlannedFile paths (pure logic, no I/O)
- IFileWriter accepts a PlannedFile and writes it to disk

Part of PRD-003: separate output planning from writing.
Adapter wraps static OutputPlanner methods behind the IOutputPlanner
interface, dispatching to PlanSingleFile or PlanMultipleFiles based on
config.GenerateMultipleFiles.

Tests mirror the existing OutputPlannerTests pattern but go through
the interface seam.
CLI adapter writes planned files to disk with directory creation and
reports progress via IGenerationReporter.ReportFileWritten().

Tests verify directory creation, existing directories, and content
preservation.
MSBuild adapter writes planned files to disk with directory creation.
Synchronous implementation (netstandard2.0 compat). No logging
dependencies — the calling RefitterGenerateTask handles reporting.

Tests verify directory creation and existing-directory scenarios.
Content-equality-aware file writer that skips writing when the file
already exists with identical content, avoiding unnecessary disk writes
during incremental/design-time builds. Synchronous implementation for
netstandard2.0 compatibility.

Tests verify: directory creation, skip-on-identical-content, and
overwrite-on-different-content.
GenerationOrchestrator no longer creates directories or calls
File.WriteAllTextAsync directly. It delegates path planning to
IOutputPlanner (OutputPlannerAdapter) and file writing to IFileWriter
(CliFileWriter). The WriteSingleFile and WriteMultipleFiles methods
became instance methods to access the planner field.

This is the first distribution form refactored as part of PRD-003.
ProcessRefitterFile now delegates path planning to OutputPlannerAdapter
and file writing to MsBuildFileWriter instead of inline
Directory.CreateDirectory + File.WriteAllText.

This is the second distribution form refactored as part of PRD-003.
Replaced inline WriteGeneratedFile logic (directory creation +
content-equality check + File.WriteAllText) with SourceGeneratorFileWriter
via the IFileWriter interface.

Added Abstractions/*.cs to the source generator's compile includes so
that SourceGeneratorFileWriter (and future abstractions) are available.

This is the third distribution form refactored as part of PRD-003.
System.Runtime.CompilerServices and System.Text were only used by
the old WriteGeneratedFile method and are no longer needed.
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 85d52f75-edb6-4f65-8599-2d6c85551434

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd4c14 and 980ee86.

📒 Files selected for processing (3)
  • src/Refitter.SourceGenerator/RefitterSourceGenerator.cs
  • src/Refitter.Tests/SourceGeneratorFileWriterTests.cs
  • src/Refitter/GenerationOrchestrator.cs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/Refitter.Tests/SourceGeneratorFileWriterTests.cs
  • src/Refitter.SourceGenerator/RefitterSourceGenerator.cs
  • src/Refitter/GenerationOrchestrator.cs

📝 Walkthrough

Walkthrough

Introduces IFileWriter and IOutputPlanner interfaces in Refitter.Core.Abstractions. Provides OutputPlannerAdapter, SourceGeneratorFileWriter, MsBuildFileWriter, and CliFileWriter implementations. Rewires GenerationOrchestrator, RefitterGenerateTask, and RefitterSourceGenerator to delegate output planning and file I/O through the new abstractions instead of inline static calls. Adds tests for all new types.

Changes

Output Planning and File-Writing Abstraction

Layer / File(s) Summary
IFileWriter and IOutputPlanner interfaces
src/Refitter.Core/Abstractions/IFileWriter.cs, src/Refitter.Core/Abstractions/IOutputPlanner.cs
Defines IFileWriter with async WriteAsync(PlannedFile, CancellationToken) and IOutputPlanner with a pure Plan method returning IReadOnlyList<PlannedFile>.
OutputPlannerAdapter
src/Refitter.Core/Abstractions/OutputPlannerAdapter.cs
Implements IOutputPlanner by branching on config.GenerateMultipleFiles to call the static OutputPlanner.PlanMultipleFiles or OutputPlanner.PlanSingleFile, returning a normalized list.
IFileWriter implementations
src/Refitter.Core/Abstractions/SourceGeneratorFileWriter.cs, src/Refitter.MSBuild/MsBuildFileWriter.cs, src/Refitter/CliFileWriter.cs
SourceGeneratorFileWriter skips writes when content is identical (UTF-8 comparison); MsBuildFileWriter uses synchronous File.WriteAllText; CliFileWriter uses async File.WriteAllTextAsync and calls IGenerationReporter.ReportFileWritten.
GenerationOrchestrator refactored
src/Refitter/GenerationOrchestrator.cs
Gains IOutputPlanner constructor and instance field, creates CliFileWriter in RunAsync, and routes WriteSingleFile and WriteMultipleFiles through _planner.Plan(...) + writer.WriteAsync(...) delegation. Output metrics now derive from planned file content.
RefitterSourceGenerator refactored
src/Refitter.SourceGenerator/RefitterSourceGenerator.cs
Removes unused usings, builds a PlannedFile from computed output path and generated code, then delegates write to SourceGeneratorFileWriter instead of inline directory/file operations.
RefitterGenerateTask refactored
src/Refitter.MSBuild/RefitterGenerateTask.cs, src/Refitter.SourceGenerator/Refitter.SourceGenerator.csproj
Replaces inline OutputPlanner + File.WriteAllText with OutputPlannerAdapter.Plan + MsBuildFileWriter.WriteAsync for both multi-file and single-file paths. Csproj updated to include ../Refitter.Core/Abstractions/*.cs compile glob.
Tests
src/Refitter.Tests/CliFileWriterTests.cs, src/Refitter.Tests/MsBuildFileWriterTests.cs, src/Refitter.Tests/SourceGeneratorFileWriterTests.cs, src/Refitter.Tests/OutputPlannerAdapterTests.cs
Validates all three IFileWriter implementations (directory creation, idempotency, overwrite) and OutputPlannerAdapter path resolution across single-file, multi-file, CLI, settings-file, and contracts-rerouting scenarios.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant GenerationOrchestrator
  participant OutputPlannerAdapter
  participant CliFileWriter
  participant IGenerationReporter

  Caller->>GenerationOrchestrator: RunAsync(settings, reporter, ct)
  GenerationOrchestrator->>GenerationOrchestrator: new CliFileWriter(reporter)
  GenerationOrchestrator->>OutputPlannerAdapter: Plan(output, config, settingsFilePath, cliOutputPath)
  OutputPlannerAdapter-->>GenerationOrchestrator: IReadOnlyList<PlannedFile>
  loop each PlannedFile
    GenerationOrchestrator->>CliFileWriter: WriteAsync(plannedFile, ct)
    CliFileWriter->>CliFileWriter: Directory.CreateDirectory
    CliFileWriter->>CliFileWriter: File.WriteAllTextAsync
    CliFileWriter->>IGenerationReporter: ReportFileWritten(path)
  end
  GenerationOrchestrator-->>Caller: result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • christianhelle/refitter#1128: Extracted orchestration out of GenerateCommand into GenerationOrchestrator, which this PR further refactors by injecting IOutputPlanner/IFileWriter.
  • christianhelle/refitter#1154: Also modifies RefitterGenerateTask.ProcessRefitterFile output generation path, directly adjacent to this PR's MSBuild planning/writer refactor.
  • christianhelle/refitter#1163: Updates OutputPlanner static APIs to accept IOutputConfiguration, which OutputPlannerAdapter.Plan in this PR calls directly.

Suggested labels

enhancement, .NET

🐇 A rabbit hopped through files one by one,
Scattering abstractions under the sun.
"No more inline writes!" cried the hare with glee,
IFileWriter now sets the output path free.
Plan and WriteAsync — the new way to run! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Separate output planning from writing' accurately and concisely summarizes the main objective of the PR, which is to decouple output planning logic from file writing operations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-output-planning-and-writing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.69231% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.68%. Comparing base (ccabf62) to head (980ee86).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/Refitter/CliFileWriter.cs 75.00% 4 Missing and 1 partial ⚠️
src/Refitter/GenerationOrchestrator.cs 87.50% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1164      +/-   ##
==========================================
- Coverage   94.81%   94.68%   -0.14%     
==========================================
  Files          69       71       +2     
  Lines        3454     3497      +43     
==========================================
+ Hits         3275     3311      +36     
- Misses         69       74       +5     
- Partials      110      112       +2     
Flag Coverage Δ
unittests 94.68% <82.69%> (-0.14%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (9)
src/Refitter/CliFileWriter.cs (2)

10-10: ⚡ Quick win

Rename the private field to camelCase without underscore.

_reporter on Line 10 violates the repository field naming rule.

As per coding guidelines, "Private fields must NOT be prefixed with underscore; use camelCase without underscore prefix (e.g., openApiPath not _openApiPath)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter/CliFileWriter.cs` at line 10, The private field `_reporter` in
the CliFileWriter class violates the repository's naming convention which
requires private fields to use camelCase without underscore prefix. Rename the
field declaration `_reporter` to `reporter` and update all references to this
field throughout the CliFileWriter class to use the new name without the
underscore prefix.

Source: Coding guidelines


26-26: ⚡ Quick win

Use an explicit local type instead of var.

The var local on Line 26 conflicts with the configured C# style in this repository.

As per coding guidelines, "Discourage use of var keyword in C# (csharp_style_var_* = false:silent)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter/CliFileWriter.cs` at line 26, Replace the `var` keyword on line
26 where the `dir` variable is declared with its explicit type `string`. The
variable `dir` is assigned the result of Path.GetDirectoryName which returns a
string, so change `var dir = Path.GetDirectoryName(file.Path);` to use the
explicit type declaration instead of the implicit var keyword to comply with the
repository's C# style guidelines that discourage use of var.

Source: Coding guidelines

src/Refitter/GenerationOrchestrator.cs (2)

10-10: ⚡ Quick win

Rename the private field to remove underscore prefix.

_planner on Line 10 violates the repository’s private-field naming rule.

As per coding guidelines, "Private fields must NOT be prefixed with underscore; use camelCase without underscore prefix (e.g., openApiPath not _openApiPath)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter/GenerationOrchestrator.cs` at line 10, The private field
_planner violates the repository's naming conventions by using an underscore
prefix. Rename this field from _planner to planner (using camelCase without the
underscore prefix) in the GenerationOrchestrator class. Ensure all references to
this field throughout the class are updated to use the new name without the
underscore.

Source: Coding guidelines


61-65: ⚡ Quick win

Use explicit local types instead of var in the new locals.

The changed locals in these ranges use var, which conflicts with repository C# style.

As per coding guidelines, "Discourage use of var keyword in C# (csharp_style_var_* = false:silent)."

Also applies to: 121-136, 151-159

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter/GenerationOrchestrator.cs` around lines 61 - 65, Replace the
`var` keyword with explicit types in local variable declarations throughout the
file to comply with repository C# style guidelines. Specifically, change `var
writer = new CliFileWriter(reporter)` to use the explicit type `CliFileWriter`
instead of `var`, and apply the same pattern to any other `var` declarations
found in the line ranges mentioned (121-136, 151-159). Always use the explicit
type name on the right side of the assignment for all local variable
declarations rather than relying on type inference with `var`.

Source: Coding guidelines

src/Refitter.Tests/SourceGeneratorFileWriterTests.cs (1)

12-22: ⚡ Quick win

Use explicit local types instead of var in test locals.

The new test locals use var, which conflicts with repository C# style.

As per coding guidelines, "Discourage use of var keyword in C# (csharp_style_var_* = false:silent)."

Also applies to: 39-52, 71-84

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter.Tests/SourceGeneratorFileWriterTests.cs` around lines 12 - 22,
Replace all `var` keyword declarations with explicit types in the test method
locals throughout the SourceGeneratorFileWriterTests class to comply with
repository C# style guidelines. In the shown diff block, replace `var` with the
explicit types for workspace (string), writer (SourceGeneratorFileWriter),
filePath (string), and planned (PlannedFile). Also apply the same change to the
additional instances mentioned in lines 39-52 and 71-84 to ensure consistency
across the entire test file.

Source: Coding guidelines

src/Refitter.Tests/CliFileWriterTests.cs (2)

13-17: ⚡ Quick win

Use explicit local types instead of var in test locals.

The new test code uses var widely, which conflicts with repository C# style.

As per coding guidelines, "Discourage use of var keyword in C# (csharp_style_var_* = false:silent)."

Also applies to: 20-24, 41-44, 49-56, 74-77, 82-86

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter.Tests/CliFileWriterTests.cs` around lines 13 - 17, Replace all
instances of the `var` keyword with explicit type declarations in the test
locals throughout the CliFileWriterTests.cs file to comply with the repository's
C# style guidelines. Specifically, change `var workspace` to use the explicit
`string` type (since Path.Combine returns a string), and apply the same pattern
to all other local variables currently declared with `var` across the lines
mentioned (20-24, 41-44, 49-56, 74-77, 82-86). Each variable declaration should
use its actual return type instead of relying on type inference.

Source: Coding guidelines


20-30: ⚡ Quick win

Add an assertion that ReportFileWritten is invoked.

These tests validate disk output, but they don’t validate the CLI-specific reporting behavior that this adapter adds. Please assert reporter interaction with a spy/mock reporter.

Also applies to: 52-63, 83-92

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter.Tests/CliFileWriterTests.cs` around lines 20 - 30, The test is
missing an assertion to verify that the reporter's ReportFileWritten method is
being invoked by the CliFileWriter. Replace the SimpleGenerationReporter
instance with a mock or spy reporter that allows verification of method calls,
then add an assertion after the WriteAsync call to verify that ReportFileWritten
was invoked with the expected file path parameter. This ensures the CLI-specific
reporting behavior is validated in addition to the file output. Apply the same
fix to the other affected test methods referenced in the comment.
src/Refitter.Tests/MsBuildFileWriterTests.cs (2)

37-56: ⚡ Quick win

Strengthen the existing-directory test by asserting written content.

WriteAsync_Does_Not_Throw_When_Directory_Already_Exists currently only checks file existence. Asserting content here would catch accidental no-op/partial-write regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter.Tests/MsBuildFileWriterTests.cs` around lines 37 - 56, The test
WriteAsync_Does_Not_Throw_When_Directory_Already_Exists only verifies that the
file exists after calling writer.WriteAsync, but does not verify that the
content was actually written correctly. Add an assertion after the File.Exists
check that reads the file content and asserts it matches the content provided to
the PlannedFile constructor (which is "// test"). This will catch regressions
where the file is created but left empty or with partial/incorrect content.

13-17: ⚡ Quick win

Use explicit local types instead of var in test locals.

The changed test locals use var, which conflicts with repository C# style.

As per coding guidelines, "Discourage use of var keyword in C# (csharp_style_var_* = false:silent)."

Also applies to: 20-23, 40-43, 49-52

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Refitter.Tests/MsBuildFileWriterTests.cs` around lines 13 - 17, Replace
the `var` keyword with explicit types in test local variables to align with
repository C# style guidelines that discourage the use of `var`. For the
workspace variable declaration that uses Path.Combine, replace `var` with
`string` since Path.Combine returns a string type. Apply this same change to all
other test local variables using `var` throughout the MsBuildFileWriterTests
class to maintain consistent coding style.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Refitter.SourceGenerator/RefitterSourceGenerator.cs`:
- Around line 102-103: The GenerateCode method receives a cancellationToken
parameter but does not pass it to the WriteGeneratedFile method calls (at lines
102-103 and 124-130), causing filesystem I/O operations to proceed even when the
source generation is canceled. Add a cancellationToken parameter to the
WriteGeneratedFile method signature, pass the cancellationToken argument from
GenerateCode to all WriteGeneratedFile calls, and forward that token to the
WriteAsync method invocation inside WriteGeneratedFile to properly respect
cancellation requests.

In `@src/Refitter.Tests/SourceGeneratorFileWriterTests.cs`:
- Around line 37-60: The test WriteAsync_Skips_Write_When_Content_Identical
currently only verifies the final file content matches expectations, but this
would pass even if the file was rewritten with identical text. To properly
assert that no write occurred, capture the file's last-write timestamp (using
File.GetLastWriteTimeUtc) immediately after the initial File.WriteAllTextAsync
call on filePath, then after calling writer.WriteAsync, compare the timestamp
again and assert that it remains unchanged to verify the skip-write optimization
actually worked.

In `@src/Refitter/GenerationOrchestrator.cs`:
- Around line 125-132: The code accesses planned[0] immediately after the
_planner.Plan() call without validating that the result contains any elements,
and similarly accesses planned[i] in a loop around line 155-169 without guards.
Add validation checks after the _planner.Plan() call to ensure the planned
collection is not null and contains at least one element before attempting to
access planned[0], and verify the collection has sufficient elements before
iterating over it with planned[i] in the loop.
- Around line 134-136: The file size and line count metrics in
GenerationOrchestrator.cs are being calculated from the `code` variable, but the
actual content being persisted is `plannedFile.Content`. If content
transformation occurs between these two, the reported metrics become inaccurate.
Update the FormatFileSize and lines calculation to use `plannedFile.Content`
instead of `code` to ensure the metrics reflect what is actually written to the
file.

---

Nitpick comments:
In `@src/Refitter.Tests/CliFileWriterTests.cs`:
- Around line 13-17: Replace all instances of the `var` keyword with explicit
type declarations in the test locals throughout the CliFileWriterTests.cs file
to comply with the repository's C# style guidelines. Specifically, change `var
workspace` to use the explicit `string` type (since Path.Combine returns a
string), and apply the same pattern to all other local variables currently
declared with `var` across the lines mentioned (20-24, 41-44, 49-56, 74-77,
82-86). Each variable declaration should use its actual return type instead of
relying on type inference.
- Around line 20-30: The test is missing an assertion to verify that the
reporter's ReportFileWritten method is being invoked by the CliFileWriter.
Replace the SimpleGenerationReporter instance with a mock or spy reporter that
allows verification of method calls, then add an assertion after the WriteAsync
call to verify that ReportFileWritten was invoked with the expected file path
parameter. This ensures the CLI-specific reporting behavior is validated in
addition to the file output. Apply the same fix to the other affected test
methods referenced in the comment.

In `@src/Refitter.Tests/MsBuildFileWriterTests.cs`:
- Around line 37-56: The test
WriteAsync_Does_Not_Throw_When_Directory_Already_Exists only verifies that the
file exists after calling writer.WriteAsync, but does not verify that the
content was actually written correctly. Add an assertion after the File.Exists
check that reads the file content and asserts it matches the content provided to
the PlannedFile constructor (which is "// test"). This will catch regressions
where the file is created but left empty or with partial/incorrect content.
- Around line 13-17: Replace the `var` keyword with explicit types in test local
variables to align with repository C# style guidelines that discourage the use
of `var`. For the workspace variable declaration that uses Path.Combine, replace
`var` with `string` since Path.Combine returns a string type. Apply this same
change to all other test local variables using `var` throughout the
MsBuildFileWriterTests class to maintain consistent coding style.

In `@src/Refitter.Tests/SourceGeneratorFileWriterTests.cs`:
- Around line 12-22: Replace all `var` keyword declarations with explicit types
in the test method locals throughout the SourceGeneratorFileWriterTests class to
comply with repository C# style guidelines. In the shown diff block, replace
`var` with the explicit types for workspace (string), writer
(SourceGeneratorFileWriter), filePath (string), and planned (PlannedFile). Also
apply the same change to the additional instances mentioned in lines 39-52 and
71-84 to ensure consistency across the entire test file.

In `@src/Refitter/CliFileWriter.cs`:
- Line 10: The private field `_reporter` in the CliFileWriter class violates the
repository's naming convention which requires private fields to use camelCase
without underscore prefix. Rename the field declaration `_reporter` to
`reporter` and update all references to this field throughout the CliFileWriter
class to use the new name without the underscore prefix.
- Line 26: Replace the `var` keyword on line 26 where the `dir` variable is
declared with its explicit type `string`. The variable `dir` is assigned the
result of Path.GetDirectoryName which returns a string, so change `var dir =
Path.GetDirectoryName(file.Path);` to use the explicit type declaration instead
of the implicit var keyword to comply with the repository's C# style guidelines
that discourage use of var.

In `@src/Refitter/GenerationOrchestrator.cs`:
- Line 10: The private field _planner violates the repository's naming
conventions by using an underscore prefix. Rename this field from _planner to
planner (using camelCase without the underscore prefix) in the
GenerationOrchestrator class. Ensure all references to this field throughout the
class are updated to use the new name without the underscore.
- Around line 61-65: Replace the `var` keyword with explicit types in local
variable declarations throughout the file to comply with repository C# style
guidelines. Specifically, change `var writer = new CliFileWriter(reporter)` to
use the explicit type `CliFileWriter` instead of `var`, and apply the same
pattern to any other `var` declarations found in the line ranges mentioned
(121-136, 151-159). Always use the explicit type name on the right side of the
assignment for all local variable declarations rather than relying on type
inference with `var`.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 48adf978-11f2-4fd3-a458-a61b8eba28ba

📥 Commits

Reviewing files that changed from the base of the PR and between 821a8ac and 4bd4c14.

📒 Files selected for processing (14)
  • src/Refitter.Core/Abstractions/IFileWriter.cs
  • src/Refitter.Core/Abstractions/IOutputPlanner.cs
  • src/Refitter.Core/Abstractions/OutputPlannerAdapter.cs
  • src/Refitter.Core/Abstractions/SourceGeneratorFileWriter.cs
  • src/Refitter.MSBuild/MsBuildFileWriter.cs
  • src/Refitter.MSBuild/RefitterGenerateTask.cs
  • src/Refitter.SourceGenerator/Refitter.SourceGenerator.csproj
  • src/Refitter.SourceGenerator/RefitterSourceGenerator.cs
  • src/Refitter.Tests/CliFileWriterTests.cs
  • src/Refitter.Tests/MsBuildFileWriterTests.cs
  • src/Refitter.Tests/OutputPlannerAdapterTests.cs
  • src/Refitter.Tests/SourceGeneratorFileWriterTests.cs
  • src/Refitter/CliFileWriter.cs
  • src/Refitter/GenerationOrchestrator.cs

Comment thread src/Refitter.SourceGenerator/RefitterSourceGenerator.cs Outdated
Comment thread src/Refitter.Tests/SourceGeneratorFileWriterTests.cs
Comment thread src/Refitter/GenerationOrchestrator.cs
Comment thread src/Refitter/GenerationOrchestrator.cs Outdated
@christianhelle christianhelle changed the title feat: separate output planning from writing (PRD-003) Separate output planning from writing Jun 20, 2026
@christianhelle christianhelle self-assigned this Jun 20, 2026
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 3 file(s) based on 4 unresolved review comments.

Files modified:

  • src/Refitter.SourceGenerator/RefitterSourceGenerator.cs
  • src/Refitter.Tests/SourceGeneratorFileWriterTests.cs
  • src/Refitter/GenerationOrchestrator.cs

Commit: 980ee86dd2818ecaad114e205ea1a61506792fcb

The changes have been pushed to the refactor-output-planning-and-writing branch.

Time taken: 3m 44s

Fixed 3 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@christianhelle
christianhelle merged commit 2b3c3d7 into main Jun 20, 2026
12 of 14 checks passed
@christianhelle
christianhelle deleted the refactor-output-planning-and-writing branch June 20, 2026 19:15
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant