forked from tangled.org/core
this repo has no description
1package workflow 2 3import ( 4 "fmt" 5 6 "tangled.sh/tangled.sh/core/api/tangled" 7) 8 9type Compiler struct { 10 Trigger tangled.Pipeline_TriggerMetadata 11 Diagnostics Diagnostics 12} 13 14type Diagnostics struct { 15 Errors []error 16 Warnings []Warning 17} 18 19func (d *Diagnostics) Combine(o Diagnostics) { 20 d.Errors = append(d.Errors, o.Errors...) 21 d.Warnings = append(d.Warnings, o.Warnings...) 22} 23 24func (d *Diagnostics) AddWarning(path string, kind WarningKind, reason string) { 25 d.Warnings = append(d.Warnings, Warning{path, kind, reason}) 26} 27 28func (d *Diagnostics) AddError(err error) { 29 d.Errors = append(d.Errors, err) 30} 31 32func (d Diagnostics) IsErr() bool { 33 return len(d.Errors) != 0 34} 35 36type Warning struct { 37 Path string 38 Type WarningKind 39 Reason string 40} 41 42type WarningKind string 43 44var ( 45 WorkflowSkipped WarningKind = "workflow skipped" 46 InvalidConfiguration WarningKind = "invalid configuration" 47) 48 49// convert a repositories' workflow files into a fully compiled pipeline that runners accept 50func (compiler *Compiler) Compile(p Pipeline) tangled.Pipeline { 51 cp := tangled.Pipeline{ 52 TriggerMetadata: &compiler.Trigger, 53 } 54 55 for _, w := range p { 56 cw := compiler.compileWorkflow(w) 57 58 // empty workflows are not added to the pipeline 59 if len(cw.Steps) == 0 { 60 continue 61 } 62 63 cp.Workflows = append(cp.Workflows, &cw) 64 } 65 66 return cp 67} 68 69func (compiler *Compiler) compileWorkflow(w Workflow) tangled.Pipeline_Workflow { 70 cw := tangled.Pipeline_Workflow{} 71 72 if !w.Match(compiler.Trigger) { 73 compiler.Diagnostics.AddWarning( 74 w.Name, 75 WorkflowSkipped, 76 fmt.Sprintf("did not match trigger %s", compiler.Trigger.Kind), 77 ) 78 return cw 79 } 80 81 if len(w.Steps) == 0 { 82 compiler.Diagnostics.AddWarning( 83 w.Name, 84 WorkflowSkipped, 85 "empty workflow", 86 ) 87 return cw 88 } 89 90 // validate clone options 91 compiler.analyzeCloneOptions(w) 92 93 cw.Name = w.Name 94 cw.Dependencies = w.Dependencies.AsRecord() 95 for _, s := range w.Steps { 96 step := tangled.Pipeline_Step{ 97 Command: s.Command, 98 Name: s.Name, 99 } 100 for k, v := range s.Environment { 101 e := &tangled.Pipeline_Pair{ 102 Key: k, 103 Value: v, 104 } 105 step.Environment = append(step.Environment, e) 106 } 107 cw.Steps = append(cw.Steps, &step) 108 } 109 for k, v := range w.Environment { 110 e := &tangled.Pipeline_Pair{ 111 Key: k, 112 Value: v, 113 } 114 cw.Environment = append(cw.Environment, e) 115 } 116 117 o := w.CloneOpts.AsRecord() 118 cw.Clone = &o 119 120 return cw 121} 122 123func (compiler *Compiler) analyzeCloneOptions(w Workflow) { 124 if w.CloneOpts.Skip && w.CloneOpts.IncludeSubmodules { 125 compiler.Diagnostics.AddWarning( 126 w.Name, 127 InvalidConfiguration, 128 "cannot apply `clone.skip` and `clone.submodules`", 129 ) 130 } 131 132 if w.CloneOpts.Skip && w.CloneOpts.Depth > 0 { 133 compiler.Diagnostics.AddWarning( 134 w.Name, 135 InvalidConfiguration, 136 "cannot apply `clone.skip` and `clone.depth`", 137 ) 138 } 139}