tooling/templatize/pkg/pipeline/inspect.go (118 lines of code) (raw):

// Copyright 2025 Microsoft Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package pipeline import ( "context" "fmt" "io" "github.com/Azure/ARO-Tools/pkg/config" ) type StepInspectScope func(context.Context, *Pipeline, Step, *InspectOptions) error func NewStepInspectScopes() map[string]StepInspectScope { return map[string]StepInspectScope{ "vars": inspectVars, } } // InspectOptions contains the options for the Inspect method type InspectOptions struct { Scope string Format string Step string Region string Configuration config.Configuration ScopeFunctions map[string]StepInspectScope OutputFile io.Writer } // NewInspectOptions creates a new PipelineInspectOptions struct func NewInspectOptions(cfg config.Configuration, region, step, scope, format string, outputFile io.Writer) *InspectOptions { return &InspectOptions{ Scope: scope, Format: format, Step: step, Region: region, Configuration: cfg, ScopeFunctions: NewStepInspectScopes(), OutputFile: outputFile, } } func (p *Pipeline) Inspect(ctx context.Context, options *InspectOptions) error { for _, rg := range p.ResourceGroups { for _, step := range rg.Steps { if step.StepName() == options.Step { if inspectFunc, ok := options.ScopeFunctions[options.Scope]; ok { err := inspectFunc(ctx, p, step, options) if err != nil { return err } } else { return fmt.Errorf("unknown inspect scope %q", options.Scope) } return nil } } } return fmt.Errorf("step %q not found", options.Step) } func inspectVars(ctx context.Context, pipeline *Pipeline, s Step, options *InspectOptions) error { var envVars map[string]string switch step := s.(type) { case *ShellStep: outputChainingDependencies := make(map[string]bool) for _, stepVar := range step.Variables { if stepVar.Input != nil && stepVar.Input.Step != "" { outputChainingDependencies[stepVar.Input.Step] = true } } outputChainingDependenciesList := make([]string, 0, len(outputChainingDependencies)) for depStep := range outputChainingDependencies { outputChainingDependenciesList = append(outputChainingDependenciesList, depStep) } inputs, err := aquireOutputChainingInputs(ctx, outputChainingDependenciesList, pipeline, options) if err != nil { return err } envVars, err = step.mapStepVariables(options.Configuration, inputs) if err != nil { return err } default: return fmt.Errorf("inspecting step variables not implemented for action type %s", s.ActionType()) } switch options.Format { case "makefile": printMakefileVars(envVars, options.OutputFile) case "shell": printShellVars(envVars, options.OutputFile) default: return fmt.Errorf("unknown output format %q", options.Format) } return nil } func aquireOutputChainingInputs(ctx context.Context, steps []string, pipeline *Pipeline, options *InspectOptions) (map[string]output, error) { inputs := make(map[string]output) for _, depStep := range steps { runOptions := &PipelineRunOptions{ DryRun: true, Configuration: options.Configuration, Region: options.Region, Step: depStep, SubsciptionLookupFunc: LookupSubscriptionID, NoPersist: true, DeploymentTimeoutSeconds: 60, } outputs, err := RunPipeline(pipeline, ctx, runOptions) if err != nil { return nil, err } for key, value := range outputs { inputs[key] = value } } return inputs, nil } func printMakefileVars(vars map[string]string, writer io.Writer) { for k, v := range vars { fmt.Fprintf(writer, "%s ?= %s\n", k, v) } } func printShellVars(vars map[string]string, writer io.Writer) { for k, v := range vars { fmt.Fprintf(writer, "export %s=\"%s\"\n", k, v) } }