-
Notifications
You must be signed in to change notification settings - Fork 541
/
Copy pathgodep.go
132 lines (110 loc) · 3.4 KB
/
godep.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
// Package godep provides basic importing of Godep dependencies.
//
// This is not a complete implementation of Godep.
package godep
import (
"encoding/json"
"os"
"path/filepath"
"github.com/Masterminds/glide/cfg"
"github.com/Masterminds/glide/msg"
gpath "github.com/Masterminds/glide/path"
"github.com/Masterminds/glide/util"
)
// This file contains commands for working with Godep.
// The Godeps struct from Godep.
//
// https://raw.githubusercontent.com/tools/godep/master/dep.go
//
// We had to copy this because it's in the package main for Godep.
type Godeps struct {
ImportPath string
GoVersion string
Packages []string `json:",omitempty"` // Arguments to save, if any.
Deps []Dependency
outerRoot string
}
// Dependency is a modified version of Godep's Dependency struct.
// It drops all of the unexported fields.
type Dependency struct {
ImportPath string
Comment string `json:",omitempty"` // Description of commit, if present.
Rev string // VCS-specific commit ID.
}
// Has is a command to detect if a package contains a Godeps.json file.
func Has(dir string) bool {
path := filepath.Join(dir, "Godeps/Godeps.json")
_, err := os.Stat(path)
return err == nil
}
// Parse parses a Godep's Godeps file.
//
// It returns the contents as a dependency array.
func Parse(dir string) ([]*cfg.Dependency, error) {
path := filepath.Join(dir, "Godeps/Godeps.json")
if _, err := os.Stat(path); err != nil {
return []*cfg.Dependency{}, nil
}
msg.Info("Found Godeps.json file in %s", gpath.StripBasepath(dir))
msg.Info("--> Parsing Godeps metadata...")
buf := []*cfg.Dependency{}
godeps := &Godeps{}
// Get a handle to the file.
file, err := os.Open(path)
if err != nil {
return buf, err
}
defer file.Close()
dec := json.NewDecoder(file)
if err := dec.Decode(godeps); err != nil {
return buf, err
}
seen := map[string]bool{}
for _, d := range godeps.Deps {
pkg, _ := util.NormalizeName(d.ImportPath)
if !seen[pkg] {
seen[pkg] = true
dep := &cfg.Dependency{Name: pkg, Version: d.Rev}
buf = append(buf, dep)
}
}
return buf, nil
}
func AsMetadataPair(dir string) ([]*cfg.Dependency, *cfg.Lockfile, error) {
path := filepath.Join(dir, "Godeps/Godeps.json")
if _, err := os.Stat(path); err != nil {
return nil, nil, err
}
var m []*cfg.Dependency
l := &cfg.Lockfile{}
godeps := &Godeps{}
// Get a handle to the file.
file, err := os.Open(path)
if err != nil {
return nil, nil, err
}
defer file.Close()
dec := json.NewDecoder(file)
if err := dec.Decode(godeps); err != nil {
return nil, nil, err
}
seen := map[string]bool{}
for _, d := range godeps.Deps {
pkg, _ := util.NormalizeName(d.ImportPath)
if _, ok := seen[pkg]; !ok {
seen[pkg] = true
// Place no real *actual* constraint on the project; instead, we
// rely on gps using the 'preferred' version mechanism by
// working from the lock file. Without this, users would end up with
// the same mind-numbing diamond dep problems as currently exist.
// This approach does make for an uncomfortably wide possibility
// space where deps aren't getting what they expect, but that's
// better than just having the solver give up completely.
m = append(m, &cfg.Dependency{Name: pkg})
l.Imports = append(l.Imports, &cfg.Lock{Name: pkg, Revision: d.Rev})
// TODO this fails to differentiate between dev and non-dev imports;
// need static analysis for that
}
}
return m, l, nil
}