I propose that even when ijar isn't used, we rewrite the compile time jar to add the desired owner to the jar manifest.
As I stated on that GitHub thread, I don't think the exports case is something we should worry about now, nor do I even think it's something that _can_ be fixed because there simply isn't a unique owner.
On Tue, Mar 20, 2018 at 7:03 AM Tom Lundell <to...@google.com> wrote:I propose that even when ijar isn't used, we rewrite the compile time jar to add the desired owner to the jar manifest.SGTM.Note that the tool that does that could be ijar--we could consider having a flag to disable the interface jar extraction part of ijar and use that for scala instead of disabling the ijar action wholesale. But that isn't really important, having a different tool that fixed up the manifest would be fine too.
It does create new jars, so if there is somehow multiple ingress points you'll now have duplicates on your classpath. Though same is true when you use ijar, so maybe it can just be done unconditionally.
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAL4Qsgvuhr_ewshT43NacArePuTP2Lds1S3REQvhYe%3D1FqLZrw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Maybe a hybrid solution is workable, i.e. exports=, but only exports= adds a .jar->label map entry, and JavaBuilder looks at the map, and if an entry is not present, uses the label in the .jar? That way, the in-memory data structure would be smaller because presumably, on any given compile action, there are much fewer .jars acquired through exports= than .jars altogether.
This is what we have at Google because add_dep was giving the wrong results.
There are several strategies to finding the right rule to add -
1. Find all rules in the same package that export and/or alias the new dependency
2. Look for rules in predetermined locations that export the new dependency (used for third-party jars)
3. Use a global index of export edges
After the list is expanded, it's filtered by visibility / tags / etc, and finally sorted (e.g. by distance from new dependency).
The first one can be implemented using `bazel query` in a Python script and doesn't require fancy tools.
Can we move ahead with this? Will the proposed solution satisfy people's requirements and concerns?
And do we need write_jar_owner to be in the API? (Setting aside the question of how to migrate to enabling it by default.) Is there a use-case for disabling it?
java_common.create_provider is deprecated and will be replaced by the JavaInfo() constructor. actions is used for more actions now (surprise surprise) besides creating the ijar, e.g. creating the output source jar action, so the argument is actually mandatory.
I think the open issue here is still exports.
If we decide this isn’t a different use-case labels wise then indeed having some tool encode it is ok.
Thing is I’m not convinced- what is the use-case (in the jvm world) for using exports unless you want people to relate to the exporting rule and not the exported one? What “convenience” does exports add over deps apart from SJD?
OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.
If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).
Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.
OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).SGTM.Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.No, having actions instead of ctx was intentional. There is an on-going (maybe stalling?) effort from the Skylark team to split ctx in 2 parts, one of which is actions. The end goal will be to pass actions instead of ctx to restrict access to some parts of ctx, since it contains too many things and its scope is too large.
On Mon, Mar 26, 2018 at 4:58 AM Irina Iancu <elena...@google.com> wrote:OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).SGTM.Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.No, having actions instead of ctx was intentional. There is an on-going (maybe stalling?) effort from the Skylark team to split ctx in 2 parts, one of which is actions. The end goal will be to pass actions instead of ctx to restrict access to some parts of ctx, since it contains too many things and its scope is too large.I don't understand this argument. If the goal is just to split ctx into multiple sub-categories of stuff, that's cool, but that doesn't prevent APIs from taking ctx as the first argument, unconditionally always. Then they can get actions out of ctx no problems.Are you going to completely remove actions from ctx? So rule functions take more arguments? Then sure, it might make sense. But I don't think that's what you are planning to do.I think we'll find that without this, future evolution of the APIs will become more painful.
On Mon, Mar 26, 2018 at 5:34 PM Tom Lundell <to...@google.com> wrote:On Mon, Mar 26, 2018 at 4:58 AM Irina Iancu <elena...@google.com> wrote:OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).SGTM.Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.No, having actions instead of ctx was intentional. There is an on-going (maybe stalling?) effort from the Skylark team to split ctx in 2 parts, one of which is actions. The end goal will be to pass actions instead of ctx to restrict access to some parts of ctx, since it contains too many things and its scope is too large.I don't understand this argument. If the goal is just to split ctx into multiple sub-categories of stuff, that's cool, but that doesn't prevent APIs from taking ctx as the first argument, unconditionally always. Then they can get actions out of ctx no problems.Are you going to completely remove actions from ctx? So rule functions take more arguments? Then sure, it might make sense. But I don't think that's what you are planning to do.I think we'll find that without this, future evolution of the APIs will become more painful.I didn't have to go very far to find an example of this :(To do this change I need the rule's target label so I can tell ijar about it. This requires either passing in the label, or getting it from ctx. But I don't have ctx. Either way it's a migration.I resubmit that these kinds of methods should all just take ctx as the first arg, and have it be mandatory. I think our methods will survive their evolution much better.It's fine for ctx to just be a container of other things, if the original concern was the size of the ctx API.
On Sat, Mar 31, 2018 at 12:54 PM Tom Lundell <to...@google.com> wrote:On Mon, Mar 26, 2018 at 5:34 PM Tom Lundell <to...@google.com> wrote:On Mon, Mar 26, 2018 at 4:58 AM Irina Iancu <elena...@google.com> wrote:OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).SGTM.Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.No, having actions instead of ctx was intentional. There is an on-going (maybe stalling?) effort from the Skylark team to split ctx in 2 parts, one of which is actions. The end goal will be to pass actions instead of ctx to restrict access to some parts of ctx, since it contains too many things and its scope is too large.I don't understand this argument. If the goal is just to split ctx into multiple sub-categories of stuff, that's cool, but that doesn't prevent APIs from taking ctx as the first argument, unconditionally always. Then they can get actions out of ctx no problems.Are you going to completely remove actions from ctx? So rule functions take more arguments? Then sure, it might make sense. But I don't think that's what you are planning to do.I think we'll find that without this, future evolution of the APIs will become more painful.I didn't have to go very far to find an example of this :(To do this change I need the rule's target label so I can tell ijar about it. This requires either passing in the label, or getting it from ctx. But I don't have ctx. Either way it's a migration.I resubmit that these kinds of methods should all just take ctx as the first arg, and have it be mandatory. I think our methods will survive their evolution much better.It's fine for ctx to just be a container of other things, if the original concern was the size of the ctx API.Just FYI this change will be stalled until there's a resolution here. I can't proceed until we figure out what to do.My opinion is to require ctx as the first arg to JavaInfo, but that's a migration so I'm not going to go do it unless people agree.
Then we'll have to take the label as an argument. This precludes it from being a seamless or behind-the-scenes migration, users will have to know about this aspect of the machinery, and explicitly pass the target label.
That could be supported by passing another argument, "injecting_rule_kind".
As an aside, this case is pretty poorly supported anyway, because its support is hard coded. add_deps takes a label and the injecting rule kind and tries to guess the name of the corresponding java_proto_library rule. Eg. "Oh I see it's the target 'foo_proto' but created by a 'java_proto_library', hopefully there exists a rule called 'foo_java_proto' then". It will not extend graciously to user-defined aspects, and it will not work for users that do not adhere to our internal naming conventions.
On Tuesday, April 3, 2018 at 4:53:35 PM UTC+2, Tom Lundell wrote:On Sat, Mar 31, 2018 at 12:54 PM Tom Lundell <to...@google.com> wrote:On Mon, Mar 26, 2018 at 5:34 PM Tom Lundell <to...@google.com> wrote:On Mon, Mar 26, 2018 at 4:58 AM Irina Iancu <elena...@google.com> wrote:OK in that case I propose to do just do it always. I'll probably just make ijar do the job unless somebody thinks it's cleaner and worth it to add another standalone tool.If actions isn't passed to create_provider then it'll silently not do anything for backwards compatibility. This does come with some risk of breakage, in case people make assumptions on the exact jars that get passed upwards (when use_ijar=False).SGTM.Tangentially, would it make sense to pass ctx always instead of actions in the API? Having ctx as the first argument is pretty common in various APIs. It feels a bit odd to have to pass piecemeal sub-components of it, and if we need more components in the future we end up having to add more arguments as part of migration, checking for null, etc.No, having actions instead of ctx was intentional. There is an on-going (maybe stalling?) effort from the Skylark team to split ctx in 2 parts, one of which is actions. The end goal will be to pass actions instead of ctx to restrict access to some parts of ctx, since it contains too many things and its scope is too large.I don't understand this argument. If the goal is just to split ctx into multiple sub-categories of stuff, that's cool, but that doesn't prevent APIs from taking ctx as the first argument, unconditionally always. Then they can get actions out of ctx no problems.Are you going to completely remove actions from ctx? So rule functions take more arguments? Then sure, it might make sense. But I don't think that's what you are planning to do.I think we'll find that without this, future evolution of the APIs will become more painful.I didn't have to go very far to find an example of this :(To do this change I need the rule's target label so I can tell ijar about it. This requires either passing in the label, or getting it from ctx. But I don't have ctx. Either way it's a migration.I resubmit that these kinds of methods should all just take ctx as the first arg, and have it be mandatory. I think our methods will survive their evolution much better.It's fine for ctx to just be a container of other things, if the original concern was the size of the ctx API.Just FYI this change will be stalled until there's a resolution here. I can't proceed until we figure out what to do.My opinion is to require ctx as the first arg to JavaInfo, but that's a migration so I'm not going to go do it unless people agree.We are not passing `ctx` as an argument to JavaInfo, because that couples JavaInfo semantics too much to the rule that creates that javaInfo. It is inflexible and most of the time produces bad results
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/f8db7c40-1764-412e-9245-0b4c0bb93953%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
We are not passing `ctx` as an argument to JavaInfo, because that couples JavaInfo semantics too much to the rule that creates that javaInfo. It is inflexible and most of the time produces bad resultsIt also constrains the implementation of said method.This came up with the methods in cc_common that return various things about the compiler -- currently, they either look at the configuration, but they will soon look at the CcToolchainProvider which they can get either from toolchain resolution or a dependency. And if we only pass in e.g. ctx.fragments, we'll have to change the Skylark interface in order to change the plumbing between various Java classes. That seemed somewhat unsatisfactory.
The exports usecase is still important for us and I’d like us to try and understand what we can do with it.
--
You received this message because you are subscribed to a topic in the Google Groups "bazel-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bazel-discuss/mt2llfwzmac/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/47dcc1fb-500c-4555-83a9-e466d741609d%40googlegroups.com.
The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have. The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.Please make breaking changes explicit.
Responding to various tangential points raised:> Accepting ctx.actions seems to indicate that you are operating in the context of a rule implementation anyway, I don't quite see how 'actions' is dramatically more narrow for this reason,ctx.actions is specially designed to be an _action factory_. It gives your API a capability of creating actions without leaking information about attributes, labels, fragments or any other bits about the calling rule. It tells you: this API creates actions on behalf of a rule/aspect - there are no information sidechannels.> This came up with the methods in cc_common that return various things about the compiler [...]As this is unrelated to Java, we discussed this offline with Lukacs. The resolution there is that for those specific set of methods, the desirable end state is the methods that do not take the ctx anyway. Some helper functions in pure Skylark can be written to facilitate the transition, but unclear at this stage if they are even needed.> [java_proto_library] could be supported by passing another argument, "injecting_rule_kind" [...]> this case is pretty poorly supported anyway, because its support is hard coded. add_deps takes a label and the injecting rule kind and tries to guess the name of the corresponding java_proto_library rule. Eg. "Oh I see it's the target 'foo_proto' but created by a 'java_proto_library', hopefully there exists a rule called 'foo_java_proto' then"injecting_rule_kind is not really sustainable as it does not generalize to custom rules in general. Any Skylark rule people add will need to be added to strict_deps/add_deps which is impossible to maintain.
We need a different solution if we want to make strict_deps/add_deps diagnostics extensible.
I see two:- instead of passing label and injecting_rule_kind and whatnot other information, make the rule pass "the instructions to add dependency on this jar" as a string and store those in the ijar manifest. The diagnostics just displays this verbatim (replacing a placeholder with offending dependency target label)- completely change how a jar to add is discovered. Instead of getting this information from a jar manifest (or, previously, command line), strict_deps will use an aspect to analyze dependencies of offending target. JVM rules will provide a provider that describes, for a target that produces jars, how to add dependencies on those jars. The aspect will discover the closest topologically closest producing target to the offending target and display that information as an "add_deps" suggestion. This will solve proto_library aspect/java_proto_library, exports, and is extensible. It is a large reinvention of how strict deps report errors though.Maybe there are other ideas here?
As a side note, I am rather uncomfortable with the fact that JavaInfo constructor (which should really be just constructing a data structure) actually creates actions. This API choice seems questionable to me - are we sure that every API usage need to create these specific actions? I understand that actual action creation is controlled by use_ijar, and if we all pinky swear we will never ever create other actions that are controlled by other parameters, it is ok, and not much harm done anyhow if we actually do, but it still is aesthetically unpleasant.
DmitryOn Tue, Apr 10, 2018 at 11:14 PM Liam Miller-Cushon <cus...@google.com> wrote:On Tue, Apr 10, 2018 at 1:02 AM 'Lukács T. Berki' via bazel-discuss <bazel-...@googlegroups.com> wrote:We are not passing `ctx` as an argument to JavaInfo, because that couples JavaInfo semantics too much to the rule that creates that javaInfo. It is inflexible and most of the time produces bad resultsIt also constrains the implementation of said method.This came up with the methods in cc_common that return various things about the compiler -- currently, they either look at the configuration, but they will soon look at the CcToolchainProvider which they can get either from toolchain resolution or a dependency. And if we only pass in e.g. ctx.fragments, we'll have to change the Skylark interface in order to change the plumbing between various Java classes. That seemed somewhat unsatisfactory.Is the concern about making JavaInfo inflexible that passing ctx allows JavaInfo to depend on attributes of the current rule? The alternative of passing actions/labels/fragments as separate arguments will make using JavaInfo more verbose and error prone, and make breaking changes to the API more frequent. This seems like a bad trade-off.--Google Germany GmbHErika-Mann-Straße 33, 80636 München, Germany
--
You received this message because you are subscribed to a topic in the Google Groups "bazel-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bazel-discuss/mt2llfwzmac/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAObu7DE%3DYwyjSRL-6q1Uw%3DNSxD%2B_VsA5_ubLcONXapop4xfwzg%40mail.gmail.com.
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAPvN2rUxmH7G9g9y2jy7d009YQrFViJ1vc2z6p8yPTtmUm2UJA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
On Thu, Apr 12, 2018 at 2:56 AM 'Dmitry Lomov' via bazel-discuss <bazel-...@googlegroups.com> wrote:The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have. The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.Please make breaking changes explicit.Point taken, but there are a class of changes that aren't "breaking", but rather are a reorg/refactor/internal change. Those get harder to do, i.e. we're making non-breaking changes explicit too.In case it isn't clear I am more than happy to defer this decision to your taste. The main point of this thread from my point of view is to resolve the immediate issue at hand. I'll do whatever it is you want me to do.Responding to various tangential points raised:> Accepting ctx.actions seems to indicate that you are operating in the context of a rule implementation anyway, I don't quite see how 'actions' is dramatically more narrow for this reason,ctx.actions is specially designed to be an _action factory_. It gives your API a capability of creating actions without leaking information about attributes, labels, fragments or any other bits about the calling rule. It tells you: this API creates actions on behalf of a rule/aspect - there are no information sidechannels.> This came up with the methods in cc_common that return various things about the compiler [...]As this is unrelated to Java, we discussed this offline with Lukacs. The resolution there is that for those specific set of methods, the desirable end state is the methods that do not take the ctx anyway. Some helper functions in pure Skylark can be written to facilitate the transition, but unclear at this stage if they are even needed.> [java_proto_library] could be supported by passing another argument, "injecting_rule_kind" [...]> this case is pretty poorly supported anyway, because its support is hard coded. add_deps takes a label and the injecting rule kind and tries to guess the name of the corresponding java_proto_library rule. Eg. "Oh I see it's the target 'foo_proto' but created by a 'java_proto_library', hopefully there exists a rule called 'foo_java_proto' then"injecting_rule_kind is not really sustainable as it does not generalize to custom rules in general. Any Skylark rule people add will need to be added to strict_deps/add_deps which is impossible to maintain.Agreed, injecting_rule_kind is totally unprincipled and a hack. Target label isn't unprincipled (there really _is_ exactly one unique creator of a jar), but as we've found it ultimately only does what people want in 80% of cases.We need a different solution if we want to make strict_deps/add_deps diagnostics extensible.This is all true. Do we want some solution _right now_ though?If we're not adding ctx, then the only remaining trivial solution seems to be to require the user to pass the target label themselves if they want the jar stamped for add_deps support. This should restore functionality to exactly what it used to be.
On Thu, Apr 12, 2018 at 3:33 PM Tom Lundell <to...@google.com> wrote:On Thu, Apr 12, 2018 at 2:56 AM 'Dmitry Lomov' via bazel-discuss <bazel-...@googlegroups.com> wrote:The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have. The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.Please make breaking changes explicit.Point taken, but there are a class of changes that aren't "breaking", but rather are a reorg/refactor/internal change. Those get harder to do, i.e. we're making non-breaking changes explicit too.In case it isn't clear I am more than happy to defer this decision to your taste. The main point of this thread from my point of view is to resolve the immediate issue at hand. I'll do whatever it is you want me to do.Responding to various tangential points raised:> Accepting ctx.actions seems to indicate that you are operating in the context of a rule implementation anyway, I don't quite see how 'actions' is dramatically more narrow for this reason,ctx.actions is specially designed to be an _action factory_. It gives your API a capability of creating actions without leaking information about attributes, labels, fragments or any other bits about the calling rule. It tells you: this API creates actions on behalf of a rule/aspect - there are no information sidechannels.> This came up with the methods in cc_common that return various things about the compiler [...]As this is unrelated to Java, we discussed this offline with Lukacs. The resolution there is that for those specific set of methods, the desirable end state is the methods that do not take the ctx anyway. Some helper functions in pure Skylark can be written to facilitate the transition, but unclear at this stage if they are even needed.> [java_proto_library] could be supported by passing another argument, "injecting_rule_kind" [...]> this case is pretty poorly supported anyway, because its support is hard coded. add_deps takes a label and the injecting rule kind and tries to guess the name of the corresponding java_proto_library rule. Eg. "Oh I see it's the target 'foo_proto' but created by a 'java_proto_library', hopefully there exists a rule called 'foo_java_proto' then"injecting_rule_kind is not really sustainable as it does not generalize to custom rules in general. Any Skylark rule people add will need to be added to strict_deps/add_deps which is impossible to maintain.Agreed, injecting_rule_kind is totally unprincipled and a hack. Target label isn't unprincipled (there really _is_ exactly one unique creator of a jar), but as we've found it ultimately only does what people want in 80% of cases.We need a different solution if we want to make strict_deps/add_deps diagnostics extensible.This is all true. Do we want some solution _right now_ though?If we're not adding ctx, then the only remaining trivial solution seems to be to require the user to pass the target label themselves if they want the jar stamped for add_deps support. This should restore functionality to exactly what it used to be.Why not go one further with my 1st solution below and instead of passing in a label, pass in "a message for add_deps"? This is trivial and helps solve protobuf. It does not help solve exports though.
On Thu, Apr 12, 2018 at 2:50 PM Dmitry Lomov <dsl...@google.com> wrote:On Thu, Apr 12, 2018 at 3:33 PM Tom Lundell <to...@google.com> wrote:On Thu, Apr 12, 2018 at 2:56 AM 'Dmitry Lomov' via bazel-discuss <bazel-...@googlegroups.com> wrote:The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have. The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.Please make breaking changes explicit.Point taken, but there are a class of changes that aren't "breaking", but rather are a reorg/refactor/internal change. Those get harder to do, i.e. we're making non-breaking changes explicit too.In case it isn't clear I am more than happy to defer this decision to your taste. The main point of this thread from my point of view is to resolve the immediate issue at hand. I'll do whatever it is you want me to do.Responding to various tangential points raised:> Accepting ctx.actions seems to indicate that you are operating in the context of a rule implementation anyway, I don't quite see how 'actions' is dramatically more narrow for this reason,ctx.actions is specially designed to be an _action factory_. It gives your API a capability of creating actions without leaking information about attributes, labels, fragments or any other bits about the calling rule. It tells you: this API creates actions on behalf of a rule/aspect - there are no information sidechannels.> This came up with the methods in cc_common that return various things about the compiler [...]As this is unrelated to Java, we discussed this offline with Lukacs. The resolution there is that for those specific set of methods, the desirable end state is the methods that do not take the ctx anyway. Some helper functions in pure Skylark can be written to facilitate the transition, but unclear at this stage if they are even needed.> [java_proto_library] could be supported by passing another argument, "injecting_rule_kind" [...]> this case is pretty poorly supported anyway, because its support is hard coded. add_deps takes a label and the injecting rule kind and tries to guess the name of the corresponding java_proto_library rule. Eg. "Oh I see it's the target 'foo_proto' but created by a 'java_proto_library', hopefully there exists a rule called 'foo_java_proto' then"injecting_rule_kind is not really sustainable as it does not generalize to custom rules in general. Any Skylark rule people add will need to be added to strict_deps/add_deps which is impossible to maintain.Agreed, injecting_rule_kind is totally unprincipled and a hack. Target label isn't unprincipled (there really _is_ exactly one unique creator of a jar), but as we've found it ultimately only does what people want in 80% of cases.We need a different solution if we want to make strict_deps/add_deps diagnostics extensible.This is all true. Do we want some solution _right now_ though?If we're not adding ctx, then the only remaining trivial solution seems to be to require the user to pass the target label themselves if they want the jar stamped for add_deps support. This should restore functionality to exactly what it used to be.Why not go one further with my 1st solution below and instead of passing in a label, pass in "a message for add_deps"? This is trivial and helps solve protobuf. It does not help solve exports though.I don't see how stamping an add_deps message is any better than just passing in the label that add_deps should try to add a dep to. If you are able to construct an add_dep command you necessarily know the correct label, let's just pass that?
I am quite sure that the principled solution for add_deps need to involve post-factum analysis of the build graph, like I outlinedю
So can we get a green light to pass a label into JavaInfo? If present, the jar is stamped with this label, and add_deps works. Going first, going second...?
I am quite sure that the principled solution for add_deps need to involve post-factum analysis of the build graph, like I outlinedюYes, I think we agree here. SJD should provide a hook to invoke some binary with the target and the jar. I feel like there is already something like that actually. Liam?
On Thu, Apr 12, 2018 at 12:31 PM Tom Lundell <to...@google.com> wrote:So can we get a green light to pass a label into JavaInfo? If present, the jar is stamped with this label, and add_deps works. Going first, going second...?Sold!
On Fri, Apr 13, 2018 at 12:48 AM Liam Miller-Cushon <cus...@google.com> wrote:On Thu, Apr 12, 2018 at 12:31 PM Tom Lundell <to...@google.com> wrote:So can we get a green light to pass a label into JavaInfo? If present, the jar is stamped with this label, and add_deps works. Going first, going second...?Sold!Having yet another flag on JavaInfo is not ideal since it puts more load on the user. It looks like passing redundant information.
IMO Skylark should have a mechanism such as the native implementation of java_common would know all basic information like labels, action factory, toolchain, javabase.
Another idea would be to create a new provider to wrap all the repetitive information and pass that to JavaInfo.
You mean some well documented "parameter object" that packs all information related to java_common into one single data structure?
You mean some well documented "parameter object" that packs all information related to java_common into one single data structure?Well documented, of course. What do you mean by "parameter object"? How is that different from a provider? Packs all information related to java_common - yes.
On Fri, Apr 13, 2018 at 2:43 PM Dmitry Lomov <dsl...@google.com> wrote:--On Fri, Apr 13, 2018 at 2:29 PM Irina Iancu <elena...@google.com> wrote:On Fri, Apr 13, 2018 at 12:48 AM Liam Miller-Cushon <cus...@google.com> wrote:On Thu, Apr 12, 2018 at 12:31 PM Tom Lundell <to...@google.com> wrote:So can we get a green light to pass a label into JavaInfo? If present, the jar is stamped with this label, and add_deps works. Going first, going second...?Sold!Having yet another flag on JavaInfo is not ideal since it puts more load on the user. It looks like passing redundant information.IMO Skylark should have a mechanism such as the native implementation of java_common would know all basic information like labels, action factory, toolchain, javabase.My objections to "just passing ctx" apply here as well. Let's not rehash these.Another idea would be to create a new provider to wrap all the repetitive information and pass that to JavaInfo.You mean some well documented "parameter object" that packs all information related to java_common into one single data structure?Certainly not opposed to this.Google Germany GmbHErika-Mann-Straße 33, 80636 München, Germany
The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have.
The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.
Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.
On Wed, Apr 11, 2018 at 11:56 PM Dmitry Lomov <dsl...@google.com> wrote:The problem with passing ctx is that the users of the API that accepts ctx _have no information whatsoever_ about which information in ctx is relevant and which is not - and ctx gives you access to *all* information the rule implementation can possibly have.If the implementation of JavaInfo restricts itself to information that is present in all rules (like actions and labels) what issues does this cause in practice?
Is the main problem that it gives us the ability to make bad implementation decisions in JavaInfo? I understand that, for example, having JavaInfo use the context to access particular attributes is problematic.The API that takes a ctx is not an API because it has _no contract_. It is not an API, it as best a functional decomposition.(Can you expand on this? I'm not sure what distinction you're making. This might just be a terminology question.)
Not passing ctx as an argument does not "make breaking changes to the API more frequent". It makes breaking changes to the API more apparent.If you method takes the entire ctx, then every time you depend on one more thing from the ctx in method implementation, you are making a breaking change, and you are doing it _silently_. This is the worst trade-off you can make.The specific example in this thread is that JavaInfo currently needs actions, and in the future we would like it to have access to the label of the current rule. If ctx was already being passed in, accessing ctx.label in addition to ctx.actions seems like it would not be a breaking change? On the other hand, adding a new parameter to JavaInfo for the label *is* a breaking change.
--
You received this message because you are subscribed to a topic in the Google Groups "bazel-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bazel-discuss/mt2llfwzmac/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAObu7DGkzLgFo-SKYYON4iEd%2BP%2B-3-YRznHBFs6-hoL_uvZvOg%40mail.gmail.com.
I am for doing the job silently, magically behind the API. I don't want to add yet one more flag to the constructor.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/6a2f27fb-f127-43ff-8f4c-9d17c62f78f6%40googlegroups.com.
load("//rules/jvm:private/label.bzl", _labeled_jars_implementation = "labeled_jars_implementation")
labeled_jars = aspect(
implementation = _labeled_jars_implementation,
attr_aspects = ["deps"], # assumption
)---
load("@rules_scala_annex//rules/jvm:provider.bzl", "LabeledJars")
def labeled_jars_implementation(target, ctx):
if JavaInfo not in target:
return []
manifest = ctx.actions.declare_file("{}/jar_exports.txt".format(ctx.label.name))
args = ctx.actions.args()
if hasattr(args, "add_all"): # Bazel 0.13.0+
args.add_all(target[JavaInfo].compile_jars)
else:
args.add(target[JavaInfo].compile_jars)
args.set_param_file_format("multiline")
ctx.actions.write(manifest, args)
deps_labeled_jars = [dep[LabeledJars] for dep in ctx.rule.attr.deps if LabeledJars in dep]
return [
LabeledJars(
labeled_manifests = depset(
[struct(label = ctx.label, manifest = manifest)], order = "preorder",
transitive = [labeled_jars.labeled_manifests for labeled_jars in deps_labeled_jars],
),
manifests = depset(
[manifest],
transitive = [labeled_jars.manifests for labeled_jars in deps_labeled_jars],
),
),
]To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAPvN2rXpij1sN%3DnXFVTZ04aEEwcmt%2BTsk0KP6%3DAmEKQk7OJ5EQ%40mail.gmail.com.