-
Notifications
You must be signed in to change notification settings - Fork 5
/
pack.go
84 lines (76 loc) · 1.81 KB
/
pack.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
package hostutils
import (
"fmt"
"sort"
"strings"
)
// PackString Pack space separated full hosts list into short abbreviated hosts.
func PackString(hosts string) (packedHosts []string) {
return Pack([]string{hosts})
}
// Pack full hosts list into short abbreviated hosts.
func Pack(hosts []string) (packedHosts []string) {
regHosts := regularizeHosts(hosts[:])
if regHosts == nil {
return nil
}
if len(regHosts) == 0 {
return []string{}
}
return packHosts(regHosts)
}
func packHosts(uniqHosts []string) []string {
hostGroups := make(map[string][]string)
var result []string
for _, fqdn := range uniqHosts {
hostname, domain := parseFQDN(fqdn)
m := reHostname.FindStringSubmatch(hostname)
if len(m) == 0 {
result = append(result, fqdn)
} else {
prefix := m[1]
num := m[2]
suffix := m[3]
key := fmt.Sprintf("%s%%s%s%s", prefix, suffix, domain)
hostGroups[key] = append(hostGroups[key], num)
}
}
for format, nums := range hostGroups {
result = append(result, fmt.Sprintf(format, groupNums(nums)))
}
sort.Strings(result)
return result
}
func groupNums(nums []string) string {
sort.Slice(nums, func(i, j int) bool {
if len(nums[i]) != len(nums[j]) {
return len(nums[i]) < len(nums[j])
}
return atoi(nums[i]) < atoi(nums[j])
})
nums = append(nums, "999999")
minStr := nums[0]
min := atoi(minStr)
prevStr := minStr
prev := min
packedNums := []string{}
for _, v := range nums {
n := atoi(v)
if n-prev > 1 || len(v) != len(prevStr) {
if min == prev {
packedNums = append(packedNums, minStr)
} else {
packedNums = append(packedNums, fmt.Sprintf("%s-%s", minStr, prevStr))
}
min = n
minStr = v
}
prev = n
prevStr = v
}
result := strings.Join(packedNums, ",")
if reIsNumber.MatchString(result) {
return result
}
return fmt.Sprintf("[%s]", result)
}