Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit cbc263f

Browse files
committed
Support importing glide configuration
* init imports by default unless -skip-tools is specified * glide config in dependencies is taken into account during solve
1 parent 66b1df0 commit cbc263f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+12709
-435
lines changed

Gopkg.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
name = "github.com/Masterminds/vcs"
77
version = "1.11.0"
88

9+
[[constraint]]
10+
branch = "v2"
11+
name = "github.com/go-yaml/yaml"
12+
913
[[constraint]]
1014
branch = "master"
1115
name = "github.com/pelletier/go-toml"

analyzer.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ import (
1414

1515
type Analyzer struct{}
1616

17-
func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) {
18-
// TODO: If we decide to support other tools manifest, this is where we would need
19-
// to add that support.
17+
// HasDepMetadata determines if a dep manifest exists at the specified path.
18+
func (a Analyzer) HasDepMetadata(path string) bool {
2019
mf := filepath.Join(path, ManifestName)
21-
if fileOK, err := fs.IsRegular(mf); err != nil || !fileOK {
22-
// Do not return an error, when does not exist.
20+
fileOK, err := fs.IsRegular(mf)
21+
return err == nil && fileOK
22+
}
23+
24+
func (a Analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Manifest, gps.Lock, error) {
25+
if !a.HasDepMetadata(path) {
2326
return nil, nil, nil
2427
}
25-
f, err := os.Open(mf)
28+
29+
f, err := os.Open(filepath.Join(path, ManifestName))
2630
if err != nil {
2731
return nil, nil, err
2832
}

cmd/dep/ensure.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ func getProjectConstraint(arg string, sm gps.SourceManager) (gps.ProjectConstrai
275275
arg = parts[0]
276276
versionStr = parts[1]
277277
}
278-
278+
279279
// TODO: if we decide to keep equals.....
280280

281281
// split on colon if there is a network location

cmd/dep/glide_importer.go

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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 main
6+
7+
import (
8+
"bytes"
9+
"io/ioutil"
10+
"os"
11+
"path"
12+
"path/filepath"
13+
14+
"github.com/go-yaml/yaml"
15+
"github.com/golang/dep"
16+
fb "github.com/golang/dep/internal/feedback"
17+
"github.com/golang/dep/internal/fs"
18+
"github.com/golang/dep/internal/gps"
19+
"github.com/pkg/errors"
20+
)
21+
22+
const glideYamlName = "glide.yaml"
23+
const glideLockName = "glide.lock"
24+
25+
// glideImporter imports glide configuration into the dep configuration format.
26+
type glideImporter struct {
27+
yaml glideYaml
28+
lock *glideLock
29+
30+
ctx *dep.Ctx
31+
sm gps.SourceManager
32+
}
33+
34+
func newGlideImporter(ctx *dep.Ctx, sm gps.SourceManager) *glideImporter {
35+
return &glideImporter{
36+
ctx: ctx,
37+
sm: sm,
38+
}
39+
}
40+
41+
type glideYaml struct {
42+
Name string `yaml:"package"`
43+
Ignores []string `yaml:"ignore"`
44+
ExcludeDirs []string `yaml:"excludeDirs"`
45+
Imports []glidePackage `yaml:"import"`
46+
TestImports []glidePackage `yaml:"testImport"`
47+
}
48+
49+
type glideLock struct {
50+
Imports []glideLockedPackage `yaml:"imports"`
51+
TestImports []glideLockedPackage `yaml:"testImports"`
52+
}
53+
54+
type glidePackage struct {
55+
Name string `yaml:"package"`
56+
Reference string `yaml:"version"`
57+
Repository string `yaml:"repo"`
58+
59+
// Unsupported fields that we will warn if used
60+
Subpackages []string `yaml:"subpackages"`
61+
OS string `yaml:"os"`
62+
Arch string `yaml:"arch"`
63+
}
64+
65+
type glideLockedPackage struct {
66+
Name string `yaml:"name"`
67+
Reference string `yaml:"version"`
68+
Repository string `yaml:"repo"`
69+
}
70+
71+
func (g *glideImporter) Name() string {
72+
return "glide"
73+
}
74+
75+
func (g *glideImporter) HasDepMetadata(dir string) bool {
76+
// Only require glide.yaml, the lock is optional
77+
y := filepath.Join(dir, glideYamlName)
78+
if _, err := os.Stat(y); err != nil {
79+
return false
80+
}
81+
82+
return true
83+
}
84+
85+
func (g *glideImporter) Import(dir string, pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
86+
err := g.load(dir)
87+
if err != nil {
88+
return nil, nil, err
89+
}
90+
91+
return g.convert(pr)
92+
}
93+
94+
// load the glide configuration files.
95+
func (g *glideImporter) load(projectDir string) error {
96+
g.ctx.Err.Println("Detected glide configuration files...")
97+
y := filepath.Join(projectDir, glideYamlName)
98+
if g.ctx.Loggers.Verbose {
99+
g.ctx.Loggers.Err.Printf(" Loading %s", y)
100+
}
101+
yb, err := ioutil.ReadFile(y)
102+
if err != nil {
103+
return errors.Wrapf(err, "Unable to read %s", y)
104+
}
105+
err = yaml.Unmarshal(yb, &g.yaml)
106+
if err != nil {
107+
return errors.Wrapf(err, "Unable to parse %s", y)
108+
}
109+
110+
l := filepath.Join(projectDir, glideLockName)
111+
if exists, _ := fs.IsRegular(l); exists {
112+
if g.ctx.Loggers.Verbose {
113+
g.ctx.Loggers.Err.Printf(" Loading %s", l)
114+
}
115+
lb, err := ioutil.ReadFile(l)
116+
if err != nil {
117+
return errors.Wrapf(err, "Unable to read %s", l)
118+
}
119+
lock := &glideLock{}
120+
err = yaml.Unmarshal(lb, lock)
121+
if err != nil {
122+
return errors.Wrapf(err, "Unable to parse %s", l)
123+
}
124+
g.lock = lock
125+
}
126+
127+
return nil
128+
}
129+
130+
// convert the glide configuration files into dep configuration files.
131+
func (g *glideImporter) convert(pr gps.ProjectRoot) (*dep.Manifest, *dep.Lock, error) {
132+
projectName := string(pr)
133+
134+
task := bytes.NewBufferString("Converting from glide.yaml")
135+
if g.lock != nil {
136+
task.WriteString(" and glide.lock")
137+
}
138+
task.WriteString("...")
139+
g.ctx.Loggers.Err.Println(task)
140+
141+
manifest := &dep.Manifest{
142+
Constraints: make(gps.ProjectConstraints),
143+
}
144+
145+
for _, pkg := range g.yaml.Imports {
146+
pc, err := g.buildProjectConstraint(pkg)
147+
if err != nil {
148+
return nil, nil, err
149+
}
150+
manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{Source: pc.Ident.Source, Constraint: pc.Constraint}
151+
}
152+
for _, pkg := range g.yaml.TestImports {
153+
pc, err := g.buildProjectConstraint(pkg)
154+
if err != nil {
155+
return nil, nil, err
156+
}
157+
manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{Source: pc.Ident.Source, Constraint: pc.Constraint}
158+
}
159+
160+
manifest.Ignored = append(manifest.Ignored, g.yaml.Ignores...)
161+
162+
if len(g.yaml.ExcludeDirs) > 0 {
163+
if g.yaml.Name != "" && g.yaml.Name != projectName {
164+
g.ctx.Loggers.Err.Printf(" Glide thinks the package is '%s' but dep thinks it is '%s', using dep's value.\n", g.yaml.Name, projectName)
165+
}
166+
167+
for _, dir := range g.yaml.ExcludeDirs {
168+
pkg := path.Join(projectName, dir)
169+
manifest.Ignored = append(manifest.Ignored, pkg)
170+
}
171+
}
172+
173+
var lock *dep.Lock
174+
if g.lock != nil {
175+
lock = &dep.Lock{}
176+
177+
for _, pkg := range g.lock.Imports {
178+
lp := g.buildLockedProject(pkg)
179+
lock.P = append(lock.P, lp)
180+
}
181+
for _, pkg := range g.lock.TestImports {
182+
lp := g.buildLockedProject(pkg)
183+
lock.P = append(lock.P, lp)
184+
}
185+
}
186+
187+
return manifest, lock, nil
188+
}
189+
190+
func (g *glideImporter) buildProjectConstraint(pkg glidePackage) (pc gps.ProjectConstraint, err error) {
191+
if pkg.Name == "" {
192+
err = errors.New("Invalid glide configuration, package name is required")
193+
return
194+
}
195+
196+
if g.ctx.Loggers.Verbose {
197+
if pkg.OS != "" {
198+
g.ctx.Loggers.Err.Printf(" The %s package specified an os, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.\n", pkg.Name)
199+
}
200+
if pkg.Arch != "" {
201+
g.ctx.Loggers.Err.Printf(" The %s package specified an arch, but that isn't supported by dep yet, and will be ignored. See https://github.com/golang/dep/issues/291.\n", pkg.Name)
202+
}
203+
}
204+
205+
pc.Ident = gps.ProjectIdentifier{ProjectRoot: gps.ProjectRoot(pkg.Name), Source: pkg.Repository}
206+
pc.Constraint, err = deduceConstraint(pkg.Reference, pc.Ident, g.sm)
207+
208+
return
209+
}
210+
211+
func (g *glideImporter) buildLockedProject(pkg glideLockedPackage) gps.LockedProject {
212+
pi := gps.ProjectIdentifier{
213+
ProjectRoot: gps.ProjectRoot(pkg.Name),
214+
Source: pkg.Repository,
215+
}
216+
revision := gps.Revision(pkg.Reference)
217+
218+
version, err := lookupVersionForRevision(revision, pi, g.sm)
219+
if err != nil {
220+
// Warn about the problem, it is not enough to warrant failing
221+
warn := errors.Wrapf(err, "Unable to lookup the version represented by %s in %s(%s). Falling back to locking the revision only.", revision, pi.ProjectRoot, pi.Source)
222+
g.ctx.Err.Printf(warn.Error())
223+
version = revision
224+
}
225+
226+
feedback(version, pi.ProjectRoot, fb.DepTypeImported, g.ctx)
227+
return gps.NewLockedProject(pi, version, nil)
228+
}

0 commit comments

Comments
 (0)