-
Notifications
You must be signed in to change notification settings - Fork 5
/
filter.go
187 lines (160 loc) · 4.25 KB
/
filter.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
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
)
/**
Flattens MergeDeps into a single-level array, and appends that onto depList
This is due to YAML limitations:
// Step 0: Flatten merge-deps with deps. Because YAML doesn't support merging sequences:
// http://yaml4r.sourceforge.net/doc/page/collections_in_yaml.htm
// https://stackoverflow.com/a/30770740/663058
*/
func flatten(deps []dep) []dep {
//Go through all of the deps, and check if they need flattening.
for key, dep := range deps {
//Cycle through the arrays of arrays of deps
for _, mdep := range dep.MergeDeps {
// and spread/merge those into the deps.
dep.DepList = append(dep.DepList, flatten(mdep)...)
}
dep.MergeDeps = nil
// The recursive part of this function
// Called after the MergeDeps, in case the anchored deps have deps
dep.DepList = flatten(dep.DepList)
deps[key] = dep
}
return deps
}
/**
Flattens the dep YAML
dep.Labels are inherited
dep.Location is expanded
*/
func unwrap(deps []dep, baseDir string, labels []string, params map[string]string) []dep {
var foundDeps []dep
for _, dep := range deps {
dep.Location = filepath.Clean(baseDir + dep.Location)
dep.Labels = append(dep.Labels, labels...) // Inherit labels
// Adding kind, name, and location to possible template params
if dep.Params == nil {
dep.Params = map[string]string{}
}
if _, ok := dep.Params["kind"]; !ok {
dep.Params["kind"] = dep.Kind
}
if _, ok := dep.Params["name"]; !ok {
dep.Params["name"] = dep.Name
}
if _, ok := dep.Params["location"]; !ok {
dep.Params["location"] = dep.Location
}
dep.Params = mergeMap(dep.Params, params) // Inherit parents Params
if dep.DepList != nil {
foundDeps = append(foundDeps, unwrap(dep.DepList, dep.Location+string(os.PathSeparator), dep.Labels, parentParms(dep.Params))...)
dep.DepList = nil
}
foundDeps = append(foundDeps, dep)
}
return foundDeps
}
/*
In mustache.go the `func lookup()` attempts to expand dot notation, so I forked that codebase
and commented that out to allow directory style parental param lookups.
*/
func parentParms(params map[string]string) map[string]string {
parents := make(map[string]string)
for name, param := range params {
parents[".."+string(os.PathSeparator)+name] = param
}
return parents
}
/**
Merge the parent map with the sibling, but allow sibling to take precedence if there are dupes.
*/
func mergeMap(sibling map[string]string, parent map[string]string) map[string]string {
for name, param := range parent {
if _, ok := sibling[name]; !ok {
sibling[name] = param
}
}
return sibling
}
/**
Filters out to just a kind
*/
func applyFilterKind(deps []dep, kind string) []dep {
var foundDeps []dep
for _, dep := range deps {
if dep.Kind != "" && dep.Kind == kind {
foundDeps = append(foundDeps, dep)
}
}
return foundDeps
}
/**
Applies filters
Splits comma separated
*/
func applyFilterLabel(deps []dep, perform perform) []dep {
if perform.Labels == "" {
if perform.Verbose || !perform.Force {
fmt.Println("Warning: No labels, using all deps of kind.")
}
if !perform.Force && !askForConfirmation("Are you sure you want to continue?\n"+
"(use --force to suppress this prompt.)", nil) {
if perform.Verbose {
fmt.Println("DepCharge cancelled.")
}
os.Exit(0)
}
// If no labels, and only kind, return that.
return deps
}
labels := strings.Split(perform.Labels, ",")
var foundDeps []dep
for _, dep := range deps { // Cycle through all of the deps
var match bool
if perform.Exclusive {
match = isExclusive(dep.Labels, labels)
} else {
match = isInclusive(dep.Labels, labels)
}
if match {
foundDeps = append(foundDeps, dep)
}
}
return foundDeps
}
func isExclusive(what []string, against []string) bool {
counter := 0
for _, item := range what {
for _, compare := range against {
if item == compare {
counter++
}
}
}
if len(against) == counter {
return true
}
return false
}
func isInclusive(what []string, against []string) bool {
if (len(what) == 0 && len(against) == 0) || len(against) == 0 {
return true
}
match := false
InclusiveSearch:
for _, item := range what {
for _, compare := range against {
if item == compare {
match = true
break InclusiveSearch
}
}
}
return match
}