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 cw.Steps = append(cw.Steps, &step) 101 } 102 for k, v := range w.Environment { 103 e := &tangled.Pipeline_Workflow_Environment_Elem{ 104 Key: k, 105 Value: v, 106 } 107 cw.Environment = append(cw.Environment, e) 108 } 109 110 o := w.CloneOpts.AsRecord() 111 cw.Clone = &o 112 113 return cw 114} 115 116func (compiler *Compiler) analyzeCloneOptions(w Workflow) { 117 if w.CloneOpts.Skip && w.CloneOpts.IncludeSubmodules { 118 compiler.Diagnostics.AddWarning( 119 w.Name, 120 InvalidConfiguration, 121 "cannot apply `clone.skip` and `clone.submodules`", 122 ) 123 } 124 125 if w.CloneOpts.Skip && w.CloneOpts.Depth > 0 { 126 compiler.Diagnostics.AddWarning( 127 w.Name, 128 InvalidConfiguration, 129 "cannot apply `clone.skip` and `clone.depth`", 130 ) 131 } 132}