diff --git a/pkg/buildplan/artifact.go b/pkg/buildplan/artifact.go index 6c79425742..4bdb28b33e 100644 --- a/pkg/buildplan/artifact.go +++ b/pkg/buildplan/artifact.go @@ -29,6 +29,8 @@ type Artifact struct { IsRuntimeDependency bool IsBuildtimeDependency bool + Builder *Artifact + platforms []strfmt.UUID children []ArtifactRelation } diff --git a/pkg/buildplan/hydrate.go b/pkg/buildplan/hydrate.go index 05f84302b9..d3894467ce 100644 --- a/pkg/buildplan/hydrate.go +++ b/pkg/buildplan/hydrate.go @@ -37,11 +37,15 @@ func (b *BuildPlan) hydrate() error { } // We have all the artifacts we're interested in now, but we still want to relate them to a source; ie. an ingredient. + // We also want to relate artifacts to their builders, because dynamically imported ingredients have a special installation process. // This will also hydrate our requirements, because they are based on the source ID. for _, artifact := range b.artifacts { if err := b.hydrateWithIngredients(artifact, platformID, ingredientLookup); err != nil { return errs.Wrap(err, "hydrating with ingredients failed") } + if err := b.hydrateWithBuilders(artifact, artifactLookup); err != nil { + return errs.Wrap(err, "hydrating with builders failed") + } } } @@ -202,6 +206,30 @@ func (b *BuildPlan) hydrateWithIngredients(artifact *Artifact, platformID *strfm return nil } +func (b *BuildPlan) hydrateWithBuilders(artifact *Artifact, artifactLookup map[strfmt.UUID]*Artifact) error { + err := b.raw.WalkViaSteps([]strfmt.UUID{artifact.ArtifactID}, raw.WalkViaBuilder, func(node interface{}, parent *raw.Artifact) error { + v, ok := node.(*raw.Artifact) + if !ok { + return nil // continue + } + + builder, ok := artifactLookup[v.NodeID] + if !ok { + builder = createArtifact(v) + b.artifacts = append(b.artifacts, builder) + artifactLookup[v.NodeID] = builder + } + + artifact.Builder = builder + return nil + }) + if err != nil { + return errs.Wrap(err, "error hydrating builders") + } + + return nil +} + // sanityCheck will for convenience sake validate that we have no duplicates here while on a dev machine. // If there are duplicates we're likely to see failures down the chain if live, though that's by no means guaranteed. // Surfacing it here will make it easier to reason about the failure. diff --git a/pkg/buildplan/raw/raw.go b/pkg/buildplan/raw/raw.go index 8680b18699..7687024082 100644 --- a/pkg/buildplan/raw/raw.go +++ b/pkg/buildplan/raw/raw.go @@ -18,6 +18,7 @@ type StepInputTag string const ( // Tag types TagSource StepInputTag = "src" + TagBuilder StepInputTag = "builder" TagDependency StepInputTag = "deps" ) diff --git a/pkg/buildplan/raw/walk.go b/pkg/buildplan/raw/walk.go index 89294a8cac..2091e59b83 100644 --- a/pkg/buildplan/raw/walk.go +++ b/pkg/buildplan/raw/walk.go @@ -27,6 +27,10 @@ var ( TagDependency, false, } + WalkViaBuilder = WalkStrategy{ + TagBuilder, + true, + } ) // WalkViaSteps walks the graph and reports on nodes it encounters diff --git a/pkg/runtime/ecosystem.go b/pkg/runtime/ecosystem.go index c46fb0da21..90ead18a38 100644 --- a/pkg/runtime/ecosystem.go +++ b/pkg/runtime/ecosystem.go @@ -5,6 +5,8 @@ import ( ecosys "github.com/ActiveState/cli/pkg/runtime/ecosystem" ) +const starBuilder = "star-builder" + type ecosystem interface { Init(runtimePath string, buildplan *buildplan.BuildPlan) error Namespaces() []string @@ -27,6 +29,10 @@ func init() { } func artifactMatchesEcosystem(a *buildplan.Artifact, e ecosystem) bool { + if a.Builder != nil && a.Builder.DisplayName != starBuilder { + return false + } + for _, namespace := range e.Namespaces() { for _, i := range a.Ingredients { if i.Namespace == namespace {