Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jkutner
Last active August 21, 2020 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkutner/e9472c1d831760fe72443363963646f6 to your computer and use it in GitHub Desktop.
Save jkutner/e9472c1d831760fe72443363963646f6 to your computer and use it in GitHub Desktop.
func (b *Builder) RegularBuild(group BuildpackGroup, workspaceDir, layersDir string) (*BuildMetadata, error) {
platformDir, err := filepath.Abs(b.PlatformDir)
if err != nil {
return nil, err
}
layersDir, err := filepath.Abs(layersDir)
if err != nil {
return nil, err
}
appDir, err := filepath.Abs(workspaceDir)
if err != nil {
return nil, err
}
planDir, err := ioutil.TempDir("", "plan.")
if err != nil {
return nil, err
}
defer os.RemoveAll(planDir)
plan := b.Plan
procMap := processMap{}
var bom []BOMEntry
var slices []layers.Slice
var labels []Label
for _, bp := range group.Group {
launch, newPlan, bpBOM, err := b.build(bp, layersDir, planDir, platformDir, appDir, plan)
if err != nil {
return nil, err
}
plan = newPlan
bom = append(bom, bpBOM...)
procMap.add(launch.Processes)
slices = append(slices, launch.Slices...)
labels = append(labels, launch.Labels...)
}
if err := b.convertMetadataToVersion(bom); err != nil {
return nil, err
}
return &BuildMetadata{
BOM: bom,
Buildpacks: b.Group.Group,
Labels: labels,
Processes: procMap.list(),
Slices: slices,
}, nil
}
func (b *Builder) StackBuild(group BuildpackGroup, workspaceDir, rawLayersDir string) (*BuildMetadata, error) {
platformDir, err := filepath.Abs(b.PlatformDir)
if err != nil {
return nil, err
}
layersDir, err := filepath.Abs(rawLayersDir)
if err != nil {
return nil, err
}
appDir, err := filepath.Abs(workspaceDir)
if err != nil {
return nil, err
}
planDir, err := ioutil.TempDir("", "plan.")
if err != nil {
return nil, err
}
defer os.RemoveAll(planDir)
plan := b.Plan
procMap := processMap{}
var bom []BOMEntry
var slices []layers.Slice
var labels []Label
for _, bp := range group.Group {
launch, newPlan, bpBOM, err := b.build(bp, layersDir, planDir, platformDir, appDir, plan)
if err != nil {
return nil, err
}
if err := b.Snapshotter.TakeSnapshot(fmt.Sprintf("%s.tgz", bpLayersDir)); err != nil {
return nil, err
}
plan = newPlan
bom = append(bom, bpBOM...)
procMap.add(launch.Processes)
slices = append(slices, launch.Slices...)
labels = append(labels, launch.Labels...)
}
if err := b.convertMetadataToVersion(bom); err != nil {
return nil, err
}
return &BuildMetadata{
BOM: bom,
Buildpacks: b.Group.Group,
Labels: labels,
Processes: procMap.list(),
Slices: slices,
}, nil
}
func (b *Builder) build(bp Buildpack, layersDir, planDir, platformDir, appDir string, plan BuildPlan) (LaunchTOML, BuildPlan, []BOMEntry, error) {
bpInfo, err := bp.Lookup(b.BuildpacksDir)
if err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
bpDirName := launch.EscapeID(bp.ID)
bpLayersDir := filepath.Join(layersDir, bpDirName)
bpPlanDir := filepath.Join(planDir, bpDirName)
if err := os.MkdirAll(bpLayersDir, 0777); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
if err := os.MkdirAll(bpPlanDir, 0777); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
bpPlanPath := filepath.Join(bpPlanDir, "plan.toml")
foundPlan := plan.find(bp.noAPI())
if api.MustParse(bp.API).Equal(api.MustParse("0.2")) {
for i := range foundPlan.Entries {
foundPlan.Entries[i].convertMetadataToVersion()
}
}
if err := WriteTOML(bpPlanPath, foundPlan); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
cmd := exec.Command(
filepath.Join(bpInfo.Path, "bin", "build"),
bpLayersDir,
platformDir,
bpPlanPath,
)
cmd.Dir = appDir
cmd.Stdout = b.Out.Writer()
cmd.Stderr = b.Err.Writer()
if bpInfo.Buildpack.ClearEnv {
cmd.Env = b.Env.List()
} else {
cmd.Env, err = b.Env.WithPlatform(platformDir)
if err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
}
cmd.Env = append(cmd.Env, EnvBuildpackDir+"="+bpInfo.Path)
if err := cmd.Run(); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, NewLifecycleError(err, ErrTypeBuildpack)
}
if err := setupEnv(b.Env, bpLayersDir); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
var bpPlanOut BuildpackPlan
if _, err := toml.DecodeFile(bpPlanPath, &bpPlanOut); err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
var bpBOM []BOMEntry
plan, bpBOM = plan.filter(bp, bpPlanOut)
var launch LaunchTOML
tomlPath := filepath.Join(bpLayersDir, "launch.toml")
if _, err := toml.DecodeFile(tomlPath, &launch); os.IsNotExist(err) {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, nil
} else if err != nil {
return LaunchTOML{}, BuildPlan{}, []BOMEntry{}, err
}
for i := range launch.Processes {
launch.Processes[i].BuildpackID = bp.ID
}
return launch, plan, bpBOM, nil
}
func (b Builder) convertMetadataToVersion(bom []BOMEntry) error {
if b.PlatformAPI.Compare(api.MustParse("0.4")) < 0 {
//plaformApiVersion is less than comparisonVersion
for i := range bom {
if err := bom[i].convertMetadataToVersion(); err != nil {
return err
}
}
} else {
for i := range bom {
if err := bom[i].convertVersionToMetadata(); err != nil {
return err
}
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment