(feat): support skipping archive extraction with file source (#3795)

Signed-off-by: Adam McClenaghan <adam@mcclenaghan.co.uk>
This commit is contained in:
Adam McClenaghan 2025-04-24 17:22:36 +01:00 committed by GitHub
parent df18edf905
commit 61a3d1784a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 17 deletions

View File

@ -26,10 +26,11 @@ import (
var _ source.Source = (*fileSource)(nil)
type Config struct {
Path string
Exclude source.ExcludeConfig
DigestAlgorithms []crypto.Hash
Alias source.Alias
Path string
Exclude source.ExcludeConfig
DigestAlgorithms []crypto.Hash
Alias source.Alias
SkipExtractArchive bool
}
type fileSource struct {
@ -58,7 +59,7 @@ func New(cfg Config) (source.Source, error) {
return nil, fmt.Errorf("given path is a directory: %q", cfg.Path)
}
analysisPath, cleanupFn := fileAnalysisPath(cfg.Path)
analysisPath, cleanupFn := fileAnalysisPath(cfg.Path, cfg.SkipExtractArchive)
var digests []file.Digest
if len(cfg.DigestAlgorithms) > 0 {
@ -206,9 +207,15 @@ func (s *fileSource) Close() error {
// fileAnalysisPath returns the path given, or in the case the path is an archive, the location where the archive
// contents have been made available. A cleanup function is provided for any temp files created (if any).
func fileAnalysisPath(path string) (string, func() error) {
var analysisPath = path
// Users can disable unpacking archives, allowing individual cataloguers to extract them instead (where
// supported)
func fileAnalysisPath(path string, skipExtractArchive bool) (string, func() error) {
var cleanupFn = func() error { return nil }
var analysisPath = path
if skipExtractArchive {
return analysisPath, cleanupFn
}
// if the given file is an archive (as indicated by the file extension and not MIME type) then unarchive it and
// use the contents as the source. Note: this does NOT recursively unarchive contents, only the given path is

View File

@ -99,13 +99,14 @@ func TestNewFromFile_WithArchive(t *testing.T) {
testutil.Chdir(t, "..") // run with source/test-fixtures
testCases := []struct {
desc string
input string
expString string
inputPaths []string
expRefs int
layer2 bool
contents string
desc string
input string
expString string
inputPaths []string
expRefs int
layer2 bool
contents string
skipExtractArchive bool
}{
{
desc: "path detected",
@ -121,14 +122,25 @@ func TestNewFromFile_WithArchive(t *testing.T) {
layer2: true,
contents: "Another .vimrc file",
},
{
desc: "skip extract archive",
input: "test-fixtures/path-detected",
inputPaths: []string{"/.vimrc"},
expRefs: 0,
layer2: false,
skipExtractArchive: true,
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
archivePath := setupArchiveTest(t, test.input, test.layer2)
src, err := New(Config{
Path: archivePath,
})
cfg := Config{
Path: archivePath,
SkipExtractArchive: test.skipExtractArchive,
}
src, err := New(cfg)
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, src.Close())