mozart icon indicating copy to clipboard operation
mozart copied to clipboard

Exclude certain FQCN prefixes

Open XedinUnknown opened this issue 5 years ago • 8 comments

We are looking for a solution that would scope our code in the manner that this tool does it in. However, one requirement is that interoperability is still maintained via interop interfaces, such as PSRs.

Is it possible to exclude certain FQCNs or FQCN prefixes from the transformation done by this tool? And if so, how?

cc @widoz.

XedinUnknown avatar Aug 19 '19 08:08 XedinUnknown

I get this, absolutely. This is not possible right now, but has been on my radar for a while. If you have ideas on how this should be implemented, I am all ears. :)

coenjacobs avatar Aug 19 '19 11:08 coenjacobs

Great, I'm happy that you agree!

What kind of suggestions are you looking for exactly? I'm not familiar with how Mozart works at all in terms of code.

XedinUnknown avatar Aug 22 '19 07:08 XedinUnknown

Given we have the configuration array in the composer.json extra settings, we can probably use that to specify what (partial) FCQN you'd want to exclude. I consider these kind of exclusions to be advanced settings, so I don't mind having developers to custom setup these in some sort of array form in their composer.json file.

That is only half of the solution though, the entire search and replace logic needs to take these exclusions into account as well. Can you explain a little bit more about your specific use case for this issue, so that I can properly determine what needs to be done and also to make it available as a solution to as many related use cases as possible?

coenjacobs avatar Sep 02 '19 06:09 coenjacobs

Yep!

Our company develops enterprize-grade WordPress plugins. Like any sane developers, we want to standardize development workflow, which includes using the same packages in our plugins, as well as those plugins' extensions. But you know how it goes when there isn't a dependency management tool responsible for installing these things, which is the case in WordPress. In other words, we cannot use the amazing fruit of the open-source community because our plugins will start conflicting with other plugins that use the same packages, which most embarrassingly includes our plugins too. Therefore, we would like to "scope" this 3rd-party code to each of our projects, thus avoiding the namespace collision and the chaos that comes with it.

The problem is that, like other sane developers, we depend on 3rd party interfaces that provide an interoperability layer between the components of our software. Such interfaces include PSR interfaces, as well as other interfaces written by us and other open-source contributors. These interfaces are vendor code as well. So, if we run your tool indiscriminately on all of the vendor code, these interfaces will be scoped as well, which defeats the purpose and the means of the abstraction they facilitate. Therefore, in order to be able to use a tool such as yours, we would need to be able to make such interfaces exempt from being processed by your tool. The FQCNidentified as such would not be altered anywhere in the code.

IMHO the easiest and most flexible way of achieving this would be to provide exclusion rules, which would identify a part of or a whole FQCN. The rules could follow a similar convention to that of autoloading prefix rule, in that it must end with \ to avoid false positive matches. In addition, the rules could allows specifying a whole FQCN, by perhaps not putting \ at the end, e.g. anything that doesn't end with \ would be considered a full FQCN, while rules ending with \ would indicate a namespace prefix.

I hope the above explanation and suggestions are understandable. Please let me know if there are any other questions. I would be up for discussing this further, even synchronously.

Thanks!

XedinUnknown avatar Sep 02 '19 10:09 XedinUnknown

Oh, just thought about something else. The convention with \ vs no \ might not work with PSR-0, because in it pseudo-namespaces are separated by _. Then again, I don't know if you want to support PSR-0. If you do, maybe a wildcard syntax would be better.

XedinUnknown avatar Sep 02 '19 10:09 XedinUnknown

So, I had a look at the code. Looks like the Replacer receives configuration from the command, which is all of the root package's config. Presumably, this will contain the exclusion rules. The Replacer class in turn creates the instance of the Replacer interface (confusing, but I used links), and thus can just as well pass down that config. Finally, that, perhaps in the RegEx callback, can compare the namespace to the config, and decide whether to perform the actual replacement on the namespace, or to leave it alone.

What do you think?

XedinUnknown avatar Sep 10 '19 11:09 XedinUnknown

I'm submitting a PR to solve this issue. I enabled to added entry namespaces_to_skip under mozart.extra to define a list of namespace starters that will be skipped from being namespaced.

For instance, my project has namespace "PoP\MyProject", so all namespaces starting with "PoP\" (not just MyProject but also its dependencies to other projects of mine, also owned by PoP\) will not be namespaced:

"mozart": {
    "packages": [
        "pop/my-project"
    ],
    "namespaces_to_skip": [
        "PoP\\"
    ]
}

leoloso avatar Feb 06 '20 07:02 leoloso

sorry if this is a totally daft question...

but is FCQN supposed to be FQCN? ie: Fully Qualified Class Name

or is FCQN something else?

tn3rb avatar Apr 26 '23 18:04 tn3rb