Merge remote-tracking branch 'upstream/main' into add-nested-archive-cataloging

This commit is contained in:
Keith Zantow
2026-10-08 09:29:45 -04:00
19 changed files with 358 additions and 62 deletions
+25
View File
@@ -0,0 +1,25 @@
package cli
import (
"io"
"testing"
"github.com/stretchr/testify/require"
"github.com/anchore/clio"
"github.com/anchore/syft/internal/redact"
)
func TestCommandCanRunMultipleTimes(t *testing.T) {
// https://github.com/anchore/syft/issues/2285
t.Cleanup(redact.Reset)
for i := 0; i < 2; i++ {
_, cmd := create(clio.Identification{Name: "syft"}, io.Discard)
cmd.SetArgs([]string{"cataloger", "list", "-o", "json"})
require.NoError(t, cmd.Execute())
// the store is released at the end of each run so the next one can set its own
require.Nil(t, redact.Get())
}
}
+9 -1
View File
@@ -41,6 +41,8 @@ func AppClioSetupConfig(id clio.Identification, out io.Writer) *clio.SetupConfig
stereoscope.SetBus(state.Bus)
bus.Set(state.Bus)
// the redact store is process-global and only cleared when a run ends (see the post-run below), so
// setting it while another run is still in flight panics rather than splitting secrets across stores.
redact.Set(state.RedactStore)
log.Set(state.Logger)
@@ -48,8 +50,14 @@ func AppClioSetupConfig(id clio.Identification, out io.Writer) *clio.SetupConfig
return nil
},
).
WithPostRuns(func(_ *clio.State, _ error) {
WithPostRuns(func(state *clio.State, _ error) {
stereoscope.Cleanup() //nolint:staticcheck // we don't have access to the image object here
// release the redact store now that nothing in this run can report anymore, so a later run in the same
// process (e.g. syft embedded as a library) can set its own. Only release the store this run set.
if redact.Get() == state.RedactStore {
redact.Reset()
}
})
return clioCfg
}
@@ -0,0 +1,32 @@
package internal
import (
"io"
"testing"
"github.com/stretchr/testify/require"
"github.com/anchore/clio"
"github.com/anchore/go-logger/adapter/discard"
gologgerredact "github.com/anchore/go-logger/adapter/redact"
"github.com/anchore/syft/internal/redact"
)
func TestAppClioSetupConfigInitializerPanicsWhileRunInFlight(t *testing.T) {
t.Cleanup(redact.Reset)
cfg := AppClioSetupConfig(clio.Identification{Name: "syft"}, io.Discard)
require.Len(t, cfg.Initializers, 1)
newState := func() *clio.State {
return &clio.State{Logger: discard.New(), RedactStore: gologgerredact.NewStore()}
}
require.NoError(t, cfg.Initializers[0](newState()))
// a second run starting before the first has finished must not silently replace the store, otherwise
// secrets added to the first store would no longer be redacted
require.PanicsWithValue(t, "replace existing redaction store (probably unintentional)", func() {
_ = cfg.Initializers[0](newState())
})
}