Add machine-readable output formats
- Default table output (when stdout is attached to a terminal) stays the same;
- When stdout is redirected, output tab-separated values and no header line;
- With `--json` flag, output structured JSON data.
Example:
$ ghcs list --json
[
{
"Branch": "main",
"Created At": "2021-06-10T15:04:46+02:00",
"Name": "mislav-playground-jvqj",
"Repository": "mislav/playground",
"State": "Shutdown"
},
{
"Branch": "master",
"Created At": "2021-07-15T15:51:08+02:00",
"Name": "mislav-github-github-pwgg365xv",
"Repository": "github/github",
"State": "Shutdown"
}
]
This commit is contained in:
parent
ebc8ce5adb
commit
140a54a009
5 changed files with 101 additions and 8 deletions
|
|
@ -73,7 +73,7 @@ func Delete(codespaceName string) error {
|
|||
|
||||
fmt.Println("Codespace deleted.")
|
||||
|
||||
return List()
|
||||
return List(&ListOptions{})
|
||||
}
|
||||
|
||||
func DeleteAll() error {
|
||||
|
|
@ -103,7 +103,7 @@ func DeleteAll() error {
|
|||
fmt.Printf("Codespace deleted: %s\n", c.Name)
|
||||
}
|
||||
|
||||
return List()
|
||||
return List(&ListOptions{})
|
||||
}
|
||||
|
||||
func DeleteByRepo(repo string) error {
|
||||
|
|
@ -143,5 +143,5 @@ func DeleteByRepo(repo string) error {
|
|||
fmt.Printf("No codespace was found for repository: %s\n", repo)
|
||||
}
|
||||
|
||||
return List()
|
||||
return List(&ListOptions{})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,21 +5,28 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
"github.com/github/ghcs/api"
|
||||
"github.com/github/ghcs/cmd/ghcs/output"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type ListOptions struct {
|
||||
AsJSON bool
|
||||
}
|
||||
|
||||
func NewListCmd() *cobra.Command {
|
||||
opts := &ListOptions{}
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List GitHub Codespaces you have on your account.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return List()
|
||||
return List(opts)
|
||||
},
|
||||
}
|
||||
|
||||
listCmd.Flags().BoolVar(&opts.AsJSON, "json", false, "Output as JSON")
|
||||
|
||||
return listCmd
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +34,7 @@ func init() {
|
|||
rootCmd.AddCommand(NewListCmd())
|
||||
}
|
||||
|
||||
func List() error {
|
||||
func List(opts *ListOptions) error {
|
||||
apiClient := api.New(os.Getenv("GITHUB_TOKEN"))
|
||||
ctx := context.Background()
|
||||
|
||||
|
|
@ -46,7 +53,7 @@ func List() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
table := output.NewTable(os.Stdout, opts.AsJSON)
|
||||
table.SetHeader([]string{"Name", "Repository", "Branch", "State", "Created At"})
|
||||
for _, codespace := range codespaces {
|
||||
table.Append([]string{
|
||||
|
|
|
|||
33
cmd/ghcs/output/format_json.go
Normal file
33
cmd/ghcs/output/format_json.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
type jsonwriter struct {
|
||||
w io.Writer
|
||||
pretty bool
|
||||
cols []string
|
||||
data []interface{}
|
||||
}
|
||||
|
||||
func (j *jsonwriter) SetHeader(cols []string) {
|
||||
j.cols = cols
|
||||
}
|
||||
|
||||
func (j *jsonwriter) Append(values []string) {
|
||||
row := make(map[string]string)
|
||||
for i, v := range values {
|
||||
row[j.cols[i]] = v
|
||||
}
|
||||
j.data = append(j.data, row)
|
||||
}
|
||||
|
||||
func (j *jsonwriter) Render() {
|
||||
enc := json.NewEncoder(j.w)
|
||||
if j.pretty {
|
||||
enc.SetIndent("", " ")
|
||||
}
|
||||
_ = enc.Encode(j.data)
|
||||
}
|
||||
28
cmd/ghcs/output/format_table.go
Normal file
28
cmd/ghcs/output/format_table.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
type Table interface {
|
||||
SetHeader([]string)
|
||||
Append([]string)
|
||||
Render()
|
||||
}
|
||||
|
||||
func NewTable(w io.Writer, asJSON bool) Table {
|
||||
f, ok := w.(*os.File)
|
||||
isTTY := ok && term.IsTerminal(int(f.Fd()))
|
||||
|
||||
if asJSON {
|
||||
return &jsonwriter{w: w, pretty: isTTY}
|
||||
}
|
||||
if isTTY {
|
||||
return tablewriter.NewWriter(w)
|
||||
}
|
||||
return &tabwriter{w: w}
|
||||
}
|
||||
25
cmd/ghcs/output/format_tsv.go
Normal file
25
cmd/ghcs/output/format_tsv.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package output
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type tabwriter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (j *tabwriter) SetHeader([]string) {}
|
||||
|
||||
func (j *tabwriter) Append(values []string) {
|
||||
var sep string
|
||||
for i, v := range values {
|
||||
if i == 1 {
|
||||
sep = "\t"
|
||||
}
|
||||
fmt.Fprintf(j.w, "%s%s", sep, v)
|
||||
}
|
||||
fmt.Fprint(j.w, "\n")
|
||||
}
|
||||
|
||||
func (j *tabwriter) Render() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue