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

Auto import Nextcloud classes in rector runs #48371

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

come-nc
Copy link
Contributor

@come-nc come-nc commented Sep 26, 2024

Summary

When using rector, fully qualified names are often outputted by the rules, like \OCP\Server or \OCP\Http\Client\IClientService. To avoid that, one can use withImportNames() to tell rector to import names with use statements, but then it will import all names.

This is not always desirable, for instance \LDAP\Connection in user_ldap would be confusing because there is an \OCA\User_LDAP\Connection class as well.

So I added a custom "SkipVoter" which skips auto-import for all classes outside of OC/OCA/OCP.

It may still be a bit confusing for common names like IManager, but I think we can live with that? Or I can add other exceptions if needed.
Note that rector is smart enough to not import two classes with the same name, but it will randomly import one of them and keep the fully qualified name for the other one.

I’m doing that so that when we apply Nextcloud rules set later we do not get fully qualified names everywhere but nice use statements instead.

Checklist

We skip all files outside of OC/OCA/OCP from "use" auto-import because
 it’s not always desirable to import classes when they have generic
 names, so it should be the developer choice.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
@come-nc come-nc added the 3. to review Waiting for reviews label Sep 26, 2024
@come-nc come-nc added this to the Nextcloud 31 milestone Sep 26, 2024
@come-nc come-nc self-assigned this Sep 26, 2024
Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

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

Psalm found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Copy link
Member

@provokateurin provokateurin left a comment

Choose a reason for hiding this comment

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

I'm not sure if I like it. In quite a few places it is nice to use the fqn to avoid mistakes.
Then there is also the case when two classes have the same name where I would actually prefer that both use the fqn and not one fqn and one import.


$nextcloudDir = dirname(__DIR__);

class NextcloudNamespaceSkipVoter implements ClassNameImportSkipVoterInterface {
Copy link
Member

Choose a reason for hiding this comment

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

This should go into nextcloud/rector then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could, yeah.
The thing is we cannot make it configurable, because it’s added as a service by class name only.
But if it stays general like this we can put in nextcloud/rector, yes. Also we can make it extendable with a protected property to override if needed.

@come-nc
Copy link
Contributor Author

come-nc commented Sep 26, 2024

In quite a few places it is nice to use the fqn to avoid mistakes.

Do you have examples in mind so that we can look if there is a pattern we could apply?

Then there is also the case when two classes have the same name where I would actually prefer that both use the fqn and not one fqn and one import.

That is quite hard to implement I think. The SkipVoter which avoid use conflict is based on the already imported use list: https://github.com/rectorphp/rector/blob/main/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/UsesClassNameImportSkipVoter.php
Doing the same thing without even adding the first use would require collecting all shortnames from the file before deciding whether to import them or not.

Comment on lines -96 to +103
$server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class), \OC::$server->get(DefaultCalendarValidator::class)));
$server->addPlugin(new Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class), \OC::$server->get(DefaultCalendarValidator::class)));
Copy link
Member

Choose a reason for hiding this comment

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

For example here it would be better to use the fqn as Plugin is a very generic name.

Same thing goes for the IManager classes. For those it would be nice to either use the fqn or at least the part before that so it is Group\IManager and so on.

Maybe this is not so bad, but to me it seems harder to read the code and easier to make mistakes when changing imports.

@provokateurin
Copy link
Member

Could we maybe limit this to a few classes like \OCP\Server and \OCP\Util for now? I don't know how many other cases we have where this happens a lot.

@come-nc
Copy link
Contributor Author

come-nc commented Sep 26, 2024

Could we maybe limit this to a few classes like \OCP\Server and \OCP\Util for now? I don't know how many other cases we have where this happens a lot.

My problem is this rule set: https://github.com/nextcloud-libraries/rector/blob/8061985c44798bac1657ba5bc2d6efa5b10e9089/config/nextcloud-25/nextcloud-25-deprecations.php#L17
Without withImportNames it will use fully qualified name for all Server::get() calls and that’s ugly.
I can try again a solution like https://github.com/nextcloud-libraries/rector/pull/11/files to instead make our rules add stuff to the use statements independantly of withImportNames. I failed before but I have a better understanding of rector internals now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review Waiting for reviews
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants