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  }