Skip to content
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

Copy the protos we need into a temp folder #848

Closed

Conversation

ianoc-stripe
Copy link
Contributor

Description

We have errors around colliding files. The copying is putting things into trees that aren't part of the sandbox per build.

Eventually i believe the virtual_imports work will be a nicer solution to this, but from what i can tell part of it is still behind a flag. I wasn't quite sure exactly how to implement it all using that today. So for now instead of copying some stuff around and maybe colliding. Just copy everything into a temp location.

Also we weren't getting any error messages from protoc when run for scalapb so i made some changes here to redirect the output to a file and reply it back so we now get the error messages

Motivation

Errors/problems in the copying approach

@ianoc-stripe
Copy link
Contributor Author

fixes #843

@johnynek
Copy link
Member

Thanks for tackling!

looks like legit test failures.

try {
val ret = new ProcessBuilder(protoc.toString +: args: _*).redirectErrorStream(true).redirectOutput(ProcessBuilder.Redirect.to(tmpFile.toFile)).start().waitFor()
Try {
scala.io.Source.fromFile(tmpFile.toFile).getLines.foreach{System.out.println}
Copy link
Member

Choose a reason for hiding this comment

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

this looks like debug. Can we remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is how we get the stdout/stderr from protoc into the bazel output stream. So can't remove.

(prior to this PR any failure in protoc would result in just seeing a message that it exited with code 1 and no further info)

Copy link
Member

Choose a reason for hiding this comment

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

oh yeah... I overlooked that. nit: can we do foreach(System.out.println) (use parens rather than {} when passing a method as a function argument)?

Copy link
Member

@johnynek johnynek left a comment

Choose a reason for hiding this comment

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

Looks good. I had some minor style nits if you have time/interest.

}.collect {
// if the to compile files contains this absolute path then we are compiling it and shoudln't try move it around(duplicate files.)
case (Some(k), v) if !protoFiles.contains(v) => (Paths.get(k), Paths.get(v))
val protoFilesToBuild = protoFiles.map { e => s"${tmpDir.toFile.toString}/${stripToVirtual(e)}"}
Copy link
Member

Choose a reason for hiding this comment

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

nit, you don't need .toString inside the interpolation. Also, I think just $tmpDir/${stripToVirtual(e)} should work. Why do we need to convert to File?

val protoFilesToBuild = protoFiles.map { e => s"${tmpDir.toFile.toString}/${stripToVirtual(e)}"}

val includedProtoSplit: List[(String, String)] = args.get(1).drop(1).split(':').map { e =>
val arr = e.split(',')
Copy link
Member

Choose a reason for hiding this comment

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

want to add a require(arr.length == 2, s"expected exactly two comma separated items in ${arr.toList}") just to guard against anything funny changing later?

val arr = e.split(',')
(arr(0), arr(1))
}.toList
val includedProto: List[(Path, Path)] = (includedProtoSplit ++ protoFiles.toList.map { e => ("", e)}).distinct.map { case (repoPath, protoPath) =>
Copy link
Member

Choose a reason for hiding this comment

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

nit: can we make this line not quite so long? Maybe newline after the ) concatenating the two lists?

(Paths.get(protoPath), relativePath)
} else {
(Paths.get(protoPath), Paths.get(protoPath))
}
}.toList
Copy link
Member

Choose a reason for hiding this comment

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

isn't this already a list?

@@ -27,7 +55,7 @@ object PBGenerateRequest {
case "-" => Nil
case s if s.charAt(0) == '-' => s.tail.split(':').toList //drop padding character
case other => sys.error(s"expected a padding character of - (dash), but found: $other")
}) ++ List(".")
}) ++ List("")
Copy link
Member

Choose a reason for hiding this comment

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

::: List("") I think is a bit more efficient on lists than ++ but maybe not...

try {
val ret = new ProcessBuilder(protoc.toString +: args: _*).redirectErrorStream(true).redirectOutput(ProcessBuilder.Redirect.to(tmpFile.toFile)).start().waitFor()
Try {
scala.io.Source.fromFile(tmpFile.toFile).getLines.foreach{System.out.println}
Copy link
Member

Choose a reason for hiding this comment

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

oh yeah... I overlooked that. nit: can we do foreach(System.out.println) (use parens rather than {} when passing a method as a function argument)?

Copy link
Member

@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.

Thanks for tackling this!
I'm approving this but to be honest I feel I don't fully understand the change and I feel there is a lot of noise in the current implementation.
@lberki @Yannic I wonder if maybe we need to do some collaboration here since it seems to me we can either improve Bazel by identifying (and later removing) proto related boilerplate we needed to do here, improve rules_scala by dropping old/unneeded/mistaken workarounds we have, or even improve both. WDYT?

@Yannic
Copy link
Contributor

Yannic commented Sep 22, 2019

I agree that writing these rules isn't as easy as it could be. We have a design doc in review that proposes some helper functions to improve this situation (cmp. p 3-5), however they assume that the generator is a protoc plugin. From what I've seen, rules_scala uses a persistent worker for this (I assume because of legacy reasons and/or startup time?), so there's probably some work required to make it work but I'm confident you'll be able to reuse at least some of the functionality.

@ignasl
Copy link
Contributor

ignasl commented Sep 23, 2019

Specifically for the issue #843 and our own build problems I might have a smaller fix that actually avoids copying altogether. I will send a PR for consideration.

@ignasl
Copy link
Contributor

ignasl commented Sep 23, 2019

See: #850

@ianoc
Copy link
Contributor

ianoc commented Sep 30, 2019

Closing in favor of #850

@ianoc-stripe ianoc-stripe deleted the ianoc/useVirtualImports branch September 30, 2019 15:43
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.

7 participants