From 99c29578fda759f6c7d1d4cf9f1bcd8d7b29980e Mon Sep 17 00:00:00 2001 From: Nick Adcock Date: Tue, 19 Nov 2019 11:33:19 +0000 Subject: [PATCH 1/4] Image inspect non-app CNABs Allow `image inspect` of CNABs not created with docker app. The command will output basic information that is read from the bundle.json file including: * metadata (version, name, description, maintainers) * services (name and image) * parameters (including default values if present) Signed-off-by: Nick Adcock --- internal/commands/image/inspect.go | 8 +- internal/inspect/inspect.go | 43 ++++ internal/inspect/inspect_test.go | 17 ++ internal/inspect/testdata/bundle-json.golden | 183 ++++++++++++++++++ .../testdata/inspect-bundle-json.golden | 44 +++++ 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 internal/inspect/testdata/bundle-json.golden create mode 100644 internal/inspect/testdata/inspect-bundle-json.golden diff --git a/internal/commands/image/inspect.go b/internal/commands/image/inspect.go index 5228e020e..1b823870b 100644 --- a/internal/commands/image/inspect.go +++ b/internal/commands/image/inspect.go @@ -10,6 +10,7 @@ import ( "github.com/deislabs/cnab-go/action" "github.com/docker/app/internal" "github.com/docker/app/internal/cnab" + "github.com/docker/app/internal/inspect" appstore "github.com/docker/app/internal/store" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -88,7 +89,12 @@ func runInspect(dockerCli command.Cli, appname string, opts inspectOptions) erro installation.SetParameter(internal.ParameterInspectFormatName, format) - if err := a.Run(&installation.Claim, nil); err != nil { + err = a.Run(&installation.Claim, nil) + if err == action.ErrUndefinedAction { + err = inspect.ImageInspectCNAB(os.Stdout, bndl.Bundle, format) + } + + if err != nil { return fmt.Errorf("inspect failed: %s\n%s", err, errBuf) } return nil diff --git a/internal/inspect/inspect.go b/internal/inspect/inspect.go index 873b00a92..3d0235e01 100644 --- a/internal/inspect/inspect.go +++ b/internal/inspect/inspect.go @@ -114,6 +114,49 @@ func ImageInspect(out io.Writer, app *types.App, argParameters map[string]string return printImageAppInfo(out, appInfo, outputFormat) } +func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) error { + meta := metadata.AppMetadata{ + Description: bndl.Description, + Name: bndl.Name, + Version: bndl.Version, + Maintainers: []metadata.Maintainer{}, + } + for _, m := range bndl.Maintainers { + meta.Maintainers = append(meta.Maintainers, metadata.Maintainer{ + Name: m.Name, + Email: m.Email, + }) + } + + paramKeys := []string{} + params := map[string]string{} + for _, v := range bndl.Parameters { + paramKeys = append(paramKeys, v.Definition) + if d, ok := bndl.Definitions[v.Definition]; ok && d.Default != nil { + params[v.Definition] = fmt.Sprint(d.Default) + } else { + params[v.Definition] = "" + } + } + + services := []Service{} + for k, v := range bndl.Images { + services = append(services, Service{ + Name: k, + Image: v.Image, + }) + } + + appInfo := ImageAppInfo{ + Metadata: meta, + parametersKeys: paramKeys, + Parameters: params, + Services: services, + } + + return printImageAppInfo(out, appInfo, outputFormat) +} + func printAppInfo(out io.Writer, app AppInfo, format string) error { switch format { case "pretty": diff --git a/internal/inspect/inspect_test.go b/internal/inspect/inspect_test.go index 11f1e2bee..3753d851c 100644 --- a/internal/inspect/inspect_test.go +++ b/internal/inspect/inspect_test.go @@ -2,6 +2,7 @@ package inspect import ( "bytes" + "encoding/json" "fmt" "os" "testing" @@ -132,6 +133,22 @@ text: hello`), }) } +func TestImageInspectCNAB(t *testing.T) { + s := golden.Get(t, "bundle-json.golden") + var bndl bundle.Bundle + err := json.Unmarshal(s, &bndl) + assert.NilError(t, err) + + expected := golden.Get(t, "inspect-bundle-json.golden") + + outBuffer := new(bytes.Buffer) + err = ImageInspectCNAB(outBuffer, &bndl, "json") + assert.NilError(t, err) + + result := outBuffer.String() + assert.Equal(t, string(expected), result) +} + func testImageInspect(t *testing.T, dir *fs.Dir, testcase inspectTestCase, suffix string) { app, err := types.NewAppFromDefaultFiles(dir.Join(testcase.name)) assert.NilError(t, err) diff --git a/internal/inspect/testdata/bundle-json.golden b/internal/inspect/testdata/bundle-json.golden new file mode 100644 index 000000000..29018c6a6 --- /dev/null +++ b/internal/inspect/testdata/bundle-json.golden @@ -0,0 +1,183 @@ +{ + "schemaVersion": "v1.0.0", + "name": "packing", + "version": "0.1.0", + "description": "hello", + "maintainers": [ + { + "name": "dev1", + "email": "dev1@example.com" + }, + { + "name": "dev2", + "email": "dev2@example.com" + } + ], + "invocationImages": [ + { + "imageType": "docker", + "image": "test-image" + } + ], + "images": { + "app-watcher": { + "imageType": "docker", + "image": "watcher", + "description": "watcher" + }, + "debug": { + "imageType": "docker", + "image": "busybox:latest", + "description": "busybox:latest" + }, + "front": { + "imageType": "docker", + "image": "nginx", + "description": "nginx" + }, + "monitor": { + "imageType": "docker", + "image": "busybox:latest", + "description": "busybox:latest" + } + }, + "actions": { + "com.docker.app.inspect": { + "stateless": true + }, + "com.docker.app.render": { + "stateless": true + }, + "io.cnab.status": {}, + "io.cnab.status+json": {} + }, + "parameters": { + "com.docker.app.args": { + "definition": "com.docker.app.args", + "applyTo": [ + "install", + "upgrade" + ], + "destination": { + "path": "/cnab/app/args.json" + } + }, + "com.docker.app.inspect-format": { + "definition": "com.docker.app.inspect-format", + "applyTo": [ + "com.docker.app.inspect" + ], + "destination": { + "env": "DOCKER_INSPECT_FORMAT" + } + }, + "com.docker.app.kubernetes-namespace": { + "definition": "com.docker.app.kubernetes-namespace", + "applyTo": [ + "install", + "upgrade", + "uninstall", + "io.cnab.status" + ], + "destination": { + "env": "DOCKER_KUBERNETES_NAMESPACE" + } + }, + "com.docker.app.orchestrator": { + "definition": "com.docker.app.orchestrator", + "applyTo": [ + "install", + "upgrade", + "uninstall", + "io.cnab.status" + ], + "destination": { + "env": "DOCKER_STACK_ORCHESTRATOR" + } + }, + "com.docker.app.render-format": { + "definition": "com.docker.app.render-format", + "applyTo": [ + "com.docker.app.render" + ], + "destination": { + "env": "DOCKER_RENDER_FORMAT" + } + }, + "com.docker.app.share-registry-creds": { + "definition": "com.docker.app.share-registry-creds", + "destination": { + "env": "DOCKER_SHARE_REGISTRY_CREDS" + } + }, + "watcher.cmd": { + "definition": "watcher.cmd", + "destination": { + "env": "docker_param1" + } + } + }, + "credentials": { + "com.docker.app.registry-creds": { + "path": "/cnab/app/registry-creds.json" + }, + "docker.context": { + "path": "/cnab/app/context.dockercontext" + } + }, + "definitions": { + "com.docker.app.args": { + "default": "", + "description": "Arguments that are passed by file to the invocation image", + "title": "Arguments", + "type": "string" + }, + "com.docker.app.inspect-format": { + "default": "json", + "description": "Output format for the inspect command", + "enum": [ + "json", + "pretty" + ], + "title": "Inspect format", + "type": "string" + }, + "com.docker.app.kubernetes-namespace": { + "default": "", + "description": "Namespace in which to deploy", + "title": "Namespace", + "type": "string" + }, + "com.docker.app.orchestrator": { + "default": "", + "description": "Orchestrator on which to deploy", + "enum": [ + "", + "swarm", + "kubernetes" + ], + "title": "Orchestrator", + "type": "string" + }, + "com.docker.app.render-format": { + "default": "yaml", + "description": "Output format for the render command", + "enum": [ + "yaml", + "json" + ], + "title": "Render format", + "type": "string" + }, + "com.docker.app.share-registry-creds": { + "default": false, + "description": "Share registry credentials with the invocation image", + "title": "Share registry credentials", + "type": "boolean" + }, + "watcher.cmd": { + "default": "foo", + "type": "string" + } + } +} \ No newline at end of file diff --git a/internal/inspect/testdata/inspect-bundle-json.golden b/internal/inspect/testdata/inspect-bundle-json.golden new file mode 100644 index 000000000..d5ee75644 --- /dev/null +++ b/internal/inspect/testdata/inspect-bundle-json.golden @@ -0,0 +1,44 @@ +{ + "Metadata": { + "version": "0.1.0", + "name": "packing", + "description": "hello", + "maintainers": [ + { + "name": "dev1", + "email": "dev1@example.com" + }, + { + "name": "dev2", + "email": "dev2@example.com" + } + ] + }, + "Services": [ + { + "Name": "app-watcher", + "Image": "watcher" + }, + { + "Name": "debug", + "Image": "busybox:latest" + }, + { + "Name": "front", + "Image": "nginx" + }, + { + "Name": "monitor", + "Image": "busybox:latest" + } + ], + "Parameters": { + "com.docker.app.args": "", + "com.docker.app.inspect-format": "json", + "com.docker.app.kubernetes-namespace": "", + "com.docker.app.orchestrator": "", + "com.docker.app.render-format": "yaml", + "com.docker.app.share-registry-creds": "false", + "watcher.cmd": "foo" + } +} From 47e1e3aca053a24943a1a277acdd94a113d81782 Mon Sep 17 00:00:00 2001 From: Nick Adcock Date: Wed, 20 Nov 2019 10:53:14 +0000 Subject: [PATCH 2/4] Check CNAB for action before call inspect Checks the CNAB for the docker app inspect action before attempting to call inspect. If the action is not defined then inspect the CNAB bundle directly. Refactors the `hasAction` func to just check for the key instead of looping through the map. Signed-off-by: Nick Adcock --- internal/commands/image/inspect.go | 40 ++++++++++++++++-------------- internal/commands/inspect.go | 8 ++---- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/internal/commands/image/inspect.go b/internal/commands/image/inspect.go index 1b823870b..a4a75fe2c 100644 --- a/internal/commands/image/inspect.go +++ b/internal/commands/image/inspect.go @@ -69,33 +69,35 @@ func runInspect(dockerCli command.Cli, appname string, opts inspectOptions) erro if err != nil { return err } - installation, err := appstore.NewInstallation("custom-action", ref.String(), bndl) - if err != nil { - return err - } - driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, opts.InstallerContextOptions, os.Stdout) - if err != nil { - return err - } - a := &action.RunCustom{ - Action: internal.ActionInspectName, - Driver: driverImpl, - } format := "json" if opts.pretty { format = "pretty" } - installation.SetParameter(internal.ParameterInspectFormatName, format) - - err = a.Run(&installation.Claim, nil) - if err == action.ErrUndefinedAction { - err = inspect.ImageInspectCNAB(os.Stdout, bndl.Bundle, format) + installation, err := appstore.NewInstallation("custom-action", ref.String(), bndl) + if err != nil { + return err } - if err != nil { - return fmt.Errorf("inspect failed: %s\n%s", err, errBuf) + if _, hasAction := installation.Bundle.Actions[internal.ActionInspectName]; hasAction { + driverImpl, errBuf, err := cnab.SetupDriver(installation, dockerCli, opts.InstallerContextOptions, os.Stdout) + if err != nil { + return err + } + a := &action.RunCustom{ + Action: internal.ActionInspectName, + Driver: driverImpl, + } + + installation.SetParameter(internal.ParameterInspectFormatName, format) + if err = a.Run(&installation.Claim, nil); err != nil { + return fmt.Errorf("inspect failed: %s\n%s", err, errBuf) + } + } else { + if err = inspect.ImageInspectCNAB(os.Stdout, bndl.Bundle, format); err != nil { + return fmt.Errorf("inspect failed: %s", err) + } } return nil } diff --git a/internal/commands/inspect.go b/internal/commands/inspect.go index 1778a7831..af4b9aebc 100644 --- a/internal/commands/inspect.go +++ b/internal/commands/inspect.go @@ -132,10 +132,6 @@ func getContextOrchestrator(dockerCli command.Cli, orchestratorFlag string) (com } func hasAction(bndl *bundle.Bundle, actionName string) bool { - for key := range bndl.Actions { - if key == actionName { - return true - } - } - return false + _, ok := bndl.Actions[actionName] + return ok } From db258447b19625cc98d0fc7d1b6b6387c94861c8 Mon Sep 17 00:00:00 2001 From: Nick Adcock Date: Wed, 20 Nov 2019 11:16:32 +0000 Subject: [PATCH 3/4] Print image inspect metadata fields in PascalCase Prints the metadata fields in PascalCase when calling `app image inspect` to match the other fields. Fixed `FromBundle` func comment Signed-off-by: Nick Adcock --- e2e/testdata/app-inspect.golden | 16 ++++++++-------- .../inspect/testdata/inspect-bundle-json.golden | 16 ++++++++-------- .../inspect/testdata/inspect-full-json.golden | 12 ++++++------ .../testdata/inspect-no-description-json.golden | 10 +++++----- .../testdata/inspect-no-maintainers-json.golden | 4 ++-- .../testdata/inspect-no-parameters-json.golden | 12 ++++++------ .../testdata/inspect-overridden-json.golden | 4 ++-- types/metadata/metadata.go | 14 +++++++------- 8 files changed, 44 insertions(+), 44 deletions(-) diff --git a/e2e/testdata/app-inspect.golden b/e2e/testdata/app-inspect.golden index 3381246dc..7e2d91a8a 100644 --- a/e2e/testdata/app-inspect.golden +++ b/e2e/testdata/app-inspect.golden @@ -1,16 +1,16 @@ { "Metadata": { - "version": "1.1.0-beta1", - "name": "simple", - "description": "new fancy webapp with microservices", - "maintainers": [ + "Version": "1.1.0-beta1", + "Name": "simple", + "Description": "new fancy webapp with microservices", + "Maintainers": [ { - "name": "John Developer", - "email": "john.dev@example.com" + "Name": "John Developer", + "Email": "john.dev@example.com" }, { - "name": "Jane Developer", - "email": "jane.dev@example.com" + "Name": "Jane Developer", + "Email": "jane.dev@example.com" } ] }, diff --git a/internal/inspect/testdata/inspect-bundle-json.golden b/internal/inspect/testdata/inspect-bundle-json.golden index d5ee75644..8f1ffa8b3 100644 --- a/internal/inspect/testdata/inspect-bundle-json.golden +++ b/internal/inspect/testdata/inspect-bundle-json.golden @@ -1,16 +1,16 @@ { "Metadata": { - "version": "0.1.0", - "name": "packing", - "description": "hello", - "maintainers": [ + "Version": "0.1.0", + "Name": "packing", + "Description": "hello", + "Maintainers": [ { - "name": "dev1", - "email": "dev1@example.com" + "Name": "dev1", + "Email": "dev1@example.com" }, { - "name": "dev2", - "email": "dev2@example.com" + "Name": "dev2", + "Email": "dev2@example.com" } ] }, diff --git a/internal/inspect/testdata/inspect-full-json.golden b/internal/inspect/testdata/inspect-full-json.golden index ac829d86d..b46a4b983 100644 --- a/internal/inspect/testdata/inspect-full-json.golden +++ b/internal/inspect/testdata/inspect-full-json.golden @@ -1,12 +1,12 @@ { "Metadata": { - "version": "0.1.0", - "name": "myapp", - "description": "some description", - "maintainers": [ + "Version": "0.1.0", + "Name": "myapp", + "Description": "some description", + "Maintainers": [ { - "name": "dev", - "email": "dev@example.com" + "Name": "dev", + "Email": "dev@example.com" } ] }, diff --git a/internal/inspect/testdata/inspect-no-description-json.golden b/internal/inspect/testdata/inspect-no-description-json.golden index f0c47fa69..7071573a8 100644 --- a/internal/inspect/testdata/inspect-no-description-json.golden +++ b/internal/inspect/testdata/inspect-no-description-json.golden @@ -1,11 +1,11 @@ { "Metadata": { - "version": "0.1.0", - "name": "myapp", - "maintainers": [ + "Version": "0.1.0", + "Name": "myapp", + "Maintainers": [ { - "name": "dev", - "email": "dev@example.com" + "Name": "dev", + "Email": "dev@example.com" } ] } diff --git a/internal/inspect/testdata/inspect-no-maintainers-json.golden b/internal/inspect/testdata/inspect-no-maintainers-json.golden index 283d17f1c..1060a88d2 100644 --- a/internal/inspect/testdata/inspect-no-maintainers-json.golden +++ b/internal/inspect/testdata/inspect-no-maintainers-json.golden @@ -1,6 +1,6 @@ { "Metadata": { - "version": "0.1.0", - "name": "myapp" + "Version": "0.1.0", + "Name": "myapp" } } diff --git a/internal/inspect/testdata/inspect-no-parameters-json.golden b/internal/inspect/testdata/inspect-no-parameters-json.golden index 4b4c3da08..d57a23ffd 100644 --- a/internal/inspect/testdata/inspect-no-parameters-json.golden +++ b/internal/inspect/testdata/inspect-no-parameters-json.golden @@ -1,12 +1,12 @@ { "Metadata": { - "version": "0.1.0", - "name": "myapp", - "description": "some description", - "maintainers": [ + "Version": "0.1.0", + "Name": "myapp", + "Description": "some description", + "Maintainers": [ { - "name": "dev", - "email": "dev@example.com" + "Name": "dev", + "Email": "dev@example.com" } ] } diff --git a/internal/inspect/testdata/inspect-overridden-json.golden b/internal/inspect/testdata/inspect-overridden-json.golden index 72e0b0ea2..ca173ebe7 100644 --- a/internal/inspect/testdata/inspect-overridden-json.golden +++ b/internal/inspect/testdata/inspect-overridden-json.golden @@ -1,7 +1,7 @@ { "Metadata": { - "version": "0.1.0", - "name": "myapp" + "Version": "0.1.0", + "Name": "myapp" }, "Services": [ { diff --git a/types/metadata/metadata.go b/types/metadata/metadata.go index 280ee73e4..863491653 100644 --- a/types/metadata/metadata.go +++ b/types/metadata/metadata.go @@ -8,8 +8,8 @@ import ( // Maintainer represents one of the apps's maintainers type Maintainer struct { - Name string `json:"name"` - Email string `json:"email,omitempty"` + Name string + Email string `json:",omitempty"` } // Maintainers is a list of maintainers @@ -35,13 +35,13 @@ func (m Maintainer) String() string { // AppMetadata is the format of the data found inside the metadata.yml file type AppMetadata struct { - Version string `json:"version"` - Name string `json:"name"` - Description string `json:"description,omitempty"` - Maintainers Maintainers `json:"maintainers,omitempty"` + Version string + Name string + Description string `json:",omitempty"` + Maintainers Maintainers `json:",omitempty"` } -// Metadata extracts the docker-app metadata from the bundle +// FromBundle extracts the docker-app metadata from the bundle func FromBundle(bndl *bundle.Bundle) AppMetadata { meta := AppMetadata{ Name: bndl.Name, From 8908b28981b3dbc1921c2f3bac0775e43219e17e Mon Sep 17 00:00:00 2001 From: Nick Adcock Date: Wed, 20 Nov 2019 11:33:30 +0000 Subject: [PATCH 4/4] Remove App-only fields from CNAB image inspect out Removes the App-only SERVICE fields from the `app image inspect --pretty` output when inspecting a non-App CNAB: * REPLICAS * PORTS Added unit test for image inspect of CNABs with pretty format. Refactored parameter key sorting code to use simpler `sort.Strings()` Signed-off-by: Nick Adcock --- internal/inspect/inspect.go | 34 +++++++++++++------ internal/inspect/inspect_test.go | 14 ++++++-- .../testdata/inspect-bundle-pretty.golden | 24 +++++++++++++ 3 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 internal/inspect/testdata/inspect-bundle-pretty.golden diff --git a/internal/inspect/inspect.go b/internal/inspect/inspect.go index 3d0235e01..9b2fdfc9f 100644 --- a/internal/inspect/inspect.go +++ b/internal/inspect/inspect.go @@ -111,7 +111,7 @@ func ImageInspect(out io.Writer, app *types.App, argParameters map[string]string } outputFormat := os.Getenv(internal.DockerInspectFormatEnvVar) - return printImageAppInfo(out, appInfo, outputFormat) + return printImageAppInfo(out, appInfo, outputFormat, true) } func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) error { @@ -138,6 +138,7 @@ func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) e params[v.Definition] = "" } } + sort.Strings(paramKeys) services := []Service{} for k, v := range bndl.Images { @@ -146,6 +147,9 @@ func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) e Image: v.Image, }) } + sort.SliceStable(services, func(i, j int) bool { + return services[i].Name < services[j].Name + }) appInfo := ImageAppInfo{ Metadata: meta, @@ -154,7 +158,7 @@ func ImageInspectCNAB(out io.Writer, bndl *bundle.Bundle, outputFormat string) e Services: services, } - return printImageAppInfo(out, appInfo, outputFormat) + return printImageAppInfo(out, appInfo, outputFormat, false) } func printAppInfo(out io.Writer, app AppInfo, format string) error { @@ -168,10 +172,10 @@ func printAppInfo(out io.Writer, app AppInfo, format string) error { } } -func printImageAppInfo(out io.Writer, app ImageAppInfo, format string) error { +func printImageAppInfo(out io.Writer, app ImageAppInfo, format string, isApp bool) error { switch format { case "pretty": - return printTable(out, app) + return printTable(out, app, isApp) case "json": return printJSON(out, app) default: @@ -209,16 +213,24 @@ func printAppTable(out io.Writer, info AppInfo) error { return nil } -func printTable(out io.Writer, appInfo ImageAppInfo) error { +func printTable(out io.Writer, appInfo ImageAppInfo, isApp bool) error { // Add Meta data printYAML(out, appInfo.Metadata) // Add Service section - printSection(out, len(appInfo.Services), func(w io.Writer) { - for _, service := range appInfo.Services { - fmt.Fprintf(w, "%s\t%d\t%s\t%s\n", service.Name, service.Replicas, service.Ports, service.Image) - } - }, "SERVICE", "REPLICAS", "PORTS", "IMAGE") + if isApp { + printSection(out, len(appInfo.Services), func(w io.Writer) { + for _, service := range appInfo.Services { + fmt.Fprintf(w, "%s\t%d\t%s\t%s\n", service.Name, service.Replicas, service.Ports, service.Image) + } + }, "SERVICE", "REPLICAS", "PORTS", "IMAGE") + } else { + printSection(out, len(appInfo.Services), func(w io.Writer) { + for _, service := range appInfo.Services { + fmt.Fprintf(w, "%s\t%s\n", service.Name, service.Image) + } + }, "SERVICE", "IMAGE") + } // Add Network section printSection(out, len(appInfo.Networks), func(w io.Writer) { @@ -369,7 +381,7 @@ func extractParameters(app *types.App, argParameters map[string]string) ([]strin for k := range allParameters { parametersKeys = append(parametersKeys, k) } - sort.Slice(parametersKeys, func(i, j int) bool { return parametersKeys[i] < parametersKeys[j] }) + sort.Strings(parametersKeys) return parametersKeys, allParameters, nil } diff --git a/internal/inspect/inspect_test.go b/internal/inspect/inspect_test.go index 3753d851c..e0bf77c22 100644 --- a/internal/inspect/inspect_test.go +++ b/internal/inspect/inspect_test.go @@ -133,16 +133,24 @@ text: hello`), }) } -func TestImageInspectCNAB(t *testing.T) { +func TestImageInspectCNABFormatJSON(t *testing.T) { + testImageInspectCNAB(t, "json") +} + +func TestImageInspectCNABFormatPretty(t *testing.T) { + testImageInspectCNAB(t, "pretty") +} + +func testImageInspectCNAB(t *testing.T, format string) { s := golden.Get(t, "bundle-json.golden") var bndl bundle.Bundle err := json.Unmarshal(s, &bndl) assert.NilError(t, err) - expected := golden.Get(t, "inspect-bundle-json.golden") + expected := golden.Get(t, fmt.Sprintf("inspect-bundle-%s.golden", format)) outBuffer := new(bytes.Buffer) - err = ImageInspectCNAB(outBuffer, &bndl, "json") + err = ImageInspectCNAB(outBuffer, &bndl, format) assert.NilError(t, err) result := outBuffer.String() diff --git a/internal/inspect/testdata/inspect-bundle-pretty.golden b/internal/inspect/testdata/inspect-bundle-pretty.golden new file mode 100644 index 000000000..2baf89def --- /dev/null +++ b/internal/inspect/testdata/inspect-bundle-pretty.golden @@ -0,0 +1,24 @@ +version: 0.1.0 +name: packing +description: hello +maintainers: +- name: dev1 + email: dev1@example.com +- name: dev2 + email: dev2@example.com + + +SERVICE IMAGE +app-watcher watcher +debug busybox:latest +front nginx +monitor busybox:latest + +PARAMETER VALUE +com.docker.app.args +com.docker.app.inspect-format json +com.docker.app.kubernetes-namespace +com.docker.app.orchestrator +com.docker.app.render-format yaml +com.docker.app.share-registry-creds false +watcher.cmd foo