Skip to content

[FEATURE] Add a virtual CodeFormatRule to stop silently swallowing formatting-only changes#430

Open
chrissonntag wants to merge 9 commits into
andreaswolf:mainfrom
chrissonntag:feature/code-format-rule
Open

[FEATURE] Add a virtual CodeFormatRule to stop silently swallowing formatting-only changes#430
chrissonntag wants to merge 9 commits into
andreaswolf:mainfrom
chrissonntag:feature/code-format-rule

Conversation

@chrissonntag

Copy link
Copy Markdown
Contributor

This PR adds a virtual CodeFormatRule so that formatting-only changes (a pure reformat, or reindentation riding along with a real rule) finally get counted, surfaced in the report, and factored into the dry-run exit code — instead of Fractor silently rewriting files with nobody the wiser. And by the way, it also fixes #427.

CodeFormatRule isn't a registrable rule, just a marker AppliedRule knows about (codeFormat() / isCodeFormat()). FractorRunner attaches it when no real rule ran or the normalized baseline differs from the raw input. In the console, a formatting-only file skips the diff dump and shows a ~ reformatted / normalized one-liner plus CodeFormatRule under "Applied rules"; real rule changes render as before.

Also includes a small YAML fix (re-dump the original as baseline so the diff shows only the rule's change; skip re-dumping for formatting alone, since the dumper drops comments) and ProcessResult coverage for every reformatting format — composer.json, TypoScript, XML, XLIFF, YAML — plus core CodeFormatRule/AppliedRule tests.

- Add a CodeFormatRule label to AppliedRule (constant, factory, predicate)
  to represent a formatting-only change that has no backing rule class
- Type the identifier precisely as class-string<FractorRule>|CodeFormatRule
  wherever it flows, and let the changelog extractor tolerate the label
  instead of reflecting on it as a real class
- Count the label in the process result so a formatting-only change is
  reported and affects the dry-run exit code
- Add the CodeFormatRule to a file's applied rules whenever a processor
  changed it without attributing a real rule, or normalized the baseline,
  so a formatting-only reformat is reported and affects the exit code
- Prove the runner attribution independently of any real processor with a
  plain-text fixture processor test
- Print "~ reformatted / normalized" for files whose only applied rule is
  the CodeFormatRule, instead of dumping a whole-file or empty diff
- Assert a pure XLIFF reformat is attributed to the CodeFormatRule, a real
  rule change to its own rule, and both when they occur together
- Assert the same CodeFormatRule attribution for the XML processor, which
  also reports a rule change and reformatting together
- Assert a pure TypoScript reformat is attributed to the CodeFormatRule
  while a rule change stays attributed to its own rule
- Re-print composer.json on every run so a formatting-only change (indentation)
  is reported instead of applied silently; the runner attributes it to the
  virtual CodeFormatRule
- Keep a real rule attributed to itself; JSON has no comments, so the re-print
  round-trip preserves content
- Cover the behaviour with a ComposerJsonProcessResult test (rule change,
  pure reformat, and an already-formatted no-op)
@chrissonntag
chrissonntag force-pushed the feature/code-format-rule branch from e7a6626 to 85b9714 Compare July 17, 2026 14:28
- On a file a rule changes, use the re-dumped original as the diff baseline so
  the reported diff shows only the rule's change, and attribute the extra
  reformatting (indentation, comments the YAML dumper cannot keep) to the
  virtual CodeFormatRule
- Leave files no rule touches byte-exact: never re-dump for formatting alone, so
  comment-only files are not rewritten project-wide
- Cover the behaviour with a YamlProcessResult test (rule only, rule plus
  reformat, and a commented file left untouched)
- The YAML processor now attributes the virtual CodeFormatRule to a rule-rewritten
  file and reports the diff against a normalized baseline; update the e2e golden
  CLI output to match
@chrissonntag
chrissonntag force-pushed the feature/code-format-rule branch from 85b9714 to ea69980 Compare July 17, 2026 14:34


[OK] 1 file has been changed by Fractor
[OK] 1 file has been changed by Fractor

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm wondering about the extra whitespace at the end here where it comes from and why it is not trimmed as before

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Those are coming from the symfony output and are technically always present in the console. I can only assume that the whitespaces had been trimmed by ones IDE in the past and therefore were formerly missing. They don't really matter and are only of cosmetic nature. We can savely remove them if you like to.

- bar@domain.com: 'Bar'
+ foo@domain.com: Bar
+ bar@domain.com: Bar
bar@domain.com: Bar

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why is there a diff?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The YAML processor now diffs against a normalized baseline (the re-dumped original) instead of the raw source. Previously the diff was raw: 'Bar' against 'Bar'. After our change we diff against Bar without quotes. That's why the expected-output.txt had to change.

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.

[BUG] dry-run don't return error code when changes are found in xlf files

2 participants