-
Notifications
You must be signed in to change notification settings - Fork 69
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 proto_common.direct_source_infos #22
Conversation
Side note, lets submit this after #26 if possible? |
sgtm |
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.
Looking good, only minor comments. Thank you!
# Before Bazel 1.0, `proto_source_root` wasn't guaranteed to be a prefix | ||
# of `file.path`. This could happend, e.g., if `file` was generated. | ||
|
||
# TODO(yannic): Remove this hack when we drop support for Bazel >= 0.29. |
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.
Do we support bazel < 1.0? If yes, we should have a CI coverage for it (I vote for only supporting the latest Bazel explicitly).
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 still migrating to 1.0, but I'm fine with not polluting rules_proto
with this. Supporting only the latest Bazel explicitly sgtm.
}, | ||
) | ||
|
||
def direct_source_infos(proto_info, blacklisted_sources = []): |
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.
SuperNit: The term blacklist seems to have a negative charge for some people. Wdyt about blocked_sources? ignored_sources? skipped_sources? Something else?
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 wasn't aware that this could offend some people, I'll put it on my list of terms to avoid.
These files are usually provided by the runtime, so [runtime_]provided_sources
sounds good.
}, | ||
) | ||
|
||
def compute_import_path_test(name, deps): |
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.
Let's see if I got this right. This test iterates over each dependency, gets ProtoInfo from the dependency, generates a new .proto file, writes is in _compute_import_path rule, and then adds a proto_library that depends on that new proto. The test assertion is actually the fact that proto_library builds. Correct?
So it seems like an integration test. I see the value of this test, but also consider adding unit-test-like tests checking that proto_common.direct_source_infos returns expected values for each proto_library in //tests/.
Pls document the flow of this integration test somewhere, it's quite too complex to assume a reader will get it just by reading 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 replaced this test with a unit test for now. Adding an integration test just for this won't provide much value. We'll add one later when we also have proto_common.generat
.
|
||
def compute_import_path_test(name, deps): | ||
for dep in deps: | ||
target_under_test = "//tests:{}".format(dep) |
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'd prefer to assume deps attribute to be list of labels, and instead of constructing the label in the macro we could cut the name part of the label for gen_name. Imho that's more idiomatic this way.
proto_library( | ||
name = "{}.{}".format(name, dep), | ||
srcs = [ | ||
":{}".format(gen_name), |
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.
You can just use gen_name, no need to prepend ":", both are valid label syntax.
) | ||
|
||
proto_library( | ||
name = "{}.{}".format(name, dep), |
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.
Maybe extract variable for this too? For consistency.. But I don't insist, it's a matter of taste I guess.
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.
Sorry for the delay. ptal
}, | ||
) | ||
|
||
def direct_source_infos(proto_info, blacklisted_sources = []): |
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 wasn't aware that this could offend some people, I'll put it on my list of terms to avoid.
These files are usually provided by the runtime, so [runtime_]provided_sources
sounds good.
# Before Bazel 1.0, `proto_source_root` wasn't guaranteed to be a prefix | ||
# of `file.path`. This could happend, e.g., if `file` was generated. | ||
|
||
# TODO(yannic): Remove this hack when we drop support for Bazel >= 0.29. |
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 still migrating to 1.0, but I'm fine with not polluting rules_proto
with this. Supporting only the latest Bazel explicitly sgtm.
}, | ||
) | ||
|
||
def compute_import_path_test(name, deps): |
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 replaced this test with a unit test for now. Adding an integration test just for this won't provide much value. We'll add one later when we also have proto_common.generat
.
e89dc51
to
2026bce
Compare
Updated design to exclude protos based on import path instead of file equality. See bazelbuild/bazel#10590 for context. |
@lberki Could we get this prioritized and merged soon? I need this functionality to fix all those proto rules that don't support |
|
||
"""Contains the implementation for `proto_common.direct_source_infos`.""" | ||
|
||
ProtoFileInfo = provider( |
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 is this a provider? You probably will not want to return this from a rule since this describes only a single file, and in that case, a struct()
does the job just as well, but is a bit less confusing.
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.
Providers make generating useful documentation easier. The alternative would be to document the structure of the struct()
in the documentation of direct_source_infos
's return type, which, to me, sounds worse than making it a provider.
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 I un-exported it from //proto:defs.bzl
. Users won't need to instantiate 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.
Au contraire! Providers convey the meaning that they are used for communication between configured targets, which isn't the case here. Mind turning it into a struct?
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.
Ack, done.
# TODO(yannic): Remove this suppression when | ||
# https://github.com/bazelbuild/buildtools/issues/774 has been fixed. | ||
# buildifier: disable=function-docstring-args | ||
def direct_source_infos(proto_info, *, provided_sources = []): |
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 isn't this a member of ProtoInfo
? Sounds like a reasonable functionality there. (I might be missing something obvious here, since I haven't been following this pull request very closely)
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 thought about making import paths of direct sources part of ProtoInfo
before but never came to a conclusion.
ProtoInfo
already is "complicated" (:cough: original sources) and I'd like to avoid adding more half-baked stuff to it. Can you file a feature request?
@Yannic , doing my best... I left a code review here, although probably all it does is make my ignorance obvious: it feels like everything I asked has an obvious answer which I should know, had I followed this progress of this change. |
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, added some comments
|
||
"""Contains the implementation for `proto_common.direct_source_infos`.""" | ||
|
||
ProtoFileInfo = provider( |
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.
Providers make generating useful documentation easier. The alternative would be to document the structure of the struct()
in the documentation of direct_source_infos
's return type, which, to me, sounds worse than making it a provider.
|
||
"""Contains the implementation for `proto_common.direct_source_infos`.""" | ||
|
||
ProtoFileInfo = provider( |
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 I un-exported it from //proto:defs.bzl
. Users won't need to instantiate it.
# TODO(yannic): Remove this suppression when | ||
# https://github.com/bazelbuild/buildtools/issues/774 has been fixed. | ||
# buildifier: disable=function-docstring-args | ||
def direct_source_infos(proto_info, *, provided_sources = []): |
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 thought about making import paths of direct sources part of ProtoInfo
before but never came to a conclusion.
ProtoInfo
already is "complicated" (:cough: original sources) and I'd like to avoid adding more half-baked stuff to it. Can you file a feature request?
f683d3c
to
590fdba
Compare
This change adds a helper to extract information about direct sources of `ProtoInfo` providers. Design doc: https://docs.google.com/document/d/1u95vlQ1lWeQNR4bUw5T4cMeHTGJla2_e1dHHx7v4Dvg/edit# Note that this was originally named `proto_common.protos_to_generate`, but was renamed because it applies more broadly.
) | ||
|
||
source_root = proto_info.proto_source_root | ||
offset = len(source_root) + 1 # + '/'. |
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.
Whoa, I think I caught an actual bug. This logic seems to want to do same thing as the the exec path -> import path logic from the Java code:
but it doesn't do that, AFAIU: it diverges for .proto
files in external repositories and generated .proto
files (yes, they do exist)
Do I understand this correctly? If so, it might be more reasonable to expose this information from Java in the interest of not re-implementing the same functionality twice. 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.
I'm not sure I understand the case in which it doesn't work.
We do have coverage for external repositories, so I'm confident that works correctly. We don't have tests for generated .proto
files here, but aren't they always simlink'ed into <pkg>/_virtual_imports/<name>/<import_path>
since bazelbuild/bazel#9215, thus work as well?
The only case I see when this logic could fail is when the file is not under proto_source_root
(which, AFAIK, cannot happen since Bazel 1.0). What am I missing?
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.
You're totally right! However, there is also the problem of the direct proto source root being a lie (e.g. if a proto_library
has both source and derived .proto
files, not all of them are going to be under .proto_source_root
.
I suppose bazelbuild/bazel#10939 will help with that?
590fdba
to
2fdaa50
Compare
@lberki this is a missing feature to have nested (proto) dependencies in grpc-web implemented 🙏 I hope you don't mind me pinging you about the pending review |
This won't happen as is. Instead, we will expose |
This change adds a helper to extract information about direct sources
of
ProtoInfo
providers.Design doc:
https://docs.google.com/document/d/1u95vlQ1lWeQNR4bUw5T4cMeHTGJla2_e1dHHx7v4Dvg/edit#
Note that this was originally named
proto_common.protos_to_generate
,but was renamed because it applies more broadly.