Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

workflow: move workflow parsing into compiler

this simplifies the error collection logic a lot.

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by
Tangled
bba4923d 99e405a1

+66 -50
+6 -10
knotserver/ingester.go
··· 152 152 return err 153 153 } 154 154 155 - var pipeline workflow.Pipeline 155 + var pipeline workflow.RawPipeline 156 156 for _, e := range workflowDir { 157 157 if !e.IsFile { 158 158 continue ··· 164 164 continue 165 165 } 166 166 167 - wf, err := workflow.FromFile(e.Name, contents) 168 - if err != nil { 169 - // TODO: log here, respond to client that is pushing 170 - h.l.Error("failed to parse workflow", "err", err, "path", fpath) 171 - continue 172 - } 173 - 174 - pipeline = append(pipeline, wf) 167 + pipeline = append(pipeline, workflow.RawWorkflow{ 168 + Name: e.Name, 169 + Contents: contents, 170 + }) 175 171 } 176 172 177 173 trigger := tangled.Pipeline_PullRequestTriggerData{ ··· 189 193 }, 190 194 } 191 195 192 - cp := compiler.Compile(pipeline) 196 + cp := compiler.Compile(compiler.Parse(pipeline)) 193 197 eventJson, err := json.Marshal(cp) 194 198 if err != nil { 195 199 return err
+15 -35
knotserver/internal.go
··· 200 200 return err 201 201 } 202 202 203 - pipelineParseErrors := []string{} 204 - 205 - var pipeline workflow.Pipeline 203 + var pipeline workflow.RawPipeline 206 204 for _, e := range workflowDir { 207 205 if !e.IsFile { 208 206 continue ··· 212 214 continue 213 215 } 214 216 215 - wf, err := workflow.FromFile(e.Name, contents) 216 - if err != nil { 217 - h.l.Error("failed to parse workflow", "err", err, "path", fpath) 218 - pipelineParseErrors = append(pipelineParseErrors, fmt.Sprintf("- at %s: %s\n", fpath, err)) 219 - continue 220 - } 221 - 222 - pipeline = append(pipeline, wf) 217 + pipeline = append(pipeline, workflow.RawWorkflow{ 218 + Name: e.Name, 219 + Contents: contents, 220 + }) 223 221 } 224 222 225 223 trigger := tangled.Pipeline_PushTriggerData{ ··· 236 242 }, 237 243 } 238 244 239 - cp := compiler.Compile(pipeline) 245 + cp := compiler.Compile(compiler.Parse(pipeline)) 240 246 eventJson, err := json.Marshal(cp) 241 247 if err != nil { 242 248 return err 243 249 } 244 250 245 251 if pushOptions.verboseCi { 246 - hasDiagnostics := false 247 - if len(pipelineParseErrors) > 0 { 248 - hasDiagnostics = true 249 - *clientMsgs = append(*clientMsgs, "error: failed to parse workflow(s):") 250 - for _, error := range pipelineParseErrors { 251 - *clientMsgs = append(*clientMsgs, error) 252 - } 253 - } 254 - if len(compiler.Diagnostics.Errors) > 0 { 255 - hasDiagnostics = true 256 - *clientMsgs = append(*clientMsgs, "error(s) on pipeline:") 257 - for _, error := range compiler.Diagnostics.Errors { 258 - *clientMsgs = append(*clientMsgs, fmt.Sprintf("- %s:", error)) 259 - } 260 - } 261 - if len(compiler.Diagnostics.Warnings) > 0 { 262 - hasDiagnostics = true 263 - *clientMsgs = append(*clientMsgs, "warning(s) on pipeline:") 264 - for _, warning := range compiler.Diagnostics.Warnings { 265 - *clientMsgs = append(*clientMsgs, fmt.Sprintf("- at %s: %s: %s", warning.Path, warning.Type, warning.Reason)) 266 - } 267 - } 268 - if !hasDiagnostics { 252 + if compiler.Diagnostics.IsEmpty() { 269 253 *clientMsgs = append(*clientMsgs, "success: pipeline compiled with no diagnostics") 254 + } 255 + 256 + for _, e := range compiler.Diagnostics.Errors { 257 + *clientMsgs = append(*clientMsgs, e.String()) 258 + } 259 + 260 + for _, w := range compiler.Diagnostics.Warnings { 261 + *clientMsgs = append(*clientMsgs, w.String()) 270 262 } 271 263 } 272 264
+45 -5
workflow/compile.go
··· 6 6 "tangled.sh/tangled.sh/core/api/tangled" 7 7 ) 8 8 9 + type RawWorkflow struct { 10 + Name string 11 + Contents []byte 12 + } 13 + 14 + type RawPipeline = []RawWorkflow 15 + 9 16 type Compiler struct { 10 17 Trigger tangled.Pipeline_TriggerMetadata 11 18 Diagnostics Diagnostics 12 19 } 13 20 14 21 type Diagnostics struct { 15 - Errors []error 22 + Errors []Error 16 23 Warnings []Warning 24 + } 25 + 26 + func (d *Diagnostics) IsEmpty() bool { 27 + return len(d.Errors) == 0 && len(d.Warnings) == 0 17 28 } 18 29 19 30 func (d *Diagnostics) Combine(o Diagnostics) { ··· 36 25 d.Warnings = append(d.Warnings, Warning{path, kind, reason}) 37 26 } 38 27 39 - func (d *Diagnostics) AddError(err error) { 40 - d.Errors = append(d.Errors, err) 28 + func (d *Diagnostics) AddError(path string, err error) { 29 + d.Errors = append(d.Errors, Error{path, err}) 41 30 } 42 31 43 32 func (d Diagnostics) IsErr() bool { 44 33 return len(d.Errors) != 0 45 34 } 46 35 36 + type Error struct { 37 + Path string 38 + Error error 39 + } 40 + 41 + func (e Error) String() string { 42 + return fmt.Sprintf("error: %s: %s", e.Path, e.Error.Error()) 43 + } 44 + 47 45 type Warning struct { 48 46 Path string 49 47 Type WarningKind 50 48 Reason string 49 + } 50 + 51 + func (w Warning) String() string { 52 + return fmt.Sprintf("warning: %s: %s: %s", w.Path, w.Type, w.Reason) 51 53 } 52 54 53 55 type WarningKind string ··· 70 46 InvalidConfiguration WarningKind = "invalid configuration" 71 47 ) 72 48 49 + func (compiler *Compiler) Parse(p RawPipeline) Pipeline { 50 + var pp Pipeline 51 + 52 + for _, w := range p { 53 + wf, err := FromFile(w.Name, w.Contents) 54 + if err != nil { 55 + compiler.Diagnostics.AddError(w.Name, err) 56 + continue 57 + } 58 + 59 + pp = append(pp, wf) 60 + } 61 + 62 + return pp 63 + } 64 + 73 65 // convert a repositories' workflow files into a fully compiled pipeline that runners accept 74 66 func (compiler *Compiler) Compile(p Pipeline) tangled.Pipeline { 75 67 cp := tangled.Pipeline{ 76 68 TriggerMetadata: &compiler.Trigger, 77 69 } 78 70 79 - for _, w := range p { 80 - cw := compiler.compileWorkflow(w) 71 + for _, wf := range p { 72 + cw := compiler.compileWorkflow(wf) 81 73 82 74 // empty workflows are not added to the pipeline 83 75 if len(cw.Steps) == 0 {