blob: c21f53b067720f8c13cb881d6e0b7827159e3bd5 [file] [log] [blame]
package gps
import (
"fmt"
"go/build"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
)
// PackageTree.ExternalReach() uses an easily separable algorithm, wmToReach(),
// to turn a discovered set of packages and their imports into a proper external
// reach map.
//
// That algorithm is purely symbolic (no filesystem interaction), and thus is
// easy to test. This is that test.
func TestWorkmapToReach(t *testing.T) {
empty := func() map[string]bool {
return make(map[string]bool)
}
table := map[string]struct {
workmap map[string]wm
basedir string
out map[string][]string
}{
"single": {
workmap: map[string]wm{
"foo": {
ex: empty(),
in: empty(),
},
},
out: map[string][]string{
"foo": nil,
},
},
"no external": {
workmap: map[string]wm{
"foo": {
ex: empty(),
in: empty(),
},
"foo/bar": {
ex: empty(),
in: empty(),
},
},
out: map[string][]string{
"foo": nil,
"foo/bar": nil,
},
},
"no external with subpkg": {
workmap: map[string]wm{
"foo": {
ex: empty(),
in: map[string]bool{
"foo/bar": true,
},
},
"foo/bar": {
ex: empty(),
in: empty(),
},
},
out: map[string][]string{
"foo": nil,
"foo/bar": nil,
},
},
"simple base transitive": {
workmap: map[string]wm{
"foo": {
ex: empty(),
in: map[string]bool{
"foo/bar": true,
},
},
"foo/bar": {
ex: map[string]bool{
"baz": true,
},
in: empty(),
},
},
out: map[string][]string{
"foo": {
"baz",
},
"foo/bar": {
"baz",
},
},
},
"missing package is poison": {
workmap: map[string]wm{
"A": {
ex: map[string]bool{
"B/foo": true,
},
in: map[string]bool{
"A/foo": true, // missing
"A/bar": true,
},
},
"A/bar": {
ex: map[string]bool{
"B/baz": true,
},
in: empty(),
},
},
out: map[string][]string{
"A/bar": {
"B/baz",
},
},
},
"transitive missing package is poison": {
workmap: map[string]wm{
"A": {
ex: map[string]bool{
"B/foo": true,
},
in: map[string]bool{
"A/foo": true, // transitively missing
"A/quux": true,
},
},
"A/foo": {
ex: map[string]bool{
"C/flugle": true,
},
in: map[string]bool{
"A/bar": true, // missing
},
},
"A/quux": {
ex: map[string]bool{
"B/baz": true,
},
in: empty(),
},
},
out: map[string][]string{
"A/quux": {
"B/baz",
},
},
},
"err'd package is poison": {
workmap: map[string]wm{
"A": {
ex: map[string]bool{
"B/foo": true,
},
in: map[string]bool{
"A/foo": true, // err'd
"A/bar": true,
},
},
"A/foo": {
err: fmt.Errorf("err pkg"),
},
"A/bar": {
ex: map[string]bool{
"B/baz": true,
},
in: empty(),
},
},
out: map[string][]string{
"A/bar": {
"B/baz",
},
},
},
"transitive err'd package is poison": {
workmap: map[string]wm{
"A": {
ex: map[string]bool{
"B/foo": true,
},
in: map[string]bool{
"A/foo": true, // transitively err'd
"A/quux": true,
},
},
"A/foo": {
ex: map[string]bool{
"C/flugle": true,
},
in: map[string]bool{
"A/bar": true, // err'd
},
},
"A/bar": {
err: fmt.Errorf("err pkg"),
},
"A/quux": {
ex: map[string]bool{
"B/baz": true,
},
in: empty(),
},
},
out: map[string][]string{
"A/quux": {
"B/baz",
},
},
},
}
for name, fix := range table {
out := wmToReach(fix.workmap, fix.basedir)
if !reflect.DeepEqual(out, fix.out) {
t.Errorf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, out, fix.out)
}
}
}
func TestListPackages(t *testing.T) {
srcdir := filepath.Join(getwd(t), "_testdata", "src")
j := func(s string) string {
return filepath.Join(srcdir, s)
}
table := map[string]struct {
fileRoot string
importRoot string
out PackageTree
err error
}{
"empty": {
fileRoot: j("empty"),
importRoot: "empty",
out: PackageTree{
ImportRoot: "empty",
Packages: map[string]PackageOrErr{
"empty": {
Err: &build.NoGoError{
Dir: j("empty"),
},
},
},
},
err: nil,
},
"code only": {
fileRoot: j("simple"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
},
},
},
},
},
"impose import path": {
fileRoot: j("simple"),
importRoot: "arbitrary",
out: PackageTree{
ImportRoot: "arbitrary",
Packages: map[string]PackageOrErr{
"arbitrary": {
P: Package{
ImportPath: "arbitrary",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
},
},
},
},
},
"test only": {
fileRoot: j("t"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{},
TestImports: []string{
"math/rand",
"strconv",
},
},
},
},
},
},
"xtest only": {
fileRoot: j("xt"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{},
TestImports: []string{
"sort",
"strconv",
},
},
},
},
},
},
"code and test": {
fileRoot: j("simplet"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
TestImports: []string{
"math/rand",
"strconv",
},
},
},
},
},
},
"code and xtest": {
fileRoot: j("simplext"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
TestImports: []string{
"sort",
"strconv",
},
},
},
},
},
},
"code, test, xtest": {
fileRoot: j("simpleallt"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
TestImports: []string{
"math/rand",
"sort",
"strconv",
},
},
},
},
},
},
"one pkg multifile": {
fileRoot: j("m1p"),
importRoot: "m1p",
out: PackageTree{
ImportRoot: "m1p",
Packages: map[string]PackageOrErr{
"m1p": {
P: Package{
ImportPath: "m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
"one nested below": {
fileRoot: j("nest"),
importRoot: "nest",
out: PackageTree{
ImportRoot: "nest",
Packages: map[string]PackageOrErr{
"nest": {
P: Package{
ImportPath: "nest",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
},
},
"nest/m1p": {
P: Package{
ImportPath: "nest/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
"two nested under empty root": {
fileRoot: j("ren"),
importRoot: "ren",
out: PackageTree{
ImportRoot: "ren",
Packages: map[string]PackageOrErr{
"ren": {
Err: &build.NoGoError{
Dir: j("ren"),
},
},
"ren/m1p": {
P: Package{
ImportPath: "ren/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
"ren/simple": {
P: Package{
ImportPath: "ren/simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
},
},
},
},
},
},
"internal name mismatch": {
fileRoot: j("doublenest"),
importRoot: "doublenest",
out: PackageTree{
ImportRoot: "doublenest",
Packages: map[string]PackageOrErr{
"doublenest": {
P: Package{
ImportPath: "doublenest",
CommentPath: "",
Name: "base",
Imports: []string{
"github.com/sdboyer/gps",
"go/parser",
},
},
},
"doublenest/namemismatch": {
P: Package{
ImportPath: "doublenest/namemismatch",
CommentPath: "",
Name: "nm",
Imports: []string{
"github.com/Masterminds/semver",
"os",
},
},
},
"doublenest/namemismatch/m1p": {
P: Package{
ImportPath: "doublenest/namemismatch/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
"file and importroot mismatch": {
fileRoot: j("doublenest"),
importRoot: "other",
out: PackageTree{
ImportRoot: "other",
Packages: map[string]PackageOrErr{
"other": {
P: Package{
ImportPath: "other",
CommentPath: "",
Name: "base",
Imports: []string{
"github.com/sdboyer/gps",
"go/parser",
},
},
},
"other/namemismatch": {
P: Package{
ImportPath: "other/namemismatch",
CommentPath: "",
Name: "nm",
Imports: []string{
"github.com/Masterminds/semver",
"os",
},
},
},
"other/namemismatch/m1p": {
P: Package{
ImportPath: "other/namemismatch/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
"code and ignored main": {
fileRoot: j("igmain"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
"unicode",
},
},
},
},
},
},
"code and ignored main with comment leader": {
fileRoot: j("igmainlong"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
"unicode",
},
},
},
},
},
},
"code, tests, and ignored main": {
fileRoot: j("igmaint"),
importRoot: "simple",
out: PackageTree{
ImportRoot: "simple",
Packages: map[string]PackageOrErr{
"simple": {
P: Package{
ImportPath: "simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"sort",
"unicode",
},
TestImports: []string{
"math/rand",
"strconv",
},
},
},
},
},
},
"two pkgs": {
fileRoot: j("twopkgs"),
importRoot: "twopkgs",
out: PackageTree{
ImportRoot: "twopkgs",
Packages: map[string]PackageOrErr{
"twopkgs": {
Err: &build.MultiplePackageError{
Dir: j("twopkgs"),
Packages: []string{"simple", "m1p"},
Files: []string{"a.go", "b.go"},
},
},
},
},
},
// imports a missing pkg
"missing import": {
fileRoot: j("missing"),
importRoot: "missing",
out: PackageTree{
ImportRoot: "missing",
Packages: map[string]PackageOrErr{
"missing": {
P: Package{
ImportPath: "missing",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"missing/missing",
"sort",
},
},
},
"missing/m1p": {
P: Package{
ImportPath: "missing/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
// has disallowed dir names
"disallowed dirs": {
fileRoot: j("disallow"),
importRoot: "disallow",
out: PackageTree{
ImportRoot: "disallow",
Packages: map[string]PackageOrErr{
"disallow": {
P: Package{
ImportPath: "disallow",
CommentPath: "",
Name: "disallow",
Imports: []string{
"disallow/testdata",
"github.com/sdboyer/gps",
"sort",
},
},
},
// disallow/.m1p is ignored by listPackages...for now. Kept
// here commented because this might change again...
//"disallow/.m1p": {
//P: Package{
//ImportPath: "disallow/.m1p",
//CommentPath: "",
//Name: "m1p",
//Imports: []string{
//"github.com/sdboyer/gps",
//"os",
//"sort",
//},
//},
//},
"disallow/testdata": {
P: Package{
ImportPath: "disallow/testdata",
CommentPath: "",
Name: "testdata",
Imports: []string{
"hash",
},
},
},
},
},
},
// This case mostly exists for the PackageTree methods, but it does
// cover a bit of range
"varied": {
fileRoot: j("varied"),
importRoot: "varied",
out: PackageTree{
ImportRoot: "varied",
Packages: map[string]PackageOrErr{
"varied": {
P: Package{
ImportPath: "varied",
CommentPath: "",
Name: "main",
Imports: []string{
"net/http",
"varied/namemismatch",
"varied/otherpath",
"varied/simple",
},
},
},
"varied/otherpath": {
P: Package{
ImportPath: "varied/otherpath",
CommentPath: "",
Name: "otherpath",
Imports: []string{},
TestImports: []string{
"varied/m1p",
},
},
},
"varied/simple": {
P: Package{
ImportPath: "varied/simple",
CommentPath: "",
Name: "simple",
Imports: []string{
"github.com/sdboyer/gps",
"go/parser",
"varied/simple/another",
},
},
},
"varied/simple/another": {
P: Package{
ImportPath: "varied/simple/another",
CommentPath: "",
Name: "another",
Imports: []string{
"hash",
"varied/m1p",
},
TestImports: []string{
"encoding/binary",
},
},
},
"varied/namemismatch": {
P: Package{
ImportPath: "varied/namemismatch",
CommentPath: "",
Name: "nm",
Imports: []string{
"github.com/Masterminds/semver",
"os",
},
},
},
"varied/m1p": {
P: Package{
ImportPath: "varied/m1p",
CommentPath: "",
Name: "m1p",
Imports: []string{
"github.com/sdboyer/gps",
"os",
"sort",
},
},
},
},
},
},
}
for name, fix := range table {
if _, err := os.Stat(fix.fileRoot); err != nil {
t.Errorf("listPackages(%q): error on fileRoot %s: %s", name, fix.fileRoot, err)
continue
}
out, err := ListPackages(fix.fileRoot, fix.importRoot)
if err != nil && fix.err == nil {
t.Errorf("listPackages(%q): Received error but none expected: %s", name, err)
} else if fix.err != nil && err == nil {
t.Errorf("listPackages(%q): Error expected but none received", name)
} else if fix.err != nil && err != nil {
if !reflect.DeepEqual(fix.err, err) {
t.Errorf("listPackages(%q): Did not receive expected error:\n\t(GOT): %s\n\t(WNT): %s", name, err, fix.err)
}
}
if fix.out.ImportRoot != "" && fix.out.Packages != nil {
if !reflect.DeepEqual(out, fix.out) {
if fix.out.ImportRoot != out.ImportRoot {
t.Errorf("listPackages(%q): Expected ImportRoot %s, got %s", name, fix.out.ImportRoot, out.ImportRoot)
}
// overwrite the out one to see if we still have a real problem
out.ImportRoot = fix.out.ImportRoot
if !reflect.DeepEqual(out, fix.out) {
if len(fix.out.Packages) < 2 {
t.Errorf("listPackages(%q): Did not get expected PackageOrErrs:\n\t(GOT): %s\n\t(WNT): %s", name, out, fix.out)
} else {
seen := make(map[string]bool)
for path, perr := range fix.out.Packages {
seen[path] = true
if operr, exists := out.Packages[path]; !exists {
t.Errorf("listPackages(%q): Expected PackageOrErr for path %s was missing from output:\n\t%s", name, path, perr)
} else {
if !reflect.DeepEqual(perr, operr) {
t.Errorf("listPackages(%q): PkgOrErr for path %s was not as expected:\n\t(GOT): %s\n\t(WNT): %s", name, path, operr, perr)
}
}
}
for path, operr := range out.Packages {
if seen[path] {
continue
}
t.Errorf("listPackages(%q): Got PackageOrErr for path %s, but none was expected:\n\t%s", name, path, operr)
}
}
}
}
}
}
}
func TestListExternalImports(t *testing.T) {
// There's enough in the 'varied' test case to test most of what matters
vptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "varied"), "varied")
if err != nil {
t.Fatalf("listPackages failed on varied test case: %s", err)
}
var expect []string
var name string
var ignore map[string]bool
var main, tests bool
validate := func() {
result := vptree.ExternalReach(main, tests, ignore).ListExternalImports()
if !reflect.DeepEqual(expect, result) {
t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
}
}
all := []string{
"encoding/binary",
"github.com/Masterminds/semver",
"github.com/sdboyer/gps",
"go/parser",
"hash",
"net/http",
"os",
"sort",
}
// helper to rewrite expect, except for a couple packages
//
// this makes it easier to see what we're taking out on each test
except := func(not ...string) {
expect = make([]string, len(all)-len(not))
drop := make(map[string]bool)
for _, npath := range not {
drop[npath] = true
}
k := 0
for _, path := range all {
if !drop[path] {
expect[k] = path
k++
}
}
}
// everything on
name = "simple"
except()
main, tests = true, true
validate()
// Now without tests, which should just cut one
name = "no tests"
tests = false
except("encoding/binary")
validate()
// Now skip main, which still just cuts out one
name = "no main"
main, tests = false, true
except("net/http")
validate()
// No test and no main, which should be additive
name = "no test, no main"
main, tests = false, false
except("net/http", "encoding/binary")
validate()
// now, the ignore tests. turn main and tests back on
main, tests = true, true
// start with non-matching
name = "non-matching ignore"
ignore = map[string]bool{
"nomatch": true,
}
except()
validate()
// should have the same effect as ignoring main
name = "ignore the root"
ignore = map[string]bool{
"varied": true,
}
except("net/http")
validate()
// now drop a more interesting one
name = "ignore simple"
ignore = map[string]bool{
"varied/simple": true,
}
// we get github.com/sdboyer/gps from m1p, too, so it should still be there
except("go/parser")
validate()
// now drop two
name = "ignore simple and namemismatch"
ignore = map[string]bool{
"varied/simple": true,
"varied/namemismatch": true,
}
except("go/parser", "github.com/Masterminds/semver")
validate()
// make sure tests and main play nice with ignore
name = "ignore simple and namemismatch, and no tests"
tests = false
except("go/parser", "github.com/Masterminds/semver", "encoding/binary")
validate()
name = "ignore simple and namemismatch, and no main"
main, tests = false, true
except("go/parser", "github.com/Masterminds/semver", "net/http")
validate()
name = "ignore simple and namemismatch, and no main or tests"
main, tests = false, false
except("go/parser", "github.com/Masterminds/semver", "net/http", "encoding/binary")
validate()
main, tests = true, true
// ignore two that should knock out gps
name = "ignore both importers"
ignore = map[string]bool{
"varied/simple": true,
"varied/m1p": true,
}
except("sort", "github.com/sdboyer/gps", "go/parser")
validate()
// finally, directly ignore some external packages
name = "ignore external"
ignore = map[string]bool{
"github.com/sdboyer/gps": true,
"go/parser": true,
"sort": true,
}
except("sort", "github.com/sdboyer/gps", "go/parser")
validate()
// The only thing varied *doesn't* cover is disallowed path patterns
ptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "disallow"), "disallow")
if err != nil {
t.Fatalf("listPackages failed on disallow test case: %s", err)
}
result := ptree.ExternalReach(false, false, nil).ListExternalImports()
expect = []string{"github.com/sdboyer/gps", "hash", "sort"}
if !reflect.DeepEqual(expect, result) {
t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
}
}
func TestExternalReach(t *testing.T) {
// There's enough in the 'varied' test case to test most of what matters
vptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "varied"), "varied")
if err != nil {
t.Fatalf("listPackages failed on varied test case: %s", err)
}
// Set up vars for validate closure
var expect map[string][]string
var name string
var main, tests bool
var ignore map[string]bool
validate := func() {
result := vptree.ExternalReach(main, tests, ignore)
if !reflect.DeepEqual(expect, result) {
seen := make(map[string]bool)
for ip, epkgs := range expect {
seen[ip] = true
if pkgs, exists := result[ip]; !exists {
t.Errorf("ver(%q): expected import path %s was not present in result", name, ip)
} else {
if !reflect.DeepEqual(pkgs, epkgs) {
t.Errorf("ver(%q): did not get expected package set for import path %s:\n\t(GOT): %s\n\t(WNT): %s", name, ip, pkgs, epkgs)
}
}
}
for ip, pkgs := range result {
if seen[ip] {
continue
}
t.Errorf("ver(%q): Got packages for import path %s, but none were expected:\n\t%s", name, ip, pkgs)
}
}
}
all := map[string][]string{
"varied": {"encoding/binary", "github.com/Masterminds/semver", "github.com/sdboyer/gps", "go/parser", "hash", "net/http", "os", "sort"},
"varied/m1p": {"github.com/sdboyer/gps", "os", "sort"},
"varied/namemismatch": {"github.com/Masterminds/semver", "os"},
"varied/otherpath": {"github.com/sdboyer/gps", "os", "sort"},
"varied/simple": {"encoding/binary", "github.com/sdboyer/gps", "go/parser", "hash", "os", "sort"},
"varied/simple/another": {"encoding/binary", "github.com/sdboyer/gps", "hash", "os", "sort"},
}
// build a map to validate the exception inputs. do this because shit is
// hard enough to keep track of that it's preferable not to have silent
// success if a typo creeps in and we're trying to except an import that
// isn't in a pkg in the first place
valid := make(map[string]map[string]bool)
for ip, expkgs := range all {
m := make(map[string]bool)
for _, pkg := range expkgs {
m[pkg] = true
}
valid[ip] = m
}
// helper to compose expect, excepting specific packages
//
// this makes it easier to see what we're taking out on each test
except := func(pkgig ...string) {
// reinit expect with everything from all
expect = make(map[string][]string)
for ip, expkgs := range all {
sl := make([]string, len(expkgs))
copy(sl, expkgs)
expect[ip] = sl
}
// now build the dropmap
drop := make(map[string]map[string]bool)
for _, igstr := range pkgig {
// split on space; first elem is import path to pkg, the rest are
// the imports to drop.
not := strings.Split(igstr, " ")
var ip string
ip, not = not[0], not[1:]
if _, exists := valid[ip]; !exists {
t.Fatalf("%s is not a package name we're working with, doofus", ip)
}
// if only a single elem was passed, though, drop the whole thing
if len(not) == 0 {
delete(expect, ip)
continue
}
m := make(map[string]bool)
for _, imp := range not {
if !valid[ip][imp] {
t.Fatalf("%s is not a reachable import of %s, even in the all case", imp, ip)
}
m[imp] = true
}
drop[ip] = m
}
for ip, pkgs := range expect {
var npkgs []string
for _, imp := range pkgs {
if !drop[ip][imp] {
npkgs = append(npkgs, imp)
}
}
expect[ip] = npkgs
}
}
// first, validate all
name = "all"
main, tests = true, true
except()
validate()
// turn off main pkgs, which necessarily doesn't affect anything else
name = "no main"
main = false
except("varied")
validate()
// ignoring the "varied" pkg has same effect as disabling main pkgs
name = "ignore root"
ignore = map[string]bool{
"varied": true,
}
main = true
validate()
// when we drop tests, varied/otherpath loses its link to varied/m1p and
// varied/simple/another loses its test import, which has a fairly big
// cascade
name = "no tests"
tests = false
ignore = nil
except(
"varied encoding/binary",
"varied/simple encoding/binary",
"varied/simple/another encoding/binary",
"varied/otherpath github.com/sdboyer/gps os sort",
)
// almost the same as previous, but varied just goes away completely
name = "no main or tests"
main = false
except(
"varied",
"varied/simple encoding/binary",
"varied/simple/another encoding/binary",
"varied/otherpath github.com/sdboyer/gps os sort",
)
validate()
// focus on ignores now, so reset main and tests
main, tests = true, true
// now, the fun stuff. punch a hole in the middle by cutting out
// varied/simple
name = "ignore varied/simple"
ignore = map[string]bool{
"varied/simple": true,
}
except(
// root pkg loses on everything in varied/simple/another
"varied hash encoding/binary go/parser",
"varied/simple",
)
validate()
// widen the hole by excluding otherpath
name = "ignore varied/{otherpath,simple}"
ignore = map[string]bool{
"varied/otherpath": true,
"varied/simple": true,
}
except(
// root pkg loses on everything in varied/simple/another and varied/m1p
"varied hash encoding/binary go/parser github.com/sdboyer/gps sort",
"varied/otherpath",
"varied/simple",
)
validate()
// remove namemismatch, though we're mostly beating a dead horse now
name = "ignore varied/{otherpath,simple,namemismatch}"
ignore["varied/namemismatch"] = true
except(
// root pkg loses on everything in varied/simple/another and varied/m1p
"varied hash encoding/binary go/parser github.com/sdboyer/gps sort os github.com/Masterminds/semver",
"varied/otherpath",
"varied/simple",
"varied/namemismatch",
)
validate()
}
var _ = map[string][]string{
"varied": {"encoding/binary", "github.com/Masterminds/semver", "github.com/sdboyer/gps", "go/parser", "hash", "net/http", "os", "sort"},
"varied/m1p": {"github.com/sdboyer/gps", "os", "sort"},
"varied/namemismatch": {"github.com/Masterminds/semver", "os"},
"varied/otherpath": {"github.com/sdboyer/gps", "os", "sort"},
"varied/simple": {"encoding/binary", "github.com/sdboyer/gps", "go/parser", "hash", "os", "sort"},
"varied/simple/another": {"encoding/binary", "github.com/sdboyer/gps", "hash", "os", "sort"},
}
func getwd(t *testing.T) string {
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
return cwd
}