github.com/loafoe/cli@v7.1.0+incompatible/util/manifestparser/process.go (about)

     1  package manifestparser
     2  
     3  import (
     4  	"errors"
     5  	"reflect"
     6  	"strings"
     7  
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
     9  )
    10  
    11  type Process struct {
    12  	DiskQuota               string                   `yaml:"disk-quota,omitempty"`
    13  	HealthCheckEndpoint     string                   `yaml:"health-check-http-endpoint,omitempty"`
    14  	HealthCheckType         constant.HealthCheckType `yaml:"health-check-type,omitempty"`
    15  	HealthCheckTimeout      int64                    `yaml:"timeout,omitempty"`
    16  	Instances               *int                     `yaml:"instances,omitempty"`
    17  	Memory                  string                   `yaml:"memory,omitempty"`
    18  	Type                    string                   `yaml:"type"`
    19  	RemainingManifestFields map[string]interface{}   `yaml:"-,inline"`
    20  }
    21  
    22  func (process *Process) SetStartCommand(command string) {
    23  	if process.RemainingManifestFields == nil {
    24  		process.RemainingManifestFields = map[string]interface{}{}
    25  	}
    26  
    27  	if command == "" {
    28  		process.RemainingManifestFields["command"] = nil
    29  	} else {
    30  		process.RemainingManifestFields["command"] = command
    31  	}
    32  }
    33  
    34  func (process *Process) UnmarshalYAML(unmarshal func(v interface{}) error) error {
    35  	// This prevents infinite recursion. The Alias type does not implement the unmarshaller interface
    36  	// so by casting application to a alias pointer, it will unmarshal in to the same memory without calling
    37  	// UnmarshalYAML on itself infinite times
    38  	type Alias Process
    39  	aliasPntr := (*Alias)(process)
    40  
    41  	err := unmarshal(aliasPntr)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	err = unmarshal(&process.RemainingManifestFields)
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	value := reflect.ValueOf(*process)
    52  	removeDuplicateMapKeys(value, process.RemainingManifestFields)
    53  	// old style was `disk_quota` (underscore not hyphen)
    54  	// we maintain backwards-compatibility by supporting both flavors
    55  	if process.RemainingManifestFields["disk_quota"] != nil {
    56  		if process.DiskQuota != "" {
    57  			return errors.New("cannot define both `disk_quota` and `disk-quota`")
    58  		}
    59  		diskQuota, ok := process.RemainingManifestFields["disk_quota"].(string)
    60  		if !ok {
    61  			return errors.New("`disk_quota` must be a string")
    62  		}
    63  		process.DiskQuota = diskQuota
    64  		delete(process.RemainingManifestFields, "disk_quota")
    65  	}
    66  
    67  	return nil
    68  }
    69  
    70  func removeDuplicateMapKeys(model reflect.Value, fieldMap map[string]interface{}) {
    71  	for i := 0; i < model.NumField(); i++ {
    72  		structField := model.Type().Field(i)
    73  
    74  		yamlTag := strings.Split(structField.Tag.Get("yaml"), ",")
    75  		yamlKey := yamlTag[0]
    76  
    77  		if yamlKey == "" {
    78  			yamlKey = structField.Name
    79  		}
    80  
    81  		delete(fieldMap, yamlKey)
    82  	}
    83  }