diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ddb7c7..10c686d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ - Refreshing an `Index` resource will no longer fail if its stored credentials have expired. (https://github.com/pulumi/pulumi-docker-build/pull/194) +### Changed + +- Local and tar exporters will now trigger an update if an export doesn't exist + at the expected path. (https://github.com/pulumi/pulumi-docker-build/pull/195) + ## 0.0.5 (2024-08-08) ### Fixed diff --git a/provider/internal/export.go b/provider/internal/export.go index 0b41a2d..81f6c37 100644 --- a/provider/internal/export.go +++ b/provider/internal/export.go @@ -17,6 +17,7 @@ package internal import ( "errors" "fmt" + "os" "slices" "strings" @@ -353,6 +354,19 @@ func (e *ExportLocal) Annotate(a infer.Annotator) { a.Describe(&e.Dest, "Output path.") } +// Exists returns true if the exported directory exists and is populated with +// some files. +func (e *ExportLocal) Exists() bool { + if e == nil { + return true // Degenerate case. + } + files, err := os.ReadDir(e.Dest) + if err != nil { + return false + } + return len(files) > 0 +} + // ExportTar is an export that uses the tar format for exporting. type ExportTar struct { ExportLocal @@ -365,6 +379,15 @@ func (e *ExportTar) String() string { return "type=tar,dest=" + e.Dest } +// Exists returns true if a file exists at the expected path. +func (e *ExportTar) Exists() bool { + if e == nil { + return true // Degenerate case. + } + _, err := os.Stat(e.Dest) + return err == nil +} + // ExportWithOCI is an export that support OCI media types. type ExportWithOCI struct { OCI *bool `pulumi:"ociMediaTypes,optional"` diff --git a/provider/internal/image.go b/provider/internal/image.go index 152cad5..e5d627d 100644 --- a/provider/internal/image.go +++ b/provider/internal/image.go @@ -913,6 +913,12 @@ func (*Image) Diff( if fmt.Sprint(olds.Exports) != fmt.Sprint(news.Exports) { diff["exports"] = update } + // Confirm local exports exist. + for idx, e := range news.Exports { + if !e.Local.Exists() || !e.Tar.Exists() { + diff[fmt.Sprintf("exports[%d]", idx)] = update + } + } if !reflect.DeepEqual(olds.Labels, news.Labels) { diff["labels"] = update } diff --git a/provider/internal/image_test.go b/provider/internal/image_test.go index ad67e52..379e481 100644 --- a/provider/internal/image_test.go +++ b/provider/internal/image_test.go @@ -757,6 +757,38 @@ func TestImageDiff(t *testing.T) { }, wantChanges: true, }, + { + name: "diff if local export doesn't exist", + olds: func(t *testing.T, state ImageState) ImageState { + state.Exports = []Export{ + {Local: &ExportLocal{Dest: "not-real"}}, + } + return state + }, + news: func(_ *testing.T, args ImageArgs) ImageArgs { + args.Exports = []Export{ + {Local: &ExportLocal{Dest: "not-real"}}, + } + return args + }, + wantChanges: true, + }, + { + name: "diff if tar export doesn't exist", + olds: func(t *testing.T, state ImageState) ImageState { + state.Exports = []Export{ + {Tar: &ExportTar{ExportLocal: ExportLocal{Dest: "not-real"}}}, + } + return state + }, + news: func(_ *testing.T, args ImageArgs) ImageArgs { + args.Exports = []Export{ + {Tar: &ExportTar{ExportLocal: ExportLocal{Dest: "not-real"}}}, + } + return args + }, + wantChanges: true, + }, } s := newServer(nil)