@@ -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\t OWNER\t REPO\t JOB\t RUNNER\t SERVER\t STATUS\t STARTED\t AGE\t LABELS\t URL\n " )
116+ } else {
117+ fmt .Fprintf (tabwriter , "OWNER\t REPO\t JOB\t STATUS\t AGE\t URL\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+ }
0 commit comments