forked from Masterminds/glide
-
Notifications
You must be signed in to change notification settings - Fork 0
/
analyzer.go
178 lines (146 loc) · 4.37 KB
/
analyzer.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package dependency
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/Masterminds/glide/cfg"
"github.com/Masterminds/glide/gb"
"github.com/Masterminds/glide/godep"
"github.com/Masterminds/glide/gom"
"github.com/Masterminds/glide/gpm"
gpath "github.com/Masterminds/glide/path"
"github.com/Masterminds/semver"
"github.com/sdboyer/gps"
)
type notApplicable struct{}
func (notApplicable) Error() string {
return ""
}
// Analyzer implements gps.ProjectAnalyzer. We inject the Analyzer into a
// gps.SourceManager, and it reports manifest and lock information to the
// SourceManager on request.
type Analyzer struct{}
func (a Analyzer) Info() (name string, version *semver.Version) {
name = "glide"
version, _ = semver.NewVersion("0.0.1")
return
}
func (a Analyzer) DeriveManifestAndLock(root string, pn gps.ProjectRoot) (gps.Manifest, gps.Lock, error) {
// this check should be unnecessary, but keeping it for now as a canary
if _, err := os.Lstat(root); err != nil {
return nil, nil, fmt.Errorf("No directory exists at %s; cannot produce ProjectInfo", root)
}
m, l, err := a.lookForGlide(root)
if err == nil {
// TODO verify project name is same as what SourceManager passed in?
return m, l, nil
} else if _, ok := err.(notApplicable); !ok {
return nil, nil, err
}
// The happy path of finding a glide manifest and/or lock file failed. Now,
// we begin our descent: we must attempt to divine just exactly *which*
// circle of hell we're in.
// Try godep first
m, l, err = a.lookForGodep(root)
if err == nil {
return m, l, nil
} else if _, ok := err.(notApplicable); !ok {
return nil, nil, err
}
// Next, gpm
m, l, err = a.lookForGPM(root)
if err == nil {
return m, l, nil
} else if _, ok := err.(notApplicable); !ok {
return nil, nil, err
}
// Next, gb
m, l, err = a.lookForGb(root)
if err == nil {
return m, l, nil
} else if _, ok := err.(notApplicable); !ok {
return nil, nil, err
}
// Next, gom
m, l, err = a.lookForGom(root)
if err == nil {
return m, l, nil
} else if _, ok := err.(notApplicable); !ok {
return nil, nil, err
}
// If none of our parsers matched, but none had actual errors, then we just
// go hands-off; gps itself will do the source analysis and use the Any
// constraint for all discovered package.
return nil, nil, nil
}
func (a Analyzer) lookForGlide(root string) (gps.Manifest, gps.Lock, error) {
mpath := filepath.Join(root, gpath.GlideFile)
if _, err := os.Lstat(mpath); err != nil {
return nil, nil, notApplicable{}
}
// Manifest found, so from here on, we're locked in - a returned error will
// make it back to the SourceManager
yml, err := ioutil.ReadFile(mpath)
if err != nil {
return nil, nil, fmt.Errorf("Error while reading glide manifest data: %s", root)
}
// We don't care here if it's legacy
m, _, err := cfg.ConfigFromYaml(yml)
if err != nil {
return nil, nil, fmt.Errorf("Error while parsing glide manifest data: %s", root)
}
// Manifest found, read, and parsed - we're on the happy path. Whether we
// find a lock or not, we will produce a valid result back to the
// SourceManager.
lpath := filepath.Join(root, gpath.LockFile)
if _, err := os.Lstat(lpath); err != nil {
return m, nil, nil
}
yml, err = ioutil.ReadFile(lpath)
if err != nil {
return m, nil, nil
}
// Again, legacy doesn't matter here
l, _, err := cfg.LockfileFromYaml(yml)
if err != nil {
return m, nil, nil
}
return m, l, nil
}
func (a Analyzer) lookForGodep(root string) (gps.Manifest, gps.Lock, error) {
if !godep.Has(root) {
return nil, nil, notApplicable{}
}
d, l, err := godep.AsMetadataPair(root)
if err != nil {
return nil, nil, err
}
return &cfg.Config{Name: root, Imports: d}, l, nil
}
func (a Analyzer) lookForGPM(root string) (gps.Manifest, gps.Lock, error) {
if !gpm.Has(root) {
return nil, nil, notApplicable{}
}
d, l, err := gpm.AsMetadataPair(root)
if err != nil {
return nil, nil, err
}
return &cfg.Config{Name: root, Imports: d}, l, nil
}
func (a Analyzer) lookForGb(root string) (gps.Manifest, gps.Lock, error) {
if !gpm.Has(root) {
return nil, nil, notApplicable{}
}
d, l, err := gb.AsMetadataPair(root)
if err != nil {
return nil, nil, err
}
return &cfg.Config{Name: root, Imports: d}, l, nil
}
func (a Analyzer) lookForGom(root string) (gps.Manifest, gps.Lock, error) {
if !gpm.Has(root) {
return nil, nil, notApplicable{}
}
return gom.AsMetadataPair(root)
}