Skip to content

Make sure that scala proto files are generated correctly for external proto dependencies #294

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

Merged
merged 7 commits into from
Oct 5, 2017

Conversation

azymnis
Copy link
Contributor

@azymnis azymnis commented Oct 3, 2017

Problem

scalapb_proto_library will not work with proto_library_targets that are imported from an external repo. The reason is that bazel's proto_library expects proto files to import external files while omitting the external/<repo name>/ bit from the file name. In addition to this java conversions will not work for the final scala library because of the fact that java_proto_library generates a separate external jar for external dependencies that scala_library cannot pull in transitively.

Solution

Two steps:

  1. Pass in the repo_root as well as the proto path for each proto file to be compiled and use a -I flag in protoc to map the actual location of proto files to the one that omits the repo root prefix.
  2. Don't automatically generate the java_proto_library dependency if with_java is true, but expect it to be passed as part of deps.

@johnynek @ittaiz let me know what you think

@bazel-io
Copy link

bazel-io commented Oct 3, 2017

Can one of the admins verify this patch?

@@ -414,7 +414,7 @@ Example:

Args:
name: A unique name for this rule
deps: Proto library targets that this rule depends on (must be of type proto_library)
deps: Proto library targets or jvm targets that this rule depends on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can't be any jvm target, right? You are expecting java_proto_library?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, any jvm targets that you pass here are going to be passed through as deps to the final output scala_library. Does that seem unreasonable?

}
(file, Paths.get(root, file).toString)
}
val imports = parsedProtoFiles.map { case (relPath, absolutePath) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you comment what these are doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@@ -414,7 +414,7 @@ Example:

Args:
name: A unique name for this rule
deps: Proto library targets that this rule depends on (must be of type proto_library)
deps: Proto library targets or jvm targets that this rule depends on
with_grpc: Enables generation of grpc service bindings for services defined in deps
with_java: Enables generation of converters to and from java protobuf bindings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to do this you must also depend on the java_proto_library? Is that right? Should we update this comment?

README.md Outdated
@@ -498,7 +498,7 @@ generated by the [ScalaPB compiler](https://github.com/scalapb/ScalaPB).
<td><code>deps</code></td>
<td>
<p><code>List of labels, required</code></p>
<p>List of proto dependencies that this target depends on. Must be of type <code>proto_library</code></p>
<p>List of dependencies for this target. All targets of type <code>proto_library</code> are passed to <code>scalapb</code> for compilation. All other targets are used to compile the final output scala library</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can these really be any generic target if not proto?

Is it anything that you might need to do the with_java, is that it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the reason I changed this is for with_java but you could potentially use this to pass other dependencies to the output scala_library (though not sure why one would want that).

visibility = visibility,
)
external_deps.append(java_proto_lib)
scala_lib_deps = external_deps + deps
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you not need the transitive compile time dependencies of any of the jvm code?

Also, I think we want to filter this so that we only include the non-proto deps. Otherwise, casual formatting changes to the proto that don't change the compile output will cause a recompilation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions:

  1. How can I get the transitive compile time deps for a jvm dep?
  2. What is the best way to do this in a macro? Remember that this is not within a rule implementation so deps is just a list of strings. Should I use native.existing_rule? https://docs.bazel.build/versions/master/skylark/lib/native.html#existing_rule

@@ -308,12 +308,13 @@ def scala_proto_repositories():
)

def _colon_paths(data):
return ':'.join([f.path for f in data])
return ':'.join(["{root},{path}".format(root=f.owner.workspace_root, path=f.path) for f in data])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is making me nervous, but maybe that's the only way to go here.

There was an old doc about fixing these kinds of issues about cross workspace dependencies like 1.5 years ago or so, but I don't think they actually ever did anything about it, unless I'm mistaken:

cc @damienmg I recall there was a plan to put all the paths rooted with the project name. That never shipped right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's a better way to deal with this, I would be happy to do that instead. Frankly I just cribbed this from what the java_proto_library tool is doing

@damienmg
Copy link
Contributor

damienmg commented Oct 3, 2017 via email

@azymnis
Copy link
Contributor Author

azymnis commented Oct 4, 2017

@johnynek ok I think this is better: I changed it only accept proto_library and java_proto_library deps and pushed the logic of figuring out jar dependencies into the rule implementation.

Note: I had to modify a couple of scala.bzl methods to be public instead of private (and also deleted a method that could be removed in scrooge). Let me know if that looks ok.

@ittaiz
Copy link
Contributor

ittaiz commented Oct 4, 2017 via email

@azymnis
Copy link
Contributor Author

azymnis commented Oct 4, 2017

@ittaiz happy to do this refactor. How can I limit a .bzl file to only be accessible from within this repo?

@johnynek
Copy link
Contributor

johnynek commented Oct 4, 2017

I think this is good.

We already had duplication about collection of jars and many scala/java related code want this.

The alternative is copy-paste.

I'm +1 on this PR.

@ittaiz
Copy link
Contributor

ittaiz commented Oct 5, 2017 via email

@johnynek
Copy link
Contributor

johnynek commented Oct 5, 2017

@ittaiz how do you apply visibility to .bzl files? I thought that was for rules. Can you give a concrete example?

I am fine with the refactoring he has done as it stands now. If it is easy to mark bazel functions or files with visibility then great, but I didn’t know we could.

@ittaiz
Copy link
Contributor

ittaiz commented Oct 5, 2017 via email

Copy link
Contributor

@ittaiz ittaiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I skimmed the PR and it looks good in general but if I'm not mistaken there's no test for the external repo problem right? Can we add one for it?

Btw, sorry for having sparse time for the proto area. I hope to free up some time to dive into it so i can share the review load

@azymnis
Copy link
Contributor Author

azymnis commented Oct 5, 2017

@ittaiz yup tests would be good but I think that would require adding an external repo dependency in WORKSPACE. Let me know if I should do that. Should I add a personal repo for this?

@johnynek
Copy link
Contributor

johnynek commented Oct 5, 2017

@azymnis you can have a nested WORKSPACE I think and use that in tests.

But this is a bit of a yak shave if you ask me. With a nested WORKSPACE I think you have to set up --deleted-packages or something to prevent the outer build from finding it.

@azymnis
Copy link
Contributor Author

azymnis commented Oct 5, 2017

@johnynek @ittaiz I'll let you two decide on this. If you feel very strongly that I should add tests for external, I will do so. The current tests at least prove that this doesn't break the non external use cases (which I suspect are much more common). I verified locally that this works for us.

@johnynek
Copy link
Contributor

johnynek commented Oct 5, 2017

personally I'm happy to merge and add an issue.

When we don't have good examples of how to do a test, I'm -1 on asking contributors to shave a new yak to fix a bug they can observe. If we can test it with existing or simple patterns I would say okay, but having used a nested workspace internally it is a pain, and I don't want to rush to it.

@azymnis
Copy link
Contributor Author

azymnis commented Oct 5, 2017

@johnynek seems like travis-ci had another transient download issue

@johnynek johnynek merged commit 0bac7fe into bazel-contrib:master Oct 5, 2017
@johnynek
Copy link
Contributor

johnynek commented Oct 5, 2017

sorry for the latency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants