diff --git a/cmd/dive/cli/internal/options/analysis.go b/cmd/dive/cli/internal/options/analysis.go index 502623db..8d3edf4a 100644 --- a/cmd/dive/cli/internal/options/analysis.go +++ b/cmd/dive/cli/internal/options/analysis.go @@ -2,11 +2,13 @@ package options import ( "fmt" + "strings" + "github.com/anchore/clio" "github.com/scylladb/go-set/strset" + "github.com/wagoodman/dive/dive" "github.com/wagoodman/dive/internal/log" - "strings" ) const defaultContainerEngine = "docker" @@ -20,6 +22,7 @@ var _ interface { type Analysis struct { Image string `yaml:"image" mapstructure:"-"` ContainerEngine string `yaml:"container-engine" mapstructure:"container-engine"` + LegacySource string `yaml:"-" mapstructure:"source"` Source dive.ImageSource `yaml:"-" mapstructure:"-"` IgnoreErrors bool `yaml:"ignore-errors" mapstructure:"ignore-errors"` AvailableContainerEngines []string `yaml:"-" mapstructure:"-"` @@ -46,6 +49,13 @@ func (c *Analysis) AddFlags(flags clio.FlagSet) { } func (c *Analysis) PostLoad() error { + // Support the legacy "source" config key (used before the CLI refactor in v0.14). + // If "container-engine" is still at its default and "source" was explicitly set, promote it. + if c.LegacySource != "" && c.ContainerEngine == defaultContainerEngine { + log.Warnf("config key 'source' is deprecated; please rename it to 'container-engine'") + c.ContainerEngine = c.LegacySource + } + validEngines := strset.New(c.AvailableContainerEngines...) if !validEngines.Has(c.ContainerEngine) { log.Warnf("invalid container engine: %s (valid options: %s), using default %q", c.ContainerEngine, strings.Join(c.AvailableContainerEngines, ", "), defaultContainerEngine) diff --git a/cmd/dive/cli/internal/options/analysis_test.go b/cmd/dive/cli/internal/options/analysis_test.go new file mode 100644 index 00000000..3bb6314f --- /dev/null +++ b/cmd/dive/cli/internal/options/analysis_test.go @@ -0,0 +1,66 @@ +package options + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/wagoodman/dive/dive" +) + +func Test_Analysis_ContainerEngine_FromConfig_Podman(t *testing.T) { + // container-engine: podman in config (current key) should resolve to SourcePodmanEngine. + a := DefaultAnalysis() + a.ContainerEngine = "podman" + a.Image = "myimage:latest" + + require.NoError(t, a.PostLoad()) + assert.Equal(t, dive.SourcePodmanEngine, a.Source, + "expected podman source when container-engine=podman and image has no scheme prefix") +} + +func Test_Analysis_ContainerEngine_FromConfig_Docker(t *testing.T) { + // Default: docker engine + a := DefaultAnalysis() + a.Image = "myimage:latest" + + require.NoError(t, a.PostLoad()) + assert.Equal(t, dive.SourceDockerEngine, a.Source, + "expected docker source when container-engine=docker (default)") +} + +func Test_Analysis_ContainerEngine_SchemeOverridesConfig(t *testing.T) { + // An explicit scheme prefix on the image overrides container-engine config. + a := DefaultAnalysis() + a.ContainerEngine = "podman" + a.Image = "docker://myimage:latest" + + require.NoError(t, a.PostLoad()) + assert.Equal(t, dive.SourceDockerEngine, a.Source, + "expected docker source when image has docker:// prefix, regardless of container-engine config") +} + +func Test_Analysis_LegacySourceKey_Podman(t *testing.T) { + // Legacy "source" config key (used before v0.14 CLI refactor) should still work when + // "container-engine" is at its default value, and should emit a deprecation warning. + a := DefaultAnalysis() + a.LegacySource = "podman" + a.Image = "myimage:latest" + + require.NoError(t, a.PostLoad()) + assert.Equal(t, dive.SourcePodmanEngine, a.Source, + "expected podman source when legacy source=podman and container-engine is at default") +} + +func Test_Analysis_LegacySourceKey_DoesNotOverrideExplicitContainerEngine(t *testing.T) { + // If the user has both keys, "container-engine" wins over the legacy "source". + a := DefaultAnalysis() + a.ContainerEngine = "podman" + a.LegacySource = "docker" + a.Image = "myimage:latest" + + require.NoError(t, a.PostLoad()) + assert.Equal(t, dive.SourcePodmanEngine, a.Source, + "container-engine should take precedence over legacy source key") +}