github.com/Cloud-Foundations/Dominator@v0.3.4/imagebuilder/builder/variables.go (about)

     1  package builder
     2  
     3  import (
     4  	"os"
     5  	"strconv"
     6  	"strings"
     7  )
     8  
     9  // expandExpression will expand the expression specified by expr and will
    10  // perform parameter expansion on each sub-expression. The mappingFunc is used
    11  // to lookup variables.
    12  func expandExpression(expr string, mappingFunc func(string) string) string {
    13  	return os.Expand(expr, func(parameter string) string {
    14  		return expandVariable(parameter, mappingFunc)
    15  	})
    16  }
    17  
    18  // expandVariable will expand the contents of the variable. If the specified
    19  // variable is immediately followed by [<sep><start>:<end>] then it is split by
    20  // the sep character, and then the components from start to end are joined.
    21  // For example, [/2:-1] will remove the first two and last pathname components.
    22  func expandVariable(variable string, mappingFunc func(string) string) string {
    23  	if len(variable) < 5 {
    24  		return mappingFunc(variable) // Not enough for a sub-expression.
    25  	}
    26  	if variable[len(variable)-1] != ']' {
    27  		return mappingFunc(variable) // Simple variable.
    28  	}
    29  	index := strings.IndexByte(variable, '[')
    30  	if index < 1 {
    31  		return ""
    32  	}
    33  	if len(variable) < index+4 {
    34  		return ""
    35  	}
    36  	variableName := variable[:index]
    37  	separator := variable[index+1 : index+2]
    38  	variableValue := mappingFunc(variableName)
    39  	if variableValue == "" {
    40  		return ""
    41  	}
    42  	splitValue := strings.Split(variableValue, separator)
    43  	splitRange := strings.Split(variable[index+2:len(variable)-1], ":")
    44  	if len(splitRange) != 2 {
    45  		return ""
    46  	}
    47  	var start, end int
    48  	var err error
    49  	if len(splitRange[0]) > 0 {
    50  		start, err = strconv.Atoi(splitRange[0])
    51  		if err != nil {
    52  			return ""
    53  		}
    54  	}
    55  	if len(splitRange[1]) > 0 {
    56  		end, err = strconv.Atoi(splitRange[1])
    57  		if err != nil {
    58  			return ""
    59  		}
    60  		if end >= len(splitValue) {
    61  			return ""
    62  		}
    63  		if end < 0 {
    64  			end += len(splitValue)
    65  			if end < start {
    66  				return ""
    67  			}
    68  		}
    69  	} else {
    70  		end = len(splitValue)
    71  	}
    72  	return strings.Join(splitValue[start:end], separator)
    73  }
    74  
    75  func (b *Builder) getVariableFunc(
    76  	extraVariables0, extraVariables1 map[string]string) func(string) string {
    77  	return func(varName string) string {
    78  		if extraVariables0 != nil {
    79  			if varValue, ok := extraVariables0[varName]; ok {
    80  				return varValue
    81  			}
    82  		}
    83  		if extraVariables1 != nil {
    84  			if varValue, ok := extraVariables1[varName]; ok {
    85  				return varValue
    86  			}
    87  		}
    88  		return b.variables[varName]
    89  	}
    90  }
    91  
    92  type variablesGetter map[string]string
    93  
    94  func (vg variablesGetter) add(key, value string) {
    95  	if value != "" {
    96  		vg[key] = value
    97  	}
    98  }
    99  
   100  func (vg variablesGetter) copy() variablesGetter {
   101  	retval := make(variablesGetter, len(vg))
   102  	for key, value := range vg {
   103  		retval[key] = value
   104  	}
   105  	return retval
   106  }
   107  
   108  func (vg variablesGetter) getenv() map[string]string {
   109  	return vg
   110  }
   111  
   112  func (vg variablesGetter) merge(vgToMerge variablesGetter) {
   113  	for key, value := range vgToMerge {
   114  		vg.add(key, value)
   115  	}
   116  }