github.com/YousefHaggyHeroku/pack@v1.5.5/internal/builder/descriptor.go (about)

     1  package builder
     2  
     3  import (
     4  	"github.com/BurntSushi/toml"
     5  	"github.com/buildpacks/lifecycle/api"
     6  	"github.com/pkg/errors"
     7  )
     8  
     9  // LifecycleDescriptor contains information described in the lifecycle.toml
    10  type LifecycleDescriptor struct {
    11  	Info LifecycleInfo `toml:"lifecycle"`
    12  	// Deprecated: Use `LifecycleAPIs` instead
    13  	API  LifecycleAPI  `toml:"api"`
    14  	APIs LifecycleAPIs `toml:"apis"`
    15  }
    16  
    17  // LifecycleInfo contains information about the lifecycle
    18  type LifecycleInfo struct {
    19  	Version *Version `toml:"version" json:"version" yaml:"version"`
    20  }
    21  
    22  // LifecycleAPI describes which API versions the lifecycle satisfies
    23  type LifecycleAPI struct {
    24  	BuildpackVersion *api.Version `toml:"buildpack" json:"buildpack"`
    25  	PlatformVersion  *api.Version `toml:"platform" json:"platform"`
    26  }
    27  
    28  // LifecycleAPIs describes the supported API versions per specification
    29  type LifecycleAPIs struct {
    30  	Buildpack APIVersions `toml:"buildpack" json:"buildpack"`
    31  	Platform  APIVersions `toml:"platform" json:"platform"`
    32  }
    33  
    34  type APISet []*api.Version
    35  
    36  func (a APISet) search(comp func(prevMatch, value *api.Version) bool) *api.Version {
    37  	var match *api.Version
    38  	for _, version := range a {
    39  		switch {
    40  		case version == nil:
    41  			continue
    42  		case match == nil:
    43  			match = version
    44  		case comp(match, version):
    45  			match = version
    46  		}
    47  	}
    48  
    49  	return match
    50  }
    51  
    52  func (a APISet) Earliest() *api.Version {
    53  	return a.search(func(prevMatch, value *api.Version) bool { return value.Compare(prevMatch) < 0 })
    54  }
    55  
    56  func (a APISet) Latest() *api.Version {
    57  	return a.search(func(prevMatch, value *api.Version) bool { return value.Compare(prevMatch) > 0 })
    58  }
    59  
    60  func (a APISet) AsStrings() []string {
    61  	verStrings := make([]string, len(a))
    62  	for i, version := range a {
    63  		verStrings[i] = version.String()
    64  	}
    65  
    66  	return verStrings
    67  }
    68  
    69  // APIVersions describes the supported API versions
    70  type APIVersions struct {
    71  	Deprecated APISet `toml:"deprecated" json:"deprecated" yaml:"deprecated"`
    72  	Supported  APISet `toml:"supported" json:"supported" yaml:"supported"`
    73  }
    74  
    75  // ParseDescriptor parses LifecycleDescriptor from toml formatted string.
    76  func ParseDescriptor(contents string) (LifecycleDescriptor, error) {
    77  	descriptor := LifecycleDescriptor{}
    78  	_, err := toml.Decode(contents, &descriptor)
    79  	if err != nil {
    80  		return descriptor, errors.Wrap(err, "decoding descriptor")
    81  	}
    82  
    83  	return descriptor, nil
    84  }
    85  
    86  // CompatDescriptor provides compatibility by mapping new fields to old and vice-versa
    87  func CompatDescriptor(descriptor LifecycleDescriptor) LifecycleDescriptor {
    88  	if len(descriptor.APIs.Buildpack.Supported) != 0 || len(descriptor.APIs.Platform.Supported) != 0 {
    89  		// select earliest value for deprecated parameters
    90  		if len(descriptor.APIs.Buildpack.Supported) != 0 {
    91  			descriptor.API.BuildpackVersion =
    92  				append(descriptor.APIs.Buildpack.Deprecated, descriptor.APIs.Buildpack.Supported...).Earliest()
    93  		}
    94  		if len(descriptor.APIs.Platform.Supported) != 0 {
    95  			descriptor.API.PlatformVersion =
    96  				append(descriptor.APIs.Platform.Deprecated, descriptor.APIs.Platform.Supported...).Earliest()
    97  		}
    98  	} else if descriptor.API.BuildpackVersion != nil && descriptor.API.PlatformVersion != nil {
    99  		// fill supported with deprecated field
   100  		descriptor.APIs = LifecycleAPIs{
   101  			Buildpack: APIVersions{
   102  				Supported: APISet{descriptor.API.BuildpackVersion},
   103  			},
   104  			Platform: APIVersions{
   105  				Supported: APISet{descriptor.API.PlatformVersion},
   106  			},
   107  		}
   108  	}
   109  
   110  	return descriptor
   111  }