Skip to content

Commit

Permalink
Merge pull request #80 from winebarrel/add_cronskd
Browse files Browse the repository at this point in the history
Add cronskd command
  • Loading branch information
winebarrel authored Nov 10, 2024
2 parents fc52e0f + e8fa029 commit 2e5b081
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
/cronviz.exe
/crongrep
/crongrep.exe
/cronskd
/cronskd.exe
/dist/
33 changes: 32 additions & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ builds:
- -X main.version={{.Version}}
env:
- CGO_ENABLED=0
- id: cronskd
binary: cronskd
dir: ./cmd/cronskd
ldflags:
- -X main.version={{.Version}}
env:
- CGO_ENABLED=0
checksum:
name_template: "checksums.txt"
archives:
Expand All @@ -46,6 +53,9 @@ archives:
- id: crongrep
builds: [crongrep]
name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
- id: cronskd
builds: [cronskd]
name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
brews:
- name: cronplan
ids: [cronplan]
Expand Down Expand Up @@ -87,6 +97,16 @@ brews:
license: MIT
install: |
bin.install 'crongrep'
- name: cronskd
ids: [cronskd]
repository:
owner: winebarrel
name: homebrew-cronplan
homepage: https://github.com/winebarrel/cronplan
description: cronskd is a tool to show a schedule of cron expressions.
license: MIT
install: |
bin.install 'cronskd'
nfpms:
- id: cronplan-nfpms
builds: [cronplan]
Expand Down Expand Up @@ -126,7 +146,18 @@ nfpms:
file_name_template: "{{ .Binary }}_{{ .Version }}_{{ .Arch }}"
homepage: https://github.com/winebarrel/cronplan
maintainer: Genki Sugawara <sugawara@winebarrel.jp>
description: crongrep is a tool to visualize cron schedule.
description: crongrep is a tool to grep with cron expression.
license: MIT
formats:
- deb
- rpm
bindir: /usr/bin
- id: cronskd-nfpms
builds: [cronskd]
file_name_template: "{{ .Binary }}_{{ .Version }}_{{ .Arch }}"
homepage: https://github.com/winebarrel/cronplan
maintainer: Genki Sugawara <sugawara@winebarrel.jp>
description: cronskd is a tool to show a schedule of cron expressions.
license: MIT
formats:
- deb
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ build:
cd ./cmd/cronmatch && go build -o ../../cronmatch
cd ./cmd/cronviz && go build -o ../../cronviz
cd ./cmd/crongrep && go build -o ../../crongrep
cd ./cmd/cronskd && go build -o ../../cronskd

.PHONY: vet
vet:
Expand All @@ -26,3 +27,4 @@ clean:
rm -f cronmatch cronmatch.exe
rm -f cronviz cronviz.exe
rm -f crongrep crongrep.exe
rm -f cronskd cronskd.exe
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,45 @@ Wed, 11 Oct 2023 12:10:00
Thu, 26 Oct 2023 12:10:00
```

# cronskd CLI

CLI to show a schedule of cron expressions.

## Installation

```
brew install winebarrel/cronplan/cronskd
```

## Usage

```
Usage: cronskd [OPTION] [FILE]
-e string
end date (default: end of day)
-s string
start date (default: beginning of day)
-version
print version and exit
```

```
$ cat exprs.txt
0 10 * * ? *
15 12 * * ? *
0 18 ? * MON-FRI *
0 8 1 * ? *
5 8-10 ? * MON-FRI *
$ cronskd -s '2024-11-11' exprs.txt
Mon, 11 Nov 2024 08:05:00 5 8-10 ? * MON-FRI *
Mon, 11 Nov 2024 09:05:00 5 8-10 ? * MON-FRI *
Mon, 11 Nov 2024 10:00:00 0 10 * * ? *
Mon, 11 Nov 2024 10:05:00 5 8-10 ? * MON-FRI *
Mon, 11 Nov 2024 12:15:00 15 12 * * ? *
Mon, 11 Nov 2024 18:00:00 0 18 ? * MON-FRI *
```

## Related Links

* [Cron expressions reference - Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html)
Expand Down
70 changes: 70 additions & 0 deletions cmd/cronskd/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
)

var (
version string
)

type flags struct {
file string
start string
end string
}

func init() {
cmdLine := flag.NewFlagSet(filepath.Base(os.Args[0]), flag.ExitOnError)

cmdLine.Usage = func() {
fmt.Fprintf(cmdLine.Output(), "Usage: %s [OPTION] [FILE]\n", cmdLine.Name())
cmdLine.PrintDefaults()
}

flag.CommandLine = cmdLine
}

func parseFlags() *flags {
flags := &flags{}
flag.StringVar(&flags.start, "s", "", "start date (default: beginning of day)")
flag.StringVar(&flags.end, "e", "", "end date (default: end of day)")
showVersion := flag.Bool("version", false, "print version and exit")
flag.Parse()

if *showVersion {
printVersionAndExit()
}

args := flag.Args()

if len(args) > 1 {
printUsageAndExit()
} else if len(args) == 0 {
flags.file = "-"
} else {
flags.file = strings.TrimSpace(args[0])
}

return flags
}

func printVersionAndExit() {
v := version

if v == "" {
v = "<nil>"
}

fmt.Fprintln(flag.CommandLine.Output(), v)
os.Exit(0)
}

func printUsageAndExit() {
flag.CommandLine.Usage()
os.Exit(0)
}
14 changes: 14 additions & 0 deletions cmd/cronskd/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/winebarrel/cronplan/cmd/cronskd

go 1.21

toolchain go1.23.3

replace github.com/winebarrel/cronplan => ../..

require (
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/winebarrel/cronplan v0.0.0-00010101000000-000000000000
)

require github.com/alecthomas/participle/v2 v2.1.1 // indirect
23 changes: 23 additions & 0 deletions cmd/cronskd/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0=
github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8=
github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
89 changes: 89 additions & 0 deletions cmd/cronskd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package main

import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strings"
"time"

"github.com/araddon/dateparse"
"github.com/winebarrel/cronplan"
)

func init() {
log.SetFlags(0)
}

func main() {
flags := parseFlags()

var scanner *bufio.Scanner

if flags.file == "-" {
scanner = bufio.NewScanner(os.Stdin)
} else {
file, err := os.Open(flags.file)

if err != nil {
log.Fatal(err)
}

defer file.Close()

scanner = bufio.NewScanner(file)
}

type exprNext struct {
expr string
next time.Time
}

schedule := []exprNext{}

for scanner.Scan() {
expr := scanner.Text()
expr = strings.TrimSpace(expr)
expr = strings.TrimPrefix(expr, "cron(")
expr = strings.TrimSuffix(expr, ")")

cron, err := cronplan.Parse(expr)

if err != nil {
log.Fatal(err)
}

var start, end time.Time

if flags.start == "" {
now := time.Now()
start = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
} else {
start, err = dateparse.ParseAny(flags.start)

if err != nil {
log.Fatal(err)
}
}

if flags.end == "" {
end = time.Date(start.Year(), start.Month(), start.Day(), 23, 59, 50, 0, start.Location())
}

nexts := cron.Between(start, end)

for _, n := range nexts {
schedule = append(schedule, exprNext{expr: expr, next: n})
}
}

sort.Slice(schedule, func(i, j int) bool {
return schedule[i].next.Before(schedule[j].next)
})

for _, ln := range schedule {
fmt.Printf("%s\t%s\n", ln.next.Format("Mon, 02 Jan 2006 15:04:05"), ln.expr)
}
}

0 comments on commit 2e5b081

Please sign in to comment.