~james/core

core/spindle/models/models.go -rw-r--r-- 2.8 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 14 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package models

import (
	"fmt"
	"regexp"
	"slices"
	"time"

	"github.com/bluesky-social/indigo/atproto/syntax"
)

var (
	re = regexp.MustCompile(`[^a-zA-Z0-9_.-]`)
)

type PipelineId syntax.RecordKey

func (p PipelineId) String() string { return string(p) }

type WorkflowId struct {
	PipelineId
	Name string
}

func (wid WorkflowId) String() string {
	return fmt.Sprintf("%s-%s", normalize(string(wid.PipelineId)), normalize(wid.Name))
}

func normalize(name string) string {
	normalized := re.ReplaceAllString(name, "-")
	return normalized
}

type StatusKind string

var (
	StatusKindPending   StatusKind = "pending"
	StatusKindBlocked   StatusKind = "blocked"
	StatusKindRunning   StatusKind = "running"
	StatusKindFailed    StatusKind = "failed"
	StatusKindTimeout   StatusKind = "timeout"
	StatusKindCancelled StatusKind = "cancelled"
	StatusKindSuccess   StatusKind = "success"

	StartStates [2]StatusKind = [2]StatusKind{
		StatusKindPending,
		StatusKindRunning,
	}
	FinishStates [4]StatusKind = [4]StatusKind{
		StatusKindFailed,
		StatusKindTimeout,
		StatusKindCancelled,
		StatusKindSuccess,
	}
)

func (s StatusKind) String() string {
	return string(s)
}

func (s StatusKind) IsStart() bool {
	return slices.Contains(StartStates[:], s)
}

func (s StatusKind) IsFinish() bool {
	return slices.Contains(FinishStates[:], s)
}

type LogKind string

var (
	// step log data
	LogKindData LogKind = "data"
	// indicates status of a step
	LogKindControl LogKind = "control"
)

// step status indicator in control log lines
type StepStatus string

var (
	StepStatusStart StepStatus = "start"
	StepStatusEnd   StepStatus = "end"
)

type StepOutcome string

var (
	StepOutcomeSuccess StepOutcome = "success"
	StepOutcomeFailed  StepOutcome = "failed"
)

func OutcomeOf(err error) StepOutcome {
	if err != nil {
		return StepOutcomeFailed
	}
	return StepOutcomeSuccess
}

type LogLine struct {
	Kind    LogKind   `json:"kind"`
	Content string    `json:"content"`
	Time    time.Time `json:"time"`
	StepId  int       `json:"step_id"`

	// fields if kind is "data"
	Stream string `json:"stream,omitempty"`

	// fields if kind is "control"
	StepStatus  StepStatus  `json:"step_status,omitempty"`
	StepKind    StepKind    `json:"step_kind,omitempty"`
	StepCommand string      `json:"step_command,omitempty"`
	StepOutcome StepOutcome `json:"step_outcome,omitempty"`
}

func NewDataLogLine(idx int, content, stream string) LogLine {
	return LogLine{
		Kind:    LogKindData,
		Time:    time.Now(),
		Content: content,
		StepId:  idx,
		Stream:  stream,
	}
}

func NewControlLogLine(idx int, step Step, status StepStatus) LogLine {
	return LogLine{
		Kind:        LogKindControl,
		Time:        time.Now(),
		Content:     step.Name(),
		StepId:      idx,
		StepStatus:  status,
		StepKind:    step.Kind(),
		StepCommand: step.Command(),
	}
}