├── rules.go ├── crond_test.go └── crond.go /rules.go: -------------------------------------------------------------------------------- 1 | package crond 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/gorhill/cronexpr" 7 | ) 8 | 9 | const ( 10 | NATIVE = iota 11 | SHELL 12 | ) 13 | 14 | type Rule struct { 15 | expr *cronexpr.Expression 16 | cmd string 17 | kind int 18 | } 19 | 20 | type Rules []Rule 21 | 22 | func (r *Rule) Cmd() string { return r.cmd } 23 | 24 | func parseCronLine(line string) (Rule, error) { 25 | rule := Rule{} 26 | 27 | elems := strings.Fields(line) 28 | 29 | exprString := strings.Join(elems[:5], " ") 30 | expr, err := cronexpr.Parse(exprString) 31 | if err != nil { 32 | return rule, err 33 | } 34 | 35 | rule.expr = expr 36 | rule.kind = SHELL 37 | rule.cmd = strings.Join(elems[5:], " ") 38 | 39 | return rule, nil 40 | } 41 | -------------------------------------------------------------------------------- /crond_test.go: -------------------------------------------------------------------------------- 1 | package crond 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestNew(t *testing.T) { 10 | Convey("Testing New", t, func() { 11 | manager := New() 12 | So(manager, ShouldHaveSameTypeAs, Manager{}) 13 | }) 14 | } 15 | 16 | func TestManager_ParseCrontab(t *testing.T) { 17 | Convey("Testing Manager.ParseCrontab", t, func() { 18 | manager := New() 19 | 20 | err := manager.ParseCrontab(` 21 | * * * * * echo minutely 22 | */2 * * * * echo every 2 minutes 23 | 0 * * * * echo hourly 24 | 0 0 * * * echo daily at midnight 25 | 0 12 * * * echo daily at noon 26 | `) 27 | 28 | So(err, ShouldBeNil) 29 | So(len(manager.Rules()), ShouldEqual, 5) 30 | // So(manager.Rules()[0].Cmd(), ShouldEqual, "echo minutely") 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /crond.go: -------------------------------------------------------------------------------- 1 | package crond 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type Manager struct { 9 | rules Rules 10 | } 11 | 12 | func New() Manager { 13 | return Manager{ 14 | rules: make(Rules, 0), 15 | } 16 | } 17 | 18 | func (m *Manager) Start() { 19 | fmt.Println("START") 20 | } 21 | 22 | func (m *Manager) AddLine(line string) error { 23 | rule, err := parseCronLine(line) 24 | if err != nil { 25 | return err 26 | } 27 | m.rules = append(m.rules, rule) 28 | return nil 29 | } 30 | 31 | func (m *Manager) ParseCrontab(content string) error { 32 | lines := strings.Split(content, "\n") 33 | 34 | rules := Rules{} 35 | for _, line := range lines { 36 | line = strings.TrimSpace(line) 37 | if line == "" || line[0] == '#' { 38 | continue 39 | } 40 | 41 | rule, err := parseCronLine(line) 42 | if err != nil { 43 | return err 44 | } 45 | rules = append(rules, rule) 46 | } 47 | 48 | m.rules = rules 49 | return nil 50 | } 51 | 52 | func (m *Manager) Rules() Rules { return m.rules } 53 | --------------------------------------------------------------------------------