Skip to content
This repository has been archived by the owner on Feb 26, 2019. It is now read-only.

Commit

Permalink
Handle go version tags
Browse files Browse the repository at this point in the history
Fixes #448

Obey the go tool's definition of how the go versions build tags work for
the purposes of dependency scanning.

Don't use the current go version, but the recorded go version in
Godeps.json.

FIXME: We still copy the files. This is sub optimal, but probably fine
in the 80% case where people are using the version of go they have
specified in the Godeps.json file. Longer term we need to obey the
gofiles / ignore lists from the package list.
  • Loading branch information
Edward Muller committed Apr 6, 2016
1 parent 245097c commit 35ee059
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 16 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#v61 (2016/04/06)

* Obey go version build tags based on recorded major go version. Fixes #448.

#v60 (2016/03/18)

* Make the $GOPATH check a warning.
Expand Down
42 changes: 28 additions & 14 deletions list.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"log"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"unicode"
Expand All @@ -17,7 +18,10 @@ import (
)

var (
gorootSrc = filepath.Join(build.Default.GOROOT, "src")
gorootSrc = filepath.Join(build.Default.GOROOT, "src")
ignoreTags = []string{"appengine", "ignore"} //TODO: appengine is a special case for now: https://github.com/tools/godep/issues/353
versionMatch = regexp.MustCompile(`\Ago\d+\.\d+\z`)
versionNegativeMatch = regexp.MustCompile(`\A\!go\d+\.\d+\z`)
)

type errorMissingDep struct {
Expand Down Expand Up @@ -250,31 +254,41 @@ func fillPackage(p *build.Package) error {
NextFile:
for _, file := range gofiles {
debugln(file)
pf, err := parser.ParseFile(token.NewFileSet(), file, nil, parser.ParseComments)
pf, err := parser.ParseFile(token.NewFileSet(), file, nil, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return err
}
testFile := strings.HasSuffix(file, "_test.go")
fname := filepath.Base(file)
if testFile {
p.TestGoFiles = append(p.TestGoFiles, fname)
} else {
p.GoFiles = append(p.GoFiles, fname)
}
if len(pf.Comments) > 0 {
for _, c := range pf.Comments {
ct := c.Text()
if i := strings.Index(ct, buildMatch); i != -1 {
for _, b := range strings.FieldsFunc(ct[i+len(buildMatch):], buildFieldSplit) {
//TODO: appengine is a special case for now: https://github.com/tools/godep/issues/353
if b == "ignore" || b == "appengine" {
for _, c := range pf.Comments {
ct := c.Text()
if i := strings.Index(ct, buildMatch); i != -1 {
for _, t := range strings.FieldsFunc(ct[i+len(buildMatch):], buildFieldSplit) {
for _, tag := range ignoreTags {
if t == tag {
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
}

if versionMatch.MatchString(t) && !isSameOrNewer(t, majorGoVersion) {
debugln("Adding", fname, "to ignored list because of version tag", t)
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
if versionNegativeMatch.MatchString(t) && isSameOrNewer(t[1:], majorGoVersion) {
debugln("Adding", fname, "to ignored list because of version tag", t)
p.IgnoredGoFiles = append(p.IgnoredGoFiles, fname)
continue NextFile
}
}
}
}
if testFile {
p.TestGoFiles = append(p.TestGoFiles, fname)
} else {
p.GoFiles = append(p.GoFiles, fname)
}
for _, is := range pf.Imports {
name, err := strconv.Unquote(is.Path.Value)
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions match_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,22 @@ func TestSubPath(t *testing.T) {
}
}
}

func TestIsSameOrNewer(t *testing.T) {
cases := []struct {
base string
check string
want bool
}{
{`go1.6`, `go1.6`, true},
{`go1.5`, `go1.6`, true},
{`go1.7`, `go1.6`, false},
}

for _, test := range cases {
ok := isSameOrNewer(test.base, test.check)
if ok != test.want {
t.Errorf("isSameOrNewer(%s,%s) = %v want %v", test.base, test.check, ok, test.want)
}
}
}
9 changes: 9 additions & 0 deletions save.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func projectPackages(dDir string, a []*Package) []*Package {
}

func save(pkgs []string) error {
var err error
dp, err := dotPackage()
if err != nil {
return err
Expand All @@ -127,6 +128,14 @@ func save(pkgs []string) error {
}

printVersionWarnings(gold.GoVersion)
if len(gold.GoVersion) == 0 {
gold.GoVersion = majorGoVersion
} else {
majorGoVersion, err = trimGoVersion(gold.GoVersion)
if err != nil {
log.Fatalf("Unable to determine go major version from value specified in %s: %s\n", gold.file(), gold.GoVersion)
}
}

gnew := &Godeps{
ImportPath: dp.ImportPath,
Expand Down
2 changes: 1 addition & 1 deletion save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
import (
{{range .Imports}} {{printf "%q" .}}
{{end}})
`))
`)) // `
)

func pkg(name string, imports ...string) string {
Expand Down
36 changes: 35 additions & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package main

import (
"fmt"
"log"
"runtime"
"strconv"
"strings"
)

const version = 60
const version = 61

var cmdVersion = &Command{
Name: "version",
Expand All @@ -24,3 +27,34 @@ func versionString() string {
func runVersion(cmd *Command, args []string) {
fmt.Printf("%s\n", versionString())
}

func GoVersionFields(c rune) bool {
return c == 'g' || c == 'o' || c == '.'
}

// isSameOrNewer go version (goA.B)
// go1.6 >= go1.6 == true
// go1.5 >= go1.6 == false
func isSameOrNewer(base, check string) bool {
if base == check {
return true
}
bp := strings.FieldsFunc(base, GoVersionFields)
cp := strings.FieldsFunc(check, GoVersionFields)
if len(bp) < 2 || len(cp) < 2 {
log.Fatalf("Error comparing %s to %s\n", base, check)
}
if bp[0] == cp[0] { // We only have go version 1 right now
bm, err := strconv.Atoi(bp[1])
// These errors are unlikely and there is nothing nice to do here anyway
if err != nil {
panic(err)
}
cm, err := strconv.Atoi(cp[1])
if err != nil {
panic(err)
}
return cm >= bm
}
return false
}

0 comments on commit 35ee059

Please sign in to comment.