github.com/golang/dep@v0.5.4/internal/importers/govendor/importer.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package govendor 6 7 import ( 8 "encoding/json" 9 "io/ioutil" 10 "log" 11 "os" 12 "path" 13 "path/filepath" 14 "strings" 15 16 "github.com/golang/dep" 17 "github.com/golang/dep/gps" 18 "github.com/golang/dep/internal/importers/base" 19 "github.com/pkg/errors" 20 ) 21 22 const govendorDir = "vendor" 23 const govendorName = "vendor.json" 24 25 // Importer imports govendor configuration into the dep configuration format. 26 type Importer struct { 27 *base.Importer 28 29 file govendorFile 30 } 31 32 // NewImporter for govendor. 33 func NewImporter(logger *log.Logger, verbose bool, sm gps.SourceManager) *Importer { 34 return &Importer{Importer: base.NewImporter(logger, verbose, sm)} 35 } 36 37 // File is the structure of the vendor file. 38 type govendorFile struct { 39 RootPath string // Import path of vendor folder 40 Ignore string 41 Package []*govendorPackage 42 } 43 44 // Package represents each package. 45 type govendorPackage struct { 46 // See the vendor spec for definitions. 47 Origin string 48 Path string 49 Revision string 50 Version string 51 } 52 53 // Name of the importer. 54 func (g *Importer) Name() string { 55 return "govendor" 56 } 57 58 // HasDepMetadata checks if a directory contains config that the importer can handle. 59 func (g *Importer) HasDepMetadata(dir string) bool { 60 y := filepath.Join(dir, govendorDir, govendorName) 61 if _, err := os.Stat(y); err != nil { 62 return false 63 } 64 return true 65 } 66 67 // Import the config found in the directory. 68 func (g *Importer) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) { 69 err := g.load(dir) 70 if err != nil { 71 return nil, nil, err 72 } 73 74 m, l := g.convert(pr) 75 return m, l, nil 76 } 77 78 func (g *Importer) load(projectDir string) error { 79 g.Logger.Println("Detected govendor configuration file...") 80 v := filepath.Join(projectDir, govendorDir, govendorName) 81 if g.Verbose { 82 g.Logger.Printf(" Loading %s", v) 83 } 84 vb, err := ioutil.ReadFile(v) 85 if err != nil { 86 return errors.Wrapf(err, "unable to read %s", v) 87 } 88 err = json.Unmarshal(vb, &g.file) 89 if err != nil { 90 return errors.Wrapf(err, "unable to parse %s", v) 91 } 92 return nil 93 } 94 95 func (g *Importer) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock) { 96 g.Logger.Println("Converting from vendor.json...") 97 98 packages := make([]base.ImportedPackage, 0, len(g.file.Package)) 99 for _, pkg := range g.file.Package { 100 // Path must not be empty 101 if pkg.Path == "" { 102 g.Logger.Println( 103 " Warning: Skipping project. Invalid govendor configuration, Path is required", 104 ) 105 continue 106 } 107 108 // There are valid govendor configs in the wild that don't have a revision set 109 // so we are not requiring it to be set during import 110 111 ip := base.ImportedPackage{ 112 Name: pkg.Path, 113 Source: pkg.Origin, 114 LockHint: pkg.Revision, 115 } 116 packages = append(packages, ip) 117 } 118 119 g.ImportPackages(packages, true) 120 121 if len(g.file.Ignore) > 0 { 122 // Govendor has three use cases here 123 // 1. 'test' - special case for ignoring test files 124 // 2. build tags - any string without a slash (/) in it 125 // 3. path and path prefix - any string with a slash (/) in it. 126 // The path case could be a full path or just a prefix. 127 // Dep doesn't support build tags right now: https://github.com/golang/dep/issues/120 128 for _, i := range strings.Split(g.file.Ignore, " ") { 129 if !strings.Contains(i, "/") { 130 g.Logger.Printf(" Govendor was configured to ignore the %s build tag, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.", i) 131 continue 132 } 133 134 var ignorePattern string 135 _, err := g.SourceManager.DeduceProjectRoot(i) 136 if err == nil { // external package 137 ignorePattern = i 138 } else { // relative package path in the current project 139 ignorePattern = path.Join(string(pr), i) 140 } 141 142 // Convert to a a wildcard ignore 143 ignorePattern = strings.TrimRight(ignorePattern, "/") 144 ignorePattern += "*" 145 146 g.Manifest.Ignored = append(g.Manifest.Ignored, ignorePattern) 147 } 148 } 149 150 return g.Manifest, g.Lock 151 }