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