mirror of https://github.com/buildpacks/libcnb.git
Compare commits
68 Commits
Author | SHA1 | Date |
---|---|---|
|
25ba7f615a | |
|
6305526cf8 | |
|
2e5389a593 | |
|
587c59c91d | |
|
5f657b5cfc | |
|
6e3b073b7b | |
|
52e0183e1d | |
|
2f1a4584c6 | |
|
963d4bea64 | |
|
71c0efab66 | |
|
3d9ff459f6 | |
|
abe34281b4 | |
|
8b98521c54 | |
|
e4b66fbc45 | |
|
5c5fb9c447 | |
|
69cca5e154 | |
|
a9e6d2093f | |
|
31fc6e39de | |
|
8ebd909600 | |
|
fdc1649156 | |
|
e2931f6866 | |
|
007e6d2e3e | |
|
0df8dedcfe | |
|
7ed3dc927c | |
|
bc167dd856 | |
|
714a5dc525 | |
|
fdc252a082 | |
|
62037e0b7a | |
|
6a941db0cd | |
|
f496f6e88d | |
|
86ede05ba0 | |
|
d3e6e18255 | |
|
a0a8708c7a | |
|
53c63e4082 | |
|
df6fd7ca71 | |
|
d91d62a519 | |
|
4d89af3641 | |
|
f4abcd0215 | |
|
f04e4e2cf2 | |
|
49c96bbc6c | |
|
2d891dd194 | |
|
896a63b4e3 | |
|
45c858b545 | |
|
c9ad73fb07 | |
|
f869c1d937 | |
|
4a789fd9d2 | |
|
d67b3ffea7 | |
|
128cdb9dbe | |
|
77cb45d022 | |
|
a33b3677ad | |
|
6d86013d6d | |
|
66f3e9f328 | |
|
6aa81e5081 | |
|
c06fd640c3 | |
|
50e1696404 | |
|
9cb9a2095d | |
|
0376b8a285 | |
|
9af239f94c | |
|
70403787d2 | |
|
ced0ee6ed8 | |
|
c564678891 | |
|
5c9b56b7c6 | |
|
8c10662dc7 | |
|
b2b6b4b4c1 | |
|
33e2828ac7 | |
|
a965403652 | |
|
bc6e6ca9a4 | |
|
536a77887b |
|
@ -14,7 +14,19 @@ test:
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
GO111MODULE=on go get -u -ldflags="-s -w" github.com/kyoh86/richgo
|
||||
echo "Installing richgo ${RICHGO_VERSION}"
|
||||
|
||||
mkdir -p "${HOME}"/bin
|
||||
echo "${HOME}/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
curl \
|
||||
--location \
|
||||
--show-error \
|
||||
--silent \
|
||||
"https://github.com/kyoh86/richgo/releases/download/v${RICHGO_VERSION}/richgo_${RICHGO_VERSION}_linux_amd64.tar.gz" \
|
||||
| tar -C "${HOME}"/bin -xz richgo
|
||||
env:
|
||||
RICHGO_VERSION: 0.3.10
|
||||
- name: Run Tests
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.12.0
|
||||
1.25.2
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
1.4.0
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: mheap/github-action-required-labels@v1
|
||||
- uses: mheap/github-action-required-labels@v2
|
||||
with:
|
||||
count: 1
|
||||
labels: semver:major, semver:minor, semver:patch
|
||||
|
@ -22,7 +22,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: mheap/github-action-required-labels@v1
|
||||
- uses: mheap/github-action-required-labels@v2
|
||||
with:
|
||||
count: 1
|
||||
labels: type:bug, type:dependency-upgrade, type:documentation, type:enhancement, type:question, type:task
|
|
@ -2,7 +2,7 @@ name: Synchronize Labels
|
|||
"on":
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-1.x
|
||||
paths:
|
||||
- .github/labels.yml
|
||||
jobs:
|
||||
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: micnncim/action-label-syncer@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
|
@ -3,29 +3,41 @@ name: Tests
|
|||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-1.x
|
||||
jobs:
|
||||
unit:
|
||||
name: Unit Test
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
path: ${{ env.HOME }}/go/pkg/mod
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.16"
|
||||
go-version: "1.18"
|
||||
- name: Install richgo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GO111MODULE=on go get -u -ldflags="-s -w" github.com/kyoh86/richgo
|
||||
echo "Installing richgo ${RICHGO_VERSION}"
|
||||
|
||||
mkdir -p "${HOME}"/bin
|
||||
echo "${HOME}/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
curl \
|
||||
--location \
|
||||
--show-error \
|
||||
--silent \
|
||||
"https://github.com/kyoh86/richgo/releases/download/v${RICHGO_VERSION}/richgo_${RICHGO_VERSION}_linux_amd64.tar.gz" \
|
||||
| tar -C "${HOME}"/bin -xz richgo
|
||||
env:
|
||||
RICHGO_VERSION: 0.3.10
|
||||
- name: Run Tests
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
|
@ -2,7 +2,7 @@ name: Update Draft Release
|
|||
"on":
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-1.x
|
||||
jobs:
|
||||
update:
|
||||
name: Update Draft Release
|
|
@ -0,0 +1,61 @@
|
|||
name: Update Go
|
||||
"on":
|
||||
schedule:
|
||||
- cron: 0 2 * * 1
|
||||
workflow_dispatch: {}
|
||||
jobs:
|
||||
update:
|
||||
name: Update Go
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.18"
|
||||
- uses: actions/checkout@v3
|
||||
- name: Update Go Version
|
||||
id: update-go
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${GO_VERSION:-}" ]; then
|
||||
echo "No go version set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OLD_GO_VERSION=$(grep -P '^go \d\.\d+' go.mod | cut -d ' ' -f 2)
|
||||
|
||||
go mod edit -go="$GO_VERSION"
|
||||
go mod tidy
|
||||
go get -u all
|
||||
go mod tidy
|
||||
|
||||
git add go.mod go.sum
|
||||
git checkout -- .
|
||||
|
||||
echo "::set-output name=old-go-version::${OLD_GO_VERSION}"
|
||||
echo "::set-output name=go-version::${GO_VERSION}"
|
||||
env:
|
||||
GO_VERSION: "1.18"
|
||||
- uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
||||
Bumps Go from `${{ steps.update-go.outputs.old-go-version }}` to `${{ steps.update-go.outputs.go-version }}`.
|
||||
|
||||
<details>
|
||||
<summary>Release Notes</summary>
|
||||
${{ steps.pipeline.outputs.release-notes }}
|
||||
</details>
|
||||
branch: update/go
|
||||
commit-message: |-
|
||||
Bump Go from ${{ steps.update-go.outputs.old-go-version }} to ${{ steps.update-go.outputs.go-version }}
|
||||
|
||||
Bumps Go from ${{ steps.update-go.outputs.old-go-version }} to ${{ steps.update-go.outputs.go-version }}.
|
||||
delete-branch: true
|
||||
labels: semver:minor, type:task
|
||||
signoff: true
|
||||
title: Bump Go from ${{ steps.update-go.outputs.old-go-version }} to ${{ steps.update-go.outputs.go-version }}
|
||||
token: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
|
@ -2,7 +2,7 @@ name: Update Pipeline
|
|||
"on":
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-1.x
|
||||
paths:
|
||||
- .github/pipeline-descriptor.yml
|
||||
schedule:
|
||||
|
@ -14,17 +14,17 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.16"
|
||||
go-version: "1.18"
|
||||
- name: Install octo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GO111MODULE=on go get -u -ldflags="-s -w" github.com/paketo-buildpacks/pipeline-builder/cmd/octo
|
||||
- uses: actions/checkout@v2
|
||||
go install -ldflags="-s -w" github.com/paketo-buildpacks/pipeline-builder/cmd/octo@latest
|
||||
- uses: actions/checkout@v3
|
||||
- name: Update Pipeline
|
||||
id: pipeline
|
||||
run: |
|
||||
|
@ -38,6 +38,7 @@ jobs:
|
|||
OLD_VERSION="0.0.0"
|
||||
fi
|
||||
|
||||
rm .github/workflows/pb-*.yml || true
|
||||
octo --descriptor "${DESCRIPTOR}"
|
||||
|
||||
PAYLOAD=$(gh api /repos/paketo-buildpacks/pipeline-builder/releases/latest)
|
||||
|
@ -62,7 +63,7 @@ jobs:
|
|||
env:
|
||||
DESCRIPTOR: .github/pipeline-descriptor.yml
|
||||
GITHUB_TOKEN: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
- uses: peter-evans/create-pull-request@v3
|
||||
- uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
|
@ -48,6 +48,9 @@ type Process struct {
|
|||
// Command is exec'd directly by the os (no profile.d scripts run)
|
||||
Direct bool `toml:"direct,omitempty"`
|
||||
|
||||
// WorkingDirectory is a directory to execute the command in, removes the need to use a shell environment to CD into working directory
|
||||
WorkingDirectory string `toml:"working-directory,omitempty"`
|
||||
|
||||
// Default can be set to true to indicate that the process
|
||||
// type being defined should be the default process type for the app image.
|
||||
Default bool `toml:"default,omitempty"`
|
||||
|
@ -73,6 +76,8 @@ type LaunchTOML struct {
|
|||
Slices []Slice `toml:"slices"`
|
||||
|
||||
// BOM is a collection of entries for the bill of materials.
|
||||
//
|
||||
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
|
||||
BOM []BOMEntry `toml:"bom"`
|
||||
}
|
||||
|
||||
|
@ -83,6 +88,8 @@ func (l LaunchTOML) isEmpty() bool {
|
|||
// BuildTOML represents the contents of build.toml.
|
||||
type BuildTOML struct {
|
||||
// BOM contains the build-time bill of materials.
|
||||
//
|
||||
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
|
||||
BOM []BOMEntry `toml:"bom"`
|
||||
|
||||
// Unmet is a collection of buildpack plan entries that should be passed through to subsequent providers.
|
||||
|
@ -94,6 +101,8 @@ func (b BuildTOML) isEmpty() bool {
|
|||
}
|
||||
|
||||
// BOMEntry contains a bill of materials entry.
|
||||
//
|
||||
// Deprecated: as of Buildpack API 0.7, BOM should use standard formats like CycloneDX going forward
|
||||
type BOMEntry struct {
|
||||
// Name represents the name of the entry.
|
||||
Name string `toml:"name"`
|
||||
|
|
116
build.go
116
build.go
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
|
||||
"github.com/buildpacks/libcnb/internal"
|
||||
"github.com/buildpacks/libcnb/poet"
|
||||
|
@ -58,6 +59,8 @@ type BuildContext struct {
|
|||
// BuildResult contains the results of detection.
|
||||
type BuildResult struct {
|
||||
// BOM contains entries to be appended to the app image Bill of Materials and/or build Bill of Materials.
|
||||
//
|
||||
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
|
||||
BOM *BOM
|
||||
|
||||
// Labels are the image labels contributed by the buildpack.
|
||||
|
@ -81,10 +84,21 @@ type BuildResult struct {
|
|||
}
|
||||
|
||||
// BOM contains all Bill of Materials entries
|
||||
//
|
||||
// Deprecated: as of Buildpack API 0.7, write to `layer.BOMPath()` instead
|
||||
type BOM struct {
|
||||
Entries []BOMEntry
|
||||
}
|
||||
|
||||
// Constants to track minimum and maximum supported Buildpack API versions
|
||||
const (
|
||||
// MinSupportedBPVersion indicates the minium supported version of the Buildpacks API
|
||||
MinSupportedBPVersion = "0.5"
|
||||
|
||||
// MaxSupportedBPVersion indicates the maximum supported version of the Buildpacks API
|
||||
MaxSupportedBPVersion = "0.8"
|
||||
)
|
||||
|
||||
// NewBuildResult creates a new BuildResult instance, initializing empty fields.
|
||||
func NewBuildResult() BuildResult {
|
||||
return BuildResult{
|
||||
|
@ -118,6 +132,7 @@ type Builder interface {
|
|||
func Build(builder Builder, options ...Option) {
|
||||
config := Config{
|
||||
arguments: os.Args,
|
||||
bomLabel: false,
|
||||
environmentWriter: internal.EnvironmentWriter{},
|
||||
exitHandler: internal.NewExitHandler(),
|
||||
tomlWriter: internal.TOMLWriter{},
|
||||
|
@ -127,11 +142,6 @@ func Build(builder Builder, options ...Option) {
|
|||
config = option(config)
|
||||
}
|
||||
|
||||
if len(config.arguments) != 4 {
|
||||
config.exitHandler.Error(fmt.Errorf("expected 3 arguments and received %d", len(config.arguments)-1))
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
file string
|
||||
|
@ -165,16 +175,47 @@ func Build(builder Builder, options ...Option) {
|
|||
}
|
||||
logger.Debugf("Buildpack: %+v", ctx.Buildpack)
|
||||
|
||||
API := strings.TrimSpace(ctx.Buildpack.API)
|
||||
if API != "0.5" && API != "0.6" {
|
||||
config.exitHandler.Error(errors.New("this version of libcnb is only compatible with buildpack APIs 0.5 and 0.6"))
|
||||
API, err := semver.NewVersion(ctx.Buildpack.API)
|
||||
if err != nil {
|
||||
config.exitHandler.Error(errors.New("version cannot be parsed"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Layers = Layers{config.arguments[1]}
|
||||
logger.Debugf("Layers: %+v", ctx.Layers)
|
||||
compatVersionCheck, _ := semver.NewConstraint(fmt.Sprintf(">= %s, <= %s", MinSupportedBPVersion, MaxSupportedBPVersion))
|
||||
if !compatVersionCheck.Check(API) {
|
||||
config.exitHandler.Error(fmt.Errorf("this version of libcnb is only compatible with buildpack APIs >= %s, <= %s", MinSupportedBPVersion, MaxSupportedBPVersion))
|
||||
return
|
||||
}
|
||||
var buildpackPlanPath string
|
||||
|
||||
ctx.Platform.Path = config.arguments[2]
|
||||
if API.LessThan(semver.MustParse("0.8")) {
|
||||
if len(config.arguments) != 4 {
|
||||
config.exitHandler.Error(fmt.Errorf("expected 3 arguments and received %d", len(config.arguments)-1))
|
||||
return
|
||||
}
|
||||
ctx.Layers = Layers{config.arguments[1]}
|
||||
ctx.Platform.Path = config.arguments[2]
|
||||
buildpackPlanPath = config.arguments[3]
|
||||
} else {
|
||||
layersDir, ok := os.LookupEnv("CNB_LAYERS_DIR")
|
||||
if !ok {
|
||||
config.exitHandler.Error(fmt.Errorf("expected CNB_LAYERS_DIR to be set"))
|
||||
return
|
||||
}
|
||||
ctx.Layers = Layers{layersDir}
|
||||
ctx.Platform.Path, ok = os.LookupEnv("CNB_PLATFORM_DIR")
|
||||
if !ok {
|
||||
config.exitHandler.Error(fmt.Errorf("expected CNB_PLATFORM_DIR to be set"))
|
||||
return
|
||||
}
|
||||
buildpackPlanPath, ok = os.LookupEnv("CNB_BP_PLAN_PATH")
|
||||
if !ok {
|
||||
config.exitHandler.Error(fmt.Errorf("expected CNB_BP_PLAN_PATH to be set"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debugf("Layers: %+v", ctx.Layers)
|
||||
if logger.IsDebugEnabled() {
|
||||
logger.Debug(PlatformFormatter(ctx.Platform))
|
||||
}
|
||||
|
@ -201,9 +242,8 @@ func Build(builder Builder, options ...Option) {
|
|||
ctx.PersistentMetadata = store.Metadata
|
||||
logger.Debugf("Persistent Metadata: %+v", ctx.PersistentMetadata)
|
||||
|
||||
file = config.arguments[3]
|
||||
if _, err = toml.DecodeFile(file, &ctx.Plan); err != nil && !os.IsNotExist(err) {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to decode buildpack plan %s\n%w", file, err))
|
||||
if _, err = toml.DecodeFile(buildpackPlanPath, &ctx.Plan); err != nil && !os.IsNotExist(err) {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to decode buildpack plan %s\n%w", buildpackPlanPath, err))
|
||||
return
|
||||
}
|
||||
logger.Debugf("Buildpack Plan: %+v", ctx.Plan)
|
||||
|
@ -274,7 +314,7 @@ func Build(builder Builder, options ...Option) {
|
|||
file = filepath.Join(ctx.Layers.Path, fmt.Sprintf("%s.toml", layer.Name))
|
||||
logger.Debugf("Writing layer metadata: %s <= %+v", file, layer)
|
||||
var toWrite interface{} = layer
|
||||
if API == "0.5" {
|
||||
if API.Equal(semver.MustParse("0.5")) {
|
||||
toWrite = internal.LayerAPI5{
|
||||
Build: layer.LayerTypes.Build,
|
||||
Cache: layer.LayerTypes.Cache,
|
||||
|
@ -302,8 +342,16 @@ func Build(builder Builder, options ...Option) {
|
|||
}
|
||||
}
|
||||
|
||||
if API.GreaterThan(semver.MustParse("0.7")) || API.Equal(semver.MustParse("0.7")) {
|
||||
if err := validateSBOMFormats(ctx.Layers.Path, ctx.Buildpack.Info.SBOMFormats); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to validate SBOM\n%w", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: as of Buildpack API 0.7, to be removed in a future version
|
||||
var launchBOM, buildBOM []BOMEntry
|
||||
if result.BOM != nil {
|
||||
if result.BOM != nil && config.bomLabel {
|
||||
for _, entry := range result.BOM.Entries {
|
||||
if entry.Launch {
|
||||
launchBOM = append(launchBOM, entry)
|
||||
|
@ -325,7 +373,7 @@ func Build(builder Builder, options ...Option) {
|
|||
file = filepath.Join(ctx.Layers.Path, "launch.toml")
|
||||
logger.Debugf("Writing application metadata: %s <= %+v", file, launch)
|
||||
|
||||
if API == "0.5" {
|
||||
if API.LessThan(semver.MustParse("0.6")) {
|
||||
for _, process := range launch.Processes {
|
||||
if process.Default {
|
||||
logger.Info("WARNING: Launch layer is setting default=true, but that is not supported until API version 0.6. This setting will be ignored.")
|
||||
|
@ -333,6 +381,15 @@ func Build(builder Builder, options ...Option) {
|
|||
}
|
||||
}
|
||||
|
||||
if API.LessThan(semver.MustParse("0.8")) {
|
||||
for i, process := range launch.Processes {
|
||||
if process.WorkingDirectory != "" {
|
||||
logger.Infof("WARNING: Launch layer is setting working-directory=%s, but that is not supported until API version 0.8. This setting will be ignored.", process.WorkingDirectory)
|
||||
launch.Processes[i].WorkingDirectory = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = config.tomlWriter.Write(file, launch); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to write application metadata %s\n%w", file, err))
|
||||
return
|
||||
|
@ -347,6 +404,7 @@ func Build(builder Builder, options ...Option) {
|
|||
if !build.isEmpty() {
|
||||
file = filepath.Join(ctx.Layers.Path, "build.toml")
|
||||
logger.Debugf("Writing build metadata: %s <= %+v", file, build)
|
||||
|
||||
if err = config.tomlWriter.Write(file, build); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to write build metadata %s\n%w", file, err))
|
||||
return
|
||||
|
@ -375,3 +433,27 @@ func contains(candidates []string, s string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
func validateSBOMFormats(layersPath string, acceptedSBOMFormats []string) error {
|
||||
sbomFiles, err := filepath.Glob(filepath.Join(layersPath, "*.sbom.*"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable find SBOM files\n%w", err)
|
||||
}
|
||||
|
||||
for _, sbomFile := range sbomFiles {
|
||||
parts := strings.Split(filepath.Base(sbomFile), ".")
|
||||
if len(parts) <= 2 {
|
||||
return fmt.Errorf("invalid format %s", filepath.Base(sbomFile))
|
||||
}
|
||||
sbomFormat, err := SBOMFormatFromString(strings.Join(parts[len(parts)-2:], "."))
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse SBOM %s\n%w", sbomFormat, err)
|
||||
}
|
||||
|
||||
if !contains(acceptedSBOMFormats, sbomFormat.MediaType()) {
|
||||
return fmt.Errorf("unable to find actual SBOM Type %s in list of supported SBOM types %s", sbomFormat.MediaType(), acceptedSBOMFormats)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
510
build_test.go
510
build_test.go
|
@ -163,6 +163,9 @@ test-key = "test-value"
|
|||
tomlWriter.On("Write", mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
Expect(os.Setenv("CNB_STACK_ID", "test-stack-id")).To(Succeed())
|
||||
Expect(os.Setenv("CNB_LAYERS_DIR", layersPath)).To(Succeed())
|
||||
Expect(os.Setenv("CNB_PLATFORM_DIR", platformPath)).To(Succeed())
|
||||
Expect(os.Setenv("CNB_BP_PLAN_PATH", buildpackPlanPath)).To(Succeed())
|
||||
|
||||
workingDir, err = os.Getwd()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -173,6 +176,9 @@ test-key = "test-value"
|
|||
Expect(os.Chdir(workingDir)).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_STACK_ID")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_PLATFORM_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BP_PLAN_PATH")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_LAYERS_DIR")).To(Succeed())
|
||||
|
||||
Expect(os.RemoveAll(applicationPath)).To(Succeed())
|
||||
Expect(os.RemoveAll(buildpackPath)).To(Succeed())
|
||||
|
@ -181,7 +187,7 @@ test-key = "test-value"
|
|||
Expect(os.RemoveAll(platformPath)).To(Succeed())
|
||||
})
|
||||
|
||||
context("buildpack API is not 0.5 or 0.6", func() {
|
||||
context("buildpack API is not within the supported range", func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
|
@ -198,20 +204,56 @@ version = "1.1.1"
|
|||
|
||||
it("fails", func() {
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError(
|
||||
"this version of libcnb is only compatible with buildpack APIs 0.5 and 0.6",
|
||||
fmt.Sprintf("this version of libcnb is only compatible with buildpack APIs >= %s, <= %s", libcnb.MinSupportedBPVersion, libcnb.MaxSupportedBPVersion),
|
||||
))
|
||||
})
|
||||
})
|
||||
|
||||
context("errors if required env vars are not set for buildpack API >=0.8", func() {
|
||||
for _, e := range []string{"CNB_LAYERS_DIR", "CNB_PLATFORM_DIR", "CNB_BP_PLAN_PATH"} {
|
||||
// We need to do this assignment because of the way that spec binds variables
|
||||
envVar := e
|
||||
context(fmt.Sprintf("when %s is unset", envVar), func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.8"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
os.Unsetenv(envVar)
|
||||
})
|
||||
|
||||
it("fails", func() {
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError(
|
||||
fmt.Sprintf("expected %s to be set", envVar),
|
||||
))
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it("encounters the wrong number of arguments", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
@ -224,6 +266,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
@ -231,64 +274,136 @@ version = "1.1.1"
|
|||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("CNB_STACK_ID not set"))
|
||||
})
|
||||
|
||||
it("creates context", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
context("when BP API >= 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.8"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
})
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
)
|
||||
it("creates context", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
ctx := builder.Calls[0].Arguments[0].(libcnb.BuildContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.6",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
ClearEnvironment: true,
|
||||
Description: "A test buildpack",
|
||||
Keywords: []string{"test", "buildpack"},
|
||||
Licenses: []libcnb.License{
|
||||
{Type: "Apache-2.0", URI: "https://spdx.org/licenses/Apache-2.0.html"},
|
||||
{Type: "Apache-1.1", URI: "https://spdx.org/licenses/Apache-1.1.html"},
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath}),
|
||||
)
|
||||
|
||||
ctx := builder.Calls[0].Arguments[0].(libcnb.BuildContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.8",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
},
|
||||
},
|
||||
Path: buildpackPath,
|
||||
Stacks: []libcnb.BuildpackStack{
|
||||
{
|
||||
ID: "test-id",
|
||||
Mixins: []string{"test-name"},
|
||||
},
|
||||
},
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
}))
|
||||
Expect(ctx.Layers).To(Equal(libcnb.Layers{Path: layersPath}))
|
||||
Expect(ctx.PersistentMetadata).To(Equal(map[string]interface{}{"test-key": "test-value"}))
|
||||
Expect(ctx.Plan).To(Equal(libcnb.BuildpackPlan{
|
||||
Entries: []libcnb.BuildpackPlanEntry{
|
||||
{
|
||||
Name: "test-name",
|
||||
Metadata: map[string]interface{}{
|
||||
"test-key": "test-value",
|
||||
Path: buildpackPath,
|
||||
}))
|
||||
Expect(ctx.Layers).To(Equal(libcnb.Layers{Path: layersPath}))
|
||||
Expect(ctx.PersistentMetadata).To(Equal(map[string]interface{}{"test-key": "test-value"}))
|
||||
Expect(ctx.Plan).To(Equal(libcnb.BuildpackPlan{
|
||||
Entries: []libcnb.BuildpackPlanEntry{
|
||||
{
|
||||
Name: "test-name",
|
||||
Metadata: map[string]interface{}{
|
||||
"test-key": "test-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
Expect(ctx.Platform).To(Equal(libcnb.Platform{
|
||||
Bindings: libcnb.Bindings{
|
||||
libcnb.Binding{
|
||||
Name: "alpha",
|
||||
Path: filepath.Join(platformPath, "bindings", "alpha"),
|
||||
Secret: map[string]string{
|
||||
"test-secret-key": "test-secret-value",
|
||||
}))
|
||||
Expect(ctx.Platform).To(Equal(libcnb.Platform{
|
||||
Bindings: libcnb.Bindings{
|
||||
libcnb.Binding{
|
||||
Name: "alpha",
|
||||
Path: filepath.Join(platformPath, "bindings", "alpha"),
|
||||
Secret: map[string]string{
|
||||
"test-secret-key": "test-secret-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Environment: map[string]string{"TEST_ENV": "test-value"},
|
||||
Path: platformPath,
|
||||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
Environment: map[string]string{"TEST_ENV": "test-value"},
|
||||
Path: platformPath,
|
||||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
})
|
||||
})
|
||||
|
||||
context("when BP API < 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.Unsetenv("CNB_PLATFORM_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BP_PLAN_PATH")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_LAYERS_DIR")).To(Succeed())
|
||||
})
|
||||
|
||||
it("creates context", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
)
|
||||
|
||||
ctx := builder.Calls[0].Arguments[0].(libcnb.BuildContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.6",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
ClearEnvironment: true,
|
||||
Description: "A test buildpack",
|
||||
Keywords: []string{"test", "buildpack"},
|
||||
Licenses: []libcnb.License{
|
||||
{Type: "Apache-2.0", URI: "https://spdx.org/licenses/Apache-2.0.html"},
|
||||
{Type: "Apache-1.1", URI: "https://spdx.org/licenses/Apache-1.1.html"},
|
||||
},
|
||||
},
|
||||
Path: buildpackPath,
|
||||
Stacks: []libcnb.BuildpackStack{
|
||||
{
|
||||
ID: "test-id",
|
||||
Mixins: []string{"test-name"},
|
||||
},
|
||||
},
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
}))
|
||||
Expect(ctx.Layers).To(Equal(libcnb.Layers{Path: layersPath}))
|
||||
Expect(ctx.PersistentMetadata).To(Equal(map[string]interface{}{"test-key": "test-value"}))
|
||||
Expect(ctx.Plan).To(Equal(libcnb.BuildpackPlan{
|
||||
Entries: []libcnb.BuildpackPlanEntry{
|
||||
{
|
||||
Name: "test-name",
|
||||
Metadata: map[string]interface{}{
|
||||
"test-key": "test-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
Expect(ctx.Platform).To(Equal(libcnb.Platform{
|
||||
Bindings: libcnb.Bindings{
|
||||
libcnb.Binding{
|
||||
Name: "alpha",
|
||||
Path: filepath.Join(platformPath, "bindings", "alpha"),
|
||||
Secret: map[string]string{
|
||||
"test-secret-key": "test-secret-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
Environment: map[string]string{"TEST_ENV": "test-value"},
|
||||
Path: platformPath,
|
||||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
})
|
||||
})
|
||||
|
||||
it("extracts buildpack path from command path if CNB_BUILDPACK_PATH is not set", func() {
|
||||
|
@ -297,6 +412,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{filepath.Join(buildpackPath, commandPath), layersPath, platformPath, buildpackPlanPath}),
|
||||
)
|
||||
|
||||
|
@ -309,6 +425,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), fmt.Errorf("test-error"))
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
@ -323,6 +440,7 @@ version = "1.1.1"
|
|||
Return(libcnb.BuildResult{Layers: []libcnb.LayerContributor{layerContributor}}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -339,6 +457,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithEnvironmentWriter(environmentWriter),
|
||||
)
|
||||
|
@ -356,6 +475,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithEnvironmentWriter(environmentWriter),
|
||||
)
|
||||
|
@ -373,6 +493,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithEnvironmentWriter(environmentWriter),
|
||||
|
@ -391,6 +512,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithEnvironmentWriter(environmentWriter),
|
||||
)
|
||||
|
@ -422,6 +544,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -453,6 +576,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(result, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -501,6 +625,7 @@ version = "1.1.1"
|
|||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -535,12 +660,79 @@ version = "1.1.1"
|
|||
}))
|
||||
})
|
||||
|
||||
it("ignore working-directory setting and writes launch.toml (API<0.8)", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command-in-dir",
|
||||
Default: true,
|
||||
WorkingDirectory: "/my/directory/",
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
||||
Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml")))
|
||||
Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.LaunchTOML{
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command-in-dir",
|
||||
Default: true,
|
||||
},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
it("writes launch.toml with working-directory setting(API>=0.8)", func() {
|
||||
var b bytes.Buffer
|
||||
err := buildpackTOML.Execute(&b, map[string]string{"APIVersion": "0.8"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command-in-dir",
|
||||
Default: true,
|
||||
WorkingDirectory: "/my/directory/",
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
||||
Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml")))
|
||||
Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.LaunchTOML{
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command-in-dir",
|
||||
Default: true,
|
||||
WorkingDirectory: "/my/directory/",
|
||||
},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
it("writes persistent metadata", func() {
|
||||
m := map[string]interface{}{"test-key": "test-value"}
|
||||
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{PersistentMetadata: m}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -553,6 +745,7 @@ version = "1.1.1"
|
|||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -573,6 +766,7 @@ version = "1.1.1"
|
|||
Return(libcnb.BuildResult{Layers: []libcnb.LayerContributor{layerContributor}}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -605,6 +799,7 @@ version = "1.1.1"
|
|||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -625,4 +820,213 @@ version = "1.1.1"
|
|||
},
|
||||
}))
|
||||
})
|
||||
|
||||
context("Config bomLabel is false", func() {
|
||||
it.Before(func() {
|
||||
var err error
|
||||
|
||||
buildpackTOML, err = template.New("buildpack.toml").Parse(bpTOMLContents)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
var b bytes.Buffer
|
||||
err = buildpackTOML.Execute(&b, map[string]string{"APIVersion": "0.7"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
})
|
||||
|
||||
it("writes launch.toml without BOM entries", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{
|
||||
BOM: &libcnb.BOM{Entries: []libcnb.BOMEntry{
|
||||
{
|
||||
Name: "test-launch-bom-entry",
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
Launch: true,
|
||||
},
|
||||
{
|
||||
Name: "test-build-bom-entry",
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
},
|
||||
}},
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command",
|
||||
Default: true,
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(false),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
||||
Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml")))
|
||||
Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.LaunchTOML{
|
||||
Processes: []libcnb.Process{
|
||||
{
|
||||
Type: "test-type",
|
||||
Command: "test-command",
|
||||
Default: true,
|
||||
},
|
||||
},
|
||||
BOM: nil,
|
||||
}))
|
||||
})
|
||||
|
||||
it("writes build.toml without BOM entries", func() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{
|
||||
BOM: &libcnb.BOM{Entries: []libcnb.BOMEntry{
|
||||
{
|
||||
Name: "test-build-bom-entry",
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
Build: true,
|
||||
},
|
||||
{
|
||||
Name: "test-launch-bom-entry",
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
Build: false,
|
||||
},
|
||||
}},
|
||||
Unmet: []libcnb.UnmetPlanEntry{
|
||||
{
|
||||
Name: "test-entry",
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(false),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
||||
Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "build.toml")))
|
||||
Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.BuildTOML{
|
||||
BOM: nil,
|
||||
Unmet: []libcnb.UnmetPlanEntry{
|
||||
{
|
||||
Name: "test-entry",
|
||||
},
|
||||
},
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
context("Validates SBOM entries", func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.7"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
sbom-formats = ["application/vnd.cyclonedx+json"]
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
builder.On("Build", mock.Anything).Return(libcnb.BuildResult{}, nil)
|
||||
})
|
||||
|
||||
it("has no SBOM files", func() {
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls).To(BeEmpty())
|
||||
})
|
||||
|
||||
it("has no accepted formats", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.7"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
sbom-formats = []
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "launch.sbom.spdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to find actual SBOM Type application/spdx+json in list of supported SBOM types []"))
|
||||
})
|
||||
|
||||
it("skips if API is not 0.7", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.6"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
sbom-formats = []
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "launch.sbom.spdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls).To(BeEmpty())
|
||||
})
|
||||
|
||||
it("has no matching formats", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "launch.sbom.spdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to find actual SBOM Type application/spdx+json in list of supported SBOM types [application/vnd.cyclonedx+json]"))
|
||||
})
|
||||
|
||||
it("has a matching format", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "launch.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "layer.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls).To(BeEmpty())
|
||||
})
|
||||
|
||||
it("has a junk format", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "launch.sbom.random.json"), []byte{}, 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "layer.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to parse SBOM unknown\nunable to translate from random.json to SBOMFormat"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@ type BuildpackInfo struct {
|
|||
|
||||
// Licenses a list of buildpack licenses.
|
||||
Licenses []License `toml:"licenses"`
|
||||
|
||||
// SBOM is the list of supported SBOM media types
|
||||
SBOMFormats []string `toml:"sbom-formats"`
|
||||
}
|
||||
|
||||
// License contains information about a Software License
|
||||
|
@ -91,7 +94,7 @@ type Buildpack struct {
|
|||
Info BuildpackInfo `toml:"buildpack"`
|
||||
|
||||
// Path is the path to the buildpack.
|
||||
Path string
|
||||
Path string `toml:"-"`
|
||||
|
||||
// Stacks is the collection of stacks supported by the buildpack.
|
||||
Stacks []BuildpackStack `toml:"stacks"`
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package libcnb_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/libcnb"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func testBuildpackTOML(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("does not serialize the Path field", func() {
|
||||
bp := libcnb.Buildpack{
|
||||
API: "0.6",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-buildpack/sample",
|
||||
Name: "sample",
|
||||
},
|
||||
Path: "../buildpack",
|
||||
}
|
||||
|
||||
output := &bytes.Buffer{}
|
||||
|
||||
Expect(toml.NewEncoder(output).Encode(bp)).To(Succeed())
|
||||
Expect(output.String()).NotTo(Or(ContainSubstring("Path = "), ContainSubstring("path = ")))
|
||||
})
|
||||
}
|
10
config.go
10
config.go
|
@ -65,6 +65,7 @@ type ExecDWriter interface {
|
|||
// Config is an object that contains configurable properties for execution.
|
||||
type Config struct {
|
||||
arguments []string
|
||||
bomLabel bool
|
||||
environmentWriter EnvironmentWriter
|
||||
exitHandler ExitHandler
|
||||
tomlWriter TOMLWriter
|
||||
|
@ -113,3 +114,12 @@ func WithExecDWriter(execdWriter ExecDWriter) Option {
|
|||
return config
|
||||
}
|
||||
}
|
||||
|
||||
// WithBOMLabel creates an Option that enables/disables writing the BOM Label
|
||||
// Deprecated: as of Buildpack API 0.7, to be removed in a future version
|
||||
func WithBOMLabel(bomLabel bool) Option {
|
||||
return func(config Config) Config {
|
||||
config.bomLabel = bomLabel
|
||||
return config
|
||||
}
|
||||
}
|
||||
|
|
53
detect.go
53
detect.go
|
@ -24,6 +24,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
|
||||
"github.com/buildpacks/libcnb/internal"
|
||||
"github.com/buildpacks/libcnb/poet"
|
||||
|
@ -77,11 +78,6 @@ func Detect(detector Detector, options ...Option) {
|
|||
config = option(config)
|
||||
}
|
||||
|
||||
if len(config.arguments) != 3 {
|
||||
config.exitHandler.Error(fmt.Errorf("expected 2 arguments and received %d", len(config.arguments)-1))
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
file string
|
||||
|
@ -115,20 +111,46 @@ func Detect(detector Detector, options ...Option) {
|
|||
}
|
||||
logger.Debugf("Buildpack: %+v", ctx.Buildpack)
|
||||
|
||||
API := strings.TrimSpace(ctx.Buildpack.API)
|
||||
if API != "0.5" && API != "0.6" {
|
||||
config.exitHandler.Error(errors.New("this version of libcnb is only compatible with buildpack API 0.5 and 0.6"))
|
||||
API, err := semver.NewVersion(ctx.Buildpack.API)
|
||||
if err != nil {
|
||||
config.exitHandler.Error(errors.New("version cannot be parsed"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Platform.Path = config.arguments[1]
|
||||
compatVersionCheck, _ := semver.NewConstraint(fmt.Sprintf(">= %s, <= %s", MinSupportedBPVersion, MaxSupportedBPVersion))
|
||||
if !compatVersionCheck.Check(API) {
|
||||
config.exitHandler.Error(fmt.Errorf("this version of libcnb is only compatible with buildpack APIs >= %s, <= %s", MinSupportedBPVersion, MaxSupportedBPVersion))
|
||||
return
|
||||
}
|
||||
|
||||
var buildPlanPath string
|
||||
|
||||
if API.LessThan(semver.MustParse("0.8")) {
|
||||
if len(config.arguments) != 3 {
|
||||
config.exitHandler.Error(fmt.Errorf("expected 2 arguments and received %d", len(config.arguments)-1))
|
||||
return
|
||||
}
|
||||
ctx.Platform.Path = config.arguments[1]
|
||||
buildPlanPath = config.arguments[2]
|
||||
} else {
|
||||
ctx.Platform.Path, ok = os.LookupEnv("CNB_PLATFORM_DIR")
|
||||
if !ok {
|
||||
config.exitHandler.Error(fmt.Errorf("expected CNB_PLATFORM_DIR to be set"))
|
||||
return
|
||||
}
|
||||
buildPlanPath, ok = os.LookupEnv("CNB_BUILD_PLAN_PATH")
|
||||
if !ok {
|
||||
config.exitHandler.Error(fmt.Errorf("expected CNB_BUILD_PLAN_PATH to be set"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if logger.IsDebugEnabled() {
|
||||
logger.Debug(PlatformFormatter(ctx.Platform))
|
||||
}
|
||||
|
||||
file = filepath.Join(ctx.Platform.Path, "bindings")
|
||||
if ctx.Platform.Bindings, err = NewBindingsFromPath(file); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to read platform bindings %s\n%w", file, err))
|
||||
if ctx.Platform.Bindings, err = NewBindingsForBuild(ctx.Platform.Path); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to read platform bindings %s\n%w", ctx.Platform.Path, err))
|
||||
return
|
||||
}
|
||||
logger.Debugf("Platform Bindings: %+v", ctx.Platform.Bindings)
|
||||
|
@ -167,10 +189,9 @@ func Detect(detector Detector, options ...Option) {
|
|||
plans.Or = result.Plans[1:]
|
||||
}
|
||||
|
||||
file = config.arguments[2]
|
||||
logger.Debugf("Writing build plans: %s <= %+v", file, plans)
|
||||
if err := config.tomlWriter.Write(file, plans); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to write buildplan %s\n%w", file, err))
|
||||
logger.Debugf("Writing build plans: %s <= %+v", buildPlanPath, plans)
|
||||
if err := config.tomlWriter.Write(buildPlanPath, plans); err != nil {
|
||||
config.exitHandler.Error(fmt.Errorf("unable to write buildplan %s\n%w", buildPlanPath, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
169
detect_test.go
169
detect_test.go
|
@ -118,6 +118,8 @@ test-key = "test-value"
|
|||
tomlWriter.On("Write", mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
Expect(os.Setenv("CNB_STACK_ID", "test-stack-id")).To(Succeed())
|
||||
Expect(os.Setenv("CNB_PLATFORM_DIR", platformPath)).To(Succeed())
|
||||
Expect(os.Setenv("CNB_BUILD_PLAN_PATH", buildPlanPath)).To(Succeed())
|
||||
|
||||
workingDir, err = os.Getwd()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -128,6 +130,8 @@ test-key = "test-value"
|
|||
Expect(os.Chdir(workingDir)).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_STACK_ID")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_PLATFORM_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BUILD_PLAN_PATH")).To(Succeed())
|
||||
|
||||
Expect(os.RemoveAll(applicationPath)).To(Succeed())
|
||||
Expect(os.RemoveAll(buildpackPath)).To(Succeed())
|
||||
|
@ -135,7 +139,7 @@ test-key = "test-value"
|
|||
Expect(os.RemoveAll(platformPath)).To(Succeed())
|
||||
})
|
||||
|
||||
context("buildpack API is not 0.5 or 0.6", func() {
|
||||
context("buildpack API is not within the supported range", func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
|
@ -157,7 +161,7 @@ version = "1.1.1"
|
|||
)
|
||||
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError(
|
||||
"this version of libcnb is only compatible with buildpack API 0.5 and 0.6",
|
||||
fmt.Sprintf("this version of libcnb is only compatible with buildpack APIs >= %s, <= %s", libcnb.MinSupportedBPVersion, libcnb.MaxSupportedBPVersion),
|
||||
))
|
||||
})
|
||||
})
|
||||
|
@ -185,53 +189,130 @@ version = "1.1.1"
|
|||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("CNB_STACK_ID not set"))
|
||||
})
|
||||
|
||||
it("creates context", func() {
|
||||
detector.On("Detect", mock.Anything).Return(libcnb.DetectResult{Pass: true}, nil)
|
||||
context("errors if required env vars are not set for buildpack API >=0.8", func() {
|
||||
for _, e := range []string{"CNB_PLATFORM_DIR", "CNB_BUILD_PLAN_PATH"} {
|
||||
// We need to do this assignment because of the way that spec binds variables
|
||||
envVar := e
|
||||
context(fmt.Sprintf("when %s is unset", envVar), func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.8"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
os.Unsetenv(envVar)
|
||||
})
|
||||
|
||||
libcnb.Detect(detector,
|
||||
libcnb.WithArguments([]string{commandPath, platformPath, buildPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
it("fails", func() {
|
||||
libcnb.Detect(detector,
|
||||
libcnb.WithArguments([]string{commandPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError(
|
||||
fmt.Sprintf("expected %s to be set", envVar),
|
||||
))
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ctx := detector.Calls[0].Arguments[0].(libcnb.DetectContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.6",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
ClearEnvironment: true,
|
||||
Description: "A test buildpack",
|
||||
Keywords: []string{"test", "buildpack"},
|
||||
Licenses: []libcnb.License{
|
||||
{Type: "Apache-2.0", URI: "https://spdx.org/licenses/Apache-2.0.html"},
|
||||
{Type: "Apache-1.1", URI: "https://spdx.org/licenses/Apache-1.1.html"},
|
||||
context("when BP API >= 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.8"
|
||||
|
||||
[buildpack]
|
||||
id = "test-id"
|
||||
name = "test-name"
|
||||
version = "1.1.1"
|
||||
`),
|
||||
0600),
|
||||
).To(Succeed())
|
||||
})
|
||||
|
||||
it("creates context", func() {
|
||||
detector.On("Detect", mock.Anything).Return(libcnb.DetectResult{Pass: true}, nil)
|
||||
|
||||
libcnb.Detect(detector,
|
||||
libcnb.WithArguments([]string{commandPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
ctx := detector.Calls[0].Arguments[0].(libcnb.DetectContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.8",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
},
|
||||
},
|
||||
Path: buildpackPath,
|
||||
Stacks: []libcnb.BuildpackStack{
|
||||
{
|
||||
ID: "test-id",
|
||||
Mixins: []string{"test-name"},
|
||||
},
|
||||
},
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
}))
|
||||
Expect(ctx.Platform).To(Equal(libcnb.Platform{
|
||||
Bindings: libcnb.Bindings{
|
||||
libcnb.Binding{
|
||||
Name: "alpha",
|
||||
Path: filepath.Join(platformPath, "bindings", "alpha"),
|
||||
Secret: map[string]string{
|
||||
"test-secret-key": "test-secret-value",
|
||||
Path: buildpackPath,
|
||||
}))
|
||||
Expect(ctx.Platform).To(Equal(libcnb.Platform{
|
||||
Bindings: libcnb.Bindings{
|
||||
libcnb.Binding{
|
||||
Name: "alpha",
|
||||
Path: filepath.Join(platformPath, "bindings", "alpha"),
|
||||
Secret: map[string]string{
|
||||
"test-secret-key": "test-secret-value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Environment: map[string]string{"TEST_ENV": "test-value"},
|
||||
Path: platformPath,
|
||||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
Environment: map[string]string{"TEST_ENV": "test-value"},
|
||||
Path: platformPath,
|
||||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
})
|
||||
})
|
||||
|
||||
context("when BP API < 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.Unsetenv("CNB_PLATFORM_DIR")).To(Succeed())
|
||||
Expect(os.Unsetenv("CNB_BUILD_PLAN_PATH")).To(Succeed())
|
||||
})
|
||||
|
||||
it("creates context", func() {
|
||||
detector.On("Detect", mock.Anything).Return(libcnb.DetectResult{Pass: true}, nil)
|
||||
|
||||
libcnb.Detect(detector,
|
||||
libcnb.WithArguments([]string{commandPath, platformPath, buildPlanPath}),
|
||||
libcnb.WithExitHandler(exitHandler),
|
||||
)
|
||||
|
||||
ctx := detector.Calls[0].Arguments[0].(libcnb.DetectContext)
|
||||
Expect(ctx.Application).To(Equal(libcnb.Application{Path: applicationPath}))
|
||||
Expect(ctx.Buildpack).To(Equal(libcnb.Buildpack{
|
||||
API: "0.6",
|
||||
Info: libcnb.BuildpackInfo{
|
||||
ID: "test-id",
|
||||
Name: "test-name",
|
||||
Version: "1.1.1",
|
||||
ClearEnvironment: true,
|
||||
Description: "A test buildpack",
|
||||
Keywords: []string{"test", "buildpack"},
|
||||
Licenses: []libcnb.License{
|
||||
{Type: "Apache-2.0", URI: "https://spdx.org/licenses/Apache-2.0.html"},
|
||||
{Type: "Apache-1.1", URI: "https://spdx.org/licenses/Apache-1.1.html"},
|
||||
},
|
||||
},
|
||||
Path: buildpackPath,
|
||||
Stacks: []libcnb.BuildpackStack{
|
||||
{
|
||||
ID: "test-id",
|
||||
Mixins: []string{"test-name"},
|
||||
},
|
||||
},
|
||||
Metadata: map[string]interface{}{"test-key": "test-value"},
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
it("extracts buildpack path from command path if CNB_BUILDPACK_PATH is not set", func() {
|
||||
|
|
20
go.mod
20
go.mod
|
@ -1,10 +1,22 @@
|
|||
module github.com/buildpacks/libcnb
|
||||
|
||||
go 1.15
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.4.1
|
||||
github.com/onsi/gomega v1.16.0
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/Masterminds/semver/v3 v3.1.1
|
||||
github.com/onsi/gomega v1.19.0
|
||||
github.com/sclevine/spec v1.4.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.4.0 // indirect
|
||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
|
||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
51
go.sum
51
go.sum
|
@ -1,10 +1,14 @@
|
|||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -15,34 +19,38 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
|
||||
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -53,8 +61,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
|
||||
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -64,24 +74,30 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
|
||||
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
@ -90,17 +106,16 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
|||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -33,5 +33,6 @@ func TestUnit(t *testing.T) {
|
|||
suite("Main", testMain)
|
||||
suite("Platform", testPlatform)
|
||||
suite("ExecD", testExecD)
|
||||
suite("BuildpackTOML", testBuildpackTOML)
|
||||
suite.Run(t)
|
||||
}
|
||||
|
|
|
@ -38,6 +38,12 @@ func (w EnvironmentWriter) Write(path string, environment map[string]string) err
|
|||
|
||||
for key, value := range environment {
|
||||
f := filepath.Join(path, key)
|
||||
|
||||
// required to support process-specific environment variables
|
||||
if err := os.MkdirAll(filepath.Dir(f), 0755); err != nil {
|
||||
return fmt.Errorf("unable to mkdir from key %s\n%w", filepath.Dir(f), err)
|
||||
}
|
||||
|
||||
// #nosec
|
||||
if err := ioutil.WriteFile(f, []byte(value), 0644); err != nil {
|
||||
return fmt.Errorf("unable to write file %s\n%w", f, err)
|
||||
|
|
|
@ -63,6 +63,17 @@ func testEnvironmentWriter(t *testing.T, context spec.G, it spec.S) {
|
|||
Expect(string(content)).To(Equal("other-content"))
|
||||
})
|
||||
|
||||
it("writes the given environment with process specific envs to a directory", func() {
|
||||
err := writer.Write(path, map[string]string{
|
||||
"some-proc/some-name": "some-content",
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
content, err := ioutil.ReadFile(filepath.Join(path, "some-proc", "some-name"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(content)).To(Equal("some-content"))
|
||||
})
|
||||
|
||||
it("writes does not create a directory of the env map is empty", func() {
|
||||
err := writer.Write(path, map[string]string{})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
|
69
layer.go
69
layer.go
|
@ -26,9 +26,18 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
const (
|
||||
BOMFormatCycloneDXExtension = "cdx.json"
|
||||
BOMFormatSPDXExtension = "spdx.json"
|
||||
BOMFormatSyftExtension = "syft.json"
|
||||
BOMMediaTypeCycloneDX = "application/vnd.cyclonedx+json"
|
||||
BOMMediaTypeSPDX = "application/spdx+json"
|
||||
BOMMediaTypeSyft = "application/vnd.syft+json"
|
||||
BOMUnknown = "unknown"
|
||||
)
|
||||
|
||||
// Exec represents the exec.d layer location
|
||||
type Exec struct {
|
||||
|
||||
// Path is the path to the exec.d directory.
|
||||
Path string
|
||||
}
|
||||
|
@ -68,9 +77,47 @@ func (p Profile) ProcessAddf(processType string, name string, format string, a .
|
|||
p.Addf(filepath.Join(processType, name), format, a...)
|
||||
}
|
||||
|
||||
// Contribute represents a layer managed by the buildpack.
|
||||
type Layer struct {
|
||||
// BOMFormat indicates the format of the SBOM entry
|
||||
type SBOMFormat int
|
||||
|
||||
const (
|
||||
CycloneDXJSON SBOMFormat = iota
|
||||
SPDXJSON
|
||||
SyftJSON
|
||||
UnknownFormat
|
||||
)
|
||||
|
||||
func (b SBOMFormat) String() string {
|
||||
return []string{
|
||||
BOMFormatCycloneDXExtension,
|
||||
BOMFormatSPDXExtension,
|
||||
BOMFormatSyftExtension,
|
||||
BOMUnknown}[b]
|
||||
}
|
||||
|
||||
func (b SBOMFormat) MediaType() string {
|
||||
return []string{
|
||||
BOMMediaTypeCycloneDX,
|
||||
BOMMediaTypeSPDX,
|
||||
BOMMediaTypeSyft,
|
||||
BOMUnknown}[b]
|
||||
}
|
||||
|
||||
func SBOMFormatFromString(from string) (SBOMFormat, error) {
|
||||
switch from {
|
||||
case CycloneDXJSON.String():
|
||||
return CycloneDXJSON, nil
|
||||
case SPDXJSON.String():
|
||||
return SPDXJSON, nil
|
||||
case SyftJSON.String():
|
||||
return SyftJSON, nil
|
||||
}
|
||||
|
||||
return UnknownFormat, fmt.Errorf("unable to translate from %s to SBOMFormat", from)
|
||||
}
|
||||
|
||||
// Layer represents a layer managed by the buildpack.
|
||||
type Layer struct {
|
||||
// LayerTypes indicates the type of layer
|
||||
LayerTypes `toml:"types"`
|
||||
|
||||
|
@ -99,6 +146,10 @@ type Layer struct {
|
|||
Exec Exec `toml:"-"`
|
||||
}
|
||||
|
||||
func (l Layer) SBOMPath(bt SBOMFormat) string {
|
||||
return filepath.Join(filepath.Dir(l.Path), fmt.Sprintf("%s.sbom.%s", l.Name, bt))
|
||||
}
|
||||
|
||||
// LayerTypes describes which types apply to a given layer. A layer may have any combination of Launch, Build, and
|
||||
// Cache types.
|
||||
type LayerTypes struct {
|
||||
|
@ -116,7 +167,6 @@ type LayerTypes struct {
|
|||
|
||||
// LayerContributor is an interface for types that create layers.
|
||||
type LayerContributor interface {
|
||||
|
||||
// Contribute accepts a layer and transforms it, returning a layer.
|
||||
Contribute(layer Layer) (Layer, error)
|
||||
|
||||
|
@ -126,7 +176,6 @@ type LayerContributor interface {
|
|||
|
||||
// Layers represents the layers part of the specification.
|
||||
type Layers struct {
|
||||
|
||||
// Path is the layers filesystem location.
|
||||
Path string
|
||||
}
|
||||
|
@ -162,3 +211,13 @@ func (l *Layers) Layer(name string) (Layer, error) {
|
|||
|
||||
return layer, nil
|
||||
}
|
||||
|
||||
// BOMBuildPath returns the full path to the build SBoM file for the buildpack
|
||||
func (l Layers) BuildSBOMPath(bt SBOMFormat) string {
|
||||
return filepath.Join(l.Path, fmt.Sprintf("build.sbom.%s", bt))
|
||||
}
|
||||
|
||||
// BOMLaunchPath returns the full path to the launch SBoM file for the buildpack
|
||||
func (l Layers) LaunchSBOMPath(bt SBOMFormat) string {
|
||||
return filepath.Join(l.Path, fmt.Sprintf("launch.sbom.%s", bt))
|
||||
}
|
||||
|
|
|
@ -110,6 +110,36 @@ func testLayer(t *testing.T, context spec.G, it spec.S) {
|
|||
Expect(l.Profile).To(Equal(libcnb.Profile{}))
|
||||
})
|
||||
|
||||
it("generates SBOM paths", func() {
|
||||
l, err := layers.Layer("test-name")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(l.Path).To(Equal(filepath.Join(path, "test-name")))
|
||||
Expect(layers.BuildSBOMPath(libcnb.CycloneDXJSON)).To(Equal(filepath.Join(path, "build.sbom.cdx.json")))
|
||||
Expect(layers.BuildSBOMPath(libcnb.SPDXJSON)).To(Equal(filepath.Join(path, "build.sbom.spdx.json")))
|
||||
Expect(layers.BuildSBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "build.sbom.syft.json")))
|
||||
Expect(layers.LaunchSBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "launch.sbom.syft.json")))
|
||||
Expect(l.SBOMPath(libcnb.SyftJSON)).To(Equal(filepath.Join(path, "test-name.sbom.syft.json")))
|
||||
})
|
||||
|
||||
it("maps from string to SBOM Format", func() {
|
||||
fmt, err := libcnb.SBOMFormatFromString("cdx.json")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(fmt).To(Equal(libcnb.CycloneDXJSON))
|
||||
|
||||
fmt, err = libcnb.SBOMFormatFromString("spdx.json")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(fmt).To(Equal(libcnb.SPDXJSON))
|
||||
|
||||
fmt, err = libcnb.SBOMFormatFromString("syft.json")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(fmt).To(Equal(libcnb.SyftJSON))
|
||||
|
||||
fmt, err = libcnb.SBOMFormatFromString("foobar.json")
|
||||
Expect(err).To(MatchError("unable to translate from foobar.json to SBOMFormat"))
|
||||
Expect(fmt).To(Equal(libcnb.UnknownFormat))
|
||||
})
|
||||
|
||||
it("reads existing 0.5 metadata", func() {
|
||||
Expect(ioutil.WriteFile(
|
||||
filepath.Join(path, "test-name.toml"),
|
||||
|
|
|
@ -43,6 +43,7 @@ const (
|
|||
|
||||
// EnvCNBBindings is the name of the environment variable that contains the path to the CNB bindings directory.
|
||||
// See the CNB bindings extension spec for more details - https://github.com/buildpacks/spec/blob/main/extensions/bindings.md
|
||||
//
|
||||
// Deprecated: Use the Service Binding Specification for Kubernetes instead -
|
||||
// https://github.com/buildpacks/rfcs/blob/main/text/0055-deprecate-service-bindings.md.
|
||||
EnvCNBBindings = "CNB_BINDINGS"
|
||||
|
|
158
tools/go.mod
158
tools/go.mod
|
@ -1,7 +1,159 @@
|
|||
module github.com/buildpacks/libcnb/tools
|
||||
|
||||
go 1.15
|
||||
go 1.17
|
||||
|
||||
require golang.org/x/tools v0.1.4
|
||||
require golang.org/x/tools v0.1.10
|
||||
|
||||
require github.com/golangci/golangci-lint v1.41.1
|
||||
require github.com/golangci/golangci-lint v1.45.2
|
||||
|
||||
require (
|
||||
4d63.com/gochecknoglobals v0.1.0 // indirect
|
||||
github.com/Antonboom/errname v0.1.5 // indirect
|
||||
github.com/Antonboom/nilnil v0.1.0 // indirect
|
||||
github.com/BurntSushi/toml v1.0.0 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/OpenPeeDeeP/depguard v1.1.0 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.3.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.1.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.0 // indirect
|
||||
github.com/blizzy78/varnamelen v0.6.1 // indirect
|
||||
github.com/bombsimon/wsl/v3 v3.3.0 // indirect
|
||||
github.com/breml/bidichk v0.2.2 // indirect
|
||||
github.com/breml/errchkjson v0.2.3 // indirect
|
||||
github.com/butuzov/ireturn v0.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/charithe/durationcheck v0.0.9 // indirect
|
||||
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect
|
||||
github.com/daixiang0/gci v0.3.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denis-tingaikin/go-header v0.4.3 // indirect
|
||||
github.com/esimonov/ifshort v1.0.4 // indirect
|
||||
github.com/ettle/strcase v0.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/fzipp/gocyclo v0.4.0 // indirect
|
||||
github.com/go-critic/go-critic v0.6.2 // indirect
|
||||
github.com/go-toolsmith/astcast v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.0.1 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.0.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.0.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.0.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.0.2 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
|
||||
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect
|
||||
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
|
||||
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
|
||||
github.com/golangci/misspell v0.3.5 // indirect
|
||||
github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
|
||||
github.com/google/go-cmp v0.5.7 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.4.2 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-version v1.4.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/jgautheron/goconst v1.5.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
github.com/julz/importas v0.1.0 // indirect
|
||||
github.com/kisielk/errcheck v1.6.0 // indirect
|
||||
github.com/kisielk/gotool v1.0.0 // indirect
|
||||
github.com/kulti/thelper v0.5.1 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.3 // indirect
|
||||
github.com/kyoh86/exportloopref v0.1.8 // indirect
|
||||
github.com/ldez/gomoddirectives v0.2.2 // indirect
|
||||
github.com/ldez/tagliatelle v0.3.1 // indirect
|
||||
github.com/leonklingele/grouper v1.1.0 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/maratori/testpackage v1.0.1 // indirect
|
||||
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
|
||||
github.com/mgechev/revive v1.1.4 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/moricho/tparallel v0.2.1 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
|
||||
github.com/nishanths/exhaustive v0.7.11 // indirect
|
||||
github.com/nishanths/predeclared v0.2.1 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v0.0.0-20211125173453-6d6d39c5bb8b // indirect
|
||||
github.com/prometheus/client_golang v1.7.1 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.10.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.3.15 // indirect
|
||||
github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.2.3 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
|
||||
github.com/securego/gosec/v2 v2.10.0 // indirect
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/sivchari/containedctx v1.0.2 // indirect
|
||||
github.com/sivchari/tenv v1.4.7 // indirect
|
||||
github.com/sonatard/noctx v0.0.1 // indirect
|
||||
github.com/sourcegraph/go-diff v0.6.1 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/cobra v1.4.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.10.1 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stretchr/objx v0.1.1 // indirect
|
||||
github.com/stretchr/testify v1.7.1 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/sylvia7788/contextcheck v1.0.4 // indirect
|
||||
github.com/tdakkota/asciicheck v0.1.1 // indirect
|
||||
github.com/tetafro/godot v1.4.11 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.5.0 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect
|
||||
github.com/ultraware/funlen v0.0.3 // indirect
|
||||
github.com/ultraware/whitespace v0.0.5 // indirect
|
||||
github.com/uudashr/gocognit v1.0.5 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.1.1-0.20210918184747-d757024714a1 // indirect
|
||||
gitlab.com/bosi/decorder v0.2.1 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
honnef.co/go/tools v0.2.2 // indirect
|
||||
mvdan.cc/gofumpt v0.3.0 // indirect
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
|
||||
mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 // indirect
|
||||
)
|
||||
|
|
728
tools/go.sum
728
tools/go.sum
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
|||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package tools
|
||||
|
|
Loading…
Reference in New Issue