github.com/YousefHaggyHeroku/pack@v1.5.5/internal/buildpackage/package.go (about) 1 package buildpackage 2 3 import ( 4 "io" 5 6 "github.com/pkg/errors" 7 8 "github.com/YousefHaggyHeroku/pack/internal/dist" 9 "github.com/YousefHaggyHeroku/pack/internal/style" 10 ) 11 12 type Package interface { 13 Label(name string) (value string, err error) 14 GetLayer(diffID string) (io.ReadCloser, error) 15 } 16 17 func ExtractBuildpacks(pkg Package) (mainBP dist.Buildpack, depBPs []dist.Buildpack, err error) { 18 md := &Metadata{} 19 if found, err := dist.GetLabel(pkg, MetadataLabel, md); err != nil { 20 return nil, nil, err 21 } else if !found { 22 return nil, nil, errors.Errorf( 23 "could not find label %s", 24 style.Symbol(MetadataLabel), 25 ) 26 } 27 28 bpLayers := dist.BuildpackLayers{} 29 ok, err := dist.GetLabel(pkg, dist.BuildpackLayersLabel, &bpLayers) 30 if err != nil { 31 return nil, nil, err 32 } 33 34 if !ok { 35 return nil, nil, errors.Errorf( 36 "could not find label %s", 37 style.Symbol(dist.BuildpackLayersLabel), 38 ) 39 } 40 41 for bpID, v := range bpLayers { 42 for bpVersion, bpInfo := range v { 43 desc := dist.BuildpackDescriptor{ 44 API: bpInfo.API, 45 Info: dist.BuildpackInfo{ 46 ID: bpID, 47 Version: bpVersion, 48 Homepage: bpInfo.Homepage, 49 }, 50 Stacks: bpInfo.Stacks, 51 Order: bpInfo.Order, 52 } 53 54 diffID := bpInfo.LayerDiffID // Allow use in closure 55 b := &openerBlob{ 56 opener: func() (io.ReadCloser, error) { 57 rc, err := pkg.GetLayer(diffID) 58 if err != nil { 59 return nil, errors.Wrapf(err, 60 "extracting buildpack %s layer (diffID %s)", 61 style.Symbol(desc.Info.FullName()), 62 style.Symbol(diffID), 63 ) 64 } 65 return rc, nil 66 }, 67 } 68 69 if desc.Info.Match(md.BuildpackInfo) { // This is the order buildpack of the package 70 mainBP = dist.BuildpackFromBlob(desc, b) 71 } else { 72 depBPs = append(depBPs, dist.BuildpackFromBlob(desc, b)) 73 } 74 } 75 } 76 77 return mainBP, depBPs, nil 78 } 79 80 type openerBlob struct { 81 opener func() (io.ReadCloser, error) 82 } 83 84 func (b *openerBlob) Open() (io.ReadCloser, error) { 85 return b.opener() 86 }