Skip to content

[ChangesReporting] List only changed files in JSON changed_files - #8917

Open
gvieira18 wants to merge 2 commits into
rectorphp:mainfrom
gvieira18:fix/json-changed-files-has-changed-flag
Open

gvieira18 wants to merge 2 commits into
rectorphp:mainfrom
gvieira18:fix/json-changed-files-has-changed-flag

Conversation

@gvieira18

Copy link
Copy Markdown

With --output-format=json, the changed_files list can contain files that Rector did not change, while totals.changed_files counts only the real changes. The e2e applied-no-diffs-format-json of this PR, on main:

{
    "totals": {
        "changed_files": 1,
        "errors": 0
    },
    "changed_files": [
        "src/AliasedSameShortName.php",
        "src/AnonymousClassDocblock.php",
        "src/RemoveAlwaysElse.php",
        "src/global_class_constant_twice_without_namespace.php",
        "src/global_class_new_twice_without_namespace.php",
        "src/global_class_type_twice_without_namespace.php"
    ]
}

Only the file src/RemoveAlwaysElse.php should be changed.

A tool or a CI script that reads the list sees changes that do not exist. In a project I work on, a cold --dry-run with withImportNames() lists 92 files with totals.changed_files: 0. See rectorphp/rector#9911 for the same result on symfony/symfony and Sylius.

Cause

A rule or a post rector can record a line change and print identical code. FileProcessor then creates a FileDiff with an empty diff. This is on purpose (#6794): AbstractRectorTestCase uses it to warn about a rule that changes nothing. JsonOutputFactory lists every FileDiff, because with --no-diffs every diff is empty and the real changes must stay in the list (#7821).

The name importing post rectors cause it in different branches of their code, for example:

  • a short name that is already in use, next to an aliased import with the same short name;
  • a global class used two or more times in a file without a namespace;
  • a fully qualified name in the docblock of an anonymous class.

A fix for one branch (#8512) leaves the others. This PR fixes the output instead, for all of them.

Change

Tests

  • JsonOutputFactoryTest: an unchanged FileDiff is not listed with --no-diffs.
  • FileDiffTest: the flag stays after the worker serialization.
  • e2e applied-no-diffs-format-json: importNames() plus one file for each case above (5 files). Without the fix, the changed_files list also contains these 5 files, which Rector does not change.

A FileDiff also records a rule that printed identical code. With
--no-diffs every diff is empty, so FileDiff carries the changed state.
Each file prints identical code but a name importing post rector
records a change, so the list must not contain it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants