-
Notifications
You must be signed in to change notification settings - Fork 4
/
schedule_attribute.go
97 lines (86 loc) · 2.49 KB
/
schedule_attribute.go
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
package validation
import (
"strings"
"github.com/teamkeel/keel/cron"
"github.com/teamkeel/keel/schema/parser"
"github.com/teamkeel/keel/schema/validation/errorhandling"
)
func ScheduleAttributeRule(asts []*parser.AST, errs *errorhandling.ValidationErrors) Visitor {
return Visitor{
EnterAttribute: func(attribute *parser.AttributeNode) {
if attribute.Name.Value != parser.AttributeSchedule {
return
}
if len(attribute.Arguments) != 1 {
errs.AppendError(errorhandling.NewValidationErrorWithDetails(
errorhandling.AttributeArgumentError,
errorhandling.ErrorDetails{
Message: "@schedule must have exactly one argument",
},
attribute.Name,
))
return
}
arg := attribute.Arguments[0]
if arg.Label != nil {
errs.AppendError(errorhandling.NewValidationErrorWithDetails(
errorhandling.AttributeArgumentError,
errorhandling.ErrorDetails{
Message: "argument to @schedule cannot be labelled",
},
arg.Label,
))
return
}
op, err := arg.Expression.ToValue()
if err != nil || op.String == nil {
errs.AppendError(errorhandling.NewValidationErrorWithDetails(
errorhandling.AttributeArgumentError,
errorhandling.ErrorDetails{
Message: "argument must be a string",
Hint: "e.g. @schedule(\"every 10 minutes\")",
},
arg.Expression,
))
return
}
src := strings.TrimPrefix(*op.String, `"`)
src = strings.TrimSuffix(src, `"`)
_, err = cron.Parse(src)
if err != nil {
cronError, ok := cron.ToError(err)
if !ok || cronError.Token == nil {
errs.AppendError(errorhandling.NewValidationErrorWithDetails(
errorhandling.AttributeArgumentError,
errorhandling.ErrorDetails{
Message: err.Error(),
},
arg.Expression,
))
return
}
start, end := arg.Expression.GetPositionRange()
tok := cronError.Token
endOffset := (len(*op.String) - tok.End)
errs.AppendError(&errorhandling.ValidationError{
Code: string(errorhandling.AttributeArgumentError),
ErrorDetails: &errorhandling.ErrorDetails{
Message: cronError.Message,
},
Pos: errorhandling.LexerPos{
Filename: start.Filename,
Offset: start.Offset + tok.Start,
Line: start.Line,
Column: start.Column + tok.Start,
},
EndPos: errorhandling.LexerPos{
Filename: end.Filename,
Offset: end.Offset - endOffset,
Line: end.Line,
Column: end.Column - endOffset,
},
})
}
},
}
}