-
Notifications
You must be signed in to change notification settings - Fork 119
Description
Description
This is similar to #47 , but there are some distinctions because we're discussing engines, which are autoloaded, vs gems that are not.
The context is that we have a mono-repo setup like this
root_dir
|- engine_1
|- engine_2
|- app_1
|- app_2
where multiple apps will use the same engines. Each engine is symlinked under an apps vendor directory like
root_dir/app_1/vendor/gems/engine_1 -> root_dir/engine_1`
We attempted to setup packwerk for a given app with a root_dir/app_1/packwerk.yml, with a root package at root_dir/app_1/package.yml and a package inside an engine like root_dir/engine_1/app/models/users/package.yml.
We found that we could properly setup the packwerk.yml include and package_paths to follow the symlinks inside of vendor and scan all the files both in the app folder, and in the engine folders, but it would never flag any violations.
In digging in, we found the problem was with the constant resolution workflow. Although the autoload paths for the engines were available in Rails.autoloaders, the path found there was root_dir/engine_1/** instead of root_dir/app_1/vendor/gems/engine_1. As a result it was being filtered out of the paths provided to the ConstantResolver by ApplicationLoadPaths.filter_relevant_paths
We experimented with monkey patching filter_relevant_paths to transform the path names for all these in-repo engines to use the full symlink path. When we did that, everything worked as expected.
I wanted to propose the idea that we upstream our patch by adding a new key to the packwerk.yml configuration file named something like load_path_aliases. This would take a hash where the keys would be the load_path as discovered in Rails.autoloaders and the value would be an alias that the path should be transformed to. Then we'd modify ApplicationLoadPaths to go through these aliases, and transform all the paths before passing them into ConstantResolver
Does this seem like a reasonable approach? If folks are open to it, I can put together a PR
To Reproduce
Setup a mono repo as described above. If folks would like a clearer example, I can setup a sample application.
Expected Behaviour
Under this proposal, a developer could a define a packwerk.yml with this new load_path_aliases something like this
load_path_aliases:
'../engine_1/': 'vendor/gems/engine_1/'
'../engine_2/': 'vendor/gems/engine_2'/
Then any paths that started with ../engine_1/ would be replaced with an equivalent starting with vendor/gems/engine_1
Version Information
- Packwerk: 2.2.0
- Ruby 2.75