Migrate onto ktsu.CodeBlocker 1.3.0 and retire the line-ending rewrite - #190
Conversation
The C# syntax template model moved to ktsu.CodeBlocker 1.3.0, so the local copy
under Templates/ goes away and the generators describe their output with the
package's model instead.
The migration is mostly mechanical - the collection properties are read-only
now, so object initializers use collection-initializer syntax, and a type's
declaration keyword comes from ClassTemplate.Kind rather than from free text in
Keywords. WithComments and WithInterfaces cover the few call sites that hold a
prebuilt sequence, which a read-only property cannot be assigned. TypeKind needs
a using alias because Microsoft.CodeAnalysis declares one too.
One substantive change: every BodyFactory used to write a leading space (" =>
Create(...)") because the old model spliced the body raw with no separator. The
package model supplies that separator itself, so the leading space became a
double space in the output and is removed at all 16 sites.
The committed output under Semantics.Quantities/Generated/ changes across 181
files, and all of it is the model doing its job:
-internal static class ConversionConstants{
+internal static class ConversionConstants
+{
Types now open their brace on its own line and close with "}" instead of "};",
members are separated by a blank line, and doc comments sit at the member's
indent instead of at column zero - the previous output had every "/// <summary>"
flush against the left margin directly after the preceding member.
PropertyTemplateTests is deleted rather than ported: it covered the local
PropertyTemplate, and ktsu.CodeBlocker now carries far better coverage of the
same behaviour, including the accessor cases this model could not express.
WriteFileHeader and WriteSourceFile go back to protected - they were narrowed to
private protected only because SourceFileTemplate was local, and it is public in
the package.
Test suite: 1015 passed, 92 failed - the same 92 Windows-path tests that fail on
main under Linux. The -4 against the previous run is exactly the deleted
PropertyTemplateTests.
Closes #187
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sagQjzFv3cnFNM3G271TJ
…inor] GeneratedSource existed only to rewrite every line ending after the fact, because IndentedTextWriter uses Environment.NewLine and committed generator output has to be byte-identical wherever it was produced. ktsu.CodeBlocker 1.3.0 lets the terminator be pinned at construction, so the rewrite is unnecessary and the type is gone; GeneratedSource.Add was a normalization wrapper, so call sites use context.AddSource directly. It is pinned to LF, not CRLF. The pass being removed rewrote everything to CRLF on the grounds - stated in its own comment - that .editorconfig said end_of_line = crlf and .gitattributes said *.cs text eol=crlf. Neither is true any more: the LF migration in #157 changed them to end_of_line = lf and * text=auto eol=lf, and nothing updated the generator. Git had been quietly normalising the difference on every commit ever since - the stored blobs are LF while every working tree carried CRLF, which is where the permanent "CRLF will be replaced by LF" warnings came from. So the generated files are byte-identical as stored (a plain git diff over Generated/ is empty), and now the working tree matches the repository instead of disagreeing with it. That also removes the reason verify-generated ran on windows-latest, which its comment gave as matching git's autocrlf to the committed CRLF. It runs on ubuntu-latest now; the alias-props step uses pwsh, which Linux runners have. Test suite unchanged: 1015 passed, 92 failed - the same Windows-path tests that fail on main under Linux. Closes #184 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sagQjzFv3cnFNM3G271TJ
|
| count | |
|---|---|
main @ 3b40272 (run) |
❌ 92 failed, 1006 passed |
this PR @ 55f4f4b (run) |
❌ 92 failed, 1015 passed |
Identical failure count, and identical to what I measured locally before pushing. All 92 are Semantics.Paths tests that assume Windows path semantics — drive letters, \ separators, the 259-character limit — and they have been red on main since 8b9df02 added Linux to the test matrix. Test on windows-latest is unaffected.
The total drops from 1112 to 1108 because this PR deletes PropertyTemplateTests: it covered the local PropertyTemplate, which has moved to ktsu.CodeBlocker along with much broader coverage of the same behaviour. 1015 = 1019 − 4 accounts for it exactly, so no test that was passing has stopped.
Not fixing it here — no fix exists to port, and reworking the path suite's platform assumptions across ~a dozen files is unrelated to this change and would bury the diff. The shape of that fix is written up in my comment on #188; it wants its own issue. Not re-running the job: it reproduces identically and is already reproduced on main.
Worth noting from this run: Generated files up to date passed on ubuntu-latest
That job moved off windows-latest in this PR, and this is its first Linux run. Passing confirms both halves of #184 at once — the generators' LF pin agrees with * text=auto eol=lf, and the drift gate no longer depends on the runner's autocrlf. Had the CRLF-vs-LF reading been wrong, this is precisely the check that would have caught it.
Generated by Claude Code
The last two tasks of #181, now that ktsu-dev/CodeBlocker#87 has merged and published
ktsu.CodeBlocker1.3.0.Closes #184, closes #187. That completes the epic's task list except the still-open question of where the Roslyn-side toolkit finally lives.
Emit through the package's template model (#187)
The local
Templates/copy is gone; the generators describe their output withktsu.CodeBlocker.Templates.Mostly mechanical — the collection properties are read-only, so object initializers use collection-initializer syntax, and a type's declaration keyword comes from
ClassTemplate.Kindrather than free text inKeywords.WithComments/WithInterfacescover the few call sites holding a prebuilt sequence.TypeKindneeds a using alias becauseMicrosoft.CodeAnalysisdeclares one too.One substantive change: every
BodyFactorywrote a leading space (" => Create(...)") because the old model spliced the body raw with no separator. The package model supplies that separator itself, so the leading space became a double space in the output — removed at all 16 sites.The output diff is large, and all of it is the model doing its job
181 files change. Representative:
Types open their brace on its own line and close with
}instead of};; members are separated by a blank line; and doc comments sit at the member's indent rather than flush against column zero, which is where every/// <summary>after the first member used to land.PropertyTemplateTestsis deleted rather than ported — it covered the localPropertyTemplate, andktsu.CodeBlockernow has much broader coverage of the same behaviour, including accessor cases this model could not express.WriteFileHeader/WriteSourceFilego back toprotected; they were narrowed only becauseSourceFileTemplatewas local.Pin the terminator, drop the rewrite (#184)
GeneratedSourceexisted only to rewrite every line ending after the fact, becauseIndentedTextWriterusesEnvironment.NewLineand committed output has to be byte-identical wherever it was produced. 1.3.0 lets the terminator be pinned at construction, so the rewrite is unnecessary and the type is gone.It is pinned to LF, not CRLF — the old pass was working from a stale premise. Its own comment justified CRLF on the grounds that
.editorconfigsaidend_of_line = crlfand.gitattributessaid*.cs text eol=crlf. Neither has been true since the LF migration in #157 changed them toend_of_line = lfand* text=auto eol=lf, and nothing updated the generator. Git had been quietly normalising the difference on every commit ever since:That mismatch is the source of the permanent
CRLF will be replaced by LFwarnings anyone touching this repo sees. So the generated files are byte-identical as stored — a plaingit diffoverGenerated/is empty — and the working tree now agrees with the repository instead of contradicting it.That also removes the reason
verify-generatedran onwindows-latest, which its comment gave as matching git's autocrlf to the committed CRLF. It runs onubuntu-latestnow; the alias-props step usespwsh, which Linux runners have. I verified the gate's actual command (git diff --exit-code) passes on Linux.Verification
git diffoverSemantics.Quantities/Generated/is empty after a clean rebuild — the drift gate's own check, run on Linux.1015 passed, 92 failed. The 92 are the same Windows-path tests that fail onmainunder Linux (see the analysis in Shape the generator infrastructure for extraction #188); the −4 against the previous run is exactly the deletedPropertyTemplateTests.EnforceCodeStyleInBuildon, so the IDE rules that only surface in CI are clean.Notes for the reviewer
Directory.Packages.propskeeps Roslyn at 5.9.0 (this container's SDK ships 5.0 and cannot load the generator otherwise), and thektsu.Sdk.Analyzersdrop is a command-line flag. That means the KTSU rules did not run locally — worth a glance at the first CI result.CLAUDE.mdanddocs/physics-generator.mdgain the template-model conventions:Kindsupplies the declaration keyword, collections use collection-initializer syntax, and aBodyFactorymust not prefix its expression body with a space.Generated by Claude Code