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
Relative paths in error messages #2736
Conversation
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
20d890d
to
835dda8
Compare
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 for working on this.
Several comments below though.
go/tools/builders/env.go
Outdated
return output | ||
} | ||
if !strings.HasSuffix(dir, "/") { | ||
dir += "/" |
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.
This won't work on Windows.
Also, I don't think this will replace the path itself with .
.
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.
Updated to use filepath.PathSeparator.
You're correct - if Getwd
appeared in an error message with no following separator, it would not be converted to .
. Do you think that's worth adding a case for?
It seems unlikely to come up, and I have a personal preference for e.g. path/to.go
instead of ./path/to.go
which would allow an implementation that "just works" for this case, so I'd be inclined to leave as-is.
Before: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/28708/execroot/corp/gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/29923/execroot/corp/gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak After: gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak Fixes bazelbuild#2061
835dda8
to
54df87e
Compare
Thanks for the review. I made all the updates you requested, with one caveat about the |
go/tools/builders/env.go
Outdated
} | ||
|
||
// runCommandToFile executes a subprocess and writes the output to the given | ||
// writer. | ||
func (e *env) runCommandToFile(w io.Writer, args []string) error { | ||
cmd := exec.Command(args[0], args[1:]...) | ||
var stderr bytes.Buffer |
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 make sure this function doesn't change. It needs to produce a file, and we shouldn't alter the content of that file.
Maybe some other function can call runAndLogCommand
with a *bytes.Buffer
, then relativizePaths
on that and copy to os.Stderr
? Then neither runAndLogCommand
nor this function need to 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.
This is a lot cleaner, very good idea!
go/tools/builders/env.go
Outdated
if verbose { | ||
fmt.Fprintln(os.Stderr, formatCommand(cmd)) | ||
} | ||
cleanup := passLongArgsInResponseFiles(cmd) | ||
defer cleanup() | ||
if err := cmd.Run(); err != nil { | ||
err := cmd.Run() | ||
os.Stderr.Write(relativizePaths(stderr.Bytes())) |
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.
In general, use fmt.Fprint
or io.Copy
when writing to an *os.File
or any unknown kind of io.Writer
. The Write
may write fewer bytes than its given, and it's important to keep calling it until there's nothing left to write.
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.
Good point, done.
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 was wrong about this: io.Copy
returns early if a Write
call doesn't write the entire slice. I was thinking of Read
, which may return fewer bytes without error. I get them confused, since they're different than the read
and write
system calls.
No need to change anything, just wanted to point that out.
go/tools/builders/env.go
Outdated
@@ -60,6 +60,8 @@ type env struct { | |||
workDirPath string | |||
|
|||
shouldPreserveWorkDir bool | |||
|
|||
execDir string |
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.
It doesn't look like this is actually used anymore. Can it be removed?
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.
Good catch, removed
go/tools/builders/env.go
Outdated
@@ -332,6 +339,21 @@ func absArgs(args []string, flags []string) { | |||
} | |||
} | |||
|
|||
// relativizePaths converts absolute paths found in the given output string to | |||
// relative, if they are within the PWD. |
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.
Replace PWD
here with working directory
. PWD
means "print working directory", and since we're not printing it, I don't think we should use that acronym here.
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.
TIL! I always thought it was "present working directory". Now the distinction between pwd and cwd makes more sense to me. Thanks
go/tools/builders/env.go
Outdated
if !bytes.HasSuffix(dirBytes, []byte{filepath.Separator}) { | ||
dirBytes = append(dirBytes, filepath.Separator) | ||
} | ||
return bytes.ReplaceAll(output, dirBytes, nil) |
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.
It looks like this still doesn't convert the working directory to .
. For completeness, I think it ought to.
(I couldn't respond to the other comment chain; maybe there was a force push?)
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.
OK, I didn't add that because there didn't seem to be a use case and it complicates the code further, but it was easy enough to add.
Ah, I didn't know that a force push prevents response. In the future I'll avoid that
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 for the review! Updated.
Bump |
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. I took last week off, and I'm still catching up on everything.
Two more small comments. Looking good though.
go/tools/builders/env.go
Outdated
cmd.Stdout = w | ||
cmd.Stderr = os.Stderr | ||
return runAndLogCommand(cmd, e.verbose) | ||
return runAndLogCommandOutput(cmd, w, os.Stderr, e.verbose) |
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 be careful that runCommandToFile
does not relativize the output. It should just call runAndLogCommand
.
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.
Apologies, missed that requirement. Updated
go/tools/builders/env.go
Outdated
cmd.Stdout = os.Stderr | ||
cmd.Stderr = os.Stderr | ||
return runAndLogCommand(cmd, e.verbose) | ||
return runAndLogCommandOutput(cmd, os.Stderr, os.Stderr, e.verbose) |
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.
Instead of introducing runAndLogCommandOutput
, I think it would be simpler to add the relativization here, especially since runCommandToFile
should not use use it. Something like:
buf := &bytes.Buffer{}
cmd := exec.Command(args[0], args[1:]...)
// Redirecting stdout to stderr. This mirrors behavior in the go command:
// https://go.googlesource.com/go/+/refs/tags/go1.15.2/src/cmd/go/internal/work/exec.go#1958 cmd.Stdout = os.Stderr
cmd.Stdout = buf
cmd.Stderr = buf
err := runAndLogCommand(cmd, e.verbose)
fmt.Fprint(os.Stderr, relativizePaths(buf.Bytes())
return err
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.
LGTM! Updated
Updated, thanks for the review! |
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.
Looks good, thanks for fixing this!
Use os.Stderr.Write instead of fmt.Fprint. The latter formats the value as a []byte, not a string. (This was due to my own bad review comment on bazelbuild#2736. Sorry.
Use os.Stderr.Write instead of fmt.Fprint. The latter formats the value as a []byte, not a string. (This was due to my own bad review comment on bazelbuild#2736. Sorry.)
Use os.Stderr.Write instead of fmt.Fprint. The latter formats the value as a []byte, not a string. (This was due to my own bad review comment on #2736. Sorry.)
Before: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/28708/execroot/corp/gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/29923/execroot/corp/gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak After: gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak Fixes #2061
Use os.Stderr.Write instead of fmt.Fprint. The latter formats the value as a []byte, not a string. (This was due to my own bad review comment on #2736. Sorry.)
Before: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/28708/execroot/corp/gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: /private/var/tmp/_bazel_robfig/1db08896ecff7e5e96a745981c3b77e6/sandbox/darwin-sandbox/29923/execroot/corp/gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak After: gocode/src/corp/analytics/searchterms/redshiftcopier.go:14:2: imported and not used: "corp/net/rpc" compilepkg: nogo: errors found by nogo during build-time code analysis: gocode/src/corp/net/rpc/server.go:125:7: the cancel function returned by context.WithTimeout should be called, not discarded, to avoid a context leak Fixes #2061
Use os.Stderr.Write instead of fmt.Fprint. The latter formats the value as a []byte, not a string. (This was due to my own bad review comment on #2736. Sorry.)
What type of PR is this?
Feature
What does this PR do? Why is it needed?
Improve the error messages seen by everyday users of rules_go
Which issues(s) does this PR fix?
Fixes #2061