-
Notifications
You must be signed in to change notification settings - Fork 280
Extract Out PreCommit Message Methods to Utils #553
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
Conversation
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.
Thanks for this PR, @taufek.
There's opportunity to reduce the scope of this change and clean up some unnecessary abstraction, but I like the direction this takes us with respect to opening up these helpers to other hooks.
| # @raise [Overcommit::Exceptions::MessageProcessingError] line of output did | ||
| # not match regex | ||
| # @return [Array<Message>] | ||
| def extract_messages(output_messages, regex, type_categorizer = nil) |
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.
Rather than deleting this entirely (and thus requiring all the hooks to reference the new Overcommit::Utils::MessagesUtils module), you could leave the method in place and call the helper.
def extract_messages(*args)
Overcommit::Utils::MessagesUtils.extract_messages(*args)
endThis also avoids breaking existing custom hooks in the wild that depend on extract_messages. Let's minimize disruption and keep the change minimal.
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.
Sounds good to me.
| end | ||
| end | ||
|
|
||
| MessageProcessor = Struct.new(:message, :regex, :type_categorizer, :index) 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.
It's not clear to me why we're creating an inner class via a Struct that shares the same name as the MessageProcessor class, even if it is isolated. Rather than create a struct and call process on it, why not just get rid of the struct and run:
# Replace `MessageProcessor.new(message, regex, type_categorizer, index).process` with:
process_message(message, regex, type_categorizer, index)...and redefine the process method below to take arguments.
This allows you to have the remaining methods in this file as regular methods. They can remain private and isolated from the outside world, since you're using class << self above.
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 do agree it is a poor choice for naming the Struct.
The reason why I created an object to process each message within the loop is to avoid passing the context to the methods.
extract_type(match, message)
extract_file(match, message)
extract_line(match, message)
If we move the methods to an object at individual message level we will methods without argument because now all the previous arguments are accessible via instance variables.
extract_type
extract_file
extract_line
This way we distinguish the methods between the list level (messages) and indivual item level ( a message)
But if you still prefer to keep the methods with arguments I will change it.
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 can see the reason why using a Struct can save you from having to pass arguments explicitly, but I don't think this really gets you much, as it hides the dependencies of the method (i.e. what it actually needs to operate).
Method calls with arguments passed to them give you much more information about what the method is actually doing, rather than having it read a number of instance variables internal to the object.
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.
Understood.
| @@ -1,79 +1,11 @@ | |||
| require 'forwardable' | |||
| require 'overcommit/utils/messages_utils' | |||
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.
@sds ,
I have a question on this file loading. It is possible to avoid defining this and use autoloading instead? I notice modules like GitRepo and FileUtils we can use them via autoloading.
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.
As we are not using autoloading anywhere else in this project, I would prefer not to introduce it at this time. I've been bitten by odd loading errors when trying to be too clever (usually not problems caused by autoloading itself, but by how others load a library locally). If someone uses your code in a way you didn't expect, they could trigger "autoloading" of classes at a time that you don't expect, which can cause difficult to debug issues.
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.
Noted.
d1381e1 to
5e2c020
Compare
Extracted PreCommit context message processor methods to Utils module. This is a step closer to make these PreCommit hooks usable on other context.
5e2c020 to
b24bdad
Compare
|
@sds , This is ready for re-review. Thanks for the feedback. |
|
Thanks for addressing those comments, @taufek! |
Extracted messages methods in PreCommit context to Utils module.
This is a step closer to make these PreCommit hooks usable on other context.