Skip to content

Commit 6b78dac

Browse files
committed
use source readers
Signed-off-by: Pablo Chacin <[email protected]>
1 parent 2050984 commit 6b78dac

6 files changed

+137
-197
lines changed

analyze.go

+52-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package k6deps
22

33
import (
4+
"bytes"
45
"encoding/json"
6+
"errors"
57
"os"
68
)
79

@@ -14,8 +16,22 @@ func Analyze(opts *Options) (Dependencies, error) {
1416
return archiveAnalizer(opts.Archive)()
1517
}
1618

17-
if err := loadSources(opts); err != nil {
18-
return nil, err
19+
// if the manifest is not specified, we try to find it
20+
// if not found, it will be empty and ignored by the analyzer
21+
if !opts.Manifest.Ignore && opts.Manifest.IsEmpty() {
22+
if err := opts.findManifest(); err != nil {
23+
return nil, err
24+
}
25+
}
26+
27+
if !opts.Script.Ignore {
28+
if err := loadScript(opts); err != nil {
29+
return nil, err
30+
}
31+
}
32+
33+
if !opts.Env.Ignore {
34+
loadEnv(opts)
1935
}
2036

2137
return mergeAnalyzers(
@@ -44,16 +60,29 @@ func filterInvalid(from Dependencies) Dependencies {
4460
}
4561

4662
func manifestAnalyzer(src Source) analyzer {
47-
if len(src.Contents) == 0 {
63+
if src.IsEmpty() {
4864
return empty
4965
}
5066

5167
return func() (Dependencies, error) {
68+
reader, closer, err := src.ContentReader()
69+
70+
// we tolerate the manifest file not existing
71+
if errors.Is(err, os.ErrNotExist) { //nolint:forbidigo
72+
return make(Dependencies), nil
73+
}
74+
75+
if err != nil {
76+
return nil, err
77+
}
78+
defer closer() //nolint:errcheck
79+
5280
var manifest struct {
5381
Dependencies Dependencies `json:"dependencies,omitempty"`
5482
}
5583

56-
if err := json.Unmarshal(src.Contents, &manifest); err != nil {
84+
err = json.NewDecoder(reader).Decode(&manifest)
85+
if err != nil {
5786
return nil, err
5887
}
5988

@@ -62,14 +91,26 @@ func manifestAnalyzer(src Source) analyzer {
6291
}
6392

6493
func scriptAnalyzer(src Source) analyzer {
65-
if len(src.Contents) == 0 {
94+
if src.IsEmpty() {
6695
return empty
6796
}
6897

6998
return func() (Dependencies, error) {
7099
var deps Dependencies
71100

72-
if err := (&deps).UnmarshalJS(src.Contents); err != nil {
101+
reader, closer, err := src.ContentReader()
102+
if err != nil {
103+
return nil, err
104+
}
105+
defer closer() //nolint:errcheck
106+
107+
buffer := new(bytes.Buffer)
108+
_, err = buffer.ReadFrom(reader)
109+
if err != nil {
110+
return nil, err
111+
}
112+
113+
if err := (&deps).UnmarshalJS(buffer.Bytes()); err != nil {
73114
return nil, err
74115
}
75116

@@ -94,6 +135,10 @@ func envAnalyzer(src Source) analyzer {
94135
}
95136

96137
func archiveAnalizer(src Source) analyzer {
138+
if src.IsEmpty() {
139+
return empty
140+
}
141+
97142
return func() (Dependencies, error) {
98143
input := src.Reader
99144
if input == nil {
@@ -106,12 +151,7 @@ func archiveAnalizer(src Source) analyzer {
106151
input = tar
107152
}
108153

109-
analyzer, err := processArchive(input)
110-
if err != nil {
111-
return nil, err
112-
}
113-
114-
return analyzer()
154+
return processArchive(input)
115155
}
116156
}
117157

analyze_internal_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func Test_scriptAnalyzer(t *testing.T) {
6767
fn := scriptAnalyzer(src)
6868
deps, err := fn()
6969

70-
require.NoError(t, err)
70+
require.Error(t, err)
7171
require.Empty(t, deps)
7272

7373
src.Contents = []byte(`"use k6 with @grafana/xk6-faker>v0.3.0";`)

archive.go

+26-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package k6deps
22

33
import (
44
"archive/tar"
5-
"bytes"
65
"encoding/json"
76
"errors"
87
"io"
@@ -17,17 +16,16 @@ type archiveMetadata struct {
1716

1817
const maxFileSize = 1024 * 1024 * 10 // 10M
1918

20-
func processArchive(input io.Reader) (analyzer, error) {
19+
func processArchive(input io.Reader) (Dependencies, error) {
2120
reader := tar.NewReader(input)
2221

23-
analyzers := make([]analyzer, 0)
24-
22+
deps := Dependencies{}
2523
for {
2624
header, err := reader.Next()
2725

2826
switch {
2927
case errors.Is(err, io.EOF):
30-
return mergeAnalyzers(analyzers...), nil
28+
return deps, nil
3129
case err != nil:
3230
return nil, err
3331
case header == nil:
@@ -38,29 +36,37 @@ func processArchive(input io.Reader) (analyzer, error) {
3836
continue
3937
}
4038

41-
content := &bytes.Buffer{}
42-
if _, err := io.CopyN(content, reader, maxFileSize); err != nil && !errors.Is(err, io.EOF) {
43-
return nil, err
44-
}
45-
4639
// if the file is metadata.json, we extract the dependencies from the env
4740
if header.Name == "metadata.json" {
48-
analyzer, err := analizeMetadata(content.Bytes())
41+
d, err := analizeMetadata(reader)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
err = deps.Merge(d)
4947
if err != nil {
5048
return nil, err
5149
}
52-
analyzers = append(analyzers, analyzer)
5350
continue
5451
}
5552

5653
// analize the file content as an script
5754
target := filepath.Clean(filepath.FromSlash(header.Name))
5855
src := Source{
59-
Name: target,
60-
Contents: content.Bytes(),
56+
Name: target,
57+
Reader: io.LimitReader(reader, maxFileSize),
58+
}
59+
60+
d, err := scriptAnalyzer(src)()
61+
if err != nil {
62+
return nil, err
6163
}
6264

63-
analyzers = append(analyzers, scriptAnalyzer(src))
65+
err = deps.Merge(d)
66+
if err != nil {
67+
return nil, err
68+
}
69+
continue
6470
}
6571
}
6672

@@ -71,9 +77,9 @@ func shouldProcess(target string) bool {
7177
}
7278

7379
// analizeMetadata extracts the dependencies from the metadata.json file
74-
func analizeMetadata(content []byte) (analyzer, error) {
80+
func analizeMetadata(input io.Reader) (Dependencies, error) {
7581
metadata := archiveMetadata{}
76-
if err := json.Unmarshal(content, &metadata); err != nil {
82+
if err := json.NewDecoder(input).Decode(&metadata); err != nil {
7783
return nil, err
7884
}
7985

@@ -82,8 +88,9 @@ func analizeMetadata(content []byte) (analyzer, error) {
8288
Name: EnvDependencies,
8389
Contents: []byte(value),
8490
}
85-
return envAnalyzer(src), nil
91+
92+
return envAnalyzer(src)()
8693
}
8794

88-
return empty, nil
95+
return Dependencies{}, nil
8996
}

cmd/help.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ Analyze the k6 test script and extract the extensions that the script depends on
22

33
### Sources
44

5-
Dependencies can come from three sources: k6 test script, manifest file, `K6_DEPENDENCIES` environment variable. Instead of these three sources, a k6 archive can also be specified, which can contain all three sources (currently two actually, because the manifest file is not yet included in the k6 archive).
5+
Dependencies can come from three sources: k6 test script, manifest file, `K6_DEPENDENCIES` environment variable. Instead of these three sources, a k6 archive can also be specified, which can contain all three sources (currently two actually, because the manifest file is not yet included in the k6 archive). An archive is a tar file, which can be created using the k6 archive command.
6+
7+
> *NOTE*: It is assumed that the script and all dependencies are in the archive. No external dependencies are analyzed.
68
79
The name of k6 test script or archive can be specified as the positional argument in the command invocation. Alternatively, the content can be provided in the stdin. If stdin is used, the input format ('js' for script of or 'tar' for archive) must be specified using the `--input` parameter.
810

0 commit comments

Comments
 (0)