This repository has been archived by the owner on Jan 17, 2023. It is now read-only.
forked from webdevops/go-crond
-
Notifications
You must be signed in to change notification settings - Fork 3
/
parser.go
135 lines (108 loc) · 3.07 KB
/
parser.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
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
package main
import (
"bufio"
"fmt"
"io"
"regexp"
"strings"
)
const (
ENV_LINE = `^(\S+)=(\S+)\s*$`
// ----spec------------------------------------ --user-- -cmd-
CRONJOB_SYSTEM = `^\s*([^@\s]+\s+\S+\s+\S+\s+\S+\s+\S+|@every\s+\S+)\s+([^\s]+)\s+(.+)$`
// ----spec------------------------------------ -cmd-
CRONJOB_USER = `^\s*([^@\s]+\s+\S+\s+\S+\s+\S+\s+\S+|@every\s+\S+)\s+(.+)$`
DEFAULT_SHELL = "sh"
)
var (
envLineRegex = regexp.MustCompile(ENV_LINE)
cronjobSystemRegex = regexp.MustCompile(CRONJOB_SYSTEM)
cronjobUserRegex = regexp.MustCompile(CRONJOB_USER)
)
type EnvVar struct {
Name string
Value string
}
type CrontabEntry struct {
Spec string
User string
Command string
Env []string
Shell string
}
type Parser struct {
cronLineRegex *regexp.Regexp
reader io.Reader
cronjobUsername string
}
// Create new crontab parser (user crontab without user specification)
func NewCronjobUserParser(reader io.Reader, username string) (*Parser, error) {
p := &Parser{
cronLineRegex: cronjobUserRegex,
reader: reader,
cronjobUsername: username,
}
return p, nil
}
// Create new crontab parser (crontab with user specification)
func NewCronjobSystemParser(reader io.Reader) (*Parser, error) {
p := &Parser{
cronLineRegex: cronjobSystemRegex,
reader: reader,
cronjobUsername: CRONTAB_TYPE_SYSTEM,
}
return p, nil
}
// Parse crontab
func (p *Parser) Parse() []CrontabEntry {
entries := p.parseLines()
return entries
}
// Parse lines from crontab
func (p *Parser) parseLines() []CrontabEntry {
var entries []CrontabEntry
var crontabSpec string
var crontabUser string
var crontabCommand string
var environment []string
shell := DEFAULT_SHELL
specCleanupRegexp := regexp.MustCompile(`\s+`)
scanner := bufio.NewScanner(p.reader)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// comment line
if strings.HasPrefix(line, "#") {
continue
}
// environment line
if envLineRegex.MatchString(line) == true {
m := envLineRegex.FindStringSubmatch(line)
envName := strings.TrimSpace(m[1])
envValue := strings.TrimSpace(m[2])
if envName == "SHELL" {
// custom shell for command
shell = envValue
} else {
// normal environment variable
environment = append(environment, fmt.Sprintf("%s=%s", envName, envValue))
}
}
// cronjob line
if p.cronLineRegex.MatchString(line) == true {
m := p.cronLineRegex.FindStringSubmatch(line)
if p.cronjobUsername == CRONTAB_TYPE_SYSTEM {
crontabSpec = strings.TrimSpace(m[1])
crontabUser = strings.TrimSpace(m[2])
crontabCommand = strings.TrimSpace(m[3])
} else {
crontabSpec = strings.TrimSpace(m[1])
crontabUser = p.cronjobUsername
crontabCommand = strings.TrimSpace(m[2])
}
// shrink white spaces for better handling
crontabSpec = specCleanupRegexp.ReplaceAllString(crontabSpec, " ")
entries = append(entries, CrontabEntry{Spec: crontabSpec, User: crontabUser, Command: crontabCommand, Env: environment, Shell: shell})
}
}
return entries
}