Skip to content

Commit

Permalink
Merge pull request #887 from buildpacks/387-inspect-builder-output-fo…
Browse files Browse the repository at this point in the history
…rmat

Add output format option to inspect-builder command
  • Loading branch information
dwillist authored Oct 28, 2020
2 parents 1bd3718 + 5ea3d97 commit cbaaac9
Show file tree
Hide file tree
Showing 54 changed files with 6,429 additions and 1,153 deletions.
148 changes: 143 additions & 5 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
Expand All @@ -21,19 +22,21 @@ import (

pubcfg "github.com/buildpacks/pack/config"

"github.com/buildpacks/pack/acceptance/buildpacks"

"github.com/docker/docker/pkg/stdcopy"
"github.com/google/go-containerregistry/pkg/name"
"github.com/ghodss/yaml"
"github.com/pelletier/go-toml"

dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/go-connections/nat"
"github.com/google/go-containerregistry/pkg/name"
"github.com/pkg/errors"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"

"github.com/buildpacks/pack/acceptance/buildpacks"

"github.com/buildpacks/pack/acceptance/assertions"
"github.com/buildpacks/pack/acceptance/config"
"github.com/buildpacks/pack/acceptance/invoke"
Expand Down Expand Up @@ -1803,7 +1806,12 @@ include = [ "*.jar", "media/mountain.jpg", "media/person.png" ]
)
assert.Equal(output, "Run Image 'pack-test/run' configured with mirror 'some-registry.com/pack-test/run1'\n")

output = pack.RunSuccessfully("inspect-builder", "--depth", "2", builderName)
depth := "2"
if pack.SupportsFeature(invoke.InspectBuilderOutputFormat) {
depth = "1" // The meaning of depth was changed
}

output = pack.RunSuccessfully("inspect-builder", "--depth", depth, builderName)

deprecatedBuildpackAPIs,
supportedBuildpackAPIs,
Expand Down Expand Up @@ -1833,6 +1841,136 @@ include = [ "*.jar", "media/mountain.jpg", "media/person.png" ]

assert.TrimmedEq(output, expectedOutput)
})

when("output format is toml", func() {
it("prints builder information in toml format", func() {
h.SkipUnless(t,
pack.SupportsFeature(invoke.InspectBuilderOutputFormat),
"inspect-builder output format is not yet implemented",
)

output := pack.RunSuccessfully(
"set-run-image-mirrors", "pack-test/run", "--mirror", "some-registry.com/pack-test/run1",
)
assert.Equal(output, "Run Image 'pack-test/run' configured with mirror 'some-registry.com/pack-test/run1'\n")

output = pack.RunSuccessfully("inspect-builder", builderName, "--output", "toml")

err := toml.NewDecoder(strings.NewReader(string(output))).Decode(&struct{}{})
assert.Nil(err)

deprecatedBuildpackAPIs,
supportedBuildpackAPIs,
deprecatedPlatformAPIs,
supportedPlatformAPIs := lifecycle.TOMLOutputForAPIs()

expectedOutput := pack.FixtureManager().TemplateVersionedFixture(
"inspect_%s_builder_nested_output_toml.txt",
createBuilderPack.Version(),
"inspect_builder_nested_output_toml.txt",
map[string]interface{}{
"builder_name": builderName,
"lifecycle_version": lifecycle.Version(),
"deprecated_buildpack_apis": deprecatedBuildpackAPIs,
"supported_buildpack_apis": supportedBuildpackAPIs,
"deprecated_platform_apis": deprecatedPlatformAPIs,
"supported_platform_apis": supportedPlatformAPIs,
"run_image_mirror": runImageMirror,
"pack_version": createBuilderPack.Version(),
},
)

assert.TrimmedEq(string(output), expectedOutput)
})
})

when("output format is yaml", func() {
it("prints builder information in yaml format", func() {
h.SkipUnless(t,
pack.SupportsFeature(invoke.InspectBuilderOutputFormat),
"inspect-builder output format is not yet implemented",
)

output := pack.RunSuccessfully(
"set-run-image-mirrors", "pack-test/run", "--mirror", "some-registry.com/pack-test/run1",
)
assert.Equal(output, "Run Image 'pack-test/run' configured with mirror 'some-registry.com/pack-test/run1'\n")

output = pack.RunSuccessfully("inspect-builder", builderName, "--output", "yaml")

err := yaml.Unmarshal([]byte(output), &struct{}{})
assert.Nil(err)

deprecatedBuildpackAPIs,
supportedBuildpackAPIs,
deprecatedPlatformAPIs,
supportedPlatformAPIs := lifecycle.YAMLOutputForAPIs(14)

expectedOutput := pack.FixtureManager().TemplateVersionedFixture(
"inspect_%s_builder_nested_output_yaml.txt",
createBuilderPack.Version(),
"inspect_builder_nested_output_yaml.txt",
map[string]interface{}{
"builder_name": builderName,
"lifecycle_version": lifecycle.Version(),
"deprecated_buildpack_apis": deprecatedBuildpackAPIs,
"supported_buildpack_apis": supportedBuildpackAPIs,
"deprecated_platform_apis": deprecatedPlatformAPIs,
"supported_platform_apis": supportedPlatformAPIs,
"run_image_mirror": runImageMirror,
"pack_version": createBuilderPack.Version(),
},
)

assert.TrimmedEq(string(output), expectedOutput)
})
})

when("output format is json", func() {
it("prints builder information in json format", func() {
h.SkipUnless(t,
pack.SupportsFeature(invoke.InspectBuilderOutputFormat),
"inspect-builder output format is not yet implemented",
)

output := pack.RunSuccessfully(
"set-run-image-mirrors", "pack-test/run", "--mirror", "some-registry.com/pack-test/run1",
)
assert.Equal(output, "Run Image 'pack-test/run' configured with mirror 'some-registry.com/pack-test/run1'\n")

output = pack.RunSuccessfully("inspect-builder", builderName, "--output", "json")

err := json.Unmarshal([]byte(output), &struct{}{})
assert.Nil(err)

var prettifiedOutput bytes.Buffer
err = json.Indent(&prettifiedOutput, []byte(output), "", " ")
assert.Nil(err)

deprecatedBuildpackAPIs,
supportedBuildpackAPIs,
deprecatedPlatformAPIs,
supportedPlatformAPIs := lifecycle.JSONOutputForAPIs(8)

expectedOutput := pack.FixtureManager().TemplateVersionedFixture(
"inspect_%s_builder_nested_output_json.txt",
createBuilderPack.Version(),
"inspect_builder_nested_output_json.txt",
map[string]interface{}{
"builder_name": builderName,
"lifecycle_version": lifecycle.Version(),
"deprecated_buildpack_apis": deprecatedBuildpackAPIs,
"supported_buildpack_apis": supportedBuildpackAPIs,
"deprecated_platform_apis": deprecatedPlatformAPIs,
"supported_platform_apis": supportedPlatformAPIs,
"run_image_mirror": runImageMirror,
"pack_version": createBuilderPack.Version(),
},
)

assert.Equal(prettifiedOutput.String(), expectedOutput)
})
})
})

it("displays configuration for a builder (local and remote)", func() {
Expand Down
87 changes: 87 additions & 0 deletions acceptance/config/lifecycle_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package config

import (
"fmt"
"strings"

"github.com/Masterminds/semver"
Expand Down Expand Up @@ -85,6 +86,92 @@ func (l *LifecycleAsset) OutputForAPIs() (deprecatedBuildpackAPIs, supportedBuil
stringify(l.descriptor.APIs.Platform.Supported)
}

func (l *LifecycleAsset) TOMLOutputForAPIs() (deprecatedBuildpacksAPIs,
supportedBuildpacksAPIs,
deprectatedPlatformAPIs,
supportedPlatformAPIS string,
) {
stringify := func(apiSet builder.APISet) string {
if len(apiSet) < 1 || apiSet == nil {
return "[]"
}

var quotedAPIs []string
for _, a := range apiSet {
quotedAPIs = append(quotedAPIs, fmt.Sprintf("%q", a))
}

return fmt.Sprintf("[%s]", strings.Join(quotedAPIs, ", "))
}

return stringify(l.descriptor.APIs.Buildpack.Deprecated),
stringify(l.descriptor.APIs.Buildpack.Supported),
stringify(l.descriptor.APIs.Platform.Deprecated),
stringify(l.descriptor.APIs.Platform.Supported)
}

func (l *LifecycleAsset) YAMLOutputForAPIs(baseIndentationWidth int) (deprecatedBuildpacksAPIs,
supportedBuildpacksAPIs,
deprectatedPlatformAPIs,
supportedPlatformAPIS string,
) {
stringify := func(apiSet builder.APISet, baseIndentationWidth int) string {
if len(apiSet) < 1 || apiSet == nil {
return "[]"
}

apiIndentation := strings.Repeat(" ", baseIndentationWidth+2)

var quotedAPIs []string
for _, a := range apiSet {
quotedAPIs = append(quotedAPIs, fmt.Sprintf(`%s- %q`, apiIndentation, a))
}

return fmt.Sprintf(`
%s`, strings.Join(quotedAPIs, "\n"))
}

return stringify(l.descriptor.APIs.Buildpack.Deprecated, baseIndentationWidth),
stringify(l.descriptor.APIs.Buildpack.Supported, baseIndentationWidth),
stringify(l.descriptor.APIs.Platform.Deprecated, baseIndentationWidth),
stringify(l.descriptor.APIs.Platform.Supported, baseIndentationWidth)
}

func (l *LifecycleAsset) JSONOutputForAPIs(baseIndentationWidth int) (
deprecatedBuildpacksAPIs,
supportedBuildpacksAPIs,
deprectatedPlatformAPIs,
supportedPlatformAPIS string,
) {
stringify := func(apiSet builder.APISet, baseIndentationWidth int) string {
if len(apiSet) < 1 {
if apiSet == nil {
return "null"
}
return "[]"
}

apiIndentation := strings.Repeat(" ", baseIndentationWidth+2)

var quotedAPIs []string
for _, a := range apiSet {
quotedAPIs = append(quotedAPIs, fmt.Sprintf(`%s%q`, apiIndentation, a))
}

lineEndSeparator := `,
`

return fmt.Sprintf(`[
%s
%s]`, strings.Join(quotedAPIs, lineEndSeparator), strings.Repeat(" ", baseIndentationWidth))
}

return stringify(l.descriptor.APIs.Buildpack.Deprecated, baseIndentationWidth),
stringify(l.descriptor.APIs.Buildpack.Supported, baseIndentationWidth),
stringify(l.descriptor.APIs.Platform.Deprecated, baseIndentationWidth),
stringify(l.descriptor.APIs.Platform.Supported, baseIndentationWidth)
}

type LifecycleFeature int

const (
Expand Down
4 changes: 4 additions & 0 deletions acceptance/invoke/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ const (
ReadWriteVolumeMounts
NoColorInBuildpacks
QuietMode
InspectBuilderOutputFormat
)

var featureTests = map[Feature]func(i *PackInvoker) bool{
Expand All @@ -242,6 +243,9 @@ var featureTests = map[Feature]func(i *PackInvoker) bool{
QuietMode: func(i *PackInvoker) bool {
return i.atLeast("0.13.2")
},
InspectBuilderOutputFormat: func(i *PackInvoker) bool {
return i.laterThan("0.14.2")
},
}

func (i *PackInvoker) SupportsFeature(f Feature) bool {
Expand Down
Loading

0 comments on commit cbaaac9

Please sign in to comment.