Open XedinUnknown opened 5 years ago
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. :)
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.
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?
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!
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.
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?
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\\"
]
}
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?
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.