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