-
Notifications
You must be signed in to change notification settings - Fork 67
/
run_list_item.go
93 lines (78 loc) · 2.5 KB
/
run_list_item.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
package chef
import (
"fmt"
"regexp"
)
const (
qualifiedRecipe string = `^recipe\[([^\]@]+)(@([0-9]+(\.[0-9]+){1,2}))?\]$`
qualifiedRole string = `^role\[([^\]]+)\]$`
versionedUnqualifiedRecipe string = `^([^@]+)(@([0-9]+(\.[0-9]+){1,2}))$`
falseFriend string = `[\[\]]`
)
var (
qualifiedRecipeRegexp *regexp.Regexp = regexp.MustCompile(qualifiedRecipe)
qualifiedRoleRegexp *regexp.Regexp = regexp.MustCompile(qualifiedRole)
versionedUnqualifiedRecipeRegexp *regexp.Regexp = regexp.MustCompile(versionedUnqualifiedRecipe)
falseFriendRegexp *regexp.Regexp = regexp.MustCompile(falseFriend)
)
// RunListItem external representation of a run list
// This module is a direct port of the Chef::RunList::RunListItem class
// see: https://github.com/chef/chef/blob/master/lib/chef/run_list/run_list_item.rb
type RunListItem struct {
Name string
Type string
Version string
}
// NewRunListItem parses a single item from a run list and returns a structure
func NewRunListItem(item string) (rli RunListItem, err error) {
switch {
case qualifiedRecipeRegexp.MatchString(item):
// recipe[name]
// recipe[[email protected]]
rli.Type = "recipe"
submatches := qualifiedRecipeRegexp.FindStringSubmatch(item)
rli.Name = submatches[1]
if len(submatches) > 2 {
rli.Version = submatches[3]
}
case qualifiedRoleRegexp.MatchString(item):
// role[role_name]
rli.Type = "role"
submatches := qualifiedRoleRegexp.FindStringSubmatch(item)
rli.Name = submatches[1]
case versionedUnqualifiedRecipeRegexp.MatchString(item):
rli.Type = "recipe"
submatches := versionedUnqualifiedRecipeRegexp.FindStringSubmatch(item)
rli.Name = submatches[1]
if len(submatches) > 2 {
rli.Version = submatches[3]
}
case falseFriendRegexp.MatchString(item):
// Recipe[recipe_name]
// roles[role_name]
err = fmt.Errorf("Invalid run-list item: %s", item)
return RunListItem{}, err
default:
rli.Type = "recipe"
rli.Name = item
}
return rli, nil
}
// String implements the String interface function
func (r RunListItem) String() (s string) {
if r.Version != "" {
s = fmt.Sprintf("%s[%s@%s]", r.Type, r.Name, r.Version)
} else {
s = fmt.Sprintf("%s[%s]", r.Type, r.Name)
}
return s
}
// IsRecipe Determines if the runlist item is a recipe
func (r RunListItem) IsRecipe() bool {
return r.Type == "recipe"
}
// IsRole Determines if the runlist item is a role
func (r RunListItem) IsRole() bool {
return r.Type == "role"
}