--
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 post to this group, send email to bazel-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAH%2BXAAqSDLC1_JNt%2BkBcQQb1D4MRGixtCKn1A-DtK6Ea%3DmAR0Q%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
On Wed, Mar 25, 2015 at 7:14 AM, 'Shawn Pearce' via bazel-discuss <bazel-...@googlegroups.com> wrote:I was looking at maven_jar and I am a little disappointed to have it missing a checksum like http_jar has.When we put Gerrit Code Review onto Buck we wrote our own maven_jar() rule that accepts SHA-1s and verifies on download. This has been very valuable to us as a project and we would hate to lose that level of verification if we moved to Bazel.
I know SHA-256 is the new thing, but Maven Central publishes SHA-1 hashes for the files it serves up. Being able to at least include that in our build rules to verify the file is likely to be what we think it is before using it has caught a number of broken caches.On another note, maven_jar() in Bazel takes the group_id, artifact_id and version as 3 separate parameters. But then uses "group:artifact" in the exclude. This is... awkward to have two different syntaxes for similar things.
Gerrit chose to use "group:artifact:version[:classifier]" for its maven_jar() rule because this is the format used by Apache Buildr; you can copy and paste it directly from search.maven.org.
Finally... maven_jar() needs a classifier option. :)
On Wed, Mar 25, 2015 at 6:21 AM, Lukács T. Berki <lbe...@google.com> wrote:On Wed, Mar 25, 2015 at 7:14 AM, 'Shawn Pearce' via bazel-discuss <bazel-...@googlegroups.com> wrote:I know SHA-256 is the new thing, but Maven Central publishes SHA-1 hashes for the files it serves up. Being able to at least include that in our build rules to verify the file is likely to be what we think it is before using it has caught a number of broken caches.
On another note, maven_jar() in Bazel takes the group_id, artifact_id and version as 3 separate parameters. But then uses "group:artifact" in the exclude. This is... awkward to have two different syntaxes for similar things.Gerrit chose to use "group:artifact:version[:classifier]" for its maven_jar() rule because this is the format used by Apache Buildr; you can copy and paste it directly from search.maven.org.Sounds like it would be better to combine the three (optionally four) fields into one string in the maven_jar rule?
Finally... maven_jar() needs a classifier option. :)Members of bazel-discuss should have access to this design doc (unfortunately I can't figure out a way to just make it public): https://docs.google.com/document/d/1RmEan3cnUldQiUBT0IySuKoisQdeuMX79D2cMluuezo/edit. If you can't see it, here's the eventual plan:maven_jar(name = "appengine",group_id = "com.google.appengine",artifact_id = "appengine-api-1.0-sdk",version = "1.9.17",type_and_classifier = [{type = "jar", classifier = "debug"},{type = "war"}, {classifier = "src"}
IIUC, a maven_jar creates a "repository" with several artifacts in there (see the bind#actual value at http://bazel.io/docs/build-encyclopedia.html#maven_jar) so my understanding would be that this creates @appengine//jar_debug (or something like that), @appengine//war and @appengine//src. So you could possibly add a sha1 to those type_and_classifier entries: { type = "jar", classifier = "debug", sha1 = "…" }But contrary to the maven_jar in Bucklets, maven_jar in Bazel reads the POM (so it would need a sha1 too) and downloads transitive dependencies (how'd you provide the sha1 for those then?)
1½ year ago, in the context of Buck, I proposed an additional, preliminary step (e.g. using Ivy or Aether) generating discrete rules for each artifact.Put differently, you define all your external (Maven) dependencies, along with rules (à la dependencyManagement in Maven, or more complex things like in Gradle, see http://gradle.org/docs/current/userguide/dependency_management.html#sub:client_module_dependencies and http://gradle.org/docs/current/userguide/dependency_management.html#N1542D), and you get rules you can depend on for each declared dependency, and with complete control on the transitive dependencies. Use cases (these are real use-cases I deal with in a project, currently built with Gradle):
- you use several dependencies that all depend on Guava or Guice in different versions, and you possibly want to use yet another version, but at least align the version;
- you depend on something that depends on Guice with some extensions, you don't use those extensions yourself, but you need to align all versions on the version of Guice you're using;
- you need to replace some dependency with another, due to licensing issues for example (e.g. replace javax.activation:activation or javax.servlet:javax.servlet-api which are CDDL with their Geronimo equivalent under Apache v2; or jcip-annotations which are under Creative Commons Attribution, with an Apache v2 equivalent), or bad practices of depending on "bundles" (e.g. mockito-all instead of mockito-core, or the old junit instead of junit-dep – this has now been fixed, so you need to replace junit-dep transitive deps with junit)
- you need to tell the build tool that two dependencies are actually the same (e.g. javassist:javassist or javax.servlet:servlet-api are the old coordinates for org.javassist:javassist and javax.servlet-api:javax.servlet-api respectively)
- you need to exclude some transitive dependencies (e.g. I use google-oauth-client only for parsing and serializing objects, I don't need the httpclient dependency)
With the "repository" concept in Bazel, you can probably come up with a DSL for that in BUILD (or WORKSPACE?) files that would do everything needed during a "bazel fetch" (instead of a first step to generate BUILD files followed by a fetch using those files).
If you don't, then I think leaving all that to an external tool (like I proposed for Buck at the time) and not resolve transitive dependencies (Bucklets' maven_jar is actually just a thin wrapper around an equivalent to Bazel's http_jar, just generating the URL from the coordinates) is better (that said, one could still use an external tool generating http_jar rules with my approach…)
Disclaimer: I haven't yet even tried Bazel and am just starting reading the docs, and I never actually experimented with the Ivy+Buck idea.
IIUC, a maven_jar creates a "repository" with several artifacts in there (see the bind#actual value at http://bazel.io/docs/build-encyclopedia.html#maven_jar) so my understanding would be that this creates @appengine//jar_debug (or something like that), @appengine//war and @appengine//src. So you could possibly add a sha1 to those type_and_classifier entries: { type = "jar", classifier = "debug", sha1 = "…" }But contrary to the maven_jar in Bucklets, maven_jar in Bazel reads the POM (so it would need a sha1 too) and downloads transitive dependencies (how'd you provide the sha1 for those then?)I updated the design doc and copied it to a document I could make public (which unfortunately lost all of the comments that were on it): https://docs.google.com/document/d/1LIF_CXwamK6MAkLDekS83TlqL50sS7GqL9ocfwcmAu8/edit#. Please feel free to comment.
1½ year ago, in the context of Buck, I proposed an additional, preliminary step (e.g. using Ivy or Aether) generating discrete rules for each artifact.Put differently, you define all your external (Maven) dependencies, along with rules (à la dependencyManagement in Maven, or more complex things like in Gradle, see http://gradle.org/docs/current/userguide/dependency_management.html#sub:client_module_dependencies and http://gradle.org/docs/current/userguide/dependency_management.html#N1542D), and you get rules you can depend on for each declared dependency, and with complete control on the transitive dependencies. Use cases (these are real use-cases I deal with in a project, currently built with Gradle):
- you use several dependencies that all depend on Guava or Guice in different versions, and you possibly want to use yet another version, but at least align the version;
- you depend on something that depends on Guice with some extensions, you don't use those extensions yourself, but you need to align all versions on the version of Guice you're using;
- you need to replace some dependency with another, due to licensing issues for example (e.g. replace javax.activation:activation or javax.servlet:javax.servlet-api which are CDDL with their Geronimo equivalent under Apache v2; or jcip-annotations which are under Creative Commons Attribution, with an Apache v2 equivalent), or bad practices of depending on "bundles" (e.g. mockito-all instead of mockito-core, or the old junit instead of junit-dep – this has now been fixed, so you need to replace junit-dep transitive deps with junit)
- you need to tell the build tool that two dependencies are actually the same (e.g. javassist:javassist or javax.servlet:servlet-api are the old coordinates for org.javassist:javassist and javax.servlet-api:javax.servlet-api respectively)
- you need to exclude some transitive dependencies (e.g. I use google-oauth-client only for parsing and serializing objects, I don't need the httpclient dependency)
With the "repository" concept in Bazel, you can probably come up with a DSL for that in BUILD (or WORKSPACE?) files that would do everything needed during a "bazel fetch" (instead of a first step to generate BUILD files followed by a fetch using those files).I added a bit to https://docs.google.com/document/d/1LIF_CXwamK6MAkLDekS83TlqL50sS7GqL9ocfwcmAu8/edit#heading=h.twhwz2g1yedf about dependencies... I think it'll be a lot easier for Bazel if people have to specify the transitive dependencies, but a lot harder for the users.
I suggested adding a command to generate all the dependencies in WORKSPACE-file format so people can copy-paste, then customize as needed (which I think would take care of most of the issues you mention above?).