Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "--only" option to process only a single rule #6441

Merged
merged 2 commits into from
Dec 10, 2024

Conversation

cweiske
Copy link
Contributor

@cweiske cweiske commented Nov 15, 2024

The option for the "process" and "list-rules" commands applies the single given rule only, without needing to modify the configuration file.

The option value must be a fully classified class name:

  --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

A hint is given when the user forgot to escape the backslashes.


It is impossible to modify the injected "$rectors" after the command line configuration is parsed, so I had to introduce the ConfigurationRuleFilter singleton.

Since both ListRulesCommand and ProcessCommand make use of the ConfigurationRuleFilter - but list-rules does not have a Configuration - I had to make the filterOnlyRule() method public to prevent code duplication.

Resolves rectorphp/rector#8899


Test it:

./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

./bin/rector list-rules --config=e2e/applied-rule-return-array-nodes/rector.php --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

@cweiske cweiske force-pushed the cli-option-only-rule branch from 985e2db to e5b3888 Compare November 15, 2024 16:13
@TomasVotruba
Copy link
Member

TomasVotruba commented Nov 15, 2024

There should be kind of e2e tests that passes and that fails if data are incorrect

@cweiske cweiske force-pushed the cli-option-only-rule branch from e5b3888 to 7de7a84 Compare November 19, 2024 09:32
@cweiske
Copy link
Contributor Author

cweiske commented Nov 19, 2024

I've added an end-to-end test that fails when e.g. the ConfigurationRuleFilter simply returns all rectors instead of filtering them.

I had to extend the e2eTestRunner to support additional command line options.

@samsonasik
Copy link
Member

Register new e2e path to

@cweiske cweiske force-pushed the cli-option-only-rule branch from 7de7a84 to 86e10d9 Compare November 19, 2024 09:51
@cweiske
Copy link
Contributor Author

cweiske commented Nov 19, 2024

e2e-test is registered.

@cweiske cweiske force-pushed the cli-option-only-rule branch from 86e10d9 to 19e7820 Compare November 25, 2024 06:59
@cweiske
Copy link
Contributor Author

cweiske commented Nov 25, 2024

Code is adjusted.
I also tested it in the windows cmd.exe, and it works:
2024-11-25 rector rule windows

@cweiske
Copy link
Contributor Author

cweiske commented Nov 25, 2024

Class name quoting on Linux

How to input backslashes in a terminal (bash)

Works

  • Double quotes + single backslash --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
  • Double quotes + double backslash --only="Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector"
  • Single quotes + single backslash --only='Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'
  • Single quotes + double backslashes --only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector' (fixed)
  • No quotes + double backslash --only=Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector
  • No equal sign between --only and rule name --only "Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only="Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector"
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only='Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector'
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only=Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only "Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

Does not work

  • No quotes + single backslashes --only=Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector
$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only=Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector

In OnlyRuleResolver.php line 46:
                                                                                        
  Rule "RectorDeadCodeRectorClassMethodRemoveUnusedPrivateMethodRector" was not found.  
  The rule has no namespace. Make sure to escape the backslashes, and add quotes around the rule name: --only="My\Rector\Rule"

Class name quoting on Windows

Standard cmd.exe shell

Works

  • Double quotes + single backslash --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"
  • Double quotes + double backslash --only="Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector"
  • Single quotes + single backslash --only='Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector' (fixed)
  • Single quotes + double backslashes --only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector' (fixed)
  • No quotes + single backslashes --only=Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector
  • No quotes + double backslash --only=Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector
  • No equal sign between --only and rule name --only "Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

@TomasVotruba
Copy link
Member

Rule "Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector" was not found.

This input should be handled to work, as we can narrow slashes to 1.

Rule "RectorDeadCodeRectorClassMethodRemoveUnusedPrivateMethodRector" was not found.

This input should make a not about slahes or quotes, to guide user to success.


These error were reasons to remove the old feature, so they should be covered now with helpful response 👍

@cweiske
Copy link
Contributor Author

cweiske commented Nov 25, 2024

This input should make a not about slahes or quotes, to guide user to success.

The error message consists of 2 lines:

Rule "RectorDeadCodeRectorClassMethodRemoveUnusedPrivateMethodRector" was not found.  
The rule has no namespace - make sure to escape the backslashes correctly.            

It mentions backslashes. How shall I phrase it better?

@samsonasik
Copy link
Member

is escapeshellarg($rule) can cover it?

@TomasVotruba
Copy link
Member

It mentions backslashes. How shall I phrase it better?

Ideally with copy paste response. The missing quotes are more helpful in this case, as slashes are correct.

@cweiske cweiske force-pushed the cli-option-only-rule branch from 19e7820 to 18de334 Compare November 25, 2024 12:49
@cweiske
Copy link
Contributor Author

cweiske commented Nov 25, 2024

I've adjusted the code and the tests:

  • Double backslashes are automatically converted to single backslashes (you get them when double-quoting backslashes while single-quoting the value: --only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector')
  • end-to-end-tests for different quoting styles with and without = between --only and the rule name.
  • Changed error message for the missing-namespaces problem:
    • note that I do not know the original CLI parameter with slashes, and cannot offer a copy-and-paste solution.
$ ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only=Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector

In OnlyRuleResolver.php line 49:
                                                                                                                                
  Rule "RectorDeadCodeRectorClassMethodRemoveUnusedPrivateMethodRector" was not found.                                          
  The rule has no namespace. Make sure to escape the backslashes, and add quotes around the rule name: --only="My\Rector\Rule"  

@cweiske cweiske force-pushed the cli-option-only-rule branch from 18de334 to acf0bb4 Compare November 25, 2024 13:26
@cweiske
Copy link
Contributor Author

cweiske commented Nov 25, 2024

I've tested all combinations on Windows (see comment above) and found that when using single quotes, the single quotes appear in the parameter value:

R:\>"c:\Program Files\php\php.exe" ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only='Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'

In OnlyRuleResolver.php line 49:

  Rule "'Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'" was not found.
  Make sure it is registered in your config or in one of the sets

R:\>"c:\Program Files\php\php.exe" ./bin/rector process --config=e2e/applied-rule-return-array-nodes/rector.php --dry-run --only='Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector'

In OnlyRuleResolver.php line 49:

  Rule "'Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector'" was not found.
  Make sure it is registered in your config or in one of the sets

So I've adjusted the code to remove them if necessary, and using single quotes on windows works now, too.

@cweiske cweiske force-pushed the cli-option-only-rule branch from acf0bb4 to 5849c7e Compare November 26, 2024 14:08
The option for the "process" and "list-rules" commands applies
the single given rule only, without needing to modify
the configuration file.

The option value must be a fully classified class name:

  --only="Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector"

A hint is given when the user forgot to escape the backslashes.

----

It is impossible to modify the injected "$rectors" after the
command line configuration is parsed, so I had to introduce the
ConfigurationRuleFilter singleton.

Since both ListRulesCommand and ProcessCommand make use of the
ConfigurationRuleFilter - but list-rules does not have a Configuration -
I had to make the filterOnlyRule() method public to prevent
code duplication.

Resolves rectorphp/rector#8899
.. but throw an exception if the name is ambiguous
@cweiske cweiske force-pushed the cli-option-only-rule branch from 5849c7e to 6ffbc3a Compare November 28, 2024 11:48
@cweiske
Copy link
Contributor Author

cweiske commented Nov 28, 2024

Anyone?

@cweiske
Copy link
Contributor Author

cweiske commented Nov 29, 2024

@TomasVotruba what do you say?

@cweiske cweiske requested a review from TomasVotruba December 2, 2024 12:44
@cweiske
Copy link
Contributor Author

cweiske commented Dec 10, 2024

@TomasVotruba Wouldn't this be nice to have in rector 2.0.0?

@TomasVotruba
Copy link
Member

TomasVotruba commented Dec 10, 2024

Thanks for the ping and your work. I'll look into this today and will merge 👍
It will land in 2.0 for sure

@TomasVotruba TomasVotruba self-assigned this Dec 10, 2024
@TomasVotruba TomasVotruba merged commit ebbada3 into rectorphp:main Dec 10, 2024
41 checks passed
@TomasVotruba
Copy link
Member

Very well done feature, thank you for your work @cweiske 👏

@cweiske cweiske deleted the cli-option-only-rule branch December 10, 2024 16:16
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.

Command line option to execute a single rule only
3 participants