mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 17:31:43 +00:00
fix(sg): make sg gen output more readable (#64406)
Closes DINF-78 The output of `sg gen` is a bit hard to read when there's an error, this is because the new line character `\n` isn't rendered as a new line. It turns out the `%q` formatting directive used to quote a string doesn't render the `\n` character as a new line. | Before | |---| |  | | After | |---| |  | I also added a func to extract error messages from a bazel command to avoid long output message when a bazel command fails and give the user relevant messages related to the error. | Before | |---| https://github.com/user-attachments/assets/2d029ec1-5804-41bf-a675-8642e169ea80 | After | |---| |  | ## Test plan <!-- REQUIRED; info at https://docs-legacy.sourcegraph.com/dev/background-information/testing_principles --> * Manual testing ## Changelog <!-- OPTIONAL; info at https://www.notion.so/sourcegraph/Writing-a-changelog-entry-dd997f411d524caabf0d8d38a24a878c -->
This commit is contained in:
parent
67f30a9d7a
commit
4d57eb1188
@ -654,7 +654,7 @@ var docsCommand = &cli.Command{
|
||||
Usage: "Render reference documentation for build pipeline types",
|
||||
Action: func(ctx *cli.Context) error {
|
||||
cmd := exec.Command("go", "run", "./dev/ci/gen-pipeline.go", "-docs")
|
||||
out, err := run.InRoot(cmd)
|
||||
out, err := run.InRoot(cmd, run.InRootArgs{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -56,7 +56,8 @@ var allGenerateTargets = generateTargets{
|
||||
}
|
||||
|
||||
func generateBazelRunner(ctx context.Context, args []string) *generate.Report {
|
||||
return generate.RunScript("bazel run //dev:write_all_generated")(ctx, args)
|
||||
runnerFunc := generate.RunScript("bazel run //dev:write_all_generated", true)
|
||||
return runnerFunc(ctx, args)
|
||||
}
|
||||
|
||||
func generateGoRunner(ctx context.Context, args []string) *generate.Report {
|
||||
|
||||
@ -34,10 +34,12 @@ type Target struct {
|
||||
// RunScript runs the given script from the root of sourcegraph/sourcegraph.
|
||||
// If arguments are to be to passed down the script, they should be incorporated
|
||||
// in the script variable.
|
||||
func RunScript(command string) Runner {
|
||||
func RunScript(command string, extractBazelError bool) Runner {
|
||||
return func(ctx context.Context, args []string) *Report {
|
||||
start := time.Now()
|
||||
out, err := run.BashInRoot(ctx, command, nil)
|
||||
out, err := run.BashInRoot(ctx, command, run.BashInRootArgs{
|
||||
ExtractBazelError: extractBazelError,
|
||||
})
|
||||
return &Report{
|
||||
Output: out,
|
||||
Err: err,
|
||||
|
||||
@ -327,13 +327,13 @@ func setupLocalDatabase(databaseName string) (_ func(error) error, err error) {
|
||||
|
||||
createLocalDatabase := func() error {
|
||||
cmd := exec.Command("createdb", databaseName)
|
||||
_, err := run.InRoot(cmd)
|
||||
_, err := run.InRoot(cmd, run.InRootArgs{})
|
||||
return err
|
||||
}
|
||||
|
||||
dropLocalDatabase := func() error {
|
||||
cmd := exec.Command("dropdb", databaseName)
|
||||
_, err := run.InRoot(cmd)
|
||||
_, err := run.InRoot(cmd, run.InRootArgs{})
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ go_library(
|
||||
"//dev/sg/interrupt",
|
||||
"//dev/sg/root",
|
||||
"//internal/download",
|
||||
"//internal/lazyregexp",
|
||||
"//lib/errors",
|
||||
"//lib/output",
|
||||
"//lib/process",
|
||||
|
||||
@ -108,9 +108,11 @@ func (cmd Command) hasBashInstaller() bool {
|
||||
}
|
||||
|
||||
func (cmd Command) bashInstall(ctx context.Context, parentEnv map[string]string) error {
|
||||
output, err := BashInRoot(ctx, cmd.Install, makeEnv(parentEnv, cmd.Config.Env))
|
||||
out, err := BashInRoot(ctx, cmd.Install, BashInRootArgs{
|
||||
Env: makeEnv(parentEnv, cmd.Config.Env),
|
||||
})
|
||||
if err != nil {
|
||||
return installErr{cmdName: cmd.Config.Name, output: output, originalErr: err}
|
||||
return installErr{cmdName: cmd.Config.Name, output: out, originalErr: err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/dev/sg/root"
|
||||
"github.com/sourcegraph/sourcegraph/internal/lazyregexp"
|
||||
)
|
||||
|
||||
func GitCmd(args ...string) (string, error) {
|
||||
@ -19,11 +20,11 @@ func GitCmd(args ...string) (string, error) {
|
||||
// And also not any other, because they can mess up output, change defaults, .. which can do unexpected things.
|
||||
"GIT_CONFIG=/dev/null")
|
||||
|
||||
return InRoot(cmd)
|
||||
return InRoot(cmd, InRootArgs{})
|
||||
}
|
||||
|
||||
func DockerCmd(args ...string) (string, error) {
|
||||
return InRoot(exec.Command("docker", args...))
|
||||
return InRoot(exec.Command("docker", args...), InRootArgs{})
|
||||
}
|
||||
|
||||
type errorWithoutOutputer interface {
|
||||
@ -37,7 +38,8 @@ type cmdInRootErr struct {
|
||||
}
|
||||
|
||||
func (e cmdInRootErr) Error() string {
|
||||
return fmt.Sprintf("'%s' failed: err = %q, output = %q", strings.Join(e.args, " "), e.err.Error(), e.output)
|
||||
return fmt.Sprintf(`'%s' failed: err = "%s", output = "%s"`, strings.Join(e.args, " "), e.err.Error(), e.output)
|
||||
|
||||
}
|
||||
|
||||
func (e cmdInRootErr) ErrorWithoutOutput() string {
|
||||
@ -46,7 +48,11 @@ func (e cmdInRootErr) ErrorWithoutOutput() string {
|
||||
|
||||
func (e cmdInRootErr) Unwrap() error { return e.err }
|
||||
|
||||
func InRoot(cmd *exec.Cmd) (string, error) {
|
||||
type InRootArgs struct {
|
||||
ExtractBazelError bool
|
||||
}
|
||||
|
||||
func InRoot(cmd *exec.Cmd, args InRootArgs) (string, error) {
|
||||
repoRoot, err := root.RepositoryRoot()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -55,12 +61,33 @@ func InRoot(cmd *exec.Cmd) (string, error) {
|
||||
cmd.Dir = repoRoot
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return string(out), cmdInRootErr{err: err, args: cmd.Args, output: string(out)}
|
||||
output := string(out)
|
||||
if args.ExtractBazelError {
|
||||
// this is still experimental and currently only works for bazel errors
|
||||
output = bazelErrorExtractor(out)
|
||||
}
|
||||
return string(out), cmdInRootErr{err: err, args: cmd.Args, output: output}
|
||||
}
|
||||
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
// `(?m)` enables multiline mode, `^` matches the start of each line
|
||||
var errorRegex = lazyregexp.New(`(?m)^ERROR:.*$`)
|
||||
|
||||
func bazelErrorExtractor(input []byte) string {
|
||||
// Find all matches
|
||||
matches := errorRegex.FindAll(input, -1)
|
||||
|
||||
// Convert [][]byte to string
|
||||
var errorLines string
|
||||
for _, match := range matches {
|
||||
errorLines += string(match) + "\n"
|
||||
}
|
||||
|
||||
return errorLines
|
||||
}
|
||||
|
||||
func SplitOutputInRoot(cmd *exec.Cmd, stdout, stderr io.Writer) error {
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
@ -72,10 +99,17 @@ func SplitOutputInRoot(cmd *exec.Cmd, stdout, stderr io.Writer) error {
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func BashInRoot(ctx context.Context, cmd string, env []string) (string, error) {
|
||||
type BashInRootArgs struct {
|
||||
Env []string
|
||||
ExtractBazelError bool
|
||||
}
|
||||
|
||||
func BashInRoot(ctx context.Context, cmd string, args BashInRootArgs) (string, error) {
|
||||
c := exec.CommandContext(ctx, "bash", "-c", cmd)
|
||||
c.Env = env
|
||||
return InRoot(c)
|
||||
c.Env = args.Env
|
||||
return InRoot(c, InRootArgs{
|
||||
ExtractBazelError: args.ExtractBazelError,
|
||||
})
|
||||
}
|
||||
|
||||
func TrimResult(s string, err error) (string, error) {
|
||||
|
||||
@ -103,7 +103,9 @@ func (d *diagnosticRunner) Run(ctx context.Context) DiagnosticReport {
|
||||
for group, diagnostics := range d.diagnostics.Diagnostic {
|
||||
d.reporter.WriteLine(output.Emojif("💊", "Running %s diagnostics", group))
|
||||
for _, diagnostic := range diagnostics {
|
||||
out, err := run.BashInRoot(ctx, diagnostic.Cmd, env)
|
||||
out, err := run.BashInRoot(ctx, diagnostic.Cmd, run.BashInRootArgs{
|
||||
Env: env,
|
||||
})
|
||||
diag := diagnostic
|
||||
report.Add(group, &DiagnosticResult{
|
||||
&diag,
|
||||
|
||||
@ -93,7 +93,7 @@ func changelogExec(ctx *cli.Context) error {
|
||||
|
||||
gitLog := exec.Command("git", append(logArgs, "--", "./dev/sg")...)
|
||||
gitLog.Env = os.Environ()
|
||||
out, err := run.InRoot(gitLog)
|
||||
out, err := run.InRoot(gitLog, run.InRootArgs{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -85,6 +85,10 @@ func (r *Regexp) FindAllIndex(b []byte, n int) [][]int {
|
||||
return r.Re().FindAllIndex(b, n)
|
||||
}
|
||||
|
||||
func (r *Regexp) FindAll(b []byte, n int) [][]byte {
|
||||
return r.Re().FindAll(b, n)
|
||||
}
|
||||
|
||||
func (r *Regexp) Match(b []byte) bool {
|
||||
return r.Re().Match(b)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user