-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathget_deps.go
192 lines (181 loc) · 5.63 KB
/
get_deps.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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package main
import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/tidwall/gjson"
)
func getProjPlats(conf *config) ([]string, []string) {
projects, err := getRbFiles("./configs/projects", &conf.SkipProjects)
if err != nil {
log.Fatal("couldn't get projects", err)
}
platforms, err := getRbFiles("./configs/platforms", &conf.SkipPlatforms)
if err != nil {
log.Fatal("couldn't get folders")
}
return projects, platforms
}
func getRbFiles(path string, skip *[]string) ([]string, error) {
var pSlice []string
err := filepath.Walk(path, func(spath string, info os.FileInfo, err error) error {
// make sure it's a ruby file and it doesn't start with an underscore
filename := filepath.Base(spath)
if strings.HasSuffix(filename, ".rb") && !strings.HasPrefix(filename, "_") {
pname := strings.Replace(filename, ".rb", "", -1)
if !inSkip(skip, pname) {
pSlice = append(pSlice, pname)
}
}
return nil
})
if err != nil {
return []string{}, err
}
return pSlice, nil
}
func inSkip(skip *[]string, pname string) bool {
// this function isn't very efficient, but it's also not called very often
for _, v := range *skip {
if pname == v {
return true
}
}
return false
}
func runVanagonDeps(projects, platforms []string, debug bool) []depsOut {
ppGems := []depsOut{}
results := make(chan depsOut)
sem := make(chan int, MAX_V_DEPS)
toProcess := 0
total := len(projects) * len(platforms)
for _, project := range projects {
for _, platform := range platforms {
sem <- 1
toProcess += 1
log.Printf("getting vdeps for %s %s. %d/%d", project, platform, toProcess, total)
go getVanagonGems(project, platform, results, sem, debug)
}
}
for i := 0; i < toProcess; i++ {
result := <-results
ppGems = append(ppGems, result)
log.Printf("done getting vdeps for %s %s", result.Project, result.Platform)
}
return ppGems
}
func parseVanagonOutput(input, project, platform string) ([]gem, error) {
components := gjson.Get(input, "components").Map()
gems := make([]gem, 0)
for name, component := range components {
version := gjson.Get(component.Raw, "version").String()
url := gjson.Get(component.Raw, "url").String()
// skip non gems
if !strings.HasSuffix(url, ".gem") {
continue
}
// check for blanks
if version == "" || url == "" {
log.Printf("blank version or url in component: %s on: %s %s", name, project, platform)
continue
}
if strings.HasPrefix(url, "https://rubygems.org") || strings.HasPrefix(url, "http://rubygems.org") {
gem, err := getGemFromURL(url)
if err != nil {
log.Println("error getting gem from url", err)
continue
}
gems = append(gems, gem)
}
}
return gems, nil
}
func getVanagonGems(project, platform string, result chan depsOut, sem chan int, debug bool) {
do := depsOut{
Platform: platform,
Project: project,
}
// log.Printf("in get deps: %s %s", project, platform)
var findex int
var lindex int
var output []byte
for try := 0; try < 3; try++ {
vcmd := exec.Command("vanagon", "dependencies", project, platform)
var cout bytes.Buffer
var stderr bytes.Buffer
vcmd.Stdout = &cout
vcmd.Stderr = &stderr
err := vcmd.Run()
log.Printf("finished vanagon deps run for %s %s", project, platform)
if err != nil {
log.Printf("Error running vanagon dependencies on: %s %s. Try #%d. Err: %s", project, platform, try, err)
if debug {
log.Printf("===DEBUG===\n%s\n===DEBUG===\n", stderr.String())
}
log.Println(string(output))
}
// strip out the any other data in stdout
findex = strings.Index(cout.String(), "{")
lindex = strings.LastIndex(cout.String(), "}")
if findex == -1 || lindex == -1 {
log.Printf("Got bad output from vanagon dependencies on %s %s. Try #%d Output: %s", project, platform, try, cout.String())
} else {
output = cout.Bytes()
break
}
}
<-sem
if output == nil {
log.Printf("Total failure to run vanagon on %s %s", project, platform)
gems := make([]gem, 0)
do.Gems = &gems
result <- do
return
}
trimString := string(output)[findex : lindex+1]
gems, err := parseVanagonOutput(trimString, project, platform)
if err != nil {
log.Printf("Error parsing vanagon Output: %s", err)
}
do.Gems = &gems
result <- do
}
// getGemFromURL returns a name and a version string. The version is quoted already
// to handle different platform specs
func getGemFromURL(url string) (gem, error) {
// trim the URL to the final part of the path and replace .gem with ""
splitString := strings.Split(url, "/")
nameAndVer := splitString[len(splitString)-1]
nameAndVer = strings.Replace(nameAndVer, ".gem", "", -1)
// find the last index of "-" and split on it, rhs is the verion, lhs
// is the gem name
//"https://rubygems.org/downloads/minitar-0.9.gem"
//"https://rubygems.org/downloads/ffi-1.15.3-x64-mingw32.gem"
if strings.Contains(nameAndVer, "x64-mingw") {
i := strings.LastIndex(nameAndVer, "-x64-mingw")
nv := nameAndVer[:i]
lastTack := strings.LastIndex(nv, "-")
name := nv[:lastTack]
version := nv[lastTack+1:]
version = fmt.Sprintf("\"%s\", :platforms => :x64_mingw", version)
return gem{Name: name, Version: version}, nil
} else if strings.Contains(nameAndVer, "x86-mingw") {
i := strings.LastIndex(nameAndVer, "-x86-mingw")
nv := nameAndVer[:i]
lastTack := strings.LastIndex(nv, "-")
name := nv[:lastTack]
version := nv[lastTack+1:]
version = fmt.Sprintf("\"%s\", :platforms => :mingw", version)
return gem{Name: name, Version: version}, nil
} else {
lastIndex := strings.LastIndex(nameAndVer, "-")
name := nameAndVer[:lastIndex]
version := nameAndVer[lastIndex+1:]
version = fmt.Sprintf("\"%s\"", version)
return gem{Name: name, Version: version}, nil
}
}