diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 117 |
1 files changed, 117 insertions, 0 deletions
@@ -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 } |
