mirror of https://github.com/buildpacks/libcnb.git
Compare commits
74 Commits
Author | SHA1 | Date |
---|---|---|
|
8b7f79763b | |
|
09cee453ad | |
|
0f3d43690e | |
|
fb77fe5013 | |
|
539663a25f | |
|
8660a07c64 | |
|
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 |
|
@ -4,6 +4,8 @@ updates:
|
|||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
ignore:
|
||||
- dependency-name: github.com/onsi/gomega
|
||||
labels:
|
||||
- semver:patch
|
||||
- type:dependency-upgrade
|
||||
|
|
|
@ -25,3 +25,18 @@
|
|||
- name: type:task
|
||||
description: A general task
|
||||
color: e3d9fc
|
||||
- name: type:informational
|
||||
description: Provides information or notice to the community
|
||||
color: e3d9fc
|
||||
- name: type:poll
|
||||
description: Request for feedback from the community
|
||||
color: e3d9fc
|
||||
- name: note:ideal-for-contribution
|
||||
description: An issue that a contributor can help us with
|
||||
color: 54f7a8
|
||||
- name: note:on-hold
|
||||
description: We can't start working on this issue yet
|
||||
color: 54f7a8
|
||||
- name: note:good-first-issue
|
||||
description: A good first issue to get started with
|
||||
color: 54f7a8
|
||||
|
|
|
@ -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.32.0
|
||||
|
|
|
@ -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@v4
|
||||
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@v4
|
||||
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 }}
|
|
@ -0,0 +1,54 @@
|
|||
name: Tests
|
||||
"on":
|
||||
merge_group:
|
||||
types:
|
||||
- checks_requested
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- release-1.x
|
||||
jobs:
|
||||
unit:
|
||||
name: Unit Test
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- 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@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- name: Install richgo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GOCMD=richgo make
|
||||
env:
|
||||
RICHGO_FORCE_COLOR: "1"
|
|
@ -2,7 +2,7 @@ name: Update Draft Release
|
|||
"on":
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-1.x
|
||||
jobs:
|
||||
update:
|
||||
name: Update Draft Release
|
|
@ -0,0 +1,72 @@
|
|||
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@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- uses: actions/checkout@v3
|
||||
- name: Update Go Version & Modules
|
||||
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 -- .
|
||||
|
||||
if [ "$OLD_GO_VERSION" == "$GO_VERSION" ]; then
|
||||
COMMIT_TITLE="Bump Go Modules"
|
||||
COMMIT_BODY="Bumps Go modules used by the project. See the commit for details on what modules were updated."
|
||||
COMMIT_SEMVER="semver:patch"
|
||||
else
|
||||
COMMIT_TITLE="Bump Go from ${OLD_GO_VERSION} to ${GO_VERSION}"
|
||||
COMMIT_BODY="Bumps Go from ${OLD_GO_VERSION} to ${GO_VERSION} and update Go modules used by the project. See the commit for details on what modules were updated."
|
||||
COMMIT_SEMVER="semver:minor"
|
||||
fi
|
||||
|
||||
echo "commit-title=${COMMIT_TITLE}" >> "$GITHUB_OUTPUT"
|
||||
echo "commit-body=${COMMIT_BODY}" >> "$GITHUB_OUTPUT"
|
||||
echo "commit-semver=${COMMIT_SEMVER}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GO_VERSION: "1.20"
|
||||
- uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
||||
${{ steps.update-go.outputs.commit-body }}
|
||||
|
||||
<details>
|
||||
<summary>Release Notes</summary>
|
||||
${{ steps.pipeline.outputs.release-notes }}
|
||||
</details>
|
||||
branch: update/go
|
||||
commit-message: |-
|
||||
${{ steps.update-go.outputs.commit-title }}
|
||||
|
||||
${{ steps.update-go.outputs.commit-body }}
|
||||
delete-branch: true
|
||||
labels: ${{ steps.update-go.outputs.commit-semver }}, type:task
|
||||
signoff: true
|
||||
title: ${{ steps.update-go.outputs.commit-title }}
|
||||
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@v4
|
||||
with:
|
||||
go-version: "1.16"
|
||||
go-version: "1.20"
|
||||
- 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)
|
||||
|
@ -56,13 +57,15 @@ jobs:
|
|||
git add .github/
|
||||
git checkout -- .
|
||||
|
||||
echo "::set-output name=old-version::${OLD_VERSION}"
|
||||
echo "::set-output name=new-version::${NEW_VERSION}"
|
||||
echo "::set-output name=release-notes::${RELEASE_NOTES//$'\n'/%0A}"
|
||||
echo "old-version=${OLD_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "new-version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
DELIMITER=$(openssl rand -hex 16) # roughly the same entropy as uuid v4 used in https://github.com/actions/toolkit/blob/b36e70495fbee083eb20f600eafa9091d832577d/packages/core/src/file-command.ts#L28
|
||||
printf "release-notes<<%s\n%s\n%s\n" "${DELIMITER}" "${RELEASE_NOTES}" "${DELIMITER}" >> "${GITHUB_OUTPUT}" # see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
|
||||
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@v5
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
|
@ -1,37 +0,0 @@
|
|||
name: Tests
|
||||
"on":
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
unit:
|
||||
name: Unit Test
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
path: ${{ env.HOME }}/go/pkg/mod
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.16"
|
||||
- name: Install richgo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GO111MODULE=on go get -u -ldflags="-s -w" github.com/kyoh86/richgo
|
||||
- name: Run Tests
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GOCMD=richgo make
|
||||
env:
|
||||
RICHGO_FORCE_COLOR: "1"
|
|
@ -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"`
|
||||
|
|
114
build.go
114
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
|
||||
|
||||
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
|
||||
}
|
||||
|
|
443
build_test.go
443
build_test.go
|
@ -19,7 +19,6 @@ package libcnb_test
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -58,15 +57,13 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
|
|||
it.Before(func() {
|
||||
var err error
|
||||
|
||||
applicationPath, err = ioutil.TempDir("", "build-application-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
applicationPath = t.TempDir()
|
||||
applicationPath, err = filepath.EvalSymlinks(applicationPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
builder = &mocks.Builder{}
|
||||
|
||||
buildpackPath, err = ioutil.TempDir("", "build-buildpack-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
buildpackPath = t.TempDir()
|
||||
Expect(os.Setenv("CNB_BUILDPACK_DIR", buildpackPath)).To(Succeed())
|
||||
|
||||
bpTOMLContents = `
|
||||
|
@ -108,14 +105,14 @@ test-key = "test-value"
|
|||
err = buildpackTOML.Execute(&b, map[string]string{"APIVersion": "0.6"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
|
||||
f, err := ioutil.TempFile("", "build-buildpackplan-path")
|
||||
f, err := os.CreateTemp("", "build-buildpackplan-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).NotTo(HaveOccurred())
|
||||
buildpackPlanPath = f.Name()
|
||||
|
||||
Expect(ioutil.WriteFile(buildpackPlanPath,
|
||||
Expect(os.WriteFile(buildpackPlanPath,
|
||||
[]byte(`
|
||||
[[entries]]
|
||||
name = "test-name"
|
||||
|
@ -137,10 +134,9 @@ test-key = "test-value"
|
|||
|
||||
layerContributor = &mocks.LayerContributor{}
|
||||
|
||||
layersPath, err = ioutil.TempDir("", "build-layers-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
layersPath = t.TempDir()
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "store.toml"),
|
||||
Expect(os.WriteFile(filepath.Join(layersPath, "store.toml"),
|
||||
[]byte(`
|
||||
[metadata]
|
||||
test-key = "test-value"
|
||||
|
@ -148,21 +144,23 @@ test-key = "test-value"
|
|||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
platformPath, err = ioutil.TempDir("", "build-platform-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
platformPath = t.TempDir()
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(platformPath, "bindings", "alpha", "test-secret-key"),
|
||||
Expect(os.WriteFile(filepath.Join(platformPath, "bindings", "alpha", "test-secret-key"),
|
||||
[]byte("test-secret-value"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "env"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
Expect(os.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
To(Succeed())
|
||||
|
||||
tomlWriter = &mocks.TOMLWriter{}
|
||||
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 +171,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,9 +182,9 @@ 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"),
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.4"
|
||||
|
||||
|
@ -198,20 +199,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(os.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 +261,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,10 +269,81 @@ version = "1.1.1"
|
|||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("CNB_STACK_ID not set"))
|
||||
})
|
||||
|
||||
context("when BP API >= 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.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() {
|
||||
builder.On("Build", mock.Anything).Return(libcnb.NewBuildResult(), nil)
|
||||
|
||||
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,
|
||||
}))
|
||||
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"))
|
||||
})
|
||||
})
|
||||
|
||||
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}),
|
||||
)
|
||||
|
||||
|
@ -290,6 +399,7 @@ version = "1.1.1"
|
|||
}))
|
||||
Expect(ctx.StackID).To(Equal("test-stack-id"))
|
||||
})
|
||||
})
|
||||
|
||||
it("extracts buildpack path from command path if CNB_BUILDPACK_PATH is not set", func() {
|
||||
Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed())
|
||||
|
@ -297,6 +407,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 +420,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 +435,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 +452,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 +470,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 +488,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 +507,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),
|
||||
)
|
||||
|
@ -404,7 +521,7 @@ version = "1.1.1"
|
|||
err := buildpackTOML.Execute(&b, map[string]string{"APIVersion": "0.5"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed())
|
||||
|
||||
layer := libcnb.Layer{
|
||||
Name: "test-name",
|
||||
|
@ -422,6 +539,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 +571,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 +620,7 @@ version = "1.1.1"
|
|||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -535,12 +655,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(os.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 +740,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),
|
||||
)
|
||||
|
@ -561,9 +749,9 @@ version = "1.1.1"
|
|||
})
|
||||
|
||||
it("removes stale layers", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "alpha.toml"), []byte(""), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "bravo.toml"), []byte(""), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "store.toml"), []byte(""), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(layersPath, "alpha.toml"), []byte(""), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(layersPath, "bravo.toml"), []byte(""), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(layersPath, "store.toml"), []byte(""), 0600)).To(Succeed())
|
||||
|
||||
layer := libcnb.Layer{Name: "alpha"}
|
||||
layerContributor.On("Contribute", mock.Anything).Return(layer, nil)
|
||||
|
@ -573,6 +761,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 +794,7 @@ version = "1.1.1"
|
|||
}, nil)
|
||||
|
||||
libcnb.Build(builder,
|
||||
libcnb.WithBOMLabel(true),
|
||||
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
|
||||
libcnb.WithTOMLWriter(tomlWriter),
|
||||
)
|
||||
|
@ -625,4 +815,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(os.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(os.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(os.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(os.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(os.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(os.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(os.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(os.WriteFile(filepath.Join(layersPath, "launch.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
|
||||
Expect(os.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(os.WriteFile(filepath.Join(layersPath, "launch.sbom.random.json"), []byte{}, 0600)).To(Succeed())
|
||||
Expect(os.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, _ 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
|
||||
}
|
||||
}
|
||||
|
|
51
detect.go
51
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
132
detect_test.go
132
detect_test.go
|
@ -18,7 +18,6 @@ package libcnb_test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -50,16 +49,15 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
|
|||
it.Before(func() {
|
||||
var err error
|
||||
|
||||
applicationPath, err = ioutil.TempDir("", "detect-application-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
applicationPath = t.TempDir()
|
||||
applicationPath, err = filepath.EvalSymlinks(applicationPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
buildpackPath, err = ioutil.TempDir("", "detect-buildpack-path")
|
||||
buildpackPath = t.TempDir()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(os.Setenv("CNB_BUILDPACK_DIR", buildpackPath)).To(Succeed())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.6"
|
||||
|
||||
|
@ -89,7 +87,7 @@ test-key = "test-value"
|
|||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
f, err := ioutil.TempFile("", "detect-buildplan-path")
|
||||
f, err := os.CreateTemp("", "detect-buildplan-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).NotTo(HaveOccurred())
|
||||
buildPlanPath = f.Name()
|
||||
|
@ -103,21 +101,22 @@ test-key = "test-value"
|
|||
exitHandler.On("Fail")
|
||||
exitHandler.On("Pass")
|
||||
|
||||
platformPath, err = ioutil.TempDir("", "detect-platform-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
platformPath = t.TempDir()
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(platformPath, "bindings", "alpha", "test-secret-key"),
|
||||
Expect(os.WriteFile(filepath.Join(platformPath, "bindings", "alpha", "test-secret-key"),
|
||||
[]byte("test-secret-value"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "env"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
Expect(os.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
To(Succeed())
|
||||
|
||||
tomlWriter = &mocks.TOMLWriter{}
|
||||
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 +127,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,9 +136,9 @@ 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"),
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.4"
|
||||
|
||||
|
@ -157,7 +158,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,6 +186,96 @@ version = "1.1.1"
|
|||
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("CNB_STACK_ID not set"))
|
||||
})
|
||||
|
||||
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(os.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.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),
|
||||
))
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
context("when BP API >= 0.8", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.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,
|
||||
}))
|
||||
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"))
|
||||
})
|
||||
})
|
||||
|
||||
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)
|
||||
|
||||
|
@ -218,20 +309,7 @@ version = "1.1.1"
|
|||
},
|
||||
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() {
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/buildpacks/libcnb"
|
||||
)
|
||||
|
||||
func testEnvironment(t *testing.T, context spec.G, it spec.S) {
|
||||
func testEnvironment(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/mocks"
|
||||
)
|
||||
|
||||
func testExecD(t *testing.T, context spec.G, it spec.S) {
|
||||
func testExecD(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package libcnb_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -39,13 +38,7 @@ func testFormatter(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
app, err = ioutil.TempDir("", "application-path-formatter")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
Expect(os.RemoveAll(app)).To(Succeed())
|
||||
app = t.TempDir()
|
||||
})
|
||||
|
||||
it("lists empty directory contents", func() {
|
||||
|
@ -67,9 +60,7 @@ func testFormatter(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
bp, err = ioutil.TempDir("", "buildpack-path-formatter")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
bp = t.TempDir()
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
|
@ -95,9 +86,7 @@ func testFormatter(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
plat.Path, err = ioutil.TempDir("", "platform-formatter")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
plat.Path = t.TempDir()
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
|
|
19
go.mod
19
go.mod
|
@ -1,10 +1,21 @@
|
|||
module github.com/buildpacks/libcnb
|
||||
|
||||
go 1.15
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.4.1
|
||||
github.com/onsi/gomega v1.16.0
|
||||
github.com/BurntSushi/toml v1.2.1
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/onsi/gomega v1.27.6
|
||||
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/google/go-cmp v0.5.9 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.4.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
120
go.sum
120
go.sum
|
@ -1,106 +1,36 @@
|
|||
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.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
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=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
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/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/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||
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/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/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=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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/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=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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/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=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
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=
|
||||
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.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=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
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=
|
||||
|
|
|
@ -5,7 +5,6 @@ linters:
|
|||
disable-all: true
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- dogsled
|
||||
- exportloopref
|
||||
- gocritic
|
||||
|
@ -18,12 +17,10 @@ linters:
|
|||
- nakedret
|
||||
- revive
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
|
|
|
@ -33,5 +33,6 @@ func TestUnit(t *testing.T) {
|
|||
suite("Main", testMain)
|
||||
suite("Platform", testPlatform)
|
||||
suite("ExecD", testExecD)
|
||||
suite("BuildpackTOML", testBuildpackTOML)
|
||||
suite.Run(t)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package internal
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
@ -45,7 +44,7 @@ func NewConfigMapFromPath(path string) (ConfigMap, error) {
|
|||
} else if stat.IsDir() {
|
||||
continue
|
||||
}
|
||||
contents, err := ioutil.ReadFile(file)
|
||||
contents, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read file %s\n%w", file, err)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package internal_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -28,7 +27,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testConfigMap(t *testing.T, context spec.G, it spec.S) {
|
||||
func testConfigMap(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
@ -36,13 +35,7 @@ func testConfigMap(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
path, err = ioutil.TempDir("", "config-map")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
Expect(os.RemoveAll(path)).To(Succeed())
|
||||
path = t.TempDir()
|
||||
})
|
||||
|
||||
it("returns an empty ConfigMap when directory does not exist", func() {
|
||||
|
@ -55,7 +48,7 @@ func testConfigMap(t *testing.T, context spec.G, it spec.S) {
|
|||
})
|
||||
|
||||
it("loads the ConfigMap from a directory", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "test-key"), []byte("test-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "test-key"), []byte("test-value"), 0600)).To(Succeed())
|
||||
|
||||
cm, err := internal.NewConfigMapFromPath(path)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -66,7 +59,7 @@ func testConfigMap(t *testing.T, context spec.G, it spec.S) {
|
|||
it("ignores dirs and follows symlinks", func() {
|
||||
// this is necessary to support bindings mounted as k8s config maps & secrets
|
||||
Expect(os.MkdirAll(filepath.Join(path, ".hidden"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(path, ".hidden", "test-key"),
|
||||
[]byte("test-value"),
|
||||
0600,
|
||||
|
@ -82,7 +75,7 @@ func testConfigMap(t *testing.T, context spec.G, it spec.S) {
|
|||
})
|
||||
|
||||
it("ignores hidden files", func() {
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, ".hidden-key"), []byte("hidden-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, ".hidden-key"), []byte("hidden-value"), 0600)).To(Succeed())
|
||||
|
||||
cm, err := internal.NewConfigMapFromPath(path)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package internal_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -28,7 +27,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testDirectoryContents(t *testing.T, context spec.G, it spec.S) {
|
||||
func testDirectoryContents(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
@ -36,13 +35,7 @@ func testDirectoryContents(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
path, err = ioutil.TempDir("", "directory-contents")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
Expect(os.RemoveAll(path)).To(Succeed())
|
||||
path = t.TempDir()
|
||||
})
|
||||
|
||||
it("lists empty directory contents", func() {
|
||||
|
|
|
@ -18,7 +18,6 @@ package internal
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
@ -38,8 +37,14 @@ 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 {
|
||||
if err := os.WriteFile(f, []byte(value), 0644); err != nil {
|
||||
return fmt.Errorf("unable to write file %s\n%w", f, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package internal_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -28,7 +27,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testEnvironmentWriter(t *testing.T, context spec.G, it spec.S) {
|
||||
func testEnvironmentWriter(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
@ -37,13 +36,7 @@ func testEnvironmentWriter(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
path, err = ioutil.TempDir("", "environment-writer")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(os.RemoveAll(path)).To(Succeed())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
path = t.TempDir()
|
||||
Expect(os.RemoveAll(path)).To(Succeed())
|
||||
})
|
||||
|
||||
|
@ -54,15 +47,26 @@ func testEnvironmentWriter(t *testing.T, context spec.G, it spec.S) {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
content, err := ioutil.ReadFile(filepath.Join(path, "some-name"))
|
||||
content, err := os.ReadFile(filepath.Join(path, "some-name"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(content)).To(Equal("some-content"))
|
||||
|
||||
content, err = ioutil.ReadFile(filepath.Join(path, "other-name"))
|
||||
content, err = os.ReadFile(filepath.Join(path, "other-name"))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
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 := os.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())
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testExecDWriter(t *testing.T, context spec.G, it spec.S) {
|
||||
func testExecDWriter(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testExitHandler(t *testing.T, context spec.G, it spec.S) {
|
||||
func testExitHandler(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package internal_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -28,7 +27,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/internal"
|
||||
)
|
||||
|
||||
func testTOMLWriter(t *testing.T, context spec.G, it spec.S) {
|
||||
func testTOMLWriter(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
@ -38,17 +37,10 @@ func testTOMLWriter(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
parent, err = ioutil.TempDir("", "toml-writer")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
parent = t.TempDir()
|
||||
path = filepath.Join(parent, "text.toml")
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
Expect(os.RemoveAll(parent)).To(Succeed())
|
||||
})
|
||||
|
||||
it("writes the contents of a given object out to a .toml file", func() {
|
||||
err := tomlWriter.Write(path, map[string]string{
|
||||
"some-field": "some-value",
|
||||
|
@ -56,7 +48,7 @@ func testTOMLWriter(t *testing.T, context spec.G, it spec.S) {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`
|
||||
Expect(os.ReadFile(path)).To(internal.MatchTOML(`
|
||||
some-field = "some-value"
|
||||
other-field = "other-value"`))
|
||||
})
|
||||
|
|
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))
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package libcnb_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -83,10 +82,7 @@ func testLayer(t *testing.T, context spec.G, it spec.S) {
|
|||
|
||||
context("Layers", func() {
|
||||
it.Before(func() {
|
||||
var err error
|
||||
path, err = ioutil.TempDir("", "layers")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
path = t.TempDir()
|
||||
layers = libcnb.Layers{Path: path}
|
||||
})
|
||||
|
||||
|
@ -110,8 +106,38 @@ 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(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(path, "test-name.toml"),
|
||||
[]byte(`
|
||||
launch = true
|
||||
|
@ -132,7 +158,7 @@ test-key = "test-value"
|
|||
})
|
||||
|
||||
it("reads existing 0.6 metadata", func() {
|
||||
Expect(ioutil.WriteFile(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(path, "test-name.toml"),
|
||||
[]byte(`
|
||||
[types]
|
||||
|
@ -154,7 +180,7 @@ test-key = "test-value"
|
|||
})
|
||||
|
||||
it("reads existing 0.6 metadata with launch, build and cache all false", func() {
|
||||
Expect(ioutil.WriteFile(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(path, "test-name.toml"),
|
||||
[]byte(`
|
||||
[types]
|
||||
|
|
30
main_test.go
30
main_test.go
|
@ -17,7 +17,6 @@
|
|||
package libcnb_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -30,7 +29,7 @@ import (
|
|||
"github.com/buildpacks/libcnb/mocks"
|
||||
)
|
||||
|
||||
func testMain(t *testing.T, context spec.G, it spec.S) {
|
||||
func testMain(t *testing.T, _ spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
|
@ -52,18 +51,17 @@ func testMain(t *testing.T, context spec.G, it spec.S) {
|
|||
it.Before(func() {
|
||||
var err error
|
||||
|
||||
applicationPath, err = ioutil.TempDir("", "main-application-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
applicationPath = t.TempDir()
|
||||
applicationPath, err = filepath.EvalSymlinks(applicationPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
builder = &mocks.Builder{}
|
||||
|
||||
buildpackPath, err = ioutil.TempDir("", "main-buildpack-path")
|
||||
buildpackPath = t.TempDir()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(os.Setenv("CNB_BUILDPACK_DIR", buildpackPath)).To(Succeed())
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"),
|
||||
[]byte(`
|
||||
api = "0.6"
|
||||
|
||||
|
@ -89,12 +87,12 @@ test-key = "test-value"
|
|||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
f, err := ioutil.TempFile("", "main-buildpackplan-path")
|
||||
f, err := os.CreateTemp("", "main-buildpackplan-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).NotTo(HaveOccurred())
|
||||
buildpackPlanPath = f.Name()
|
||||
|
||||
Expect(ioutil.WriteFile(buildpackPlanPath,
|
||||
Expect(os.WriteFile(buildpackPlanPath,
|
||||
[]byte(`
|
||||
[[entries]]
|
||||
name = "test-name"
|
||||
|
@ -106,7 +104,7 @@ test-key = "test-value"
|
|||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
f, err = ioutil.TempFile("", "main-buildplan-path")
|
||||
f, err = os.CreateTemp("", "main-buildplan-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).NotTo(HaveOccurred())
|
||||
buildPlanPath = f.Name()
|
||||
|
@ -121,10 +119,9 @@ test-key = "test-value"
|
|||
exitHandler.On("Pass", mock.Anything)
|
||||
exitHandler.On("Fail", mock.Anything)
|
||||
|
||||
layersPath, err = ioutil.TempDir("", "main-layers-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
layersPath = t.TempDir()
|
||||
|
||||
Expect(ioutil.WriteFile(filepath.Join(layersPath, "store.toml"),
|
||||
Expect(os.WriteFile(filepath.Join(layersPath, "store.toml"),
|
||||
[]byte(`
|
||||
[metadata]
|
||||
test-key = "test-value"
|
||||
|
@ -132,24 +129,23 @@ test-key = "test-value"
|
|||
0600),
|
||||
).To(Succeed())
|
||||
|
||||
platformPath, err = ioutil.TempDir("", "main-platform-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
platformPath = t.TempDir()
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha", "metadata"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(platformPath, "bindings", "alpha", "metadata", "test-metadata-key"),
|
||||
[]byte("test-metadata-value"),
|
||||
0600,
|
||||
)).To(Succeed())
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha", "secret"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(
|
||||
Expect(os.WriteFile(
|
||||
filepath.Join(platformPath, "bindings", "alpha", "secret", "test-secret-key"),
|
||||
[]byte("test-secret-value"),
|
||||
0600,
|
||||
)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(platformPath, "env"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
Expect(os.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0600)).
|
||||
To(Succeed())
|
||||
|
||||
tomlWriter = &mocks.TOMLWriter{}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -18,13 +18,16 @@ func (_m *Builder) Build(context libcnb.BuildContext) (libcnb.BuildResult, error
|
|||
ret := _m.Called(context)
|
||||
|
||||
var r0 libcnb.BuildResult
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(libcnb.BuildContext) (libcnb.BuildResult, error)); ok {
|
||||
return rf(context)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(libcnb.BuildContext) libcnb.BuildResult); ok {
|
||||
r0 = rf(context)
|
||||
} else {
|
||||
r0 = ret.Get(0).(libcnb.BuildResult)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(libcnb.BuildContext) error); ok {
|
||||
r1 = rf(context)
|
||||
} else {
|
||||
|
@ -33,3 +36,18 @@ func (_m *Builder) Build(context libcnb.BuildContext) (libcnb.BuildResult, error
|
|||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewBuilder interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewBuilder creates a new instance of Builder. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewBuilder(t mockConstructorTestingTNewBuilder) *Builder {
|
||||
mock := &Builder{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -18,13 +18,16 @@ func (_m *Detector) Detect(context libcnb.DetectContext) (libcnb.DetectResult, e
|
|||
ret := _m.Called(context)
|
||||
|
||||
var r0 libcnb.DetectResult
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(libcnb.DetectContext) (libcnb.DetectResult, error)); ok {
|
||||
return rf(context)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(libcnb.DetectContext) libcnb.DetectResult); ok {
|
||||
r0 = rf(context)
|
||||
} else {
|
||||
r0 = ret.Get(0).(libcnb.DetectResult)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(libcnb.DetectContext) error); ok {
|
||||
r1 = rf(context)
|
||||
} else {
|
||||
|
@ -33,3 +36,18 @@ func (_m *Detector) Detect(context libcnb.DetectContext) (libcnb.DetectResult, e
|
|||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewDetector interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewDetector creates a new instance of Detector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewDetector(t mockConstructorTestingTNewDetector) *Detector {
|
||||
mock := &Detector{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -22,3 +22,18 @@ func (_m *EnvironmentWriter) Write(dir string, environment map[string]string) er
|
|||
|
||||
return r0
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewEnvironmentWriter interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewEnvironmentWriter creates a new instance of EnvironmentWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewEnvironmentWriter(t mockConstructorTestingTNewEnvironmentWriter) *EnvironmentWriter {
|
||||
mock := &EnvironmentWriter{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -14,6 +14,10 @@ func (_m *ExecD) Execute() (map[string]string, error) {
|
|||
ret := _m.Called()
|
||||
|
||||
var r0 map[string]string
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() (map[string]string, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() map[string]string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
|
@ -22,7 +26,6 @@ func (_m *ExecD) Execute() (map[string]string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
|
@ -31,3 +34,18 @@ func (_m *ExecD) Execute() (map[string]string, error) {
|
|||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewExecD interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewExecD creates a new instance of ExecD. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewExecD(t mockConstructorTestingTNewExecD) *ExecD {
|
||||
mock := &ExecD{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -22,3 +22,18 @@ func (_m *ExecDWriter) Write(value map[string]string) error {
|
|||
|
||||
return r0
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewExecDWriter interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewExecDWriter creates a new instance of ExecDWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewExecDWriter(t mockConstructorTestingTNewExecDWriter) *ExecDWriter {
|
||||
mock := &ExecDWriter{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -23,3 +23,18 @@ func (_m *ExitHandler) Fail() {
|
|||
func (_m *ExitHandler) Pass() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewExitHandler interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewExitHandler creates a new instance of ExitHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewExitHandler(t mockConstructorTestingTNewExitHandler) *ExitHandler {
|
||||
mock := &ExitHandler{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -18,13 +18,16 @@ func (_m *LayerContributor) Contribute(layer libcnb.Layer) (libcnb.Layer, error)
|
|||
ret := _m.Called(layer)
|
||||
|
||||
var r0 libcnb.Layer
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(libcnb.Layer) (libcnb.Layer, error)); ok {
|
||||
return rf(layer)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(libcnb.Layer) libcnb.Layer); ok {
|
||||
r0 = rf(layer)
|
||||
} else {
|
||||
r0 = ret.Get(0).(libcnb.Layer)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(libcnb.Layer) error); ok {
|
||||
r1 = rf(layer)
|
||||
} else {
|
||||
|
@ -47,3 +50,18 @@ func (_m *LayerContributor) Name() string {
|
|||
|
||||
return r0
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewLayerContributor interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewLayerContributor creates a new instance of LayerContributor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewLayerContributor(t mockConstructorTestingTNewLayerContributor) *LayerContributor {
|
||||
mock := &LayerContributor{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by mockery 2.9.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.24.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
|
@ -22,3 +22,18 @@ func (_m *TOMLWriter) Write(path string, value interface{}) error {
|
|||
|
||||
return r0
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewTOMLWriter interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewTOMLWriter creates a new instance of TOMLWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewTOMLWriter(t mockConstructorTestingTNewTOMLWriter) *TOMLWriter {
|
||||
mock := &TOMLWriter{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -18,7 +18,6 @@ package libcnb_test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
@ -37,39 +36,33 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) {
|
|||
)
|
||||
|
||||
it.Before(func() {
|
||||
var err error
|
||||
platformPath, err = ioutil.TempDir("", "platform")
|
||||
platformPath = t.TempDir()
|
||||
path = filepath.Join(platformPath, "bindings")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
it.After(func() {
|
||||
Expect(os.RemoveAll(path)).To(Succeed())
|
||||
})
|
||||
|
||||
context("CNB Bindings", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.MkdirAll(filepath.Join(path, "alpha", "metadata"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "metadata", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "metadata", "test-metadata-key"), []byte("test-metadata-value"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "metadata", "test-metadata-key-trimmed"), []byte(" test-metadata-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "metadata", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "metadata", "test-metadata-key"), []byte("test-metadata-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "metadata", "test-metadata-key-trimmed"), []byte(" test-metadata-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.MkdirAll(filepath.Join(path, "alpha", "secret"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "secret", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "secret", "test-secret-key-trimmed"), []byte(" test-secret-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "secret", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "secret", "test-secret-key-trimmed"), []byte(" test-secret-value-trimmed \n"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(path, "bravo", "metadata"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "metadata", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "metadata", "test-metadata-key"), []byte("test-metadata-value"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "metadata", "test-metadata-key-trimmed"), []byte(" test-metadata-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "metadata", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "metadata", "test-metadata-key"), []byte("test-metadata-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "metadata", "test-metadata-key-trimmed"), []byte(" test-metadata-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.MkdirAll(filepath.Join(path, "bravo", "secret"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "secret", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "secret", "test-secret-key-trimmed"), []byte(" test-secret-value-trimmed \n"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "secret", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "secret", "test-secret-key-trimmed"), []byte(" test-secret-value-trimmed \n"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(path, ".hidden", "metadata"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, ".hidden", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, ".hiddenFile"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, ".hidden", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, ".hiddenFile"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
})
|
||||
|
||||
context("Binding", func() {
|
||||
|
@ -201,18 +194,18 @@ func testPlatform(t *testing.T, context spec.G, it spec.S) {
|
|||
context("Kubernetes Service Bindings", func() {
|
||||
it.Before(func() {
|
||||
Expect(os.MkdirAll(filepath.Join(path, "alpha"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "type"), []byte("test-type"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "alpha", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "type"), []byte("test-type"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "alpha", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(path, "bravo"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "type"), []byte("test-type"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, "bravo", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "type"), []byte("test-type"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "provider"), []byte("test-provider"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, "bravo", "test-secret-key"), []byte("test-secret-value"), 0600)).To(Succeed())
|
||||
|
||||
Expect(os.MkdirAll(filepath.Join(path, ".hidden", "metadata"), 0755)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, ".hidden", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(ioutil.WriteFile(filepath.Join(path, ".hiddenFile"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, ".hidden", "metadata", "kind"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
Expect(os.WriteFile(filepath.Join(path, ".hiddenFile"), []byte("test-kind"), 0600)).To(Succeed())
|
||||
})
|
||||
|
||||
context("Binding", func() {
|
||||
|
|
183
tools/go.mod
183
tools/go.mod
|
@ -1,7 +1,184 @@
|
|||
module github.com/buildpacks/libcnb/tools
|
||||
|
||||
go 1.15
|
||||
go 1.20
|
||||
|
||||
require golang.org/x/tools v0.1.4
|
||||
require golang.org/x/tools v0.8.0
|
||||
|
||||
require github.com/golangci/golangci-lint v1.41.1
|
||||
require github.com/golangci/golangci-lint v1.52.2
|
||||
|
||||
require (
|
||||
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
|
||||
4d63.com/gochecknoglobals v0.2.1 // indirect
|
||||
github.com/Abirdcfly/dupword v0.0.11 // indirect
|
||||
github.com/Antonboom/errname v0.1.9 // indirect
|
||||
github.com/Antonboom/nilnil v0.1.4 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.5.1 // 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.8.0 // indirect
|
||||
github.com/bombsimon/wsl/v3 v3.4.0 // indirect
|
||||
github.com/breml/bidichk v0.2.4 // indirect
|
||||
github.com/breml/errchkjson v0.3.1 // indirect
|
||||
github.com/butuzov/ireturn v0.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||
github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect
|
||||
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
||||
github.com/daixiang0/gci v0.10.1 // 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.15.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/go-critic/go-critic v0.7.0 // indirect
|
||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.1.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.1.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.1.0 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // 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-20220329215616-d24fe342adfe // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // 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.4.0 // indirect
|
||||
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // 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.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.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/junk1tm/musttag v0.5.0 // indirect
|
||||
github.com/kisielk/errcheck v1.6.3 // indirect
|
||||
github.com/kisielk/gotool v1.0.0 // indirect
|
||||
github.com/kkHAIKE/contextcheck v1.1.4 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.6 // indirect
|
||||
github.com/kyoh86/exportloopref v0.1.11 // indirect
|
||||
github.com/ldez/gomoddirectives v0.2.3 // indirect
|
||||
github.com/ldez/tagliatelle v0.4.0 // indirect
|
||||
github.com/leonklingele/grouper v1.1.1 // indirect
|
||||
github.com/lufeee/execinquery v1.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.1 // indirect
|
||||
github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
|
||||
github.com/mgechev/revive v1.3.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moricho/tparallel v0.3.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.10.0 // indirect
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/nunnatsa/ginkgolinter v0.11.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // 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 v1.4.0 // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.3.19 // indirect
|
||||
github.com/quasilyte/gogrep v0.5.0 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.3.0 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect
|
||||
github.com/securego/gosec/v2 v2.15.0 // indirect
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||
github.com/sivchari/nosnakecase v1.7.0 // indirect
|
||||
github.com/sivchari/tenv v1.7.1 // indirect
|
||||
github.com/sonatard/noctx v0.0.2 // indirect
|
||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.15.0 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/stretchr/testify v1.8.2 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/sylvia7788/contextcheck v1.0.9 // indirect
|
||||
github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
|
||||
github.com/tdakkota/asciicheck v0.2.0 // indirect
|
||||
github.com/tetafro/godot v1.4.11 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect
|
||||
github.com/timonwong/loggercheck v0.9.4 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/ultraware/funlen v0.0.3 // indirect
|
||||
github.com/ultraware/whitespace v0.0.5 // indirect
|
||||
github.com/uudashr/gocognit v1.0.6 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.2.0 // indirect
|
||||
gitlab.com/bosi/decorder v0.2.3 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
honnef.co/go/tools v0.4.3 // indirect
|
||||
mvdan.cc/gofumpt v0.5.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-20230312165513-e84e2d14e3b8 // indirect
|
||||
)
|
||||
|
|
1058
tools/go.sum
1058
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