Skip to content

Commit 0b5a254

Browse files
authored
Merge pull request #398 from snyk/feat/resue-code
Feat/resue code
2 parents 762c6d1 + 3ac1a15 commit 0b5a254

File tree

9 files changed

+166
-84
lines changed

9 files changed

+166
-84
lines changed

.circleci/config.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defaults: &defaults
1010
resource_class: small
1111
working_directory: ~/vervet
1212
docker:
13-
- image: cimg/go:1.22.5-node
13+
- image: cimg/go:1.23-node
1414

1515
test_defaults: &test_defaults
1616
resource_class: medium
@@ -59,7 +59,7 @@ jobs:
5959
steps:
6060
- checkout
6161
- go/install:
62-
version: 1.22.5
62+
version: 1.23.2
6363
- go/mod-download-cached
6464
- run:
6565
name: Verify testdata/output up to date
@@ -70,7 +70,7 @@ jobs:
7070

7171
lint:
7272
docker:
73-
- image: golangci/golangci-lint:v1.59.1
73+
- image: golangci/golangci-lint:v1.61.0
7474
steps:
7575
- checkout
7676
- run:

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ARG GO_VERSION=1.22.5
1+
ARG GO_VERSION=1.23
22

33
###############
44
# Build stage #

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ GO_BIN=$(shell pwd)/.bin/go
33

44
SHELL:=env PATH="$(GO_BIN):$(PATH)" $(SHELL)
55

6-
GOCI_LINT_V?=v1.59.1
6+
GOCI_LINT_V?=v1.61.0
77

88
.PHONY: all
99
all: lint test build

config/loader.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package config
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
// FromFile loads a vervet Project from a vervet.yaml file at given configPath,
9+
// defaults to ".vervet.yaml".
10+
func FromFile(configPath string) (*Project, error) {
11+
if configPath == "" {
12+
configPath = ".vervet.yaml"
13+
}
14+
f, err := os.Open(configPath)
15+
if err != nil {
16+
return nil, fmt.Errorf("failed to open %q: %w", configPath, err)
17+
}
18+
defer f.Close()
19+
return Load(f)
20+
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/snyk/vervet/v8
22

3-
go 1.22.5
3+
go 1.23
44

55
require (
66
cloud.google.com/go/storage v1.41.0

internal/cmd/compiler.go

+20-29
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cmd
22

33
import (
44
"fmt"
5-
"os"
65

76
"github.com/urfave/cli/v2"
87

@@ -144,34 +143,26 @@ func projectFromContext(ctx *cli.Context) (*config.Project, error) {
144143
} else {
145144
configPath = ".vervet.yaml"
146145
}
147-
f, err := os.Open(configPath)
148-
if err != nil {
149-
return nil, fmt.Errorf("failed to open %q: %w", configPath, err)
150-
}
151-
defer f.Close()
152-
project, err = config.Load(f)
153-
if err != nil {
154-
return nil, err
155-
}
156-
} else {
157-
api := &config.API{
158-
Resources: []*config.ResourceSet{{
159-
Path: ctx.Args().Get(0),
160-
}},
161-
Output: &config.Output{
162-
Path: ctx.Args().Get(1),
163-
},
164-
}
165-
if includePath := ctx.String("include"); includePath != "" {
166-
api.Overlays = append(api.Overlays, &config.Overlay{
167-
Include: includePath,
168-
})
169-
}
170-
project = &config.Project{
171-
APIs: map[string]*config.API{
172-
"": api,
173-
},
174-
}
146+
return config.FromFile(configPath)
147+
}
148+
149+
api := &config.API{
150+
Resources: []*config.ResourceSet{{
151+
Path: ctx.Args().Get(0),
152+
}},
153+
Output: &config.Output{
154+
Path: ctx.Args().Get(1),
155+
},
156+
}
157+
if includePath := ctx.String("include"); includePath != "" {
158+
api.Overlays = append(api.Overlays, &config.Overlay{
159+
Include: includePath,
160+
})
161+
}
162+
project = &config.Project{
163+
APIs: map[string]*config.API{
164+
"": api,
165+
},
175166
}
176167
return project, nil
177168
}

internal/simplebuild/build.go

+33-48
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/snyk/vervet/v8"
2323
"github.com/snyk/vervet/v8/config"
2424
"github.com/snyk/vervet/v8/internal/files"
25+
"github.com/snyk/vervet/v8/specs"
2526
)
2627

2728
// Build compiles the versioned resources in a project configuration based on
@@ -250,60 +251,44 @@ func LoadPaths(ctx context.Context, api *config.API) (Operations, error) {
250251
if err != nil {
251252
return nil, err
252253
}
253-
254-
for _, resource := range api.Resources {
255-
paths, err := ResourceSpecFiles(resource)
254+
for doc, err := range specs.GetInputSpecsItr(ctx, api) {
256255
if err != nil {
257256
return nil, err
258257
}
259-
for _, path := range paths {
260-
versionDir := filepath.Dir(path)
261-
versionStr := filepath.Base(versionDir)
262-
resourceName := filepath.Base(filepath.Dir(filepath.Dir(path)))
263-
264-
doc, err := vervet.NewDocumentFile(path)
265-
if err != nil {
266-
return nil, fmt.Errorf("failed to load spec from %q: %w", path, err)
267-
}
268-
269-
stabilityStr, err := vervet.ExtensionString(doc.T.Extensions, vervet.ExtSnykApiStability)
270-
if err != nil {
271-
return nil, err
272-
}
273-
if stabilityStr != "ga" {
274-
versionStr = fmt.Sprintf("%s~%s", versionStr, stabilityStr)
275-
}
276-
version, err := vervet.ParseVersion(versionStr)
277-
if err != nil {
278-
return nil, fmt.Errorf("invalid version %q", versionStr)
279-
}
280258

281-
doc.InternalizeRefs(ctx, vervet.ResolveRefsWithoutSourceName)
282-
err = doc.ResolveRefs()
283-
if err != nil {
284-
return nil, fmt.Errorf("failed to localize refs: %w", err)
285-
}
259+
version, err := doc.Version()
260+
if err != nil {
261+
return nil, fmt.Errorf("invalid version on path %q", doc.Location().String())
262+
}
263+
stabilityStr, err := vervet.ExtensionString(doc.T.Extensions, vervet.ExtSnykApiStability)
264+
if err != nil {
265+
return nil, err
266+
}
267+
version.Stability, err = vervet.ParseStability(stabilityStr)
268+
if err != nil {
269+
return nil, fmt.Errorf("invalid stability %q", stabilityStr)
270+
}
271+
resourceName := filepath.Base(filepath.Dir(doc.RelativePath()))
286272

287-
for _, pathName := range doc.T.Paths.InMatchingOrder() {
288-
pathDef := doc.T.Paths.Value(pathName)
289-
for opName, opDef := range pathDef.Operations() {
290-
if opDef.Extensions == nil {
291-
opDef.Extensions = make(map[string]interface{})
292-
}
293-
opDef.Extensions[vervet.ExtSnykApiOwner] = ownerFinder.Owners(path)
294-
k := OpKey{
295-
Path: pathName,
296-
Method: opName,
297-
}
298-
if operations[k] == nil {
299-
operations[k] = []VersionedOp{}
300-
}
301-
operations[k] = append(operations[k], VersionedOp{
302-
Version: version,
303-
Operation: opDef,
304-
ResourceName: resourceName,
305-
})
273+
for _, pathName := range doc.T.Paths.InMatchingOrder() {
274+
pathDef := doc.T.Paths.Value(pathName)
275+
for opName, opDef := range pathDef.Operations() {
276+
if opDef.Extensions == nil {
277+
opDef.Extensions = make(map[string]interface{})
278+
}
279+
opDef.Extensions[vervet.ExtSnykApiOwner] = ownerFinder.Owners(doc.Location().String())
280+
k := OpKey{
281+
Path: pathName,
282+
Method: opName,
283+
}
284+
if operations[k] == nil {
285+
operations[k] = []VersionedOp{}
306286
}
287+
operations[k] = append(operations[k], VersionedOp{
288+
Version: version,
289+
Operation: opDef,
290+
ResourceName: resourceName,
291+
})
307292
}
308293
}
309294
}

resource.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func LoadResourceVersions(epPath string) (*ResourceVersions, error) {
199199
for _, spec := range specs {
200200
dir := filepath.Dir(spec)
201201
if _, ok := specDirs[dir]; ok {
202-
return nil, fmt.Errorf("duplicate spec found in " + dir)
202+
return nil, fmt.Errorf("duplicate spec found in %s", dir)
203203
} else {
204204
specDirs[dir] = struct{}{}
205205
}

specs/load.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package specs
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"iter"
7+
8+
"github.com/snyk/vervet/v8"
9+
"github.com/snyk/vervet/v8/config"
10+
"github.com/snyk/vervet/v8/internal/files"
11+
)
12+
13+
// GetInputSpecs returns a list of all of the input specs for a given project.
14+
// It will resolve all references in the spec so the output can be consumed by
15+
// tooling unaware applications.
16+
func GetInputSpecs(ctx context.Context, api *config.API) ([]*vervet.Document, error) {
17+
return gather(GetInputSpecsItr(ctx, api))
18+
}
19+
20+
// GetInputSpecsItr is a iterator version of GetInputSpecs. It is preferred for
21+
// lazy operations.
22+
func GetInputSpecsItr(ctx context.Context, api *config.API) iter.Seq2[*vervet.Document, error] {
23+
return func(yield func(*vervet.Document, error) bool) {
24+
for _, resource := range api.Resources {
25+
paths, err := files.LocalFSSource{}.Match(resource)
26+
if err != nil {
27+
if !yield(nil, err) {
28+
return
29+
}
30+
}
31+
for _, path := range paths {
32+
doc, err := vervet.NewDocumentFile(path)
33+
if err != nil {
34+
if !yield(nil, fmt.Errorf("failed to load spec: %w", err)) {
35+
return
36+
}
37+
}
38+
doc.InternalizeRefs(ctx, vervet.ResolveRefsWithoutSourceName)
39+
err = doc.ResolveRefs()
40+
if !yield(doc, err) {
41+
return
42+
}
43+
}
44+
}
45+
}
46+
}
47+
48+
// GetOutputSpecs returns a list of all of the compiled specs for a given
49+
// project. Assumes that the specs have already been compiled by vervet and are
50+
// up to date.
51+
func GetOutputSpecs(ctx context.Context, api *config.API) ([]*vervet.Document, error) {
52+
return gather(GetOutputSpecsItr(ctx, api))
53+
}
54+
55+
// GetOutputSpecsItr is a iterator version of GetOutputSpecs. It is preferred for
56+
// lazy operations.
57+
func GetOutputSpecsItr(ctx context.Context, api *config.API) iter.Seq2[*vervet.Document, error] {
58+
return func(yield func(*vervet.Document, error) bool) {
59+
resource := &config.ResourceSet{
60+
Path: api.Output.Path,
61+
}
62+
paths, err := files.LocalFSSource{}.Match(resource)
63+
if err != nil {
64+
if !yield(nil, err) {
65+
return
66+
}
67+
}
68+
for _, path := range paths {
69+
doc, err := vervet.NewDocumentFile(path)
70+
if !yield(doc, err) {
71+
return
72+
}
73+
}
74+
}
75+
}
76+
77+
func gather(itr iter.Seq2[*vervet.Document, error]) ([]*vervet.Document, error) {
78+
docs := []*vervet.Document{}
79+
for doc, err := range itr {
80+
if err != nil {
81+
return nil, err
82+
}
83+
docs = append(docs, doc)
84+
}
85+
return docs, nil
86+
}

0 commit comments

Comments
 (0)