Skip to content

Commit ae7921d

Browse files
committed
Make jobs command far less verbose
Add way to see URLs for each jobs Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent c266a27 commit ae7921d

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

cmd/jobs.go

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import (
44
"bytes"
55
"encoding/json"
66
"fmt"
7+
"io"
78
"net/http"
89
"os"
910
"strings"
11+
"text/tabwriter"
12+
"time"
13+
14+
"github.com/docker/go-units"
1015

1116
"github.com/self-actuated/actuated-cli/pkg"
1217
"github.com/spf13/cobra"
@@ -29,6 +34,8 @@ func makeJobs() *cobra.Command {
2934

3035
cmd.RunE = runJobsE
3136

37+
cmd.Flags().BoolP("verbose", "v", false, "Show additional columns in the output")
38+
3239
cmd.Flags().BoolP("json", "j", false, "Request output in JSON format")
3340

3441
return cmd
@@ -56,13 +63,20 @@ func runJobsE(cmd *cobra.Command, args []string) error {
5663
return err
5764
}
5865

66+
verbose, err := cmd.Flags().GetBool("verbose")
67+
if err != nil {
68+
return err
69+
}
70+
5971
if len(pat) == 0 {
6072
return fmt.Errorf("pat is required")
6173
}
6274

6375
c := pkg.NewClient(http.DefaultClient, os.Getenv("ACTUATED_URL"))
6476

65-
res, status, err := c.ListJobs(pat, owner, staff, requestJson)
77+
acceptJSON := true
78+
79+
res, status, err := c.ListJobs(pat, owner, staff, acceptJSON)
6680

6781
if err != nil {
6882
return err
@@ -80,9 +94,94 @@ func runJobsE(cmd *cobra.Command, args []string) error {
8094
return err
8195
}
8296
res = prettyJSON.String()
97+
fmt.Println(res)
98+
} else {
99+
100+
var statuses []JobStatus
101+
102+
if err := json.Unmarshal([]byte(res), &statuses); err != nil {
103+
return err
104+
}
105+
printEvents(os.Stdout, statuses, verbose)
83106
}
84-
fmt.Println(res)
85107

86108
return nil
87109

88110
}
111+
112+
func printEvents(w io.Writer, statuses []JobStatus, verbose bool) {
113+
tabwriter := tabwriter.NewWriter(w, 0, 0, 1, ' ', tabwriter.TabIndent)
114+
if verbose {
115+
fmt.Fprintf(tabwriter, "JOB ID\tOWNER\tREPO\tJOB\tRUNNER\tSERVER\tSTATUS\tSTARTED\tAGE\tLABELS\tURL\n")
116+
} else {
117+
fmt.Fprintf(tabwriter, "OWNER\tREPO\tJOB\tSTATUS\tAGE\tURL\n")
118+
}
119+
120+
for _, status := range statuses {
121+
duration := ""
122+
123+
if status.StartedAt != nil && !status.StartedAt.IsZero() {
124+
duration = humanDuration(time.Since(*status.StartedAt))
125+
}
126+
127+
if verbose {
128+
fmt.Fprintf(tabwriter, "%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
129+
status.JobID,
130+
status.Owner,
131+
status.Repo,
132+
status.JobName,
133+
status.RunnerName,
134+
status.AgentName,
135+
status.Status,
136+
status.StartedAt.Format(time.RFC3339),
137+
duration,
138+
strings.Join(status.Labels, ","),
139+
fmt.Sprintf("https://github.com/%s/%s/runs/%d", status.Owner, status.Repo, status.JobID),
140+
)
141+
} else {
142+
fmt.Fprintf(tabwriter, "%s\t%s\t%s\t%s\t%s\t%s\n",
143+
status.Owner,
144+
status.Repo,
145+
status.JobName,
146+
status.Status,
147+
duration,
148+
fmt.Sprintf("https://github.com/%s/%s/runs/%d", status.Owner, status.Repo, status.JobID))
149+
150+
}
151+
152+
}
153+
tabwriter.Flush()
154+
}
155+
156+
type JobStatus struct {
157+
JobID int64 `json:"job_id"`
158+
Owner string `json:"owner"`
159+
Repo string `json:"repo"`
160+
WorkflowName string `json:"workflow_name"`
161+
JobName string `json:"job_name"`
162+
Actor string `json:"actor,omitempty"`
163+
164+
RunnerName string `json:"runner_name,omitempty"`
165+
Status string `json:"status"`
166+
Conclusion string `json:"conclusion,omitempty"`
167+
Labels []string `json:"labels,omitempty"`
168+
169+
UpdatedAt *time.Time `json:"updated_at"`
170+
StartedAt *time.Time `json:"startedAt,omitempty"`
171+
CompletedAt *time.Time `json:"completedAt,omitempty"`
172+
173+
AgentName string `json:"agent_name,omitempty"`
174+
}
175+
176+
// types.HumanDuration fixes a long string for a value < 1s
177+
func humanDuration(duration time.Duration) string {
178+
v := strings.ToLower(units.HumanDuration(duration))
179+
180+
if v == "less than a second" {
181+
return fmt.Sprintf("%d ms", duration.Milliseconds())
182+
} else if v == "about a minute" {
183+
return fmt.Sprintf("%d seconds", int(duration.Seconds()))
184+
}
185+
186+
return v
187+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ module github.com/self-actuated/actuated-cli
33
go 1.22
44

55
require (
6+
github.com/docker/go-units v0.5.0
67
github.com/google/go-github/v52 v52.0.0
78
github.com/morikuni/aec v1.0.0
89
github.com/olekukonko/tablewriter v0.0.5
10+
github.com/openfaasltd/actuated/types v0.0.0-20240729175505-d862db002103
911
github.com/spf13/cobra v1.8.0
1012
golang.org/x/oauth2 v0.21.0
1113
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK
55
github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI=
66
github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
77
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
8+
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
9+
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
810
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
911
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
1012
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -21,6 +23,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
2123
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
2224
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
2325
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
26+
github.com/openfaasltd/actuated/types v0.0.0-20240729175505-d862db002103 h1:/Yut1iB0gjNwSrzWnwR/EUiirResccGwEoKVPYPZ4Gc=
27+
github.com/openfaasltd/actuated/types v0.0.0-20240729175505-d862db002103/go.mod h1:B2zlss5C6piwLY00cfk7UZBgxbEE3K6Gv0NK3ktxsjU=
2428
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
2529
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
2630
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=

0 commit comments

Comments
 (0)