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  }