summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..515407f
--- /dev/null
+++ b/main.go
@@ -0,0 +1,117 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/robfig/cron/v3"
+)
+
+type inputLine struct {
+ Schedule string
+ Task string
+}
+
+var lastSeenInput = map[inputLine]struct{}{}
+
+func main() {
+ p, err := inputFilePath()
+ if err != nil {
+ log.Fatalf("getting input file: %s", err)
+ }
+
+ c := cron.New()
+
+ for {
+ input, err := readInput(p)
+ if err != nil {
+ log.Printf("reading input: %s", err)
+ }
+ changed := inputChanged(lastSeenInput, input)
+ if changed {
+ fmt.Println("changed!")
+ lastSeenInput = input
+ c.Stop()
+ c := cron.New()
+ err := addJobs(c)
+ if err != nil {
+ log.Printf("adding jobs: %s", err)
+ }
+ c.Start()
+ } else {
+ fmt.Println("not changed!")
+ }
+
+ time.Sleep(time.Minute) // re-read the input file every minute
+ }
+
+}
+
+func inputFilePath() (string, error) {
+ args := os.Args
+ if len(args) != 2 {
+ return "", fmt.Errorf("expected one argument (input file path), got %d", len(args)-1)
+ }
+ p := filepath.Clean(args[1])
+
+ // While we're here, check that the input path actually exists and
+ // is stat-able.
+ if _, err := os.Stat(p); err != nil {
+ return "", fmt.Errorf("cannot stat input file: %w", err)
+ }
+
+ return p, nil
+}
+
+var inputFileRe = regexp.MustCompile(`([^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+)\s+(.*)`)
+
+func readInput(p string) (map[inputLine]struct{}, error) {
+ input := map[inputLine]struct{}{}
+
+ f, err := os.Open(p)
+ if err != nil {
+ return nil, fmt.Errorf("opening '%s': %w", p, err)
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if line == "" {
+ continue
+ }
+
+ matches := inputFileRe.FindStringSubmatch(line)
+ if matches == nil || len(matches) != 1+2 {
+ log.Printf("failed to parse input line: '%s'", line)
+ }
+
+ input[inputLine{Schedule: matches[1], Task: matches[2]}] = struct{}{}
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, fmt.Errorf("scanning: %w", err)
+ }
+
+ return input, nil
+}
+
+func inputChanged(old, new map[inputLine]struct{}) bool {
+ if len(new) != len(old) {
+ return true
+ }
+ for k := range old {
+ if _, ok := new[k]; !ok {
+ return true
+ }
+ }
+ return false
+}
+
+func addJobs(c *cron.Cron) error { return nil }