in step_includeworkflow.go [35:138]
func (i *IncludeWorkflow) populate(ctx context.Context, s *Step) DError {
// Typically s.Workflow is instantiated when the parent workflow is read in NewFromFile.
// Workflow could be nil when the parent workflow is constructed manually using Go structs.
if i.Path != "" && i.Workflow == nil {
var err error
if i.Workflow, err = s.w.NewIncludedWorkflowFromFile(i.Path); err != nil {
return newErr("failed to parse duration for step includeworkflow", err)
}
} else {
if i.Workflow == nil {
return Errf(fmt.Sprintf("IncludeWorkflow %q does not have a workflow", s.name))
}
s.w.includeWorkflow(i.Workflow)
}
i.Workflow.id = i.Workflow.parent.id
i.Workflow.username = i.Workflow.parent.username
i.Workflow.ComputeClient = i.Workflow.parent.ComputeClient
i.Workflow.StorageClient = i.Workflow.parent.StorageClient
i.Workflow.CloudLoggingClient = i.Workflow.parent.CloudLoggingClient
i.Workflow.GCSPath = i.Workflow.parent.GCSPath
i.Workflow.Name = i.Workflow.parent.Name
i.Workflow.Project = i.Workflow.parent.Project
i.Workflow.Zone = i.Workflow.parent.Zone
i.Workflow.DefaultTimeout = i.Workflow.parent.DefaultTimeout
i.Workflow.autovars = i.Workflow.parent.autovars
i.Workflow.bucket = i.Workflow.parent.bucket
i.Workflow.scratchPath = i.Workflow.parent.scratchPath
i.Workflow.sourcesPath = i.Workflow.parent.sourcesPath
i.Workflow.logsPath = i.Workflow.parent.logsPath
i.Workflow.outsPath = i.Workflow.parent.outsPath
i.Workflow.externalLogging = i.Workflow.parent.externalLogging
i.Workflow.Logger = i.Workflow.parent.Logger
i.Workflow.Name = s.name
i.Workflow.DefaultTimeout = s.Timeout
var errs DError
Loop:
for k, v := range i.Vars {
for wv := range i.Workflow.Vars {
if k == wv {
i.Workflow.AddVar(k, v)
continue Loop
}
}
errs = addErrs(errs, Errf("unknown workflow Var %q passed to IncludeWorkflow %q", k, s.name))
}
if errs != nil {
return errs
}
var replacements []string
for k, v := range i.Workflow.autovars {
if k == "NAME" {
v = s.name
}
if k == "WFDIR" {
v = i.Workflow.workflowDir
}
replacements = append(replacements, fmt.Sprintf("${%s}", k), v)
}
substitute(reflect.ValueOf(i.Workflow).Elem(), strings.NewReplacer(replacements...))
for k, v := range i.Workflow.Vars {
replacements = append(replacements, fmt.Sprintf("${%s}", k), v.Value)
}
substitute(reflect.ValueOf(i.Workflow).Elem(), strings.NewReplacer(replacements...))
for name, st := range i.Workflow.Steps {
st.name = name
st.w = i.Workflow
if err := st.w.populateStep(ctx, st); err != nil {
return err
}
}
// We do this here, and not in validate, as embedded startup scripts could
// have what we think are daisy variables.
if err := i.Workflow.validateVarsSubbed(); err != nil {
return err
}
if err := i.Workflow.substituteSourceVars(ctx, reflect.ValueOf(i.Workflow).Elem()); err != nil {
return err
}
// Copy Sources up to parent resolving relative paths as we go.
for k, v := range i.Workflow.Sources {
if v == "" {
continue
}
if _, ok := s.w.Sources[k]; ok {
return Errf("source %q already exists in workflow", k)
}
if s.w.Sources == nil {
s.w.Sources = map[string]string{}
}
if _, _, err := splitGCSPath(v); err != nil && !filepath.IsAbs(v) {
v = filepath.Join(i.Workflow.workflowDir, v)
}
s.w.Sources[k] = v
}
return nil
}