Skip to content

Commit

Permalink
fix: running optic linter from docker
Browse files Browse the repository at this point in the history
Fix comparison paths to work with the volume mounts used when Optic CI
is run as a Docker image.

Update the default Docker image used by the Optic CI linter to the
latest official release on Docker Hub,
https://hub.docker.com/r/snyk/sweater-comb.
  • Loading branch information
cmars committed Jan 18, 2022
1 parent 5ea660d commit 49acac4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
2 changes: 1 addition & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ apis:
"ci-rules": {
Name: "ci-rules",
OpticCI: &config.OpticCILinter{
Image: "ghcr.io/snyk/sweater-comb:latest",
Image: "snyk/sweater-comb:latest",
Original: "target-branch",
},
},
Expand Down
2 changes: 1 addition & 1 deletion config/linter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "fmt"

const (
defaultSweaterCombImage = "gcr.io/snyk-main/sweater-comb:latest"
defaultOpticCIImage = "ghcr.io/snyk/sweater-comb:latest"
defaultOpticCIImage = "snyk/sweater-comb:latest"
)

var defaultSpectralExtraArgs = []string{"--format", "text"}
Expand Down
28 changes: 26 additions & 2 deletions internal/linter/optic/linter.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,25 @@ func (o *Optic) Run(ctx context.Context, root string, paths ...string) error {
return err
}
var dockerArgs []string
var fromFilter, toFilter func(string) string
if localFrom != "" {
dockerArgs = append(dockerArgs, "-v", localFrom+":/from/"+root)
if o.isDocker() {
fromFilter = func(s string) string {
return strings.Replace(s, localFrom, "/from/"+root, 1)
}
}
}
if localTo != "" {
dockerArgs = append(dockerArgs, "-v", localTo+":/to/"+root)
if o.isDocker() {
toFilter = func(s string) string {
return strings.Replace(s, localTo, "/to/"+root, 1)
}
}
}
for i := range paths {
comparison, volumeArgs, err := o.newComparison(paths[i])
comparison, volumeArgs, err := o.newComparison(paths[i], fromFilter, toFilter)
if err != nil {
errs = multierr.Append(errs, err)
} else {
Expand Down Expand Up @@ -191,7 +202,7 @@ type bulkCompareInput struct {
Comparisons []comparison `json:"comparisons,omitempty"`
}

func (o *Optic) newComparison(path string) (comparison, []string, error) {
func (o *Optic) newComparison(path string, fromFilter, toFilter func(string) string) (comparison, []string, error) {
var volumeArgs []string

// TODO: This assumes the file being linted is a resource version spec
Expand All @@ -212,12 +223,18 @@ func (o *Optic) newComparison(path string) (comparison, []string, error) {
return comparison{}, nil, err
}
cmp.From = fromFile
if fromFilter != nil {
cmp.From = fromFilter(cmp.From)
}

toFile, err := o.toSource.Fetch(path)
if err != nil {
return comparison{}, nil, err
}
cmp.To = toFile
if toFilter != nil {
cmp.To = toFilter(cmp.To)
}

return cmp, volumeArgs, nil
}
Expand All @@ -235,6 +252,13 @@ func (o *Optic) bulkCompareScript(ctx context.Context, comparisons []comparison)
if err != nil {
return err
}
if o.debug {
log.Println("input.json:")
err = json.NewEncoder(os.Stderr).Encode(&input)
if err != nil {
return err
}
}
if err := inputFile.Sync(); err != nil {
return err
}
Expand Down
31 changes: 29 additions & 2 deletions internal/linter/optic/linter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package optic

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -145,10 +147,15 @@ func TestNewGitFile(t *testing.T) {
err = l.Run(ctx, "hello", "hello/2021-06-01/spec.yaml")
c.Assert(err, qt.IsNil)
c.Assert(runner.runs, qt.HasLen, 1)
c.Assert(strings.Join(runner.runs[0], " "), qt.Matches,
cmdline := strings.Join(runner.runs[0], " ")
c.Assert(cmdline, qt.Matches,
``+
`^docker run --rm -v .*:/input.json -v .*/hello:/to/hello `+
`some-image bulk-compare --input /input.json`)
assertInputJSON(c, `^.* -v (.*):/input.json .*`, cmdline, func(c *qt.C, cmp comparison) {
c.Assert(cmp.From, qt.Matches, `^/from/.*`)
c.Assert(cmp.To, qt.Matches, `^/to/.*`)
})

// Command failed.
runner = &mockRunner{err: fmt.Errorf("bad wolf")}
Expand Down Expand Up @@ -195,8 +202,13 @@ func TestGitScript(t *testing.T) {
err = l.Run(ctx, "hello", "hello/2021-06-01/spec.yaml")
c.Assert(err, qt.IsNil)
c.Assert(runner.runs, qt.HasLen, 1)
c.Assert(strings.Join(runner.runs[0], " "), qt.Matches,
cmdline := strings.Join(runner.runs[0], " ")
c.Assert(cmdline, qt.Matches,
`/usr/local/lib/node_modules/.bin/sweater-comb bulk-compare --input `+filepath.Clean(os.TempDir())+`.*-input.json`)
assertInputJSON(c, `^.* --input (.*-input\.json).*`, cmdline, func(c *qt.C, cmp comparison) {
c.Assert(cmp.From, qt.Not(qt.Contains), "/from")
c.Assert(cmp.To, qt.Not(qt.Contains), "/to")
})

// Command failed.
runner = &mockRunner{err: fmt.Errorf("bad wolf")}
Expand All @@ -205,6 +217,21 @@ func TestGitScript(t *testing.T) {
c.Assert(err, qt.ErrorMatches, ".*: bad wolf")
}

func assertInputJSON(c *qt.C, pattern, s string, f func(*qt.C, comparison)) {
re, err := regexp.Compile(pattern)
c.Assert(err, qt.IsNil)
matches := re.FindAllStringSubmatch(s, -1)
s = matches[0][1]
contents, err := ioutil.ReadFile(s)
c.Assert(err, qt.IsNil)
var input bulkCompareInput
err = json.Unmarshal(contents, &input)
c.Assert(err, qt.IsNil)
for i := range input.Comparisons {
f(c, input.Comparisons[i])
}
}

func TestMatchDisjointSources(t *testing.T) {
c := qt.New(t)
o := &Optic{
Expand Down

0 comments on commit 49acac4

Please sign in to comment.