Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GO LIST JSON? WHY NOT!? #150

Merged
merged 9 commits into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ dist/

# ci config for local ci build
.circleci/local-config.yml

# VS Code
.vscode
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,13 @@ func doStdInAndParse(config configuration.Configuration) (err error) {
LogLady.Info("Instantiating go.mod package")

mod := packages.Mod{}
scanner := bufio.NewScanner(os.Stdin)

LogLady.Info("Beginning to parse StdIn")
mod.ProjectList, _ = parse.GoList(scanner)
mod.ProjectList, err = parse.GoListAgnostic(os.Stdin)
if err != nil {
LogLady.Error(err)
return
}
LogLady.WithFields(logrus.Fields{
"projectList": mod.ProjectList,
}).Debug("Obtained project list")
Expand Down
74 changes: 74 additions & 0 deletions parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ package parse

import (
"bufio"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"strings"

Expand All @@ -39,6 +43,68 @@ func GoList(stdIn *bufio.Scanner) (deps types.ProjectList, err error) {
return deps, nil
}

// GoListAgnostic will take a io.Reader that is likely the os.StdIn, try to parse it as
// if `go list -json -m all` was ran, and then try to reparse it as if `go list -m all`
// was ran instead. It returns either an error, or a deps of types.ProjectList
func GoListAgnostic(stdIn io.Reader) (deps types.ProjectList, err error) {
// stdIn should never be massive, so taking this approach over reading from a stream
// multiple times
johnnyFiveNeedInput, err := ioutil.ReadAll(stdIn)
if err != nil {
return
}
decoder := json.NewDecoder(strings.NewReader(string(johnnyFiveNeedInput)))

for {
var mod types.GoListModule

err = decoder.Decode(&mod)
if err == io.EOF {
err = nil
break
}
if err != nil {
break
}

project, err := modToProjectList(mod)
if _, ok := err.(*NoVersionError); ok {
continue
}
deps.Projects = append(deps.Projects, project)
}

if err != nil {
err = nil
scanner := bufio.NewScanner(strings.NewReader(string(johnnyFiveNeedInput)))
deps, err = GoList(scanner)
if err != nil {
return
}
}

return
}

func modToProjectList(mod types.GoListModule) (dep types.Projects, err error) {
if mod.Replace != nil {
if mod.Replace.Version == "" {
err = &NoVersionError{err: fmt.Errorf("No version found for mod")}
return
}
dep.Name = mod.Replace.Path
dep.Version = mod.Replace.Version
return
}
Comment on lines +90 to +98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since #142 called this out as an issue i think we should add a test around it to make sure it is working as expected.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad i should have been more clear :) that just handles replace for go list and not go list -json. We should probably have a replace test for the json path too.

{
        "Path": "github.com/gorilla/websocket",
        "Version": "v1.4.0",
        "Replace": {
                "Path": "github.com/gorilla/websocket",
                "Version": "v1.4.2",
                "Time": "2020-03-19T17:50:51Z",
                "GoMod": "/Users/ME/go/pkg/mod/cache/download/github.com/gorilla/websocket/@v/v1.4.2.mod"
        },
        "Update": {
                "Path": "github.com/gorilla/websocket",
                "Version": "v1.4.2",
                "Time": "2020-03-19T17:50:51Z"
        },
        "Indirect": true,
        "GoMod": "/Users/ME/go/pkg/mod/cache/download/github.com/gorilla/websocket/@v/v1.4.2.mod"
}

One of those testdata files but with that and maybe another in it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In: 64079e0

if mod.Version == "" {
err = &NoVersionError{err: fmt.Errorf("No version found for mod")}
return
}
dep.Name = mod.Path
dep.Version = mod.Version
return
}

// GoSum parses the go.sum file and returns an error if unsuccessful
func GoSum(path string) (deps types.ProjectList, err error) {
file, err := os.Open(path)
Expand All @@ -62,3 +128,11 @@ func parseSpaceSeparatedDependency(scanner *bufio.Scanner, deps *types.ProjectLi
deps.Projects = append(deps.Projects, types.Projects{Name: s[0], Version: s[1]})
}
}

type NoVersionError struct {
err error
}

func (n *NoVersionError) Error() string {
return n.err.Error()
}
29 changes: 29 additions & 0 deletions parse/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package parse

import (
"bufio"
"os"
"strings"
"testing"
)
Expand All @@ -33,6 +34,34 @@ func TestGoSum(t *testing.T) {
}
}

func TestGoListAgnostic(t *testing.T) {
goListFile, err := os.Open("testdata/golist.out")
if err != nil {
t.Error(err)
}

deps, err := GoListAgnostic(goListFile)
if err != nil {
t.Error(err)
}
if len(deps.Projects) != 48 {
t.Errorf("Unsuccessfully parsed go list -m all output, 48 dependencies were expected, but %d encountered", len(deps.Projects))
}

goListJSONFile, err := os.Open("testdata/golistjson.out")
if err != nil {
t.Error(err)
}

deps, err = GoListAgnostic(goListJSONFile)
if err != nil {
t.Error(err)
}
if len(deps.Projects) != 48 {
t.Errorf("Unsuccessfully parsed go list -json -m all output, 48 dependencies were expected, but %d encountered", len(deps.Projects))
}
}

func TestGoListAll(t *testing.T) {
goListMAllOutput := `github.com/sonatype-nexus-community/nancy
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7
Expand Down
49 changes: 49 additions & 0 deletions parse/testdata/golist.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
github.com/sonatype-nexus-community/nancy
github.com/BurntSushi/toml v0.3.1
github.com/Flaque/filet v0.0.0-20190209224823-fc4d33cfcf93
github.com/Masterminds/semver v0.0.0-20180403130225-3c92f33da7a8
github.com/Masterminds/vcs v1.13.1
github.com/armon/go-radix v1.0.0
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
github.com/beevik/etree v1.1.0
github.com/boltdb/bolt v1.3.1
github.com/common-nighthawk/go-figure v0.0.0-20190529165535-67e0ed34491a
github.com/davecgh/go-spew v1.1.1
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
github.com/go-openapi/errors v0.19.0
github.com/go-openapi/strfmt v0.19.0
github.com/golang/dep v0.5.4
github.com/golang/protobuf v1.2.0
github.com/google/go-cmp v0.4.0
github.com/google/uuid v1.1.1
github.com/jarcoal/httpmock v1.0.4
github.com/jedib0t/go-pretty/v6 v6.0.2
github.com/jmank88/nuts v0.3.0
github.com/konsorten/go-windows-terminal-sequences v1.0.2
github.com/kr/pretty v0.1.0
github.com/kr/pty v1.1.1
github.com/kr/text v0.1.0
github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b
github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983
github.com/mattn/go-runewidth v0.0.9
github.com/mitchellh/mapstructure v1.1.2
github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443
github.com/package-url/packageurl-go v0.1.0
github.com/pelletier/go-toml v1.4.0
github.com/pkg/errors v0.8.0
github.com/pkg/profile v1.2.1
github.com/pmezard/go-difflib v1.0.0
github.com/recoilme/pudge v1.0.3
github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24
github.com/sirupsen/logrus v1.5.0
github.com/spf13/afero v1.2.2
github.com/stretchr/objx v0.1.0
github.com/stretchr/testify v1.3.0
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
golang.org/x/text v0.3.0
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
gopkg.in/go-playground/assert.v1 v1.2.1
gopkg.in/yaml.v2 v2.2.8