github.com/go-chef/chef@v0.30.1/run_list_item.go (about) 1 package chef 2 3 import ( 4 "fmt" 5 "regexp" 6 ) 7 8 const ( 9 qualifiedRecipe string = `^recipe\[([^\]@]+)(@([0-9]+(\.[0-9]+){1,2}))?\]$` 10 qualifiedRole string = `^role\[([^\]]+)\]$` 11 versionedUnqualifiedRecipe string = `^([^@]+)(@([0-9]+(\.[0-9]+){1,2}))$` 12 falseFriend string = `[\[\]]` 13 ) 14 15 var ( 16 qualifiedRecipeRegexp *regexp.Regexp = regexp.MustCompile(qualifiedRecipe) 17 qualifiedRoleRegexp *regexp.Regexp = regexp.MustCompile(qualifiedRole) 18 versionedUnqualifiedRecipeRegexp *regexp.Regexp = regexp.MustCompile(versionedUnqualifiedRecipe) 19 falseFriendRegexp *regexp.Regexp = regexp.MustCompile(falseFriend) 20 ) 21 22 // RunListItem external representation of a run list 23 // This module is a direct port of the Chef::RunList::RunListItem class 24 // see: https://github.com/chef/chef/blob/master/lib/chef/run_list/run_list_item.rb 25 type RunListItem struct { 26 Name string 27 Type string 28 Version string 29 } 30 31 // NewRunListItem parses a single item from a run list and returns a structure 32 func NewRunListItem(item string) (rli RunListItem, err error) { 33 switch { 34 case qualifiedRecipeRegexp.MatchString(item): 35 // recipe[name] 36 // recipe[name@1.0.0] 37 rli.Type = "recipe" 38 39 submatches := qualifiedRecipeRegexp.FindStringSubmatch(item) 40 rli.Name = submatches[1] 41 42 if len(submatches) > 2 { 43 rli.Version = submatches[3] 44 } 45 case qualifiedRoleRegexp.MatchString(item): 46 // role[role_name] 47 rli.Type = "role" 48 49 submatches := qualifiedRoleRegexp.FindStringSubmatch(item) 50 rli.Name = submatches[1] 51 case versionedUnqualifiedRecipeRegexp.MatchString(item): 52 // recipe_name@1.0.0 53 rli.Type = "recipe" 54 submatches := versionedUnqualifiedRecipeRegexp.FindStringSubmatch(item) 55 56 rli.Name = submatches[1] 57 58 if len(submatches) > 2 { 59 rli.Version = submatches[3] 60 } 61 case falseFriendRegexp.MatchString(item): 62 // Recipe[recipe_name] 63 // roles[role_name] 64 err = fmt.Errorf("Invalid run-list item: %s", item) 65 return RunListItem{}, err 66 default: 67 rli.Type = "recipe" 68 rli.Name = item 69 } 70 71 return rli, nil 72 } 73 74 // String implements the String interface function 75 func (r RunListItem) String() (s string) { 76 if r.Version != "" { 77 s = fmt.Sprintf("%s[%s@%s]", r.Type, r.Name, r.Version) 78 } else { 79 s = fmt.Sprintf("%s[%s]", r.Type, r.Name) 80 } 81 82 return s 83 } 84 85 // IsRecipe Determines if the runlist item is a recipe 86 func (r RunListItem) IsRecipe() bool { 87 return r.Type == "recipe" 88 } 89 90 // IsRole Determines if the runlist item is a role 91 func (r RunListItem) IsRole() bool { 92 return r.Type == "role" 93 }