Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moves layer types to table #238

Merged
merged 2 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func Build(f BuildFunc, options ...Option) {
}

for _, layer := range result.Layers {
err = config.tomlWriter.Write(filepath.Join(layersPath, fmt.Sprintf("%s.toml", layer.Name)), layer)
err = config.tomlWriter.Write(filepath.Join(layersPath, fmt.Sprintf("%s.toml", layer.Name)), formattedLayer{layer, apiVersion})
if err != nil {
config.exitHandler.Error(err)
return
Expand Down
47 changes: 47 additions & 0 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,60 @@ api = "0.4"
Expect(err).NotTo(HaveOccurred())

Expect(string(contents)).To(MatchTOML(`
[types]
launch = true
build = true
cache = true

[metadata]
some-key = "some-value"
`))
})

context("when the buildpack api version is less than 0.6", func() {
it.Before(func() {
bpTOML := []byte(`
api = "0.5"
[buildpack]
id = "some-id"
name = "some-name"
version = "some-version"
`)
Expect(os.WriteFile(filepath.Join(cnbDir, "buildpack.toml"), bpTOML, 0600)).To(Succeed())
})
it("persists layer metadata", func() {
packit.Build(func(ctx packit.BuildContext) (packit.BuildResult, error) {
layerPath := filepath.Join(ctx.Layers.Path, "some-layer")
Expect(os.MkdirAll(layerPath, os.ModePerm)).To(Succeed())

return packit.BuildResult{
Layers: []packit.Layer{
packit.Layer{
Path: layerPath,
Name: "some-layer",
Build: true,
Launch: true,
Cache: true,
Metadata: map[string]interface{}{
"some-key": "some-value",
},
},
},
}, nil
}, packit.WithArgs([]string{binaryPath, layersDir, platformDir, planPath}))

contents, err := os.ReadFile(filepath.Join(layersDir, "some-layer.toml"))
Expect(err).NotTo(HaveOccurred())

Expect(string(contents)).To(MatchTOML(`
launch = true
build = true
cache = true

[metadata]
some-key = "some-value"
`))
})
})

context("when there are existing layer.toml files", func() {
Expand Down
49 changes: 39 additions & 10 deletions layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,58 @@ package packit
import (
"fmt"
"os"

"github.com/Masterminds/semver/v3"
"github.com/pelletier/go-toml"
)

// Layer provides a representation of a layer managed by a buildpack as
// described by the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#layers.
type Layer struct {
// Path is the absolute location of the layer on disk.
Path string `toml:"-"`
Path string

// Name is the descriptive name of the layer.
Name string `toml:"-"`
Name string

// Build indicates whether the layer is available to subsequent buildpacks
// during their build phase according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#build-layers.
Build bool `toml:"build"`
Build bool

// Launch indicates whether the layer is exported into the application image
// and made available during the launch phase according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#launch-layers.
Launch bool `toml:"launch"`
Launch bool

// Cache indicates whether the layer is persisted and made available to
// subsequent builds of the same application according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#launch-layers
// and
// https://github.com/buildpacks/spec/blob/main/buildpack.md#build-layers.
Cache bool `toml:"cache"`
Cache bool

// SharedEnv is the set of environment variables attached to the layer and
// made available during both the build and launch phases according to the
// specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#provided-by-the-buildpacks.
SharedEnv Environment `toml:"-"`
SharedEnv Environment

// BuildEnv is the set of environment variables attached to the layer and
// made available during the build phase according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#provided-by-the-buildpacks.
BuildEnv Environment `toml:"-"`
BuildEnv Environment

// LaunchEnv is the set of environment variables attached to the layer and
// made available during the launch phase according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#provided-by-the-buildpacks.
LaunchEnv Environment `toml:"-"`
LaunchEnv Environment

// ProcessLaunchEnv is a map of environment variables attached to the layer and
// made available to specified proccesses in the launch phase accoring to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#provided-by-the-buildpacks
ProcessLaunchEnv map[string]Environment `toml:"-"`
ProcessLaunchEnv map[string]Environment

// Metadata is an unspecified field allowing buildpacks to communicate extra
// details about the layer. Examples of this type of metadata might include
Expand All @@ -60,7 +63,7 @@ type Layer struct {
// layer if suitable. The Metadata field ultimately fills the metadata field
// of the Layer Content Metadata TOML file according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md#layer-content-metadata-toml.
Metadata map[string]interface{} `toml:"metadata"`
Metadata map[string]interface{}
}

// Reset clears the state of a layer such that the layer can be replaced with
Expand Down Expand Up @@ -89,3 +92,29 @@ func (l Layer) Reset() (Layer, error) {

return l, nil
}

type formattedLayer struct {
layer Layer
api *semver.Version
}

func (l formattedLayer) MarshalTOML() ([]byte, error) {
layer := map[string]interface{}{
"metadata": l.layer.Metadata,
}

apiV06, _ := semver.NewVersion("0.6")
if l.api.LessThan(apiV06) {
layer["build"] = l.layer.Build
layer["launch"] = l.layer.Launch
layer["cache"] = l.layer.Cache
} else {
layer["types"] = map[string]bool{
"build": l.layer.Build,
"launch": l.layer.Launch,
"cache": l.layer.Cache,
}
}

return toml.Marshal(layer)
}