func Elaborate()

in cmd/hub/compose/elaborate.go [39:150]


func Elaborate(manifestFilename string,
	parametersFilenames []string, environmentOverrides, explicitProvides string,
	stateManifests []string, useStateStackParameters bool, elaborateManifests []string, componentsBaseDir string,
	pipe io.WriteCloser) {

	if config.Verbose {
		parametersFrom := ""
		if len(parametersFilenames) > 0 {
			parametersFrom = fmt.Sprintf(" with parameters from %s", strings.Join(parametersFilenames, ", "))
		}
		overrides := ""
		if environmentOverrides != "" {
			overrides = fmt.Sprintf(" with environment overrides: %s", environmentOverrides)
		}
		state := ""
		if len(stateManifests) > 0 {
			state = fmt.Sprintf(" with state from %v", stateManifests)
		}
		log.Printf("Assembling %v from `%s`%s%s%s", elaborateManifests, manifestFilename,
			parametersFrom, overrides, state)
	}

	environment, err := util.ParseKvList(environmentOverrides)
	if err != nil {
		log.Fatalf("Unable to parse environment settings `%s`: %v", environmentOverrides, err)
	}

	wellKnown, err := manifest.GetWellKnownParametersManifest()
	if err != nil {
		log.Printf("No well-known parameters loaded: %v", err)
		wellKnown = &manifest.WellKnownParametersManifest{}
	}
	wellKnownKV := make(map[string]manifest.Parameter)
	for _, known := range wellKnown.Parameters {
		wellKnownKV[known.Name] = known
	}

	var st *state.StateManifest
	if len(stateManifests) > 0 {
		st = state.MustParseStateFiles(stateManifests)
	}

	extraKubernetesParams := func(elaborated manifest.Manifest) []manifest.Parameter {
		if st != nil && util.ContainsAny(elaborated.Requires, []string{"kubernetes", "kubectl"}) {
			outputs := findKubernetesProvider(st)
			if len(outputs) > 0 {
				apiParameters := make([]string, 0, len(kube.KubernetesParameters))
				for _, output := range outputs {
					if util.Contains(kube.KubernetesParameters, output.Name) && !util.Empty(output.Value) {
						apiParameters = append(apiParameters, output.Name)
					}
				}
				return manifest.MakeParameters(util.Uniq(apiParameters))
			}
		}
		return nil
	}

	stackManifest, componentsManifests := elaborate(manifestFilename, parametersFilenames, environment,
		wellKnownKV, componentsBaseDir, []string{}, 0, extraKubernetesParams)

	if pipe != nil {
		metricTags := fmt.Sprintf("stack:%s", stackManifest.Meta.Name)
		pipe.Write([]byte(metricTags))
		pipe.Close()
	}

	isApplication := stackManifest.Kind == "application"

	if isApplication {
		checkApplicationNameClash(stackManifest)
	}

	platformProvides := util.SplitPaths(explicitProvides)
	if len(platformProvides) > 0 {
		stackManifest.Requires = connectExplicitProvides(stackManifest.Requires, platformProvides)
		sort.Strings(platformProvides)
	}
	if st != nil {
		// we might get in trouble here setting `dns.domain` from Kubernetes state on empty
		// `kind: user` parameter with `fromEnv:`
		// at least there will be a warning for mismatched values
		setValuesFromState(stackManifest.Parameters, st, useStateStackParameters)
		stackManifest.Requires = connectStateProvides(stackManifest.Requires, st.Provides)
		platformProvides = util.MergeUnique(platformProvides, util.SortedKeys2(st.Provides))
	}
	if len(platformProvides) > 0 {
		stackManifest.Platform.Provides = util.MergeUnique(stackManifest.Platform.Provides, platformProvides)
	}
	warnNoValue(stackManifest.Parameters)
	warnFromEnvValueMismatch(stackManifest.Parameters)

	if isApplication {
		bare := stackManifest.Lifecycle.Bare
		if bare != "" && bare != "allow" {
			util.Warn("`lifecycle.bare` specify `%s` but the only value recognized is `allow`", bare)
		}
		componentsManifests = transformApplicationIntoComponent(stackManifest, componentsManifests)
	}

	setDefaultLifecycleVerbs(componentsManifests)

	guessAndMarkSecrets(stackManifest.Outputs)
	for i := range componentsManifests {
		guessAndMarkSecrets(componentsManifests[i].Outputs)
	}

	err = writeStackManifest(elaborateManifests, stackManifest, componentsManifests)
	if err != nil {
		log.Fatalf("Unable to write: %v", err)
	}
}