Fix optional/pointer indirection errors
This commit is contained in:
@@ -342,7 +342,7 @@ func (c *CacheFromS3) String() string {
|
|||||||
|
|
||||||
// CacheWithMode is a cache that can configure its mode.
|
// CacheWithMode is a cache that can configure its mode.
|
||||||
type CacheWithMode struct {
|
type CacheWithMode struct {
|
||||||
Mode CacheMode `pulumi:"mode,optional"`
|
Mode *CacheMode `pulumi:"mode,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotate sets docstrings and defaults on CacheWithMode.
|
// Annotate sets docstrings and defaults on CacheWithMode.
|
||||||
@@ -354,10 +354,10 @@ func (c *CacheWithMode) Annotate(a infer.Annotator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c CacheWithMode) String() string {
|
func (c CacheWithMode) String() string {
|
||||||
if c.Mode == "" {
|
if c.Mode == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("mode=%s", c.Mode)
|
return fmt.Sprintf("mode=%s", *c.Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CacheWithIgnoreError exposes an option to ignore errors during caching.
|
// CacheWithIgnoreError exposes an option to ignore errors during caching.
|
||||||
@@ -552,9 +552,9 @@ func (c *CacheToRegistry) String() string {
|
|||||||
// CacheWithCompression is a cache with options to configure compression
|
// CacheWithCompression is a cache with options to configure compression
|
||||||
// settings.
|
// settings.
|
||||||
type CacheWithCompression struct {
|
type CacheWithCompression struct {
|
||||||
Compression CompressionType `pulumi:"compression,optional"`
|
Compression *CompressionType `pulumi:"compression,optional"`
|
||||||
CompressionLevel int `pulumi:"compressionLevel,optional"`
|
CompressionLevel int `pulumi:"compressionLevel,optional"`
|
||||||
ForceCompression *bool `pulumi:"forceCompression,optional"`
|
ForceCompression *bool `pulumi:"forceCompression,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotate sets docstrings and defaults on CacheWithCompression.
|
// Annotate sets docstrings and defaults on CacheWithCompression.
|
||||||
@@ -575,8 +575,8 @@ func (c CacheWithCompression) String() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
parts := []string{}
|
parts := []string{}
|
||||||
if c.Compression != "" {
|
if c.Compression != nil {
|
||||||
parts = append(parts, fmt.Sprintf("compression=%s", c.Compression))
|
parts = append(parts, fmt.Sprintf("compression=%s", *c.Compression))
|
||||||
}
|
}
|
||||||
if c.CompressionLevel > 0 {
|
if c.CompressionLevel > 0 {
|
||||||
cl := c.CompressionLevel
|
cl := c.CompressionLevel
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
func TestCacheString(t *testing.T) {
|
func TestCacheString(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
gzip := Gzip
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -81,12 +82,12 @@ func TestCacheString(t *testing.T) {
|
|||||||
given: CacheTo{Local: &CacheToLocal{
|
given: CacheTo{Local: &CacheToLocal{
|
||||||
Dest: "/foo",
|
Dest: "/foo",
|
||||||
CacheWithCompression: CacheWithCompression{
|
CacheWithCompression: CacheWithCompression{
|
||||||
Compression: "gz2",
|
Compression: &gzip,
|
||||||
CompressionLevel: 100,
|
CompressionLevel: 100,
|
||||||
ForceCompression: pulumi.BoolRef(true),
|
ForceCompression: pulumi.BoolRef(true),
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
want: "type=local,dest=/foo,compression=gz2,compression-level=22,force-compression=true",
|
want: "type=local,dest=/foo,compression=gzip,compression-level=22,force-compression=true",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "ignore-error",
|
name: "ignore-error",
|
||||||
|
|||||||
@@ -90,8 +90,9 @@ func TestBuild(t *testing.T) {
|
|||||||
pctx.EXPECT().Deadline().Return(ctx.Deadline()).AnyTimes()
|
pctx.EXPECT().Deadline().Return(ctx.Deadline()).AnyTimes()
|
||||||
|
|
||||||
tmpdir := t.TempDir()
|
tmpdir := t.TempDir()
|
||||||
|
max := Max
|
||||||
|
|
||||||
exampleContext := BuildContext{Context: Context{Location: "../../examples/app"}}
|
exampleContext := &BuildContext{Context: Context{Location: "../../examples/app"}}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -104,7 +105,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "multiPlatform",
|
name: "multiPlatform",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.multiPlatform",
|
Location: "../../examples/app/Dockerfile.multiPlatform",
|
||||||
},
|
},
|
||||||
Platforms: []Platform{"plan9/amd64", "plan9/arm64"},
|
Platforms: []Platform{"plan9/amd64", "plan9/arm64"},
|
||||||
@@ -131,7 +132,7 @@ func TestBuild(t *testing.T) {
|
|||||||
Tags: []string{"cached"},
|
Tags: []string{"cached"},
|
||||||
CacheTo: []CacheTo{{Local: &CacheToLocal{
|
CacheTo: []CacheTo{{Local: &CacheToLocal{
|
||||||
Dest: filepath.Join(tmpdir, "cache"),
|
Dest: filepath.Join(tmpdir, "cache"),
|
||||||
CacheWithMode: CacheWithMode{Mode: "max"},
|
CacheWithMode: CacheWithMode{Mode: &max},
|
||||||
}}},
|
}}},
|
||||||
CacheFrom: []CacheFrom{{Local: &CacheFromLocal{
|
CacheFrom: []CacheFrom{{Local: &CacheFromLocal{
|
||||||
Src: filepath.Join(tmpdir, "cache"),
|
Src: filepath.Join(tmpdir, "cache"),
|
||||||
@@ -142,7 +143,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "buildArgs",
|
name: "buildArgs",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.buildArgs",
|
Location: "../../examples/app/Dockerfile.buildArgs",
|
||||||
},
|
},
|
||||||
BuildArgs: map[string]string{
|
BuildArgs: map[string]string{
|
||||||
@@ -154,7 +155,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "extraHosts",
|
name: "extraHosts",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.extraHosts",
|
Location: "../../examples/app/Dockerfile.extraHosts",
|
||||||
},
|
},
|
||||||
AddHosts: []string{
|
AddHosts: []string{
|
||||||
@@ -167,7 +168,7 @@ func TestBuild(t *testing.T) {
|
|||||||
skip: os.Getenv("SSH_AUTH_SOCK") == "",
|
skip: os.Getenv("SSH_AUTH_SOCK") == "",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.sshMount",
|
Location: "../../examples/app/Dockerfile.sshMount",
|
||||||
},
|
},
|
||||||
SSH: []SSH{{ID: "default"}},
|
SSH: []SSH{{ID: "default"}},
|
||||||
@@ -177,7 +178,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "secrets",
|
name: "secrets",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.secrets",
|
Location: "../../examples/app/Dockerfile.secrets",
|
||||||
},
|
},
|
||||||
Secrets: map[string]string{
|
Secrets: map[string]string{
|
||||||
@@ -199,7 +200,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "target",
|
name: "target",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.target",
|
Location: "../../examples/app/Dockerfile.target",
|
||||||
},
|
},
|
||||||
Target: "build-me",
|
Target: "build-me",
|
||||||
@@ -208,7 +209,7 @@ func TestBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "namedContext",
|
name: "namedContext",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: BuildContext{
|
Context: &BuildContext{
|
||||||
Context: Context{
|
Context: Context{
|
||||||
Location: "../../examples/app",
|
Location: "../../examples/app",
|
||||||
},
|
},
|
||||||
@@ -218,7 +219,7 @@ func TestBuild(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Location: "../../examples/app/Dockerfile.namedContexts",
|
Location: "../../examples/app/Dockerfile.namedContexts",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -226,7 +227,7 @@ func TestBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "remoteContext",
|
name: "remoteContext",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: BuildContext{
|
Context: &BuildContext{
|
||||||
Context: Context{
|
Context: Context{
|
||||||
Location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
Location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||||
},
|
},
|
||||||
@@ -236,12 +237,12 @@ func TestBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "remoteContextWithInline",
|
name: "remoteContextWithInline",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: BuildContext{
|
Context: &BuildContext{
|
||||||
Context: Context{
|
Context: Context{
|
||||||
Location: "https://github.com/docker-library/hello-world.git",
|
Location: "https://github.com/docker-library/hello-world.git",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Inline: dedent(`
|
Inline: dedent(`
|
||||||
FROM busybox
|
FROM busybox
|
||||||
COPY hello.c ./
|
COPY hello.c ./
|
||||||
@@ -253,7 +254,7 @@ func TestBuild(t *testing.T) {
|
|||||||
name: "inline",
|
name: "inline",
|
||||||
args: ImageArgs{
|
args: ImageArgs{
|
||||||
Context: exampleContext,
|
Context: exampleContext,
|
||||||
Dockerfile: Dockerfile{
|
Dockerfile: &Dockerfile{
|
||||||
Inline: dedent(`
|
Inline: dedent(`
|
||||||
FROM alpine
|
FROM alpine
|
||||||
RUN echo 👍
|
RUN echo 👍
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ type BuildContext struct {
|
|||||||
Named NamedContexts `pulumi:"named,optional"`
|
Named NamedContexts `pulumi:"named,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bc *BuildContext) namedMap() map[string]string {
|
||||||
|
if bc == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return bc.Named.Map()
|
||||||
|
}
|
||||||
|
|
||||||
// NamedContexts correspond to Docker's `--build-context name=path` options.
|
// NamedContexts correspond to Docker's `--build-context name=path` options.
|
||||||
// The path can be local or a remote URL.
|
// The path can be local or a remote URL.
|
||||||
type NamedContexts map[string]Context
|
type NamedContexts map[string]Context
|
||||||
@@ -84,23 +91,31 @@ func (c *Context) Annotate(a infer.Annotator) {
|
|||||||
// validate returns a non-nil CheckError if the Context is invalid. The
|
// validate returns a non-nil CheckError if the Context is invalid. The
|
||||||
// returned Dockerfile may have defaults set to match Docker's default
|
// returned Dockerfile may have defaults set to match Docker's default
|
||||||
// handling. The returned Dockerfile should be validated separately.
|
// handling. The returned Dockerfile should be validated separately.
|
||||||
func (c *Context) validate(preview bool, d Dockerfile) (Dockerfile, error) {
|
func (bc *BuildContext) validate(preview bool, d *Dockerfile) (*Dockerfile, *Context, error) {
|
||||||
|
if d == nil {
|
||||||
|
d = &Dockerfile{}
|
||||||
|
}
|
||||||
|
c := &Context{}
|
||||||
|
if bc != nil {
|
||||||
|
c = &bc.Context
|
||||||
|
}
|
||||||
|
|
||||||
if c.Location == "" && preview {
|
if c.Location == "" && preview {
|
||||||
// The field is required so we normally wouldn't need to check if it
|
// The field is required so we normally wouldn't need to check if it
|
||||||
// exists, but during previews it can still be empty if the value is
|
// exists, but during previews it can still be empty if the value is
|
||||||
// unknown. This isn't an error, but it does prevent us from performing
|
// unknown. This isn't an error, but it does prevent us from performing
|
||||||
// a build later.
|
// a build later.
|
||||||
return d, nil
|
return d, c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if buildx.IsRemoteURL(c.Location) {
|
if buildx.IsRemoteURL(c.Location) {
|
||||||
// We assume remote URLs are always valid.
|
// We assume remote URLs are always valid.
|
||||||
return d, nil
|
return d, c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
abs, err := filepath.Abs(c.Location)
|
abs, err := filepath.Abs(c.Location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d, newCheckFailure(err, "context.location")
|
return d, c, newCheckFailure(err, "context.location")
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Location == "" && d.Inline == "" {
|
if d.Location == "" && d.Inline == "" {
|
||||||
@@ -111,17 +126,17 @@ func (c *Context) validate(preview bool, d Dockerfile) (Dockerfile, error) {
|
|||||||
|
|
||||||
if isLocalDir(afero.NewOsFs(), abs) {
|
if isLocalDir(afero.NewOsFs(), abs) {
|
||||||
// Our context exists -- nothing else to check.
|
// Our context exists -- nothing else to check.
|
||||||
return d, nil
|
return d, c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Location != "-" {
|
if c.Location != "-" {
|
||||||
return d, newCheckFailure(
|
return d, c, newCheckFailure(
|
||||||
fmt.Errorf("%q: not a valid directory or URL", c.Location),
|
fmt.Errorf("%q: not a valid directory or URL", c.Location),
|
||||||
"context.location",
|
"context.location",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return d, nil
|
return d, c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotate sets docstrings on BuildContext.
|
// Annotate sets docstrings on BuildContext.
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ func TestValidateContext(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
d, err := tt.c.validate(tt.preview, tt.givenD)
|
bc := &BuildContext{Context: tt.c}
|
||||||
|
d, _, err := bc.validate(tt.preview, &tt.givenD)
|
||||||
|
|
||||||
if tt.wantErr == "" {
|
if tt.wantErr == "" {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func (d *Dockerfile) Annotate(a infer.Annotator) {
|
|||||||
`))
|
`))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dockerfile) validate(preview bool, c Context) error {
|
func (d *Dockerfile) validate(preview bool, c *Context) error {
|
||||||
if d.Location != "" && d.Inline != "" {
|
if d.Location != "" && d.Inline != "" {
|
||||||
return newCheckFailure(
|
return newCheckFailure(
|
||||||
errors.New(`only specify "file" or "inline", not both`),
|
errors.New(`only specify "file" or "inline", not both`),
|
||||||
@@ -88,7 +88,7 @@ func (d *Dockerfile) validate(preview bool, c Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !preview && !buildx.IsRemoteURL(c.Location) {
|
if !preview && c != nil && !buildx.IsRemoteURL(c.Location) {
|
||||||
return newCheckFailure(errors.New("missing 'location' or 'inline'"), "dockerfile")
|
return newCheckFailure(errors.New("missing 'location' or 'inline'"), "dockerfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func TestValidateDockerfile(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
err := tt.d.validate(tt.preview, tt.givenC)
|
err := tt.d.validate(tt.preview, &tt.givenC)
|
||||||
|
|
||||||
if tt.wantErr == "" {
|
if tt.wantErr == "" {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@@ -386,9 +386,9 @@ func (c ExportWithOCI) String() string {
|
|||||||
// ExportWithCompression is an export with options to configure compression
|
// ExportWithCompression is an export with options to configure compression
|
||||||
// settings.
|
// settings.
|
||||||
type ExportWithCompression struct {
|
type ExportWithCompression struct {
|
||||||
Compression CompressionType `pulumi:"compression,optional"`
|
Compression *CompressionType `pulumi:"compression,optional"`
|
||||||
CompressionLevel int `pulumi:"compressionLevel,optional"`
|
CompressionLevel int `pulumi:"compressionLevel,optional"`
|
||||||
ForceCompression *bool `pulumi:"forceCompression,optional"`
|
ForceCompression *bool `pulumi:"forceCompression,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotate sets docstrings and defaults on ExportWithCompression.
|
// Annotate sets docstrings and defaults on ExportWithCompression.
|
||||||
@@ -407,8 +407,8 @@ func (e ExportWithCompression) String() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
parts := []string{}
|
parts := []string{}
|
||||||
if e.Compression != "" {
|
if e.Compression != nil {
|
||||||
parts = append(parts, fmt.Sprintf("compression=%s", e.Compression))
|
parts = append(parts, fmt.Sprintf("compression=%s", *e.Compression))
|
||||||
}
|
}
|
||||||
if e.CompressionLevel > 0 {
|
if e.CompressionLevel > 0 {
|
||||||
cl := e.CompressionLevel
|
cl := e.CompressionLevel
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ func TestValidateExport(t *testing.T) {
|
|||||||
|
|
||||||
func TestExportString(t *testing.T) {
|
func TestExportString(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
gzip := Gzip
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
given Export
|
given Export
|
||||||
@@ -113,13 +114,13 @@ func TestExportString(t *testing.T) {
|
|||||||
given: Export{Registry: &ExportRegistry{
|
given: Export{Registry: &ExportRegistry{
|
||||||
ExportImage: ExportImage{
|
ExportImage: ExportImage{
|
||||||
ExportWithCompression: ExportWithCompression{
|
ExportWithCompression: ExportWithCompression{
|
||||||
Compression: "gz2",
|
Compression: &gzip,
|
||||||
CompressionLevel: 100,
|
CompressionLevel: 100,
|
||||||
ForceCompression: pulumi.BoolRef(true),
|
ForceCompression: pulumi.BoolRef(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
want: "type=registry,compression=gz2,compression-level=22,force-compression=true",
|
want: "type=registry,compression=gzip,compression-level=22,force-compression=true",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "registry-without-push",
|
name: "registry-without-push",
|
||||||
|
|||||||
@@ -93,15 +93,15 @@ type ImageArgs struct {
|
|||||||
AddHosts []string `pulumi:"addHosts,optional"`
|
AddHosts []string `pulumi:"addHosts,optional"`
|
||||||
BuildArgs map[string]string `pulumi:"buildArgs,optional"`
|
BuildArgs map[string]string `pulumi:"buildArgs,optional"`
|
||||||
BuildOnPreview *bool `pulumi:"buildOnPreview,optional"`
|
BuildOnPreview *bool `pulumi:"buildOnPreview,optional"`
|
||||||
Builder BuilderConfig `pulumi:"builder,optional"`
|
Builder *BuilderConfig `pulumi:"builder,optional"`
|
||||||
CacheFrom []CacheFrom `pulumi:"cacheFrom,optional"`
|
CacheFrom []CacheFrom `pulumi:"cacheFrom,optional"`
|
||||||
CacheTo []CacheTo `pulumi:"cacheTo,optional"`
|
CacheTo []CacheTo `pulumi:"cacheTo,optional"`
|
||||||
Context BuildContext `pulumi:"context,optional"`
|
Context *BuildContext `pulumi:"context,optional"`
|
||||||
Dockerfile Dockerfile `pulumi:"dockerfile,optional"`
|
Dockerfile *Dockerfile `pulumi:"dockerfile,optional"`
|
||||||
Exports []Export `pulumi:"exports,optional"`
|
Exports []Export `pulumi:"exports,optional"`
|
||||||
Labels map[string]string `pulumi:"labels,optional"`
|
Labels map[string]string `pulumi:"labels,optional"`
|
||||||
Load bool `pulumi:"load,optional"`
|
Load bool `pulumi:"load,optional"`
|
||||||
Network NetworkMode `pulumi:"network,optional"`
|
Network *NetworkMode `pulumi:"network,optional"`
|
||||||
NoCache bool `pulumi:"noCache,optional"`
|
NoCache bool `pulumi:"noCache,optional"`
|
||||||
Platforms []Platform `pulumi:"platforms,optional"`
|
Platforms []Platform `pulumi:"platforms,optional"`
|
||||||
Pull bool `pulumi:"pull,optional"`
|
Pull bool `pulumi:"pull,optional"`
|
||||||
@@ -555,13 +555,13 @@ func (ia *ImageArgs) validate(preview bool) (controllerapi.BuildOptions, error)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerfile, err := ia.Context.validate(preview, ia.Dockerfile)
|
dockerfile, context, err := ia.Context.validate(preview, ia.Dockerfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
multierr = errors.Join(multierr, err)
|
multierr = errors.Join(multierr, err)
|
||||||
}
|
}
|
||||||
ia.Dockerfile = dockerfile
|
ia.Dockerfile = dockerfile
|
||||||
|
|
||||||
if err := ia.Dockerfile.validate(preview, ia.Context.Context); err != nil {
|
if err := ia.Dockerfile.validate(preview, context); err != nil {
|
||||||
multierr = errors.Join(multierr, err)
|
multierr = errors.Join(multierr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,19 +644,24 @@ func (ia *ImageArgs) validate(preview bool) (controllerapi.BuildOptions, error)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder := BuilderConfig{}
|
||||||
|
if normalized.Builder != nil {
|
||||||
|
builder = *normalized.Builder
|
||||||
|
}
|
||||||
|
|
||||||
opts := controllerapi.BuildOptions{
|
opts := controllerapi.BuildOptions{
|
||||||
BuildArgs: normalized.BuildArgs,
|
BuildArgs: normalized.BuildArgs,
|
||||||
Builder: normalized.Builder.Name,
|
Builder: builder.Name,
|
||||||
CacheFrom: cacheFrom,
|
CacheFrom: cacheFrom,
|
||||||
CacheTo: cacheTo,
|
CacheTo: cacheTo,
|
||||||
ContextPath: normalized.Context.Location,
|
ContextPath: context.Location,
|
||||||
DockerfileName: dockerfile.Location,
|
DockerfileName: dockerfile.Location,
|
||||||
Exports: exports,
|
Exports: exports,
|
||||||
ExtraHosts: normalized.AddHosts,
|
ExtraHosts: normalized.AddHosts,
|
||||||
Labels: normalized.Labels,
|
Labels: normalized.Labels,
|
||||||
NetworkMode: string(normalized.Network),
|
NetworkMode: normalized.Network.String(),
|
||||||
NoCache: normalized.NoCache,
|
NoCache: normalized.NoCache,
|
||||||
NamedContexts: normalized.Context.Named.Map(),
|
NamedContexts: normalized.Context.namedMap(),
|
||||||
Platforms: platforms,
|
Platforms: platforms,
|
||||||
Pull: normalized.Pull,
|
Pull: normalized.Pull,
|
||||||
Secrets: secrets,
|
Secrets: secrets,
|
||||||
@@ -926,7 +931,7 @@ func (*Image) Diff(
|
|||||||
if olds.Load != news.Load {
|
if olds.Load != news.Load {
|
||||||
diff["load"] = update
|
diff["load"] = update
|
||||||
}
|
}
|
||||||
if olds.Network != news.Network {
|
if !reflect.DeepEqual(olds.Network, news.Network) {
|
||||||
diff["network"] = update
|
diff["network"] = update
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(olds.NoCache, news.NoCache) {
|
if !reflect.DeepEqual(olds.NoCache, news.NoCache) {
|
||||||
|
|||||||
@@ -365,12 +365,13 @@ func TestRead(t *testing.T) {
|
|||||||
func TestImageDiff(t *testing.T) {
|
func TestImageDiff(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
emptyDir := t.TempDir()
|
emptyDir := t.TempDir()
|
||||||
|
host := Host
|
||||||
|
|
||||||
hash, err := hashBuildContext(emptyDir, "", nil)
|
hash, err := hashBuildContext(emptyDir, "", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
baseArgs := ImageArgs{
|
baseArgs := ImageArgs{
|
||||||
Context: BuildContext{Context: Context{Location: emptyDir}},
|
Context: &BuildContext{Context: Context{Location: emptyDir}},
|
||||||
Dockerfile: Dockerfile{Location: "testdata/noop"},
|
Dockerfile: &Dockerfile{Location: "testdata/noop"},
|
||||||
Tags: []string{},
|
Tags: []string{},
|
||||||
}
|
}
|
||||||
baseState := ImageState{
|
baseState := ImageState{
|
||||||
@@ -414,6 +415,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no diff if pull=true but no exports",
|
name: "no diff if pull=true but no exports",
|
||||||
olds: func(_ *testing.T, is ImageState) ImageState {
|
olds: func(_ *testing.T, is ImageState) ImageState {
|
||||||
|
fmt.Println("WHOA NELLY")
|
||||||
is.Pull = true
|
is.Pull = true
|
||||||
return is
|
return is
|
||||||
},
|
},
|
||||||
@@ -566,7 +568,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if context changes",
|
name: "diff if context changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Context.Location = "testdata/ignores"
|
a.Context = &BuildContext{Context: Context{Location: "testdata/ignores"}}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -575,7 +577,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if named context changes",
|
name: "diff if named context changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Context.Named = NamedContexts{"foo": Context{Location: "bar"}}
|
a.Context = &BuildContext{Named: NamedContexts{"foo": Context{Location: "bar"}}}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -584,7 +586,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if network changes",
|
name: "diff if network changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Network = Host
|
a.Network = &host
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -593,7 +595,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if dockerfile location changes",
|
name: "diff if dockerfile location changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Dockerfile.Location = "testdata/ignores/basedir/Dockerfile"
|
a.Dockerfile = &Dockerfile{Location: "testdata/ignores/basedir/Dockerfile"}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -602,7 +604,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if dockerfile inline changes",
|
name: "diff if dockerfile inline changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Dockerfile.Inline = "FROM scratch"
|
a.Dockerfile = &Dockerfile{Inline: "FROM scratch"}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -629,7 +631,7 @@ func TestImageDiff(t *testing.T) {
|
|||||||
name: "diff if builder changes",
|
name: "diff if builder changes",
|
||||||
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
olds: func(*testing.T, ImageState) ImageState { return baseState },
|
||||||
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
news: func(_ *testing.T, a ImageArgs) ImageArgs {
|
||||||
a.Builder.Name = "foo"
|
a.Builder = &BuilderConfig{Name: "foo"}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -709,6 +711,8 @@ func TestImageDiff(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
tt := tt
|
tt := tt
|
||||||
|
baseState := baseState
|
||||||
|
baseArgs := baseArgs
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
resp, err := s.Diff(provider.DiffRequest{
|
resp, err := s.Diff(provider.DiffRequest{
|
||||||
@@ -729,7 +733,7 @@ func TestValidateImageArgs(t *testing.T) {
|
|||||||
args := ImageArgs{
|
args := ImageArgs{
|
||||||
Tags: []string{"a/bad:tag:format"},
|
Tags: []string{"a/bad:tag:format"},
|
||||||
Exports: []Export{{Raw: "badexport,-"}},
|
Exports: []Export{{Raw: "badexport,-"}},
|
||||||
Context: BuildContext{Context: Context{Location: "./testdata"}},
|
Context: &BuildContext{Context: Context{Location: "./testdata"}},
|
||||||
Platforms: []Platform{","},
|
Platforms: []Platform{","},
|
||||||
CacheFrom: []CacheFrom{{Raw: "=badcachefrom"}},
|
CacheFrom: []CacheFrom{{Raw: "=badcachefrom"}},
|
||||||
CacheTo: []CacheTo{{Raw: "=badcacheto"}},
|
CacheTo: []CacheTo{{Raw: "=badcacheto"}},
|
||||||
@@ -747,7 +751,7 @@ func TestValidateImageArgs(t *testing.T) {
|
|||||||
t.Run("buildOnPreview", func(t *testing.T) {
|
t.Run("buildOnPreview", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
args := ImageArgs{
|
args := ImageArgs{
|
||||||
Context: BuildContext{Context: Context{Location: "testdata/noop"}},
|
Context: &BuildContext{Context: Context{Location: "testdata/noop"}},
|
||||||
Tags: []string{"my-tag"},
|
Tags: []string{"my-tag"},
|
||||||
Exports: []Export{{Registry: &ExportRegistry{ExportImage{Push: pulumi.BoolRef(true)}}}},
|
Exports: []Export{{Registry: &ExportRegistry{ExportImage{Push: pulumi.BoolRef(true)}}}},
|
||||||
}
|
}
|
||||||
@@ -775,12 +779,12 @@ func TestValidateImageArgs(t *testing.T) {
|
|||||||
"known": "value",
|
"known": "value",
|
||||||
"": "",
|
"": "",
|
||||||
},
|
},
|
||||||
Builder: BuilderConfig{},
|
Builder: nil,
|
||||||
CacheFrom: []CacheFrom{{GHA: &CacheFromGitHubActions{}}, {Raw: ""}},
|
CacheFrom: []CacheFrom{{GHA: &CacheFromGitHubActions{}}, {Raw: ""}},
|
||||||
CacheTo: []CacheTo{{GHA: &CacheToGitHubActions{}}, {Raw: ""}},
|
CacheTo: []CacheTo{{GHA: &CacheToGitHubActions{}}, {Raw: ""}},
|
||||||
Context: BuildContext{},
|
Context: nil,
|
||||||
Exports: []Export{{Raw: ""}},
|
Exports: []Export{{Raw: ""}},
|
||||||
Dockerfile: Dockerfile{},
|
Dockerfile: nil,
|
||||||
Platforms: []Platform{"linux/amd64", ""},
|
Platforms: []Platform{"linux/amd64", ""},
|
||||||
Registries: []Registry{
|
Registries: []Registry{
|
||||||
{
|
{
|
||||||
@@ -803,7 +807,7 @@ func TestValidateImageArgs(t *testing.T) {
|
|||||||
t.Run("disabled caches", func(t *testing.T) {
|
t.Run("disabled caches", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
args := ImageArgs{
|
args := ImageArgs{
|
||||||
Context: BuildContext{Context: Context{Location: "testdata/noop"}},
|
Context: &BuildContext{Context: Context{Location: "testdata/noop"}},
|
||||||
CacheFrom: []CacheFrom{{Raw: "type=registry", Disabled: true}},
|
CacheFrom: []CacheFrom{{Raw: "type=registry", Disabled: true}},
|
||||||
CacheTo: []CacheTo{{Raw: "type=registry", Disabled: true}},
|
CacheTo: []CacheTo{{Raw: "type=registry", Disabled: true}},
|
||||||
Exports: []Export{{Raw: "type=registry", Disabled: true}},
|
Exports: []Export{{Raw: "type=registry", Disabled: true}},
|
||||||
@@ -853,7 +857,8 @@ func TestValidateImageArgs(t *testing.T) {
|
|||||||
for _, d := range []Dockerfile{
|
for _, d := range []Dockerfile{
|
||||||
{Location: path}, {Inline: string(data)},
|
{Location: path}, {Inline: string(data)},
|
||||||
} {
|
} {
|
||||||
args := ImageArgs{Dockerfile: d}
|
d := d
|
||||||
|
args := ImageArgs{Dockerfile: &d}
|
||||||
_, err := args.validate(false)
|
_, err := args.validate(false)
|
||||||
assert.ErrorContains(t, err, "unknown instruction: RUNN (did you mean RUN?)")
|
assert.ErrorContains(t, err, "unknown instruction: RUNN (did you mean RUN?)")
|
||||||
}
|
}
|
||||||
@@ -943,13 +948,14 @@ func TestToBuild(t *testing.T) {
|
|||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
pctx := NewMockProviderContext(ctrl)
|
pctx := NewMockProviderContext(ctrl)
|
||||||
pctx.EXPECT().Log(gomock.Any(), gomock.Any()).AnyTimes()
|
pctx.EXPECT().Log(gomock.Any(), gomock.Any()).AnyTimes()
|
||||||
|
max := Max
|
||||||
|
|
||||||
ia := ImageArgs{
|
ia := ImageArgs{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
Platforms: []Platform{"linux/amd64"},
|
Platforms: []Platform{"linux/amd64"},
|
||||||
Context: BuildContext{Context: Context{Location: "testdata/noop"}},
|
Context: &BuildContext{Context: Context{Location: "testdata/noop"}},
|
||||||
CacheTo: []CacheTo{
|
CacheTo: []CacheTo{
|
||||||
{GHA: &CacheToGitHubActions{CacheWithMode: CacheWithMode{Max}}},
|
{GHA: &CacheToGitHubActions{CacheWithMode: CacheWithMode{&max}}},
|
||||||
{
|
{
|
||||||
Registry: &CacheToRegistry{
|
Registry: &CacheToRegistry{
|
||||||
CacheFromRegistry: CacheFromRegistry{Ref: "docker.io/foo/bar"},
|
CacheFromRegistry: CacheFromRegistry{Ref: "docker.io/foo/bar"},
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ type Index struct{}
|
|||||||
|
|
||||||
// IndexArgs instantiate an Index.
|
// IndexArgs instantiate an Index.
|
||||||
type IndexArgs struct {
|
type IndexArgs struct {
|
||||||
Tag string `pulumi:"tag"`
|
Tag string `pulumi:"tag"`
|
||||||
Sources []string `pulumi:"sources"`
|
Sources []string `pulumi:"sources"`
|
||||||
Push bool `pulumi:"push,optional"`
|
Push bool `pulumi:"push,optional"`
|
||||||
Registry Registry `pulumi:"registry,optional"`
|
Registry *Registry `pulumi:"registry,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexState captures the state of an Index.
|
// IndexState captures the state of an Index.
|
||||||
@@ -268,14 +268,20 @@ func (i *Index) Diff(
|
|||||||
if !reflect.DeepEqual(olds.Sources, news.Sources) {
|
if !reflect.DeepEqual(olds.Sources, news.Sources) {
|
||||||
diff["sources"] = update
|
diff["sources"] = update
|
||||||
}
|
}
|
||||||
if olds.Registry.Address != news.Registry.Address {
|
if olds.Registry != nil && news.Registry != nil {
|
||||||
diff["registry.address"] = update
|
if olds.Registry.Address != news.Registry.Address {
|
||||||
if olds.Registry.Address != "" {
|
diff["registry.address"] = update
|
||||||
diff["registry.address"] = replace
|
if olds.Registry.Address != "" {
|
||||||
|
diff["registry.address"] = replace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if olds.Registry.Username != news.Registry.Username {
|
||||||
|
diff["registry.username"] = update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if olds.Registry.Username != news.Registry.Username {
|
if (olds.Registry == nil && news.Registry != nil) ||
|
||||||
diff["registry.username"] = update
|
(olds.Registry != nil && news.Registry == nil) {
|
||||||
|
diff["registry"] = update
|
||||||
}
|
}
|
||||||
// Intentionally ignore changes to registry.password
|
// Intentionally ignore changes to registry.password
|
||||||
|
|
||||||
@@ -301,9 +307,14 @@ func (i *Index) client(
|
|||||||
// We prefer auth from args, the provider, and state in that order. We
|
// We prefer auth from args, the provider, and state in that order. We
|
||||||
// build a slice in reverse order because wrap() will overwrite earlier
|
// build a slice in reverse order because wrap() will overwrite earlier
|
||||||
// entries with later ones.
|
// entries with later ones.
|
||||||
auths := []Registry{state.Registry}
|
auths := []Registry{}
|
||||||
|
if state.Registry != nil {
|
||||||
|
auths = append(auths, *state.Registry)
|
||||||
|
}
|
||||||
auths = append(auths, cfg.Registries...)
|
auths = append(auths, cfg.Registries...)
|
||||||
auths = append(auths, args.Registry)
|
if args.Registry != nil {
|
||||||
|
auths = append(auths, *args.Registry)
|
||||||
|
}
|
||||||
|
|
||||||
return wrap(cfg.host, auths...)
|
return wrap(cfg.host, auths...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ func TestIndexDiff(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no diff if registry password changes",
|
name: "no diff if registry password changes",
|
||||||
olds: func(_ *testing.T, s IndexState) IndexState {
|
olds: func(_ *testing.T, s IndexState) IndexState {
|
||||||
s.Registry = Registry{
|
s.Registry = &Registry{
|
||||||
Address: "foo",
|
Address: "foo",
|
||||||
Username: "foo",
|
Username: "foo",
|
||||||
Password: "foo",
|
Password: "foo",
|
||||||
@@ -146,7 +146,7 @@ func TestIndexDiff(t *testing.T) {
|
|||||||
return s
|
return s
|
||||||
},
|
},
|
||||||
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
||||||
a.Registry = Registry{
|
a.Registry = &Registry{
|
||||||
Address: "foo",
|
Address: "foo",
|
||||||
Username: "foo",
|
Username: "foo",
|
||||||
Password: "DIFFERENT PASSWORD",
|
Password: "DIFFERENT PASSWORD",
|
||||||
@@ -159,7 +159,7 @@ func TestIndexDiff(t *testing.T) {
|
|||||||
name: "diff if registry added",
|
name: "diff if registry added",
|
||||||
olds: func(*testing.T, IndexState) IndexState { return baseState },
|
olds: func(*testing.T, IndexState) IndexState { return baseState },
|
||||||
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
||||||
a.Registry = Registry{Address: "foo.com", Username: "foo", Password: "foo"}
|
a.Registry = &Registry{Address: "foo.com", Username: "foo", Password: "foo"}
|
||||||
return a
|
return a
|
||||||
},
|
},
|
||||||
wantChanges: true,
|
wantChanges: true,
|
||||||
@@ -167,7 +167,7 @@ func TestIndexDiff(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "diff if registry user changes",
|
name: "diff if registry user changes",
|
||||||
olds: func(_ *testing.T, s IndexState) IndexState {
|
olds: func(_ *testing.T, s IndexState) IndexState {
|
||||||
s.Registry = Registry{
|
s.Registry = &Registry{
|
||||||
Address: "foo",
|
Address: "foo",
|
||||||
Username: "foo",
|
Username: "foo",
|
||||||
Password: "foo",
|
Password: "foo",
|
||||||
@@ -175,7 +175,7 @@ func TestIndexDiff(t *testing.T) {
|
|||||||
return s
|
return s
|
||||||
},
|
},
|
||||||
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
news: func(_ *testing.T, a IndexArgs) IndexArgs {
|
||||||
a.Registry = Registry{
|
a.Registry = &Registry{
|
||||||
Address: "DIFFERENT USER",
|
Address: "DIFFERENT USER",
|
||||||
Username: "foo",
|
Username: "foo",
|
||||||
Password: "foo",
|
Password: "foo",
|
||||||
|
|||||||
@@ -44,3 +44,10 @@ func (NetworkMode) Values() []infer.EnumValue[NetworkMode] {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *NetworkMode) String() string {
|
||||||
|
if n == nil {
|
||||||
|
return string(Default)
|
||||||
|
}
|
||||||
|
return string(*n)
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ func (k mapKeeper) keep(m map[string]string) map[string]string {
|
|||||||
|
|
||||||
type contextKeeper struct{ preview bool }
|
type contextKeeper struct{ preview bool }
|
||||||
|
|
||||||
func (k contextKeeper) keep(bc BuildContext) BuildContext {
|
func (k contextKeeper) keep(bc *BuildContext) *BuildContext {
|
||||||
if !k.preview || len(bc.Named) == 0 {
|
if !k.preview || bc == nil || len(bc.Named) == 0 {
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ func (k contextKeeper) keep(bc BuildContext) BuildContext {
|
|||||||
named[k] = v
|
named[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuildContext{
|
return &BuildContext{
|
||||||
Context: Context{bc.Location},
|
Context: Context{bc.Location},
|
||||||
Named: named,
|
Named: named,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user