-
-
Notifications
You must be signed in to change notification settings - Fork 286
Use a provider for jars2labels #534
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
@ittaiz please take a look. |
the intellij test failure seems unrelated. Added #536. |
if _provider_of_dependency_contains_label_of(dependency, jar): | ||
jars2labels[jar.path] = dependency.jars_to_labels[jar.path] | ||
path = jar.path | ||
if path not in jars2labels: |
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.
this seems to introduce order dependency: if you find an unknown provider first, but later it is seen as a direct dependency, you'll only see the unknown, right?
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.
not for direct but if you find an unknown and then another sub graph finds it as direct and afterwards a third target depends on both of these then indeed it can miss the known label.
- We can fix it by also checking if the path starts with
Unknown label
(I'd rather we not do it on this PR) - This should not happen now that we're moving everything to scala_import/scala_import_external
- We're considering dropping this mechanism of passing the jars2labels in favor of what java_rules are doing (reading the labels of "offending" jars from the manifest and then using (offline) bazel query to understand which target exactly to add [for example support exports])
looked a bit, not sure I understand the change. I'll take a look soon because I think I'm just too tired... |
@@ -38,7 +42,7 @@ def _collect_jars_when_dependency_analyzer_is_off(dep_targets): | |||
return struct( | |||
compile_jars = depset(transitive = compile_jars), | |||
transitive_runtime_jars = depset(transitive = runtime_jars), | |||
jars2labels = {}, | |||
jars2labels = _empty_jars2labels, |
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.
Inlining this seems better for readability, IMHO. Is there a performance benefit to reusing the same empty provider instance?
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.
Well, I don't know, but I to me, I felt the opposite: it appeared clearer to me (here is an empty value) vs inlining JarsToLabels(jars_to_labels = {})
which someone has to read an understand as an empty value.
Next, it also seemed it could be faster.
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.
But if you would strongly prefer the change, I will make it. Please let me know.
@ittaiz any chance you could take a look at this? I’m out this week but jars2labels is the last barrier to move to the modern style. I’d really like to solve this in the next two weeks. |
Will take a look this week |
@johnynek actually, any chance you can resolve the conflicts? |
@ittaiz I have merged master. |
@ittaiz okay, I think I have fixed it. I had forgotten to update scala_import. Seems to be working locally for me. Let's see if CI passes. |
green! |
@@ -91,33 +96,23 @@ def filter_not_sources(deps): | |||
|
|||
def add_labels_of_jars_to(jars2labels, dependency, all_jars, direct_jars): | |||
for jar in direct_jars: | |||
_add_label_of_direct_jar_to(jars2labels, dependency, jar) | |||
jars2labels[jar.path] = dependency.label |
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.
why did you remove the private methods?
I thought they added a bit of a declarative feeling in an otherwise very imperative code
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.
so, I found it pretty hard to follow these very tiny methods. They were generally only called one time, and they didn't encapsulate much: they were just rewriting in english what the function was doing.
I think we ideally want some logical chunk, which isn't huge, maybe 5-10 lines, or something that is called many times. Here we often had 1 call, and really a lot of methods below the logical grouping, in my view.
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.
hmm, so I subscribe to a different style. I factor much less how much it's called and the size and much more the readability of the story.
Keep it on same level of abstraction. For example:
for jar in direct_jars:
_add_label_of_direct_jar_to(jars2labels, dependency, jar)
for jar in all_jars:
_add_label_of_indirect_jar_to(jars2labels, dependency, jar)
How should we proceed?
Currently we can get into a sort of tug war where whenever one of us refactors they change to how they like 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 am kind of liberal in what I accept, so I tend to accept code written by others as long as I don't have strong objections, but at the same time, I have super limited time and for some, probably foolish, reason I have been trying to get this modernization done. I'd rather not sink more time in to write the code in a style I don't agree with, for code we don't use, if no one on your team has the time to help us move forward on this.
I would say: let's merge this it is a 80 line change that retires the second to last custom provider.
I have sunk a ton of time into this, and Stripe does not even use it at all. If you want to structure it differently, I don't mind, you can follow up with another PR as long as you keep the provider around. I don't think it is really fair for one of us to task the other to implement the style they prefer. The one doing the work should get the lion's share of the say on style questions we don't agree about.
@ianoc @andyscott do you have any views on this?
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. One more point I'd love for us to be able to agree on is that if we're going to change a style we should probably say up front in case another contributor feels strongly about it (and so avoid rework). WDYT?
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.
To be concrete:
def _add_label_of_direct_jar_to(jars2labels, dependency, jar):
jars2labels[jar.path] = dependency.label
this is not a helpful method in my view. If a reader cannot understand the 1 line you have replaced with a string description, I don't think the strings are going to help. A comment is possibly useful if there is something tricky going on, but using a dict to point to what a jar came from couldn't be a ton clearer.
If we take this to the extreme, every line of code is replaced with a function that names what it is doing:
def increment_int(x, y):
return x + y
def lookup_from_dict(d, k):
return d[k]
etc...
if _provider_of_dependency_contains_label_of(dependency, jar): | ||
jars2labels[jar.path] = dependency.jars_to_labels[jar.path] | ||
path = jar.path | ||
if path not in jars2labels: |
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.
not for direct but if you find an unknown and then another sub graph finds it as direct and afterwards a third target depends on both of these then indeed it can miss the known label.
- We can fix it by also checking if the path starts with
Unknown label
(I'd rather we not do it on this PR) - This should not happen now that we're moving everything to scala_import/scala_import_external
- We're considering dropping this mechanism of passing the jars2labels in favor of what java_rules are doing (reading the labels of "offending" jars from the manifest and then using (offline) bazel query to understand which target exactly to add [for example support exports])
To recap:
|
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.
Please rebase (conflicts) and merge
@@ -91,33 +96,23 @@ def filter_not_sources(deps): | |||
|
|||
def add_labels_of_jars_to(jars2labels, dependency, all_jars, direct_jars): | |||
for jar in direct_jars: | |||
_add_label_of_direct_jar_to(jars2labels, dependency, jar) | |||
jars2labels[jar.path] = dependency.label |
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. One more point I'd love for us to be able to agree on is that if we're going to change a style we should probably say up front in case another contributor feels strongly about it (and so avoid rework). WDYT?
Thanks for the flexibility @ittaiz. I think it may help to grow the maintainers here. It would be great to have another company actively using rules_scala have an engineer contribute to the rules and help us develop a broader view to make sure we have good buy in, and good continuity as people and companies come and go from the project. |
part of #450 to modernize our rules.
We still have extra_information, which I will take a stab at next.