From 5ad64344c0378a54c70c014d76363d78865d990a Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Wed, 26 Feb 2025 09:16:15 +0100 Subject: [PATCH] Introduces Reader into k6deps.Source --- archive_test.go | 21 ++++++++++++++++++ options.go | 57 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/archive_test.go b/archive_test.go index afd337c..ae3cea7 100644 --- a/archive_test.go +++ b/archive_test.go @@ -1,6 +1,7 @@ package k6deps import ( + "os" "path/filepath" "testing" @@ -30,3 +31,23 @@ func Test_analyzeArchive(t *testing.T) { require.Equal(t, expected.String(), actual.String()) } + +func Test_analyzeArchive_Reader(t *testing.T) { + t.Parallel() + + file, err := os.Open(filepath.Join("testdata", "archive.tar")) //nolint:forbidigo + require.NoError(t, err) + defer file.Close() //nolint:errcheck + + opts := &Options{ + Archive: Source{Reader: file}, + } + + actual, err := Analyze(opts) + require.NoError(t, err) + + expected, err := Analyze(opts) + require.NoError(t, err) + + require.Equal(t, expected.String(), actual.String()) +} diff --git a/options.go b/options.go index ad9ddc1..5a638ed 100644 --- a/options.go +++ b/options.go @@ -18,12 +18,41 @@ const EnvDependencies = "K6_DEPENDENCIES" type Source struct { // Name contains the name of the source (file, environment variable, etc.). Name string + // Reader provides streaming access to the source content as an alternative to Contents. + Reader io.Reader // Contents contains the content of the source (e.g. script) Contents []byte // Ignore disables automatic search and processing of that source. Ignore bool } +// IsEmpty returns true if the source is empty. +func (s *Source) IsEmpty() bool { + return len(s.Contents) == 0 && s.Reader == nil && len(s.Name) == 0 +} + +func (s *Source) getReader() (io.Reader, func() error, error) { + if s.Reader != nil { + return s.Reader, nil, nil + } + + if len(s.Contents) > 0 { + return bytes.NewReader(s.Contents), nil, nil + } + + fileName, err := filepath.Abs(s.Name) + if err != nil { + return nil, nil, err + } + + file, err := os.Open(filepath.Clean(fileName)) //nolint:forbidigo + if err != nil { + return nil, nil, err + } + + return file, file.Close, nil +} + // Options contains the parameters of the dependency analysis. type Options struct { // Script contains the properties of the k6 test script to be analyzed. @@ -70,7 +99,7 @@ func (opts *Options) lookupEnv(key string) (string, bool) { } func loadSources(opts *Options) error { - if !opts.Archive.Ignore && (len(opts.Archive.Contents) > 0 || len(opts.Archive.Name) > 0) { + if !opts.Archive.Ignore && !opts.Archive.IsEmpty() { return loadArchive(opts) } @@ -188,28 +217,16 @@ func findManifest(filename string) ([]byte, string, bool, error) { //nolint:forbidigo func loadArchive(opts *Options) error { - if opts.Archive.Ignore || (len(opts.Archive.Name) == 0 && len(opts.Archive.Contents) == 0) { + if opts.Archive.Ignore || opts.Archive.IsEmpty() { return nil } - var reader io.Reader - - if len(opts.Archive.Contents) == 0 { - archivefile, err := filepath.Abs(opts.Archive.Name) - if err != nil { - return err - } - - file, err := os.Open(filepath.Clean(archivefile)) - if err != nil { - return err - } - - defer file.Close() //nolint:errcheck - - reader = file - } else { - reader = bytes.NewReader(opts.Archive.Contents) + reader, closer, err := opts.Archive.getReader() + if err != nil { + return err + } + if closer != nil { + defer closer() //nolint:errcheck } dir, err := os.MkdirTemp("", "k6deps-*")