diff --git a/pkg/client/inspect_image.go b/pkg/client/inspect_image.go index 84fa04430..909d7b00c 100644 --- a/pkg/client/inspect_image.go +++ b/pkg/client/inspect_image.go @@ -2,6 +2,7 @@ package client import ( "context" + "fmt" "strings" "github.com/Masterminds/semver" @@ -88,6 +89,11 @@ const ( windowsPrefix = "c:" ) +type EnhancedProcess struct { + launch.Process + ArgsDisplay string +} + // InspectImage reads the Label metadata of an image. It initializes a ImageInfo object // using this metadata, and returns it. // If daemon is true, first the local registry will be searched for the image. @@ -173,16 +179,25 @@ func (c *Client) InspectImage(name string, daemon bool) (*ImageInfo, error) { } var processDetails ProcessDetails + + // Update to how processes are handled to include enhanced argument information. for _, proc := range buildMD.Processes { - proc := proc + enhancedProc := EnhancedProcess{ + Process: proc, + ArgsDisplay: formatArgsDisplay(proc.Args), // Utilize the new formatArgsDisplay to enhance arg visibility + } + if proc.WorkingDirectory == "" { - proc.WorkingDirectory = workingDir + enhancedProc.WorkingDirectory = workingDir } + if proc.Type == defaultProcessType { - processDetails.DefaultProcess = &proc + defaultProc := enhancedProc.Process + processDetails.DefaultProcess = &defaultProc continue } - processDetails.OtherProcesses = append(processDetails.OtherProcesses, proc) + + processDetails.OtherProcesses = append(processDetails.OtherProcesses, enhancedProc.Process) } var stackCompat files.Stack @@ -229,3 +244,20 @@ func getRebasableLabel(labeled dist.Labeled) (bool, error) { return rebasableOutput, nil } + +func formatArgsDisplay(args []string) string { + if len(args) == 0 { + return "" // Indicates no arguments are present. + } + + var result strings.Builder + result.WriteString(fmt.Sprintf("(count = %d) ", len(args))) + for _, arg := range args { + if arg == "" { + result.WriteString(`"" `) // Represent empty string arguments visibly. + } else { + result.WriteString(fmt.Sprintf("%q ", arg)) + } + } + return strings.TrimSpace(result.String()) +} diff --git a/pkg/client/inspect_image_test.go b/pkg/client/inspect_image_test.go index 1ab862ae1..48ceaff05 100644 --- a/pkg/client/inspect_image_test.go +++ b/pkg/client/inspect_image_test.go @@ -1023,3 +1023,67 @@ func testInspectImage(t *testing.T, when spec.G, it spec.S) { }) }) } + +func TestArgumentParsing(t *testing.T) { + spec.Run(t, "Argument Parsing", testArgumentParsing, spec.Parallel(), spec.Report(report.Terminal{})) +} + +func testArgumentParsing(t *testing.T, when spec.G, it spec.S) { + var ( + mockController *gomock.Controller + mockImageFetcher *testmocks.MockImageFetcher + subject *Client + out bytes.Buffer + ) + + it.Before(func() { + mockController = gomock.NewController(t) + mockImageFetcher = testmocks.NewMockImageFetcher(mockController) + + var err error + subject, err = NewClient(WithLogger(logging.NewLogWithWriters(&out, &out)), WithFetcher(mockImageFetcher)) + h.AssertNil(t, err) + }) + + it.After(func() { + mockController.Finish() + }) + + when("inspecting images with different argument configurations", func() { + it("properly displays the arguments", func() { + images := map[string]string{ + "imageNoArgs": `[]`, + "imageEmptyArgs": `[""]`, + "imageNonEmptyArgs": `["-p", "8080"]`, + } + + for imageName, args := range images { + mockImage := testmocks.NewImage(imageName, "", nil) + h.AssertNil(t, mockImage.SetLabel("io.buildpacks.build.metadata", fmt.Sprintf(`{ + "processes": [ + { + "type": "web", + "command": "/start/web-process", + "args": %s, + "direct": false + } + ] + }`, args))) + + mockImageFetcher.EXPECT().Fetch(gomock.Any(), imageName, gomock.Any()).Return(mockImage, nil).Times(1) + + info, err := subject.InspectImage(imageName, true) + h.AssertNil(t, err) + + switch args { + case `[]`: + h.AssertEq(t, info.Processes.DefaultProcess.Args, []string{}) + case `[""]`: + h.AssertEq(t, info.Processes.DefaultProcess.Args, []string{""}) + default: + h.AssertEq(t, info.Processes.DefaultProcess.Args, []string{"-p", "8080"}) + } + } + }) + }) +}