-
Notifications
You must be signed in to change notification settings - Fork 116
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
Packwerk doesn't support custom root namespaces for root directories in the load path #186
Comments
Just to be clear, if there is no opposition to this change (which shouldn't affect anyone except those using the esoteric |
I think this generally makes sense. I'm curious to see what the implementation would look like, but I don't expect any blockers there. It looks like the bulk of the implementation for this would live in I'd also be curious to hear what @rafaelfranca and @alexevanczuk think about this change, in case I'm missing something. My impression is that this adds a small amount of complexity, in a pretty contained fashion--I don't expect many additions to |
I'm ok with this change, we already require Zeitwerk to be used in the application in order to Packwerk to check. |
Agreed – my understanding is this is all about making sure that we can properly identify the file path where a constant is defined, and part of doing so is making sure that Quick question... is there any reason we don't just ask |
We investigated that in the beginning, but for zeitwerk determining the location of a constant involves loading constants. IIRC, to resolve My memory is a little fuzzy but the takeaway is that for zeitwerk, resolving constants involves loading constants, and we deemed that to be too slow, especially seeing as loading one constant can create a whole cascade of other constants to load. |
In Zeitwerk, the load path is list of directories that it calls "root directories". They are "root" because any files that reside in them are expected to represent modules that are part of the root namespace. If an object is nested in some more specific namespace, it needs to be placed in a subdirectory of one of these roots. For example, in the following,
lib
is a "root directory" with the following structure and the ruby files have the noted expected constants:The thing is, Zeitwerk also supports setting a "default namespace" to each root directory via
push_dir
which is called when the Zeitwerk loader is being configured. So in the above, it was assumedlib
was added to the loader vialoader.push_dir("lib")
but it could also be added withloader.push_dir("lib", MyCompany)
which means the constants inside would be expected to be declared asMyCompany::MyNamespace::MyFile
andMyCompany::MyOtherFile
.At GitHub we rely on this feature to work around some extremely legacy directories in our load path that do not conform to Zeitwerk's expectations. Up until now, we have worked around them in Packwerk by skipping some and "hacking" at others. At this point, we'd like to just add support for custom namespaces to Packwerk so we can be confident in Packwerk's operation.
While I haven't dived into the Packwerk's source for this yet, I suspect this would mean moving
Packwerk::ApplicationLoadPaths
fromconfig.autoload_paths
,eager_load_paths
, andautoload_once_paths
toRails.autoloaders
to get our list of root directories as a hash of paths to modules. By default, these modules would all just beObject
as they are in Zeitwerk, but it would allow us to override that default as needed for certain paths.I realize this would also necessitate a change to
ConstantResolver
as well and have a WIP branch here. This branch uses strings instead of module instances for the namespaces in order to keep us as disentangled from a dependency standpoint as possible.While I realize this is a change that is probably not needed for most codebases, I think that improving Packwerk's support for Zeitwerk's configuration is overall a positive.
So at this point, before I go ahead with a PR for Packwerk, what do folks think about adding such support?
The text was updated successfully, but these errors were encountered: