-
Notifications
You must be signed in to change notification settings - Fork 4
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
Implement original source verification #11
Conversation
e59801d
to
163e7a4
Compare
@kennyadsl @mtylty @elia curious to hear your thoughts here! |
163e7a4
to
4d3a42d
Compare
I like this! Being optional this will only impact people wanting to use it. Not sure it's possibile with the new implementation but this could not be breaking if we deprecate calling |
@kennyadsl I think that could work, I'll give it a try in a few. |
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.
Looks great! I left a few comments and a suggestion for a simpler API when the macro method is not used. 👏
I would also like to suggest an alternative name for "acts_as_prepender" (which sounds a bit dated to me) but I don't have a good counter-proposal so just take it as some useless feedback 😅
base.singleton_class.class_eval <<~RUBY, __FILE__, __LINE__ + 1 | ||
def __prependers_namespace__ | ||
#{@namespace} | ||
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.
any reason for not using define_singleton_method
here? I mean performance or otherwise…
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.
define_singleton_method
forces me to assign the namespace to a temporary variable due to scoping issues, which I didn't really like:
_namespace = @namespace
base.define_singleton_method(:__prependers_namespace__) { _namespace }
I feel like a plain class_eval
is much more straightforward. However, if there are any specific reasons for preferring define_singleton_method
, please let me know!
559ab37
to
24bf010
Compare
24bf010
to
7c3ad0f
Compare
f3a0423
to
2c21833
Compare
@kennyadsl @elia this should be ready for a final review, thanks for the feedback! |
I like the idea but I don't think this is needed, we're adding complexity and making the gem harder to understand. I'm also a bit biased because I've always seen developers struggling completely with Deface's I think we should work on providing better tools for testing what you're prepending instead of adding some better workarounds. |
@mtylty I see your point — tests are definitely the way to go for testing most decorators. However, I think there are some cases that are not covered by tests: for instance, what if the feature you are implementing or the bug you are fixing in your prepender is fixed in the upstream? In that case, you should remove your prepender entirely, and a test won't be able to tell you that. The feature itself is quite simple (it's just 60 lines of code, all the other changes in this PR are not specific to the verification) and I think it could be a useful additional tool in our suite, but I also think it should be used with caution and not be treated as a substitute for writing 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.
Works for me!
This PR implements original source verification. It closes #10.
Behavior and implementation
The verification behavior is very similar to Deface's
:original
option.Basically, we compute a combined hash of all the files where a given module is defined. The hash is stored in a prepender for that module. If any of the original source locations are updated, the hash changes and causes Prependers to throw an error, asking the user to make sure their prepender is still relevant.
There are a few aspects of the implementation I am still not sure about:
There are also a couple additional features we may implement:
While implementing the feature, I had to radically change the Prependers API. This shouldn't be a problem since we're still in 0.x. Instead of just relying on the
Prependers::Prepender
module doing everything, I introduced the concept of annotations, i.e. modules that extend the functionality of Prependers. Original source verification was implemented as theVerify
annotation, and the:namespace
option was turned into theNamespace
annotation.