gopkg.in/tools/godep.v63@v63.0.0-20160503185544-51f9ea00dbee/save_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"go/build"
     7  	"io/ioutil"
     8  	"math"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"reflect"
    13  	"runtime"
    14  	"strings"
    15  	"testing"
    16  	"text/template"
    17  )
    18  
    19  // node represents a file tree or a VCS repo
    20  type node struct {
    21  	path    string      // file name or commit type
    22  	body    interface{} // file contents or commit tag
    23  	entries []*node     // nil if the entry is a file
    24  }
    25  
    26  var (
    27  	pkgtpl = template.Must(template.New("package").Parse(`package {{.Name}}
    28  
    29  import (
    30  {{range .Imports}}	{{printf "%q" .}}
    31  {{end}})
    32  `)) // `
    33  )
    34  
    35  func pkg(name string, imports ...string) string {
    36  	v := struct {
    37  		Name    string
    38  		Tags    string
    39  		Imports []string
    40  	}{name, "", imports}
    41  	var buf bytes.Buffer
    42  	err := pkgtpl.Execute(&buf, v)
    43  	if err != nil {
    44  		panic(err)
    45  	}
    46  	return buf.String()
    47  }
    48  
    49  func license() string {
    50  	return "I AM A LICENSE FILE"
    51  }
    52  
    53  func pkgWithTags(name, tags string, imports ...string) string {
    54  	return "// +build " + tags + "\n\n" + pkg(name, imports...)
    55  }
    56  
    57  func pkgWithImpossibleTag(name string, imports ...string) string {
    58  	return pkgWithTags(name, impossibleTag(), imports...)
    59  }
    60  
    61  func impossibleTag() string {
    62  	return "!" + runtime.GOOS
    63  }
    64  
    65  func decl(name string) string {
    66  	return "var " + name + " int\n"
    67  }
    68  
    69  func setGOPATH(paths ...string) {
    70  	build.Default.GOPATH = strings.Join(paths, string(os.PathListSeparator))
    71  }
    72  
    73  func clearPkgCache() {
    74  	pkgCache = make(map[string]*build.Package)
    75  }
    76  
    77  func godeps(importpath string, keyval ...string) *Godeps {
    78  	g := &Godeps{
    79  		ImportPath: importpath,
    80  	}
    81  	for i := 0; i < len(keyval); i += 2 {
    82  		g.Deps = append(g.Deps, Dependency{
    83  			ImportPath: keyval[i],
    84  			Comment:    keyval[i+1],
    85  		})
    86  	}
    87  	return g
    88  }
    89  
    90  func setGlobals(vendor bool) {
    91  	clearPkgCache()
    92  	VendorExperiment = vendor
    93  	sep = defaultSep(VendorExperiment)
    94  	//debug = testing.Verbose()
    95  	//verbose = testing.Verbose()
    96  }
    97  
    98  func TestSave(t *testing.T) {
    99  	var cases = []struct {
   100  		cwd      string
   101  		args     []string
   102  		flagR    bool
   103  		flagT    bool
   104  		vendor   bool
   105  		start    []*node
   106  		altstart []*node
   107  		want     []*node
   108  		wdep     Godeps
   109  		werr     bool
   110  	}{
   111  		{ // 0 - simple case, one dependency
   112  			cwd:   "C",
   113  			flagR: false,
   114  			start: []*node{
   115  				{
   116  					"C",
   117  					"",
   118  					[]*node{
   119  						{"main.go", pkg("main", "D"), nil},
   120  						{"+git", "", nil},
   121  					},
   122  				},
   123  				{
   124  					"D",
   125  					"",
   126  					[]*node{
   127  						{"main.go", pkg("D"), nil},
   128  						{"+git", "D1", nil},
   129  					},
   130  				},
   131  			},
   132  			want: []*node{
   133  				{"C/main.go", pkg("main", "D"), nil},
   134  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
   135  			},
   136  			wdep: Godeps{
   137  				ImportPath: "C",
   138  				Deps: []Dependency{
   139  					{ImportPath: "D", Comment: "D1"},
   140  				},
   141  			},
   142  		},
   143  		{ // 1 - strip import comment
   144  			cwd: "C",
   145  			start: []*node{
   146  				{
   147  					"C",
   148  					"",
   149  					[]*node{
   150  						{"main.go", pkg("main", "D"), nil},
   151  						{"+git", "", nil},
   152  					},
   153  				},
   154  				{
   155  					"D",
   156  					"",
   157  					[]*node{
   158  						{"main.go", `package D // import "D"`, nil},
   159  						{"+git", "D1", nil},
   160  					},
   161  				},
   162  			},
   163  			want: []*node{
   164  				{"C/main.go", pkg("main", "D"), nil},
   165  				{"C/Godeps/_workspace/src/D/main.go", "package D\n", nil},
   166  			},
   167  			wdep: Godeps{
   168  				ImportPath: "C",
   169  				Deps: []Dependency{
   170  					{ImportPath: "D", Comment: "D1"},
   171  				},
   172  			},
   173  		},
   174  		{
   175  			// 2 - dependency in same repo with existing manifest
   176  			// see bug https://github.com/tools/godep/issues/69
   177  			cwd:  "P",
   178  			args: []string{"./..."},
   179  			start: []*node{
   180  				{
   181  					"P",
   182  					"",
   183  					[]*node{
   184  						{"main.go", pkg("P", "P/Q"), nil},
   185  						{"Q/main.go", pkg("Q"), nil},
   186  						{"Godeps/Godeps.json", `{}`, nil},
   187  						{"+git", "C1", nil},
   188  					},
   189  				},
   190  			},
   191  			want: []*node{
   192  				{"P/main.go", pkg("P", "P/Q"), nil},
   193  				{"P/Q/main.go", pkg("Q"), nil},
   194  			},
   195  			wdep: Godeps{
   196  				ImportPath: "P",
   197  				Deps:       []Dependency{},
   198  			},
   199  		},
   200  		{
   201  			// 3 - dependency on parent directory in same repo
   202  			// see bug https://github.com/tools/godep/issues/70
   203  			cwd:  "P",
   204  			args: []string{"./..."},
   205  			start: []*node{
   206  				{
   207  					"P",
   208  					"",
   209  					[]*node{
   210  						{"main.go", pkg("P"), nil},
   211  						{"Q/main.go", pkg("Q", "P"), nil},
   212  						{"+git", "C1", nil},
   213  					},
   214  				},
   215  			},
   216  			want: []*node{
   217  				{"P/main.go", pkg("P"), nil},
   218  				{"P/Q/main.go", pkg("Q", "P"), nil},
   219  			},
   220  			wdep: Godeps{
   221  				ImportPath: "P",
   222  				Deps:       []Dependency{},
   223  			},
   224  		},
   225  		{ // 4 - transitive dependency
   226  			cwd: "C",
   227  			start: []*node{
   228  				{
   229  					"C",
   230  					"",
   231  					[]*node{
   232  						{"main.go", pkg("main", "D"), nil},
   233  						{"+git", "", nil},
   234  					},
   235  				},
   236  				{
   237  					"D",
   238  					"",
   239  					[]*node{
   240  						{"main.go", pkg("D", "T"), nil},
   241  						{"+git", "D1", nil},
   242  					},
   243  				},
   244  				{
   245  					"T",
   246  					"",
   247  					[]*node{
   248  						{"main.go", pkg("T"), nil},
   249  						{"+git", "T1", nil},
   250  					},
   251  				},
   252  			},
   253  			want: []*node{
   254  				{"C/main.go", pkg("main", "D"), nil},
   255  				{"C/Godeps/_workspace/src/D/main.go", pkg("D", "T"), nil},
   256  				{"C/Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   257  			},
   258  			wdep: Godeps{
   259  				ImportPath: "C",
   260  				Deps: []Dependency{
   261  					{ImportPath: "D", Comment: "D1"},
   262  					{ImportPath: "T", Comment: "T1"},
   263  				},
   264  			},
   265  		},
   266  		{ // 5 - two packages, one in a subdirectory
   267  			cwd: "C",
   268  			start: []*node{
   269  				{
   270  					"C",
   271  					"",
   272  					[]*node{
   273  						{"main.go", pkg("main", "D", "D/P"), nil},
   274  						{"+git", "", nil},
   275  					},
   276  				},
   277  				{
   278  					"D",
   279  					"",
   280  					[]*node{
   281  						{"main.go", pkg("D"), nil},
   282  						{"P/main.go", pkg("P"), nil},
   283  						{"+git", "D1", nil},
   284  					},
   285  				},
   286  			},
   287  			want: []*node{
   288  				{"C/main.go", pkg("main", "D", "D/P"), nil},
   289  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
   290  				{"C/Godeps/_workspace/src/D/P/main.go", pkg("P"), nil},
   291  			},
   292  			wdep: Godeps{
   293  				ImportPath: "C",
   294  				Deps: []Dependency{
   295  					{ImportPath: "D", Comment: "D1"},
   296  					{ImportPath: "D/P", Comment: "D1"},
   297  				},
   298  			},
   299  		},
   300  		{ // 6 - repo root is not a package (no go files)
   301  			cwd: "C",
   302  			start: []*node{
   303  				{
   304  					"C",
   305  					"",
   306  					[]*node{
   307  						{"main.go", pkg("main", "D/P", "D/Q"), nil},
   308  						{"+git", "", nil},
   309  					},
   310  				},
   311  				{
   312  					"D",
   313  					"",
   314  					[]*node{
   315  						{"P/main.go", pkg("P"), nil},
   316  						{"Q/main.go", pkg("Q"), nil},
   317  						{"+git", "D1", nil},
   318  					},
   319  				},
   320  			},
   321  			want: []*node{
   322  				{"C/main.go", pkg("main", "D/P", "D/Q"), nil},
   323  				{"C/Godeps/_workspace/src/D/P/main.go", pkg("P"), nil},
   324  				{"C/Godeps/_workspace/src/D/Q/main.go", pkg("Q"), nil},
   325  			},
   326  			wdep: Godeps{
   327  				ImportPath: "C",
   328  				Deps: []Dependency{
   329  					{ImportPath: "D/P", Comment: "D1"},
   330  					{ImportPath: "D/Q", Comment: "D1"},
   331  				},
   332  			},
   333  		},
   334  		{ // 7 - symlink
   335  			cwd: "C",
   336  			start: []*node{
   337  				{
   338  					"C",
   339  					"",
   340  					[]*node{
   341  						{"main.x", pkg("main", "D"), nil},
   342  						{"main.go", "symlink:main.x", nil},
   343  						{"+git", "", nil},
   344  					},
   345  				},
   346  				{
   347  					"D",
   348  					"",
   349  					[]*node{
   350  						{"main.go", pkg("D"), nil},
   351  						{"+git", "D1", nil},
   352  					},
   353  				},
   354  			},
   355  			want: []*node{
   356  				{"C/main.go", pkg("main", "D"), nil},
   357  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
   358  			},
   359  			wdep: Godeps{
   360  				ImportPath: "C",
   361  				Deps: []Dependency{
   362  					{ImportPath: "D", Comment: "D1"},
   363  				},
   364  			},
   365  		},
   366  		{ // 8 - add one dependency; keep other dependency version
   367  			cwd: "C",
   368  			start: []*node{
   369  				{
   370  					"D",
   371  					"",
   372  					[]*node{
   373  						{"main.go", pkg("D") + decl("D1"), nil},
   374  						{"+git", "D1", nil},
   375  						{"main.go", pkg("D") + decl("D2"), nil},
   376  						{"+git", "D2", nil},
   377  					},
   378  				},
   379  				{
   380  					"E",
   381  					"",
   382  					[]*node{
   383  						{"main.go", pkg("E"), nil},
   384  						{"+git", "E1", nil},
   385  					},
   386  				},
   387  				{
   388  					"C",
   389  					"",
   390  					[]*node{
   391  						{"main.go", pkg("main", "D", "E"), nil},
   392  						{"Godeps/Godeps.json", godeps("C", "D", "D1"), nil},
   393  						{"Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   394  						{"+git", "", nil},
   395  					},
   396  				},
   397  			},
   398  			want: []*node{
   399  				{"C/main.go", pkg("main", "D", "E"), nil},
   400  				{"C/Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   401  				{"C/Godeps/_workspace/src/E/main.go", pkg("E"), nil},
   402  			},
   403  			wdep: Godeps{
   404  				ImportPath: "C",
   405  				Deps: []Dependency{
   406  					{ImportPath: "D", Comment: "D1"},
   407  					{ImportPath: "E", Comment: "E1"},
   408  				},
   409  			},
   410  		},
   411  		{ // 9 - remove one dependency; keep other dependency version
   412  			cwd: "C",
   413  			start: []*node{
   414  				{
   415  					"D",
   416  					"",
   417  					[]*node{
   418  						{"main.go", pkg("D") + decl("D1"), nil},
   419  						{"+git", "D1", nil},
   420  						{"main.go", pkg("D") + decl("D2"), nil},
   421  						{"+git", "D2", nil},
   422  					},
   423  				},
   424  				{
   425  					"E",
   426  					"",
   427  					[]*node{
   428  						{"main.go", pkg("E") + decl("E1"), nil},
   429  						{"+git", "E1", nil},
   430  					},
   431  				},
   432  				{
   433  					"C",
   434  					"",
   435  					[]*node{
   436  						{"main.go", pkg("main", "D"), nil},
   437  						{"Godeps/Godeps.json", godeps("C", "D", "D1", "E", "E1"), nil},
   438  						{"Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   439  						{"Godeps/_workspace/src/E/main.go", pkg("E") + decl("E1"), nil},
   440  						{"+git", "", nil},
   441  					},
   442  				},
   443  			},
   444  			want: []*node{
   445  				{"C/Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   446  				{"C/Godeps/_workspace/src/E/main.go", "(absent)", nil},
   447  			},
   448  			wdep: Godeps{
   449  				ImportPath: "C",
   450  				Deps: []Dependency{
   451  					{ImportPath: "D", Comment: "D1"},
   452  				},
   453  			},
   454  		},
   455  		{ // 10 - add one dependency from same repo
   456  			cwd: "C",
   457  			start: []*node{
   458  				{
   459  					"D",
   460  					"",
   461  					[]*node{
   462  						{"A/main.go", pkg("A") + decl("A1"), nil},
   463  						{"B/main.go", pkg("B") + decl("B1"), nil},
   464  						{"+git", "D1", nil},
   465  					},
   466  				},
   467  				{
   468  					"C",
   469  					"",
   470  					[]*node{
   471  						{"main.go", pkg("main", "D/A", "D/B"), nil},
   472  						{"Godeps/Godeps.json", godeps("C", "D/A", "D1"), nil},
   473  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   474  						{"+git", "", nil},
   475  					},
   476  				},
   477  			},
   478  			want: []*node{
   479  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   480  				{"C/Godeps/_workspace/src/D/B/main.go", pkg("B") + decl("B1"), nil},
   481  			},
   482  			wdep: Godeps{
   483  				ImportPath: "C",
   484  				Deps: []Dependency{
   485  					{ImportPath: "D/A", Comment: "D1"},
   486  					{ImportPath: "D/B", Comment: "D1"},
   487  				},
   488  			},
   489  		},
   490  		{ // 11 - add one dependency from same repo, require same version
   491  			cwd: "C",
   492  			start: []*node{
   493  				{
   494  					"D",
   495  					"",
   496  					[]*node{
   497  						{"A/main.go", pkg("A") + decl("A1"), nil},
   498  						{"B/main.go", pkg("B") + decl("B1"), nil},
   499  						{"+git", "D1", nil},
   500  						{"A/main.go", pkg("A") + decl("A2"), nil},
   501  						{"B/main.go", pkg("B") + decl("B2"), nil},
   502  						{"+git", "D2", nil},
   503  					},
   504  				},
   505  				{
   506  					"C",
   507  					"",
   508  					[]*node{
   509  						{"main.go", pkg("main", "D/A", "D/B"), nil},
   510  						{"Godeps/Godeps.json", godeps("C", "D/A", "D1"), nil},
   511  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   512  						{"+git", "", nil},
   513  					},
   514  				},
   515  			},
   516  			want: []*node{
   517  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   518  			},
   519  			wdep: Godeps{
   520  				ImportPath: "C",
   521  				Deps: []Dependency{
   522  					{ImportPath: "D/A", Comment: "D1"},
   523  				},
   524  			},
   525  			werr: true,
   526  		},
   527  		{ // 12 - replace dependency from same repo parent dir
   528  			cwd: "C",
   529  			start: []*node{
   530  				{
   531  					"D",
   532  					"",
   533  					[]*node{
   534  						{"main.go", pkg("D") + decl("D1"), nil},
   535  						{"A/main.go", pkg("A") + decl("A1"), nil},
   536  						{"+git", "D1", nil},
   537  					},
   538  				},
   539  				{
   540  					"C",
   541  					"",
   542  					[]*node{
   543  						{"main.go", pkg("main", "D"), nil},
   544  						{"Godeps/Godeps.json", godeps("C", "D/A", "D1"), nil},
   545  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   546  						{"+git", "", nil},
   547  					},
   548  				},
   549  			},
   550  			want: []*node{
   551  				{"C/Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   552  				{"C/Godeps/_workspace/src/D/A/main.go", "(absent)", nil},
   553  			},
   554  			wdep: Godeps{
   555  				ImportPath: "C",
   556  				Deps: []Dependency{
   557  					{ImportPath: "D", Comment: "D1"},
   558  				},
   559  			},
   560  		},
   561  		{ // 13 - replace dependency from same repo parent dir, require same version
   562  			cwd: "C",
   563  			start: []*node{
   564  				{
   565  					"D",
   566  					"",
   567  					[]*node{
   568  						{"main.go", pkg("D") + decl("D1"), nil},
   569  						{"A/main.go", pkg("A") + decl("A1"), nil},
   570  						{"+git", "D1", nil},
   571  						{"main.go", pkg("D") + decl("D2"), nil},
   572  						{"A/main.go", pkg("A") + decl("A2"), nil},
   573  						{"+git", "D2", nil},
   574  					},
   575  				},
   576  				{
   577  					"C",
   578  					"",
   579  					[]*node{
   580  						{"main.go", pkg("main", "D"), nil},
   581  						{"Godeps/Godeps.json", godeps("C", "D/A", "D1"), nil},
   582  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   583  						{"+git", "", nil},
   584  					},
   585  				},
   586  			},
   587  			want: []*node{
   588  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   589  			},
   590  			wdep: Godeps{
   591  				ImportPath: "C",
   592  				Deps: []Dependency{
   593  					{ImportPath: "D/A", Comment: "D1"},
   594  				},
   595  			},
   596  			werr: true,
   597  		},
   598  		{ // 14 - replace dependency from same repo child dir
   599  			cwd: "C",
   600  			start: []*node{
   601  				{
   602  					"D",
   603  					"",
   604  					[]*node{
   605  						{"main.go", pkg("D") + decl("D1"), nil},
   606  						{"A/main.go", pkg("A") + decl("A1"), nil},
   607  						{"+git", "D1", nil},
   608  					},
   609  				},
   610  				{
   611  					"C",
   612  					"",
   613  					[]*node{
   614  						{"main.go", pkg("main", "D/A"), nil},
   615  						{"Godeps/Godeps.json", godeps("C", "D", "D1"), nil},
   616  						{"Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   617  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   618  						{"+git", "", nil},
   619  					},
   620  				},
   621  			},
   622  			want: []*node{
   623  				{"C/Godeps/_workspace/src/D/main.go", "(absent)", nil},
   624  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   625  			},
   626  			wdep: Godeps{
   627  				ImportPath: "C",
   628  				Deps: []Dependency{
   629  					{ImportPath: "D/A", Comment: "D1"},
   630  				},
   631  			},
   632  		},
   633  		{ // 15 - replace dependency from same repo child dir, require same version
   634  			cwd: "C",
   635  			start: []*node{
   636  				{
   637  					"D",
   638  					"",
   639  					[]*node{
   640  						{"main.go", pkg("D") + decl("D1"), nil},
   641  						{"A/main.go", pkg("A") + decl("A1"), nil},
   642  						{"+git", "D1", nil},
   643  						{"main.go", pkg("D") + decl("D2"), nil},
   644  						{"A/main.go", pkg("A") + decl("A2"), nil},
   645  						{"+git", "D2", nil},
   646  					},
   647  				},
   648  				{
   649  					"C",
   650  					"",
   651  					[]*node{
   652  						{"main.go", pkg("main", "D/A"), nil},
   653  						{"Godeps/Godeps.json", godeps("C", "D", "D1"), nil},
   654  						{"Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   655  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   656  						{"+git", "", nil},
   657  					},
   658  				},
   659  			},
   660  			want: []*node{
   661  				{"C/Godeps/_workspace/src/D/main.go", pkg("D") + decl("D1"), nil},
   662  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   663  			},
   664  			wdep: Godeps{
   665  				ImportPath: "C",
   666  				Deps: []Dependency{
   667  					{ImportPath: "D", Comment: "D1"},
   668  				},
   669  			},
   670  			werr: true,
   671  		},
   672  		{ // 16 - Bug https://github.com/tools/godep/issues/85
   673  			cwd: "C",
   674  			start: []*node{
   675  				{
   676  					"D",
   677  					"",
   678  					[]*node{
   679  						{"A/main.go", pkg("A") + decl("A1"), nil},
   680  						{"B/main.go", pkg("B") + decl("B1"), nil},
   681  						{"+git", "D1", nil},
   682  						{"A/main.go", pkg("A") + decl("A2"), nil},
   683  						{"B/main.go", pkg("B") + decl("B2"), nil},
   684  						{"+git", "D2", nil},
   685  					},
   686  				},
   687  				{
   688  					"C",
   689  					"",
   690  					[]*node{
   691  						{"main.go", pkg("main", "D/A", "D/B"), nil},
   692  						{"Godeps/Godeps.json", godeps("C", "D/A", "D1", "D/B", "D1"), nil},
   693  						{"Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   694  						{"Godeps/_workspace/src/D/B/main.go", pkg("B") + decl("B1"), nil},
   695  						{"+git", "", nil},
   696  					},
   697  				},
   698  			},
   699  			want: []*node{
   700  				{"C/Godeps/_workspace/src/D/A/main.go", pkg("A") + decl("A1"), nil},
   701  				{"C/Godeps/_workspace/src/D/B/main.go", pkg("B") + decl("B1"), nil},
   702  			},
   703  			wdep: Godeps{
   704  				ImportPath: "C",
   705  				Deps: []Dependency{
   706  					{ImportPath: "D/A", Comment: "D1"},
   707  					{ImportPath: "D/B", Comment: "D1"},
   708  				},
   709  			},
   710  		},
   711  		{ // 17 - intermediate dependency that uses godep save -r, main -r=false
   712  			cwd: "C",
   713  			start: []*node{
   714  				{
   715  					"C",
   716  					"",
   717  					[]*node{
   718  						{"main.go", pkg("main", "D"), nil},
   719  						{"+git", "", nil},
   720  					},
   721  				},
   722  				{
   723  					"T",
   724  					"",
   725  					[]*node{
   726  						{"main.go", pkg("T"), nil},
   727  						{"+git", "T1", nil},
   728  					},
   729  				},
   730  				{
   731  					"D",
   732  					"",
   733  					[]*node{
   734  						{"main.go", pkg("D", "D/Godeps/_workspace/src/T"), nil},
   735  						{"Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   736  						{"Godeps/Godeps.json", godeps("D", "T", "T1"), nil},
   737  						{"+git", "D1", nil},
   738  					},
   739  				},
   740  			},
   741  			want: []*node{
   742  				{"C/main.go", pkg("main", "D"), nil},
   743  				{"C/Godeps/_workspace/src/D/main.go", pkg("D", "T"), nil},
   744  				{"C/Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   745  			},
   746  			wdep: Godeps{
   747  				ImportPath: "C",
   748  				Deps: []Dependency{
   749  					{ImportPath: "D", Comment: "D1"},
   750  					{ImportPath: "T", Comment: "T1"},
   751  				},
   752  			},
   753  		},
   754  		{ // 18 - intermediate dependency that uses godep save -r, main -r too
   755  			cwd:   "C",
   756  			flagR: true,
   757  			start: []*node{
   758  				{
   759  					"C",
   760  					"",
   761  					[]*node{
   762  						{"main.go", pkg("main", "D"), nil},
   763  						{"+git", "", nil},
   764  					},
   765  				},
   766  				{
   767  					"T",
   768  					"",
   769  					[]*node{
   770  						{"main.go", pkg("T"), nil},
   771  						{"+git", "T1", nil},
   772  					},
   773  				},
   774  				{
   775  					"D",
   776  					"",
   777  					[]*node{
   778  						{"main.go", pkg("D", "D/Godeps/_workspace/src/T"), nil},
   779  						{"Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   780  						{"Godeps/Godeps.json", godeps("D", "T", "T1"), nil},
   781  						{"+git", "D1", nil},
   782  					},
   783  				},
   784  			},
   785  			want: []*node{
   786  				{"C/main.go", pkg("main", "C/Godeps/_workspace/src/D"), nil},
   787  				{"C/Godeps/_workspace/src/D/main.go", pkg("D", "C/Godeps/_workspace/src/T"), nil},
   788  				{"C/Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   789  			},
   790  			wdep: Godeps{
   791  				ImportPath: "C",
   792  				Deps: []Dependency{
   793  					{ImportPath: "D", Comment: "D1"},
   794  					{ImportPath: "T", Comment: "T1"},
   795  				},
   796  			},
   797  		},
   798  		{ // 19 - rewrite files under build constraints
   799  			cwd:   "C",
   800  			flagR: true,
   801  			start: []*node{
   802  				{
   803  					"C",
   804  					"",
   805  					[]*node{
   806  						{"main.go", pkg("main", "D"), nil},
   807  						{"x.go", "// +build x\n\n" + pkg("main", "D"), nil},
   808  						{"+git", "", nil},
   809  					},
   810  				},
   811  				{
   812  					"D",
   813  					"",
   814  					[]*node{
   815  						{"main.go", pkg("D"), nil},
   816  						{"+git", "D1", nil},
   817  					},
   818  				},
   819  			},
   820  			want: []*node{
   821  				{"C/main.go", pkg("main", "C/Godeps/_workspace/src/D"), nil},
   822  				{"C/x.go", "// +build x\n\n" + pkg("main", "C/Godeps/_workspace/src/D"), nil},
   823  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
   824  			},
   825  			wdep: Godeps{
   826  				ImportPath: "C",
   827  				Deps: []Dependency{
   828  					{ImportPath: "D", Comment: "D1"},
   829  				},
   830  			},
   831  		},
   832  		{ // 20 - include flattened, rewritten deps
   833  			cwd: "C",
   834  			start: []*node{
   835  				{
   836  					"C",
   837  					"",
   838  					[]*node{
   839  						{"main.go", pkg("main", "D", "T"), nil},
   840  						{"+git", "", nil},
   841  					},
   842  				},
   843  				{
   844  					"T",
   845  					"",
   846  					[]*node{
   847  						{"main.go", pkg("T"), nil},
   848  						{"X/main.go", pkg("X"), nil},
   849  						{"+git", "T1", nil},
   850  					},
   851  				},
   852  				{
   853  					"D",
   854  					"",
   855  					[]*node{
   856  						{"main.go", pkg("D", "D/Godeps/_workspace/src/T/X"), nil},
   857  						{"Godeps/_workspace/src/T/X/main.go", pkg("X"), nil},
   858  						{"Godeps/Godeps.json", godeps("D", "T/X", "T1"), nil},
   859  						{"+git", "D1", nil},
   860  					},
   861  				},
   862  			},
   863  			want: []*node{
   864  				{"C/main.go", pkg("main", "D", "T"), nil},
   865  				{"C/Godeps/_workspace/src/D/main.go", pkg("D", "T/X"), nil},
   866  				{"C/Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   867  				{"C/Godeps/_workspace/src/T/X/main.go", pkg("X"), nil},
   868  			},
   869  			wdep: Godeps{
   870  				ImportPath: "C",
   871  				Deps: []Dependency{
   872  					{ImportPath: "D", Comment: "D1"},
   873  					{ImportPath: "T", Comment: "T1"},
   874  					{ImportPath: "T/X", Comment: "T1"},
   875  				},
   876  			},
   877  		},
   878  		{ // 21 - find transitive dependencies across roots
   879  			cwd:   "C",
   880  			flagR: true,
   881  			altstart: []*node{
   882  				{
   883  					"T",
   884  					"",
   885  					[]*node{
   886  						{"main.go", pkg("T"), nil},
   887  						{"+git", "T1", nil},
   888  					},
   889  				},
   890  			},
   891  			start: []*node{
   892  				{
   893  					"C",
   894  					"",
   895  					[]*node{
   896  						{"main.go", pkg("main", "D"), nil},
   897  						{"+git", "", nil},
   898  					},
   899  				},
   900  				{
   901  					"D",
   902  					"",
   903  					[]*node{
   904  						{"main.go", pkg("D", "D/Godeps/_workspace/src/T"), nil},
   905  						{"Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   906  						{"Godeps/Godeps.json", godeps("D", "T", "T1"), nil},
   907  						{"+git", "D1", nil},
   908  					},
   909  				},
   910  			},
   911  			want: []*node{
   912  				{"C/main.go", pkg("main", "C/Godeps/_workspace/src/D"), nil},
   913  				{"C/Godeps/_workspace/src/D/main.go", pkg("D", "C/Godeps/_workspace/src/T"), nil},
   914  				{"C/Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   915  			},
   916  			wdep: Godeps{
   917  				ImportPath: "C",
   918  				Deps: []Dependency{
   919  					{ImportPath: "D", Comment: "D1"},
   920  					{ImportPath: "T", Comment: "T1"},
   921  				},
   922  			},
   923  		},
   924  		{ // 22 - pull in minimal dependencies, see https://github.com/tools/godep/issues/93
   925  			cwd:   "C",
   926  			flagR: true,
   927  			start: []*node{
   928  				{
   929  					"C",
   930  					"",
   931  					[]*node{
   932  						{"main.go", pkg("main", "D/X"), nil},
   933  						{"+git", "", nil},
   934  					},
   935  				},
   936  				{
   937  					"T",
   938  					"",
   939  					[]*node{
   940  						{"main.go", pkg("T"), nil},
   941  						{"+git", "T1", nil},
   942  					},
   943  				},
   944  				{
   945  					"D",
   946  					"",
   947  					[]*node{
   948  						{"main.go", pkg("D", "D/Godeps/_workspace/src/T"), nil},
   949  						{"X/main.go", pkg("X"), nil},
   950  						{"Godeps/_workspace/src/T/main.go", pkg("T"), nil},
   951  						{"Godeps/Godeps.json", godeps("D", "T", "T1"), nil},
   952  						{"+git", "D1", nil},
   953  					},
   954  				},
   955  			},
   956  			want: []*node{
   957  				{"C/main.go", pkg("main", "C/Godeps/_workspace/src/D/X"), nil},
   958  				{"C/Godeps/_workspace/src/D/X/main.go", pkg("X"), nil},
   959  			},
   960  			wdep: Godeps{
   961  				ImportPath: "C",
   962  				Deps: []Dependency{
   963  					{ImportPath: "D/X", Comment: "D1"},
   964  				},
   965  			},
   966  		},
   967  		{ // 23 - don't require packages contained in dest to be in VCS
   968  			cwd:   "C",
   969  			flagR: true,
   970  			start: []*node{
   971  				{
   972  					"C",
   973  					"",
   974  					[]*node{
   975  						{"main.go", pkg("main"), nil},
   976  					},
   977  				},
   978  			},
   979  			want: []*node{
   980  				{"C/main.go", pkg("main"), nil},
   981  			},
   982  			wdep: Godeps{
   983  				ImportPath: "C",
   984  				Deps:       []Dependency{},
   985  			},
   986  		},
   987  		{ // 24 - include command line packages in the set to be copied
   988  			cwd:   "C",
   989  			args:  []string{"P"},
   990  			flagR: true,
   991  			start: []*node{
   992  				{
   993  					"C",
   994  					"",
   995  					[]*node{
   996  						{"main.go", pkg("main"), nil},
   997  					},
   998  				},
   999  				{
  1000  					"P",
  1001  					"",
  1002  					[]*node{
  1003  						{"main.go", pkg("P"), nil},
  1004  						{"+git", "P1", nil},
  1005  					},
  1006  				},
  1007  			},
  1008  			want: []*node{
  1009  				{"C/main.go", pkg("main"), nil},
  1010  				{"C/Godeps/_workspace/src/P/main.go", pkg("P"), nil},
  1011  			},
  1012  			wdep: Godeps{
  1013  				ImportPath: "C",
  1014  				Deps: []Dependency{
  1015  					{ImportPath: "P", Comment: "P1"},
  1016  				},
  1017  			},
  1018  		},
  1019  		{ // 25 - don't copy untracked files in the source directory
  1020  			cwd: "C",
  1021  			start: []*node{
  1022  				{
  1023  					"C",
  1024  					"",
  1025  					[]*node{
  1026  						{"main.go", pkg("main", "D"), nil},
  1027  						{"+git", "", nil},
  1028  					},
  1029  				},
  1030  				{
  1031  					"D",
  1032  					"",
  1033  					[]*node{
  1034  						{"main.go", pkg("D"), nil},
  1035  						{"+git", "D1", nil},
  1036  						{"untracked", "garbage", nil},
  1037  					},
  1038  				},
  1039  			},
  1040  			want: []*node{
  1041  				{"C/main.go", pkg("main", "D"), nil},
  1042  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
  1043  				{"C/Godeps/_workspace/src/D/untracked", "(absent)", nil},
  1044  			},
  1045  			wdep: Godeps{
  1046  				ImportPath: "C",
  1047  				Deps: []Dependency{
  1048  					{ImportPath: "D", Comment: "D1"},
  1049  				},
  1050  			},
  1051  		},
  1052  		{ // 26 - don't copy _test.go files
  1053  			cwd: "C",
  1054  			start: []*node{
  1055  				{
  1056  					"C",
  1057  					"",
  1058  					[]*node{
  1059  						{"main.go", pkg("main", "D"), nil},
  1060  						{"+git", "", nil},
  1061  					},
  1062  				},
  1063  				{
  1064  					"D",
  1065  					"",
  1066  					[]*node{
  1067  						{"main.go", pkg("D"), nil},
  1068  						{"main_test.go", pkg("D"), nil},
  1069  						{"+git", "D1", nil},
  1070  					},
  1071  				},
  1072  			},
  1073  			want: []*node{
  1074  				{"C/main.go", pkg("main", "D"), nil},
  1075  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
  1076  			},
  1077  			wdep: Godeps{
  1078  				ImportPath: "C",
  1079  				Deps: []Dependency{
  1080  					{ImportPath: "D", Comment: "D1"},
  1081  				},
  1082  			},
  1083  		},
  1084  		{ // 27 - do copy _test.go files
  1085  			cwd:   "C",
  1086  			flagT: true,
  1087  			start: []*node{
  1088  				{
  1089  					"C",
  1090  					"",
  1091  					[]*node{
  1092  						{"main.go", pkg("main", "D"), nil},
  1093  						{"+git", "", nil},
  1094  					},
  1095  				},
  1096  				{
  1097  					"D",
  1098  					"",
  1099  					[]*node{
  1100  						{"main.go", pkg("D"), nil},
  1101  						{"main_test.go", pkg("D"), nil},
  1102  						{"+git", "D1", nil},
  1103  					},
  1104  				},
  1105  			},
  1106  			want: []*node{
  1107  				{"C/main.go", pkg("main", "D"), nil},
  1108  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
  1109  				{"C/Godeps/_workspace/src/D/main_test.go", pkg("D"), nil},
  1110  			},
  1111  			wdep: Godeps{
  1112  				ImportPath: "C",
  1113  				Deps: []Dependency{
  1114  					{ImportPath: "D", Comment: "D1"},
  1115  				},
  1116  			},
  1117  		},
  1118  		{ // 28 - Copy legal files in parent and dependency directory
  1119  			cwd: "C",
  1120  			start: []*node{
  1121  				{
  1122  					"C",
  1123  					"",
  1124  					[]*node{
  1125  						{"main.go", pkg("main", "D/P", "D/Q"), nil},
  1126  						{"+git", "", nil},
  1127  					},
  1128  				},
  1129  				{
  1130  					"D",
  1131  					"",
  1132  					[]*node{
  1133  						{"LICENSE", license(), nil},
  1134  						{"P/main.go", pkg("P"), nil},
  1135  						{"P/LICENSE", license(), nil},
  1136  						{"Godeps/_workspace/src/E/LICENSE", license(), nil},
  1137  						{"Godeps/_workspace/src/E/main.go", pkg("E"), nil},
  1138  						{"Q/main.go", pkg("Q"), nil},
  1139  						{"Z/main.go", pkg("Z"), nil},
  1140  						{"Z/LICENSE", license(), nil},
  1141  						{"+git", "D1", nil},
  1142  					},
  1143  				},
  1144  			},
  1145  			want: []*node{
  1146  				{"C/main.go", pkg("main", "D/P", "D/Q"), nil},
  1147  				{"C/Godeps/_workspace/src/D/LICENSE", license(), nil},
  1148  				{"C/Godeps/_workspace/src/D/P/main.go", pkg("P"), nil},
  1149  				{"C/Godeps/_workspace/src/D/P/LICENSE", license(), nil},
  1150  				{"C/Godeps/_workspace/src/D/Q/main.go", pkg("Q"), nil},
  1151  				{"C/Godeps/_workspace/src/D/Godeps/_workspace/src/E/LICENSE", "(absent)", nil}, // E is also not used, technically this wouldn't even be here
  1152  				{"C/Godeps/_workspace/src/Z/LICENSE", "(absent)", nil},                         // Z Isn't a dep, so shouldn't have a LICENSE file.
  1153  			},
  1154  			wdep: Godeps{
  1155  				ImportPath: "C",
  1156  				Deps: []Dependency{
  1157  					{ImportPath: "D/P", Comment: "D1"},
  1158  					{ImportPath: "D/Q", Comment: "D1"},
  1159  				},
  1160  			},
  1161  		},
  1162  		{ // 29 - two packages, one in a subdirectory that's included only on other OS
  1163  			cwd: "C",
  1164  			start: []*node{
  1165  				{
  1166  					"C",
  1167  					"",
  1168  					[]*node{
  1169  						{"main.go", pkg("main", "D"), nil},
  1170  						{"+git", "", nil},
  1171  					},
  1172  				},
  1173  				{
  1174  					"D",
  1175  					"",
  1176  					[]*node{
  1177  						{"main.go", pkgWithImpossibleTag("D", "D/P"), nil},
  1178  						{"P/main.go", pkg("P"), nil},
  1179  						{"+git", "D1", nil},
  1180  					},
  1181  				},
  1182  			},
  1183  			want: []*node{
  1184  				{"C/main.go", pkg("main", "D"), nil},
  1185  				{"C/Godeps/_workspace/src/D/main.go", pkgWithImpossibleTag("D", "D/P"), nil},
  1186  				{"C/Godeps/_workspace/src/D/P/main.go", pkg("P"), nil},
  1187  			},
  1188  			wdep: Godeps{
  1189  				ImportPath: "C",
  1190  				Deps: []Dependency{
  1191  					{ImportPath: "D", Comment: "D1"},
  1192  					{ImportPath: "D/P", Comment: "D1"},
  1193  				},
  1194  			},
  1195  		},
  1196  		{ // 30 - build +ignore: #345, #348
  1197  			cwd: "C",
  1198  			start: []*node{
  1199  				{
  1200  					"C",
  1201  					"",
  1202  					[]*node{
  1203  						{"main.go", pkg("main", "D"), nil},
  1204  						{"+git", "", nil},
  1205  					},
  1206  				},
  1207  				{
  1208  					"D",
  1209  					"",
  1210  					[]*node{
  1211  						{"main.go", pkg("D"), nil},
  1212  						{"ignore.go", pkgWithTags("M", "ignore"), nil},
  1213  						{"+git", "D1", nil},
  1214  					},
  1215  				},
  1216  			},
  1217  			want: []*node{
  1218  				{"C/main.go", pkg("main", "D"), nil},
  1219  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
  1220  				{"C/Godeps/_workspace/src/D/ignore.go", pkgWithTags("M", "ignore"), nil},
  1221  			},
  1222  			wdep: Godeps{
  1223  				ImportPath: "C",
  1224  				Deps: []Dependency{
  1225  					{ImportPath: "D", Comment: "D1"},
  1226  				},
  1227  			},
  1228  		},
  1229  		{ // 31 - No buildable . #346
  1230  			cwd:  "C",
  1231  			args: []string{"./..."},
  1232  			start: []*node{
  1233  				{
  1234  					"C",
  1235  					"",
  1236  					[]*node{
  1237  						{"sub/main.go", pkg("main"), nil},
  1238  						{"+git", "C", nil},
  1239  					},
  1240  				},
  1241  			},
  1242  			want: []*node{
  1243  				{"C/sub/main.go", pkg("main"), nil},
  1244  			},
  1245  			wdep: Godeps{
  1246  				ImportPath: "C",
  1247  				Deps:       []Dependency{},
  1248  				Packages:   []string{"./..."},
  1249  			},
  1250  		},
  1251  		{ // 32 - ignore `// +build appengine` as well for now: #353
  1252  			cwd: "C",
  1253  			start: []*node{
  1254  				{
  1255  					"C",
  1256  					"",
  1257  					[]*node{
  1258  						{"main.go", pkg("main", "D"), nil},
  1259  						{"+git", "", nil},
  1260  					},
  1261  				},
  1262  				{
  1263  					"D",
  1264  					"",
  1265  					[]*node{
  1266  						{"main.go", pkg("D"), nil},
  1267  						{"ignore.go", pkgWithTags("M", "appengine"), nil},
  1268  						{"+git", "D1", nil},
  1269  					},
  1270  				},
  1271  			},
  1272  			want: []*node{
  1273  				{"C/main.go", pkg("main", "D"), nil},
  1274  				{"C/Godeps/_workspace/src/D/main.go", pkg("D"), nil},
  1275  				{"C/Godeps/_workspace/src/D/ignore.go", pkgWithTags("M", "appengine"), nil},
  1276  			},
  1277  			wdep: Godeps{
  1278  				ImportPath: "C",
  1279  				Deps: []Dependency{
  1280  					{ImportPath: "D", Comment: "D1"},
  1281  				},
  1282  			},
  1283  		},
  1284  		{ // 33 - -r does not modify packages outside the project
  1285  			cwd:   "C",
  1286  			args:  []string{"./...", "P", "CS"},
  1287  			flagR: true,
  1288  			start: []*node{
  1289  				{
  1290  					"C",
  1291  					"",
  1292  					[]*node{
  1293  						{"main.go", pkg("main"), nil},
  1294  					},
  1295  				},
  1296  				{
  1297  					"CS", // tricky name for prefix matching
  1298  					"",
  1299  					[]*node{
  1300  						{"main.go", pkg("main", "D"), nil},
  1301  						{"+git", "CS1", nil},
  1302  					},
  1303  				},
  1304  				{
  1305  					"P",
  1306  					"",
  1307  					[]*node{
  1308  						{"main.go", pkg("main", "D"), nil},
  1309  						{"+git", "P1", nil},
  1310  					},
  1311  				},
  1312  				{
  1313  					"D",
  1314  					"",
  1315  					[]*node{
  1316  						{"lib.go", pkg("D"), nil},
  1317  						{"+git", "D1", nil},
  1318  					},
  1319  				},
  1320  			},
  1321  			want: []*node{
  1322  				{"C/main.go", pkg("main"), nil},
  1323  				{"C/Godeps/_workspace/src/CS/main.go", pkg("main", "C/Godeps/_workspace/src/D"), nil},
  1324  				{"C/Godeps/_workspace/src/P/main.go", pkg("main", "C/Godeps/_workspace/src/D"), nil},
  1325  				{"C/Godeps/_workspace/src/D/lib.go", pkg("D"), nil},
  1326  				// unmodified external projects
  1327  				{"D/lib.go", pkg("D"), nil},
  1328  				{"CS/main.go", pkg("main", "D"), nil},
  1329  				{"P/main.go", pkg("main", "D"), nil},
  1330  			},
  1331  			wdep: Godeps{
  1332  				ImportPath: "C",
  1333  				Deps: []Dependency{
  1334  					{ImportPath: "CS", Comment: "CS1"},
  1335  					{ImportPath: "D", Comment: "D1"},
  1336  					{ImportPath: "P", Comment: "P1"},
  1337  				},
  1338  			},
  1339  		},
  1340  		{ // 34 - vendor (#1) on, simple case, one dependency
  1341  			vendor: true,
  1342  			cwd:    "C",
  1343  			start: []*node{
  1344  				{
  1345  					"C",
  1346  					"",
  1347  					[]*node{
  1348  						{"main.go", pkg("main", "D"), nil},
  1349  						{"+git", "", nil},
  1350  					},
  1351  				},
  1352  				{
  1353  					"D",
  1354  					"",
  1355  					[]*node{
  1356  						{"main.go", pkg("D"), nil},
  1357  						{"+git", "D1", nil},
  1358  					},
  1359  				},
  1360  			},
  1361  			want: []*node{
  1362  				{"C/main.go", pkg("main", "D"), nil},
  1363  				{"C/vendor/D/main.go", pkg("D"), nil},
  1364  			},
  1365  			wdep: Godeps{
  1366  				ImportPath: "C",
  1367  				Deps: []Dependency{
  1368  					{ImportPath: "D", Comment: "D1"},
  1369  				},
  1370  			},
  1371  		},
  1372  		{ // 35 - vendor (#4) transitive dependency
  1373  			vendor: true,
  1374  			cwd:    "C",
  1375  			start: []*node{
  1376  				{
  1377  					"C",
  1378  					"",
  1379  					[]*node{
  1380  						{"main.go", pkg("main", "D"), nil},
  1381  						{"+git", "", nil},
  1382  					},
  1383  				},
  1384  				{
  1385  					"D",
  1386  					"",
  1387  					[]*node{
  1388  						{"main.go", pkg("D", "T"), nil},
  1389  						{"+git", "D1", nil},
  1390  					},
  1391  				},
  1392  				{
  1393  					"T",
  1394  					"",
  1395  					[]*node{
  1396  						{"main.go", pkg("T"), nil},
  1397  						{"+git", "T1", nil},
  1398  					},
  1399  				},
  1400  			},
  1401  			want: []*node{
  1402  				{"C/main.go", pkg("main", "D"), nil},
  1403  				{"C/vendor/D/main.go", pkg("D", "T"), nil},
  1404  				{"C/vendor/T/main.go", pkg("T"), nil},
  1405  			},
  1406  			wdep: Godeps{
  1407  				ImportPath: "C",
  1408  				Deps: []Dependency{
  1409  					{ImportPath: "D", Comment: "D1"},
  1410  					{ImportPath: "T", Comment: "T1"},
  1411  				},
  1412  			},
  1413  		},
  1414  		{ // 36 vendor (#21) find transitive dependencies across roots
  1415  			vendor: true,
  1416  			cwd:    "C",
  1417  			altstart: []*node{
  1418  				{
  1419  					"T",
  1420  					"",
  1421  					[]*node{
  1422  						{"main.go", pkg("T"), nil},
  1423  						{"+git", "T1", nil},
  1424  					},
  1425  				},
  1426  			},
  1427  			start: []*node{
  1428  				{
  1429  					"C",
  1430  					"",
  1431  					[]*node{
  1432  						{"main.go", pkg("main", "D"), nil},
  1433  						{"+git", "", nil},
  1434  					},
  1435  				},
  1436  				{
  1437  					"D",
  1438  					"",
  1439  					[]*node{
  1440  						{"main.go", pkg("D", "T"), nil},
  1441  						{"vendor/T/main.go", pkg("T"), nil},
  1442  						{"Godeps/Godeps.json", godeps("D", "T", "T1"), nil},
  1443  						{"+git", "D1", nil},
  1444  					},
  1445  				},
  1446  			},
  1447  			want: []*node{
  1448  				{"C/main.go", pkg("main", "D"), nil},
  1449  				{"C/vendor/D/main.go", pkg("D", "T"), nil},
  1450  				{"C/vendor/T/main.go", pkg("T"), nil},
  1451  			},
  1452  			wdep: Godeps{
  1453  				ImportPath: "C",
  1454  				Deps: []Dependency{
  1455  					{ImportPath: "D", Comment: "D1"},
  1456  					{ImportPath: "T", Comment: "T1"},
  1457  				},
  1458  			},
  1459  		},
  1460  		{ // 37 Do not copy in sub directories that aren't required
  1461  			vendor: true,
  1462  			cwd:    "C",
  1463  			start: []*node{
  1464  				{
  1465  					"C",
  1466  					"",
  1467  					[]*node{
  1468  						{"main.go", pkg("main", "D"), nil},
  1469  						{"+git", "", nil},
  1470  					},
  1471  				},
  1472  				{
  1473  					"D",
  1474  					"",
  1475  					[]*node{
  1476  						{"main.go", pkg("D"), nil},
  1477  						{"sub/main.go", pkg("sub"), nil},
  1478  						{"sub/sub/main.go", pkg("subsub"), nil},
  1479  						{"+git", "D1", nil},
  1480  					},
  1481  				},
  1482  			},
  1483  			want: []*node{
  1484  				{"C/main.go", pkg("main", "D"), nil},
  1485  				{"C/vendor/D/main.go", pkg("D"), nil},
  1486  				{"C/vendor/D/sub/main.go", "(absent)", nil},
  1487  				{"C/vendor/D/sub/sub/main.go", "(absent)", nil},
  1488  			},
  1489  			wdep: Godeps{
  1490  				ImportPath: "C",
  1491  				Deps: []Dependency{
  1492  					{ImportPath: "D", Comment: "D1"},
  1493  				},
  1494  			},
  1495  		},
  1496  	}
  1497  
  1498  	wd, err := os.Getwd()
  1499  	if err != nil {
  1500  		t.Fatal(err)
  1501  	}
  1502  	const scratch = "godeptest"
  1503  	defer os.RemoveAll(scratch)
  1504  	for pos, test := range cases {
  1505  		setGlobals(test.vendor)
  1506  
  1507  		err = os.RemoveAll(scratch)
  1508  		if err != nil {
  1509  			t.Fatal(err)
  1510  		}
  1511  		altsrc := filepath.Join(scratch, "r2", "src")
  1512  		if test.altstart != nil {
  1513  			makeTree(t, &node{altsrc, "", test.altstart}, "")
  1514  		}
  1515  		src := filepath.Join(scratch, "r1", "src")
  1516  		makeTree(t, &node{src, "", test.start}, altsrc)
  1517  		dir := filepath.Join(wd, src, test.cwd)
  1518  		err = os.Chdir(dir)
  1519  		if err != nil {
  1520  			panic(err)
  1521  		}
  1522  		root1 := filepath.Join(wd, scratch, "r1")
  1523  		root2 := filepath.Join(wd, scratch, "r2")
  1524  		setGOPATH(root1, root2)
  1525  		saveR = test.flagR
  1526  		saveT = test.flagT
  1527  		err = save(test.args)
  1528  		if g := err != nil; g != test.werr {
  1529  			if err != nil {
  1530  				t.Log(pos, err)
  1531  			}
  1532  			t.Errorf("%d save err = %v want %v", pos, g, test.werr)
  1533  		}
  1534  		err = os.Chdir(wd)
  1535  		if err != nil {
  1536  			panic(err)
  1537  		}
  1538  
  1539  		checkTree(t, pos, &node{src, "", test.want})
  1540  
  1541  		f, err := os.Open(filepath.Join(dir, "Godeps/Godeps.json"))
  1542  		if err != nil {
  1543  			t.Error(err)
  1544  		}
  1545  		g := new(Godeps)
  1546  		err = json.NewDecoder(f).Decode(g)
  1547  		if err != nil {
  1548  			t.Error(err)
  1549  		}
  1550  		f.Close()
  1551  
  1552  		if g.ImportPath != test.wdep.ImportPath {
  1553  			t.Errorf("%d ImportPath = %s want %s", pos, g.ImportPath, test.wdep.ImportPath)
  1554  		}
  1555  		for i := range g.Deps {
  1556  			g.Deps[i].Rev = ""
  1557  		}
  1558  		if !reflect.DeepEqual(g.Deps, test.wdep.Deps) {
  1559  			t.Errorf("%d Deps = %v want %v", pos, g.Deps, test.wdep.Deps)
  1560  		}
  1561  	}
  1562  }
  1563  
  1564  func makeTree(t *testing.T, tree *node, altpath string) (gopath string) {
  1565  	walkTree(tree, tree.path, func(path string, n *node) {
  1566  		g, isGodeps := n.body.(*Godeps)
  1567  		body, _ := n.body.(string)
  1568  		switch {
  1569  		case isGodeps:
  1570  			for i, dep := range g.Deps {
  1571  				rel := filepath.FromSlash(dep.ImportPath)
  1572  				dir := filepath.Join(tree.path, rel)
  1573  				if _, err := os.Stat(dir); os.IsNotExist(err) {
  1574  					dir = filepath.Join(altpath, rel)
  1575  				}
  1576  				tag := dep.Comment
  1577  				rev := strings.TrimSpace(run(t, dir, "git", "rev-parse", tag))
  1578  				g.Deps[i].Rev = rev
  1579  			}
  1580  			os.MkdirAll(filepath.Dir(path), 0770)
  1581  			f, err := os.Create(path)
  1582  			if err != nil {
  1583  				t.Errorf("makeTree: %v", err)
  1584  				return
  1585  			}
  1586  			defer f.Close()
  1587  			err = json.NewEncoder(f).Encode(g)
  1588  			if err != nil {
  1589  				t.Errorf("makeTree: %v", err)
  1590  			}
  1591  		case n.path == "+git":
  1592  			dir := filepath.Dir(path)
  1593  			run(t, dir, "git", "init") // repo might already exist, but ok
  1594  			run(t, dir, "git", "add", "-A", ".")
  1595  			run(t, dir, "git", "commit", "-m", "godep")
  1596  			if body != "" {
  1597  				run(t, dir, "git", "tag", body)
  1598  			}
  1599  		case n.entries == nil && strings.HasPrefix(body, "symlink:"):
  1600  			target := strings.TrimPrefix(body, "symlink:")
  1601  			os.Symlink(target, path)
  1602  		case n.entries == nil && body == "(absent)":
  1603  			panic("is this gonna be forever")
  1604  		case n.entries == nil:
  1605  			os.MkdirAll(filepath.Dir(path), 0770)
  1606  			err := ioutil.WriteFile(path, []byte(body), 0660)
  1607  			if err != nil {
  1608  				t.Errorf("makeTree: %v", err)
  1609  			}
  1610  		default:
  1611  			os.MkdirAll(path, 0770)
  1612  		}
  1613  	})
  1614  	return gopath
  1615  }
  1616  
  1617  func checkTree(t *testing.T, pos int, want *node) {
  1618  	walkTree(want, want.path, func(path string, n *node) {
  1619  		body := n.body.(string)
  1620  		switch {
  1621  		case n.path == "+git":
  1622  			panic("is this real life")
  1623  		case n.entries == nil && strings.HasPrefix(body, "symlink:"):
  1624  			panic("why is this happening to me")
  1625  		case n.entries == nil && body == "(absent)":
  1626  			body, err := ioutil.ReadFile(path)
  1627  			if !os.IsNotExist(err) {
  1628  				t.Errorf("%d checkTree: %s = %s want absent", pos, path, string(body))
  1629  				return
  1630  			}
  1631  		case n.entries == nil:
  1632  			gbody, err := ioutil.ReadFile(path)
  1633  			if err != nil {
  1634  				t.Errorf("%d checkTree: %v", pos, err)
  1635  				return
  1636  			}
  1637  			if got := string(gbody); got != body {
  1638  				t.Errorf("%d %s = got: %q want: %q", pos, path, got, body)
  1639  			}
  1640  		default:
  1641  			os.MkdirAll(path, 0770)
  1642  		}
  1643  	})
  1644  }
  1645  
  1646  func walkTree(n *node, path string, f func(path string, n *node)) {
  1647  	f(path, n)
  1648  	for _, e := range n.entries {
  1649  		walkTree(e, filepath.Join(path, filepath.FromSlash(e.path)), f)
  1650  	}
  1651  }
  1652  
  1653  func run(t *testing.T, dir, name string, args ...string) string {
  1654  	cmd := exec.Command(name, args...)
  1655  	cmd.Dir = dir
  1656  	cmd.Stderr = os.Stderr
  1657  	out, err := cmd.Output()
  1658  	if err != nil {
  1659  		panic(name + " " + strings.Join(args, " ") + ": " + err.Error())
  1660  	}
  1661  	return string(out)
  1662  }
  1663  
  1664  func TestStripImportComment(t *testing.T) {
  1665  	var cases = []struct{ s, w string }{
  1666  		{`package foo`, `package foo`},
  1667  		{`anything else`, `anything else`},
  1668  		{`package foo // import "bar/foo"`, `package foo`},
  1669  		{`package foo /* import "bar/foo" */`, `package foo`},
  1670  		{`package  foo  //  import  "bar/foo" `, `package  foo`},
  1671  		{"package foo // import `bar/foo`", `package foo`},
  1672  		{`package foo /* import "bar/foo" */; var x int`, `package foo; var x int`},
  1673  		{`package foo // import "bar/foo" garbage`, `package foo // import "bar/foo" garbage`},
  1674  		{`package xpackage foo // import "bar/foo"`, `package xpackage foo // import "bar/foo"`},
  1675  	}
  1676  
  1677  	for _, test := range cases {
  1678  		g := string(stripImportComment([]byte(test.s)))
  1679  		if g != test.w {
  1680  			t.Errorf("stripImportComment(%q) = %q want %q", test.s, g, test.w)
  1681  		}
  1682  	}
  1683  }
  1684  
  1685  func TestCopyWithoutImportCommentLongLines(t *testing.T) {
  1686  	tmp := make([]byte, int(math.Pow(2, 16)))
  1687  	for i := range tmp {
  1688  		tmp[i] = 111 // fill it with "o"s
  1689  	}
  1690  
  1691  	iStr := `package foo` + string(tmp) + `\n`
  1692  
  1693  	o := new(bytes.Buffer)
  1694  	i := strings.NewReader(iStr)
  1695  	err := copyWithoutImportComment(o, i)
  1696  	if err != nil {
  1697  		t.Fatalf("copyWithoutImportComment errored: %s", err.Error())
  1698  	}
  1699  }