github.com/olljanat/moby@v1.13.1/cli/compose/interpolation/interpolation.go (about)

     1  package interpolation
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/docker/docker/cli/compose/template"
     7  	"github.com/docker/docker/cli/compose/types"
     8  )
     9  
    10  // Interpolate replaces variables in a string with the values from a mapping
    11  func Interpolate(config types.Dict, section string, mapping template.Mapping) (types.Dict, error) {
    12  	out := types.Dict{}
    13  
    14  	for name, item := range config {
    15  		if item == nil {
    16  			out[name] = nil
    17  			continue
    18  		}
    19  		interpolatedItem, err := interpolateSectionItem(name, item.(types.Dict), section, mapping)
    20  		if err != nil {
    21  			return nil, err
    22  		}
    23  		out[name] = interpolatedItem
    24  	}
    25  
    26  	return out, nil
    27  }
    28  
    29  func interpolateSectionItem(
    30  	name string,
    31  	item types.Dict,
    32  	section string,
    33  	mapping template.Mapping,
    34  ) (types.Dict, error) {
    35  
    36  	out := types.Dict{}
    37  
    38  	for key, value := range item {
    39  		interpolatedValue, err := recursiveInterpolate(value, mapping)
    40  		if err != nil {
    41  			return nil, fmt.Errorf(
    42  				"Invalid interpolation format for %#v option in %s %#v: %#v",
    43  				key, section, name, err.Template,
    44  			)
    45  		}
    46  		out[key] = interpolatedValue
    47  	}
    48  
    49  	return out, nil
    50  
    51  }
    52  
    53  func recursiveInterpolate(
    54  	value interface{},
    55  	mapping template.Mapping,
    56  ) (interface{}, *template.InvalidTemplateError) {
    57  
    58  	switch value := value.(type) {
    59  
    60  	case string:
    61  		return template.Substitute(value, mapping)
    62  
    63  	case types.Dict:
    64  		out := types.Dict{}
    65  		for key, elem := range value {
    66  			interpolatedElem, err := recursiveInterpolate(elem, mapping)
    67  			if err != nil {
    68  				return nil, err
    69  			}
    70  			out[key] = interpolatedElem
    71  		}
    72  		return out, nil
    73  
    74  	case []interface{}:
    75  		out := make([]interface{}, len(value))
    76  		for i, elem := range value {
    77  			interpolatedElem, err := recursiveInterpolate(elem, mapping)
    78  			if err != nil {
    79  				return nil, err
    80  			}
    81  			out[i] = interpolatedElem
    82  		}
    83  		return out, nil
    84  
    85  	default:
    86  		return value, nil
    87  
    88  	}
    89  
    90  }