Skip to content
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

Allow OffensesFormatter to be configured via packwerk.yml and CLI flag #266

Merged
merged 1 commit into from
Nov 28, 2022

Conversation

alexevanczuk
Copy link
Contributor

@alexevanczuk alexevanczuk commented Nov 20, 2022

What are you trying to accomplish?

Today, packwerk supports a configurable OffensesFormatter. However, the only way to configure it is to load the CLI itself. This means that this feature is not usable if a user has run bundle binstubs packwerk. Instead, the user needs to copy exe/packwerk into their local bin/packwerk and pass in a different formatter to Packwerk::Cli.new.

This PR makes this more user-friendly by leveraging the extension system to load in a new formatter. This way, a user can use the vanilla packwerk binstub and load in their own offenses formatter more easily.

This was originally attempted here: #264
However, I believe both the implementation and the UX of this approach is better and more consistent.

What approach did you choose and why?

I chose to use the require directive in packwerk.yml to load in a formatter via a setting on Packwerk::Configuration. The system first prioritizes the local input variable, then the configuration, then the default.

I chose to use a similar approach as the Checker and Validator to keep things consistent. That is, by requiring a file that implements the interface, the extension is "loaded." Then to turn "on" the extension, the user needs to set it (via packwerk.yml).

What should reviewers focus on?

There are some subtle changes that I've pointed out via comments. Looking for feedback on it!

Type of Change

  • Bugfix
  • New feature
  • Non-breaking change (a change that doesn't alter functionality - i.e., code refactor, configs, etc.)

Additional Release Notes

  • Breaking change (fix or feature that would cause existing functionality to change)

You could definitely argue that this is a breaking change because I change the interface to OffensesFormatter. It now requires an identifier. I also removed the initialize method that passes in a style so that the formatters can be initialized consistently. Therefore those using the OffensesFormatter directly will experience a breaking API change.

Checklist

  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • It is safe to rollback this change.

USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/cli.rb Outdated Show resolved Hide resolved
@alexevanczuk alexevanczuk marked this pull request as ready for review November 21, 2022 14:01
@alexevanczuk alexevanczuk requested a review from a team as a code owner November 21, 2022 14:01
@alexevanczuk alexevanczuk changed the title Proof of concept for configurable formatters Allow OffensesFormatter to be configured via packwerk.yml Nov 21, 2022
USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/formatters/offenses_formatter_plain.rb Outdated Show resolved Hide resolved
USAGE.md Outdated Show resolved Hide resolved
USAGE.md Outdated Show resolved Hide resolved
USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/configuration.rb Outdated Show resolved Hide resolved
lib/packwerk/offenses_formatter.rb Outdated Show resolved Hide resolved
lib/packwerk/offenses_formatter.rb Outdated Show resolved Hide resolved
lib/packwerk/offenses_formatter.rb Outdated Show resolved Hide resolved
lib/packwerk/offenses_formatter.rb Show resolved Hide resolved
@alexevanczuk
Copy link
Contributor Author

@gmcgibbon I think I've addressed/responded to all of your feedback.

@alexevanczuk alexevanczuk changed the title Allow OffensesFormatter to be configured via packwerk.yml Allow OffensesFormatter to be configured via packwerk.yml and CLI Nov 22, 2022
@alexevanczuk alexevanczuk changed the title Allow OffensesFormatter to be configured via packwerk.yml and CLI Allow OffensesFormatter to be configured via packwerk.yml and CLI flag Nov 22, 2022
@alexevanczuk
Copy link
Contributor Author

@gmcgibbon I pushed a command line option, as I realized that without it, there is no path for a user to use different formatters in different options without modifying packwerk.yml, so it felt essential.

USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/offenses_formatter.rb Show resolved Hide resolved
USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/formatters/offenses_formatter.rb Outdated Show resolved Hide resolved
private

sig { void }
def load_default_formatter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't a need to referencer the constant if we require the offense formatter at the top of the file. If the formatter is only used when checking, maybe the best thing to do would be to do a runtime require "packwerk/formatters/offenses_formatter" in this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I like that! Definitely clearer that we're explicitly loading rather than loading through invoking auto load.

@@ -13,6 +13,11 @@ def setup_application_fixture
@old_working_dir = Dir.pwd
end

def remove_extensions
Object.send(:remove_const, :MyLocalExtension) if defined?(MyLocalExtension)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Object.send(:remove_const, :MyLocalExtension) if defined?(MyLocalExtension)
Object.send(:remove_const, :MyLocalExtension)

If we expect it to be there, it should be there. Otherwise our test is wrong for calling this method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure makes sense! Will change.

Copy link
Member

@gmcgibbon gmcgibbon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after some small changes.

USAGE.md Outdated Show resolved Hide resolved
lib/packwerk/cli.rb Outdated Show resolved Hide resolved
test/test_helper.rb Outdated Show resolved Hide resolved
Packwerk::OffensesFormatter.instance_variable_set(:@formatter_by_identifier, nil)
current_formatters = Packwerk::OffensesFormatter.instance_variable_get(:@offenses_formatters)
new_formatters = current_formatters.delete_if { |f| f.new.identifier == "my_offenses_formatter" }
Packwerk::OffensesFormatter.instance_variable_set(:@offenses_formatters, new_formatters)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just leave it at setting nil, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't because @offenses_formatters is initialized when the interface is included when a file is required, so if we reset to nil in the test suite, then no more offense formatter will be required, so nil.map will raise an error.

lib/packwerk/offenses_formatter.rb Show resolved Hide resolved
USAGE.md Outdated

You can also pass in a formatter on the command line:
```
bin/packwerk check --format=my_offenses_formatter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure this is using the correct flag before merging.

@alexevanczuk alexevanczuk merged commit d447a38 into main Nov 28, 2022
@alexevanczuk alexevanczuk deleted the ae-extensible-formatter-take-2 branch November 28, 2022 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants