From 820883e60c9936a0e4b63fdf8b2329388652c1e9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 2 Jul 2023 04:36:08 -0400 Subject: [PATCH] feat: add json format output to cron:list command This makes it easier to parse output in a machine-readable format - such as when interacting with cron tasks via jq for writing tests. --- docs/processes/scheduled-cron-tasks.md | 14 ++++++++-- plugins/cron/cron.go | 12 ++++---- plugins/cron/src/commands/commands.go | 2 +- plugins/cron/src/subcommands/subcommands.go | 3 +- plugins/cron/subcommands.go | 31 +++++++++++++++++---- tests/unit/cron.bats | 20 +++++++++++++ 6 files changed, 66 insertions(+), 16 deletions(-) diff --git a/docs/processes/scheduled-cron-tasks.md b/docs/processes/scheduled-cron-tasks.md index fc7c59859..adeab9dcf 100644 --- a/docs/processes/scheduled-cron-tasks.md +++ b/docs/processes/scheduled-cron-tasks.md @@ -3,8 +3,8 @@ > New as of 0.23.0 ``` -cron:list # List scheduled cron tasks for an app -cron:report [] [] # Display report about an app +cron:list [--format json|stdout] # List scheduled cron tasks for an app +cron:report [] [] # Display report about an app ``` ## Usage @@ -62,6 +62,16 @@ cGhwPT09cGhwIHRlc3QucGhwPT09QGRhaWx5 @daily node index.js cGhwPT09dHJ1ZT09PSogKiAqICogKg== * * * * * true ``` +The output can also be displayed in json format: + +```shell +dokku cron:list node-js-app --format json +``` + +``` +[{"id":"cGhwPT09cGhwIHRlc3QucGhwPT09QGRhaWx5","app":"node-js-app","command":"node index.js","schedule":"@daily"}] +``` + #### Displaying reports You can get a report about the cron configuration for apps using the `cron:report` command: diff --git a/plugins/cron/cron.go b/plugins/cron/cron.go index d315583df..7c71f0735 100644 --- a/plugins/cron/cron.go +++ b/plugins/cron/cron.go @@ -14,12 +14,12 @@ import ( ) type TemplateCommand struct { - ID string - App string - Command string - Schedule string - AltCommand string - LogFile string + ID string `json:"id"` + App string `json:"app"` + Command string `json:"command"` + Schedule string `json:"schedule"` + AltCommand string `json:"-"` + LogFile string `json:"-"` } func (t TemplateCommand) CronCommand() string { diff --git a/plugins/cron/src/commands/commands.go b/plugins/cron/src/commands/commands.go index 402ac2799..90f825fc2 100644 --- a/plugins/cron/src/commands/commands.go +++ b/plugins/cron/src/commands/commands.go @@ -18,7 +18,7 @@ Manage scheduled cron tasks Additional commands:` helpContent = ` - cron:list , List scheduled cron tasks for an app + cron:list [--format json|stdout], List scheduled cron tasks for an app cron:report [] [], Display report about an app ` ) diff --git a/plugins/cron/src/subcommands/subcommands.go b/plugins/cron/src/subcommands/subcommands.go index 12daa862f..302fdef6e 100644 --- a/plugins/cron/src/subcommands/subcommands.go +++ b/plugins/cron/src/subcommands/subcommands.go @@ -20,9 +20,10 @@ func main() { switch subcommand { case "list": args := flag.NewFlagSet("cron:list", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") args.Parse(os.Args[2:]) appName := args.Arg(0) - err = cron.CommandList(appName) + err = cron.CommandList(appName, *format) case "report": args := flag.NewFlagSet("cron:report", flag.ExitOnError) format := args.String("format", "stdout", "format: [ stdout | json ]") diff --git a/plugins/cron/subcommands.go b/plugins/cron/subcommands.go index 72a13f89b..b34bf758b 100644 --- a/plugins/cron/subcommands.go +++ b/plugins/cron/subcommands.go @@ -1,6 +1,7 @@ package cron import ( + "encoding/json" "fmt" "github.com/dokku/dokku/plugins/common" @@ -8,22 +9,40 @@ import ( ) // CommandList lists all scheduled cron tasks for a given app -func CommandList(appName string) error { +func CommandList(appName string, format string) error { if err := common.VerifyAppName(appName); err != nil { return err } + if format == "" { + format = "stdout" + } + + if format != "stdout" && format != "json" { + return fmt.Errorf("Invalid format specified, supported formats: json, stdout") + } + entries, err := FetchCronEntries(appName) if err != nil { return err } - output := []string{"ID | Schedule | Command"} - for _, entry := range entries { - output = append(output, fmt.Sprintf("%s | %s | %s", entry.ID, entry.Schedule, entry.Command)) + if format == "stdout" { + output := []string{"ID | Schedule | Command"} + for _, entry := range entries { + output = append(output, fmt.Sprintf("%s | %s | %s", entry.ID, entry.Schedule, entry.Command)) + } + + result := columnize.SimpleFormat(output) + fmt.Println(result) + return nil } - result := columnize.SimpleFormat(output) - fmt.Println(result) + + out, err := json.Marshal(entries) + if err != nil { + return err + } + common.Log(string(out)) return nil } diff --git a/tests/unit/cron.bats b/tests/unit/cron.bats index 6f7f20afd..4349027bc 100644 --- a/tests/unit/cron.bats +++ b/tests/unit/cron.bats @@ -177,6 +177,26 @@ teardown() { assert_failure } +@test "(cron) cron:list --format json" { + run deploy_app python dokku@dokku.me:$TEST_APP template_cron_file_valid + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku cron:list $TEST_APP --format json" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_exists + + cron_id="$(dokku cron:list $TEST_APP --format json | jq -r '.[0].id')" + run /bin/bash -c "echo $cron_id" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_exists +} + template_cron_file_invalid() { local APP="$1" local APP_REPO_DIR="$2"