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 }