Skip to content

Commit

Permalink
add sourceInfoMap callback when printing warnings for with command.
Browse files Browse the repository at this point in the history
Signed-off-by: Talon Bowler <[email protected]>
  • Loading branch information
daghack committed Sep 4, 2024
1 parent c01c148 commit 6111e72
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 37 deletions.
13 changes: 11 additions & 2 deletions commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,17 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
res = sp.ExporterResponse
}

printArgs := &printResultArgs{
callFunc: pf,
res: res,
contextPath: req.Inputs.ContextPath,
dockerfileName: req.Inputs.DockerfilePath,
}
if callFormatJSON {
jsonResults[name] = map[string]any{}
buf := &bytes.Buffer{}
if code, err := printResult(buf, pf, res); err != nil {
printArgs.writer = buf
if code, err := printResult(printArgs); err != nil {
jsonResults[name]["error"] = err.Error()
exitCode = 1
} else if code != 0 && exitCode == 0 {
Expand All @@ -355,13 +362,15 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
} else {
sep = true
}

fmt.Fprintf(dockerCli.Out(), "%s\n", name)
if descr := tgts[name].Description; descr != "" {
fmt.Fprintf(dockerCli.Out(), "%s\n", descr)
}

fmt.Fprintln(dockerCli.Out())
if code, err := printResult(dockerCli.Out(), pf, res); err != nil {
printArgs.writer = dockerCli.Out()
if code, err := printResult(printArgs); err != nil {
fmt.Fprintf(dockerCli.Out(), "error: %v\n", err)
exitCode = 1
} else if code != 0 && exitCode == 0 {
Expand Down
101 changes: 66 additions & 35 deletions commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/moby/buildkit/frontend/subrequests/outline"
"github.com/moby/buildkit/frontend/subrequests/targets"
"github.com/moby/buildkit/solver/errdefs"
solverpb "github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/grpcerrors"
"github.com/moby/buildkit/util/progress/progressui"
"github.com/morikuni/aec"
Expand Down Expand Up @@ -387,7 +388,14 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
}
}
if opts.CallFunc != nil {
if exitcode, err := printResult(dockerCli.Out(), opts.CallFunc, resp.ExporterResponse); err != nil {
printArgs := &printResultArgs{
writer: os.Stdout,
callFunc: opts.CallFunc,
res: resp.ExporterResponse,
contextPath: options.contextPath,
dockerfileName: options.dockerfileName,
}
if exitcode, err := printResult(printArgs); err != nil {
return err
} else if exitcode != 0 {
os.Exit(exitcode)
Expand Down Expand Up @@ -882,38 +890,66 @@ func printWarnings(w io.Writer, warnings []client.VertexWarning, mode progressui
}
}

func printResult(w io.Writer, f *controllerapi.CallFunc, res map[string]string) (int, error) {
switch f.Name {
type printResultArgs struct {
writer io.Writer
callFunc *controllerapi.CallFunc
res map[string]string
contextPath string
dockerfileName string
}

func printResult(printArgs *printResultArgs) (int, error) {
switch printArgs.callFunc.Name {
case "outline":
return 0, printValue(w, outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res)
return 0, printValue(printArgs, outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version)
case "targets":
return 0, printValue(w, targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res)
return 0, printValue(printArgs, targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version)
case "subrequests.describe":
return 0, printValue(w, subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res)
return 0, printValue(printArgs, subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version)
case "lint":
lintResults := lint.LintResults{}
if result, ok := res["result.json"]; ok {
if result, ok := printArgs.res["result.json"]; ok {
if err := json.Unmarshal([]byte(result), &lintResults); err != nil {
return 0, err
}
}

warningCount := len(lintResults.Warnings)
if f.Format != "json" && warningCount > 0 {
if printArgs.callFunc.Format != "json" && warningCount > 0 {
var warningCountMsg string
if warningCount == 1 {
warningCountMsg = "1 warning has been found!"
} else if warningCount > 1 {
warningCountMsg = fmt.Sprintf("%d warnings have been found!", warningCount)
}
fmt.Fprintf(w, "Check complete, %s\n", warningCountMsg)
fmt.Fprintf(printArgs.writer, "Check complete, %s\n", warningCountMsg)
}

sourceInfoMap := func(sourceInfo *solverpb.SourceInfo) *solverpb.SourceInfo {
newSourceInfo := &solverpb.SourceInfo{}
*newSourceInfo = *sourceInfo

contextPath := "."
if printArgs.contextPath != "" {
contextPath = printArgs.contextPath
}

dockerfileName := printArgs.dockerfileName
if dockerfileName == "" {
dockerfileName = filepath.Join(contextPath, "Dockerfile")
}

if strings.HasSuffix(dockerfileName, sourceInfo.Filename) {
newSourceInfo.Filename = dockerfileName
}
return newSourceInfo
}

lintPrintFunc := func(b []byte, w io.Writer) error {
return lintResults.PrintTo(w, nil)
return lintResults.PrintTo(w, sourceInfoMap)
}

err := printValue(w, lintPrintFunc, lint.SubrequestLintDefinition.Version, f.Format, res)
err := printValue(printArgs, lintPrintFunc, lint.SubrequestLintDefinition.Version)
if err != nil {
return 0, err
}
Expand All @@ -923,32 +959,27 @@ func printResult(w io.Writer, f *controllerapi.CallFunc, res map[string]string)
// Normally, we would use `errdefs.WithSource` to attach the source to the
// error and let the error be printed by the handling that's already in place,
// but here we want to print the error in a way that's consistent with how
// the lint warnings are printed via the `lint.PrintLintViolations` function,
// the lint warnings are printed via the `lintResults.PrintTo` function,
// which differs from the default error printing.
if f.Format != "json" && len(lintResults.Warnings) > 0 {
fmt.Fprintln(w)
}
lintBuf := bytes.NewBuffer([]byte(lintResults.Error.Message + "\n"))
sourceInfo := lintResults.Sources[lintResults.Error.Location.SourceIndex]
source := errdefs.Source{
Info: sourceInfo,
Ranges: lintResults.Error.Location.Ranges,
if printArgs.callFunc.Format != "json" && len(lintResults.Warnings) > 0 {
fmt.Fprintln(printArgs.writer)
}
source.Print(lintBuf)
lintBuf := bytes.NewBuffer(nil)
lintResults.PrintErrorTo(lintBuf)
return 0, errors.New(lintBuf.String())
} else if len(lintResults.Warnings) == 0 && f.Format != "json" {
fmt.Fprintln(w, "Check complete, no warnings found.")
} else if len(lintResults.Warnings) == 0 && printArgs.callFunc.Format != "json" {
fmt.Fprintln(printArgs.writer, "Check complete, no warnings found.")
}
default:
if dt, ok := res["result.json"]; ok && f.Format == "json" {
fmt.Fprintln(w, dt)
} else if dt, ok := res["result.txt"]; ok {
fmt.Fprint(w, dt)
if dt, ok := printArgs.res["result.json"]; ok && printArgs.callFunc.Format == "json" {
fmt.Fprintln(printArgs.writer, dt)
} else if dt, ok := printArgs.res["result.txt"]; ok {
fmt.Fprint(printArgs.writer, dt)
} else {
fmt.Fprintf(w, "%s %+v\n", f, res)
fmt.Fprintf(printArgs.writer, "%s %+v\n", printArgs.callFunc, printArgs.res)
}
}
if v, ok := res["result.statuscode"]; !f.IgnoreStatus && ok {
if v, ok := printArgs.res["result.statuscode"]; !printArgs.callFunc.IgnoreStatus && ok {
if n, err := strconv.Atoi(v); err == nil && n != 0 {
return n, nil
}
Expand All @@ -958,18 +989,18 @@ func printResult(w io.Writer, f *controllerapi.CallFunc, res map[string]string)

type callFunc func([]byte, io.Writer) error

func printValue(w io.Writer, printer callFunc, version string, format string, res map[string]string) error {
if format == "json" {
fmt.Fprintln(w, res["result.json"])
func printValue(printArgs *printResultArgs, printer callFunc, version string) error {
if printArgs.callFunc.Format == "json" {
fmt.Fprintln(printArgs.writer, printArgs.res["result.json"])
return nil
}

if res["version"] != "" && versions.LessThan(version, res["version"]) && res["result.txt"] != "" {
if printArgs.res["version"] != "" && versions.LessThan(version, printArgs.res["version"]) && printArgs.res["result.txt"] != "" {
// structure is too new and we don't know how to print it
fmt.Fprint(w, res["result.txt"])
fmt.Fprint(printArgs.writer, printArgs.res["result.txt"])
return nil
}
return printer([]byte(res["result.json"]), w)
return printer([]byte(printArgs.res["result.json"]), printArgs.writer)
}

type invokeConfig struct {
Expand Down

0 comments on commit 6111e72

Please sign in to comment.