-
Notifications
You must be signed in to change notification settings - Fork 117
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
Add ability to load in extensions to packwerk #245
Conversation
@@ -275,3 +276,16 @@ Above is an example of a constant violation entry in `deprecated_references.yml` | |||
* `components/merchant/app/public/merchant/generate_order.rb` - path to the file containing the violated constant | |||
|
|||
Violations exist within the package that makes a violating reference. This means privacy violations of your package can be found listed in `deprecated_references.yml` files in the packages with the reference to a private constant. | |||
|
|||
# Loading Extensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Later, when we support offenses formatter, checkers, and parsers to be configured using a consistent API, we can add more information about how to configure these within this section.
efa1e25
to
53c259e
Compare
8c0691f
to
539950d
Compare
Applied your suggestions @gmcgibbon ! Thank you for using the suggestions feature – made it really easy to respond to code review 🙏 |
@@ -0,0 +1,2 @@ | |||
module MySpecialExtension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module MySpecialExtension | |
module MyLocalExtension |
I would also rename the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed!
refute defined?(MySpecialExtension) | ||
Configuration.from_path | ||
assert defined?(MySpecialExtension) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
end | |
ensure | |
Object.send(:remove_const, :MyLocalExtension) if defined?(MyLocalExtension) | |
end |
You need to clean up globals after the test is ran to make it not have side effects for other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Thank you.
@@ -49,6 +49,12 @@ def initialize(configs = {}, config_path: nil) | |||
@cache_directory = Pathname.new(configs["cache_directory"] || "tmp/cache/packwerk") | |||
@config_path = config_path | |||
|
|||
if configs.key?("require") | |||
configs["require"].each do |require_directive| | |||
ExtensionLoader.load(require_directive, @root_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to understand why we need a module to do this. Why can't we just use require
and assume relative paths are from the current working directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't necessarily need a module – I just wanted to encapsulate its logic into one place. I made it a private module with private_constant
. I also thought that it could potentially expand, so wanted to make room for that.
Let me know if you'd prefer to inline as private methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. You've changed my mind, this is worth keeping.
lib/packwerk/extension_loader.rb
Outdated
module Packwerk | ||
# This class handles loading extensions to packwerk using the `require` directive | ||
# in the `packwerk.yml` configuration. | ||
class ExtensionLoader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class ExtensionLoader | |
module ExtensionLoader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change!
test/unit/configuration_test.rb
Outdated
use_template(:skeleton) | ||
|
||
required_things = [] | ||
require_method = ->(required_thing) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require_method = ->(required_thing) do | |
mock_require_method = ->(required_thing) do |
You could technically just check $LOADED_FEATURES
, but I think is is cleaner 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed!
b7882b8
to
5a334c8
Compare
5a334c8
to
925e147
Compare
test/fixtures/skeleton/packwerk.yml
Outdated
@@ -4,3 +4,6 @@ include: | |||
exclude: | |||
- "**/temp.rb" | |||
parallel: false | |||
require: | |||
- ./config/my_local_extension.rb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- ./config/my_local_extension.rb | |
- ./config/my_local_extension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, changed
test/fixtures/skeleton/packwerk.yml
Outdated
@@ -4,3 +4,6 @@ include: | |||
exclude: | |||
- "**/temp.rb" | |||
parallel: false | |||
require: | |||
- ./config/my_local_extension.rb | |||
- pathname |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- pathname | |
- my_gem_extension |
Personally I think this would make more sense, but it breaks existing tests I think. This probably means we should make a new fixture since I wouldn't expect the skeleton / barebones fixture to reference extensions. Let's do this before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I agree. I'll make a new fixture.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmcgibbon You approved this already, but I just want to double check that my change is what you had in mind. I created a new fixture extended
which let me better colocate test concerns related to extending packwerk.
Let me know if you're still good with it, in which case I'll squash the commits and merge in the PR.
4da8f4e
to
353f217
Compare
353f217
to
bd1c27b
Compare
Commits
What are you trying to accomplish?
As packwerk enables more types of configuration, we need an easy to use and consistent experience for clients trying to extend packwerk. We have three things that we want to be able to extend:
Ideally, the user can use a consistent pattern to define their extensions, such as defining a method that inherits a packwerk Sorbet interface. Regardless of what that interface is (this PR does not decide that), the user will need a way to have that code load when
packwerk
is executed. This PR creates this ability by requiring files as determined by the user inpackwerk.yml
.What approach did you choose and why?
Since
packwerk
is a static analysis tool, we usedrubocop
as inspiration for this API:https://docs.rubocop.org/rubocop/extensions.html#loading-extensions
What should reviewers focus on?
Let me know if there's another approach that makes more sense to you!
Type of Change
Checklist