Skip to content

Commit

Permalink
allow specifying default columns for each sub command
Browse files Browse the repository at this point in the history
I am a heavy user of the hcloud-cli. However, I usually change the columns that are displayed and don't like the default and would prefer specifying the default columns used in the config file.
Note: This PR adds on top of the work of #421 and should not be merged
before #421.

Currently, I always type `hcloud server list -o 'columns=name,status,ipv6,private_net'` to only get the columns that I'm interested in

since the `-o` flag is part of the `list` subcommand and not the `hcloud` base command (like in many other software that makes use of the Cobra framework),
I cannot simply `alias hcloud-"hcloud -o 'columns='"` in my shell to default the columns.

This commit adds a `[defaults]` section to the config toml which allows to override the default sorting behavior for individual `hcloud` subcommands.

The following behavior is used to determine the displayed columns

| config file | flag    | result                      |
|-------------|---------|-----------------------------|
| not-set     | not-set | display default columns     |
| not-set     | set     | display -o flag columns     |
| set         | not-set | display config file columns |
| set         | set     | display -o flag columns     |
  • Loading branch information
cedi committed Nov 16, 2022
1 parent e3ffaf9 commit 45de449
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 1 deletion.
4 changes: 4 additions & 0 deletions internal/cmd/base/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func (lc *ListCmd) CobraCommand(

cmd.Flags().StringSliceP("sort", "s", sortingDefault, "Determine the sorting of the result")

if defaults != nil && len(defaults.DefaultColumns) > 0 {
lc.DefaultColumns = defaults.DefaultColumns
}

return cmd
}

Expand Down
2 changes: 2 additions & 0 deletions internal/cmd/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"github.com/hetznercloud/cli/internal/cmd/config/defaultcolumns"
"github.com/hetznercloud/cli/internal/cmd/config/sorting"
"github.com/hetznercloud/cli/internal/state"
"github.com/spf13/cobra"
Expand All @@ -16,6 +17,7 @@ func NewCommand(cli *state.State) *cobra.Command {
}
cmd.AddCommand(
sorting.NewSortCommand(cli),
defaultcolumns.NewDefaultColumnsCommand(cli),
)
return cmd
}
24 changes: 24 additions & 0 deletions internal/cmd/config/defaultcolumns/columns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package defaultcolumns

import (
"github.com/hetznercloud/cli/internal/state"
"github.com/spf13/cobra"
)

func NewDefaultColumnsCommand(cli *state.State) *cobra.Command {
cmd := &cobra.Command{
Use: "columns COMMAND",
Short: "Configure the default sorting order for a command",
Args: cobra.MinimumNArgs(2),
TraverseChildren: true,
DisableFlagsInUseLine: true,
}

cmd.AddCommand(
newSetCommand(cli),
newListCommand(cli),
newResetCommand(cli),
)

return cmd
}
102 changes: 102 additions & 0 deletions internal/cmd/config/defaultcolumns/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package defaultcolumns

import (
"strings"

"github.com/hetznercloud/cli/internal/cmd/output"
"github.com/hetznercloud/cli/internal/state"
"github.com/spf13/cobra"
)

var listTableOutput *output.Table

func init() {
listTableOutput = output.NewTable().
AddAllowedFields(ColumnsPresentation{})
}

type ColumnsPresentation struct {
Command string
Columns string
}

func newListCommand(cli *state.State) *cobra.Command {
cmd := &cobra.Command{
Use: "list [COMMAND]",
Short: "See the default sorting order for a command",
Args: cobra.MaximumNArgs(1),
TraverseChildren: true,
DisableFlagsInUseLine: true,
RunE: cli.Wrap(runList),
}

return cmd
}

func runList(cli *state.State, cmd *cobra.Command, args []string) error {
if len(args) == 1 {
return runListCommand(cli, cmd, args)
}

return runListAll(cli, cmd, args)
}

func runListAll(cli *state.State, cmd *cobra.Command, args []string) error {
outOpts := output.FlagsForCommand(cmd)

cols := []string{"command", "columns"}

tw := listTableOutput
if err := tw.ValidateColumns(cols); err != nil {
return err
}

if !outOpts.IsSet("noheader") {
tw.WriteHeader(cols)
}

for command, defaults := range cli.Config.SubcommandDefaults {
if defaults != nil {
presentation := ColumnsPresentation{
Command: command,
Columns: strings.Join(defaults.DefaultColumns, ", "),
}

tw.Write(cols, presentation)
}
}

tw.Flush()
return nil
}

func runListCommand(cli *state.State, cmd *cobra.Command, args []string) error {
outOpts := output.FlagsForCommand(cmd)

cols := []string{"command", "columns"}

command := args[0]

tw := listTableOutput
if err := tw.ValidateColumns(cols); err != nil {
return err
}

if !outOpts.IsSet("noheader") {
tw.WriteHeader(cols)
}

defaults := cli.Config.SubcommandDefaults[command]

if defaults != nil {
presentation := ColumnsPresentation{
Command: command,
Columns: strings.Join(defaults.DefaultColumns, ", "),
}

tw.Write(cols, presentation)
}

tw.Flush()
return nil
}
49 changes: 49 additions & 0 deletions internal/cmd/config/defaultcolumns/reset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package defaultcolumns

import (
"errors"
"fmt"
"strings"

"github.com/hetznercloud/cli/internal/state"
"github.com/spf13/cobra"
)

func newResetCommand(cli *state.State) *cobra.Command {
cmd := &cobra.Command{
Use: "reset COMMAND",
Short: "Reset to the application default columns for a command",
Args: cobra.ExactArgs(1),
TraverseChildren: true,
DisableFlagsInUseLine: true,
RunE: cli.Wrap(runReset),
}

return cmd
}

func runReset(cli *state.State, cmd *cobra.Command, args []string) error {
command := strings.TrimSpace(args[0])
if command == "" {
return errors.New("invalid command")
}

if cli.Config.SubcommandDefaults == nil {
return nil
}

defaults := cli.Config.SubcommandDefaults[command]
if defaults != nil {
defaults.DefaultColumns = nil
}

cli.Config.SubcommandDefaults[command] = defaults

if err := cli.WriteConfig(); err != nil {
return err
}

fmt.Printf("Reset to the default display columns for command '%s list'\n", command)

return nil
}
62 changes: 62 additions & 0 deletions internal/cmd/config/defaultcolumns/set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package defaultcolumns

import (
"errors"
"fmt"
"strings"

"github.com/hetznercloud/cli/internal/state"
"github.com/spf13/cobra"
)

func newSetCommand(cli *state.State) *cobra.Command {
cmd := &cobra.Command{
Use: "set COMMAND COLUMNS...",
Short: "Set which columns to show by default for a command",
Args: cobra.MinimumNArgs(2),
TraverseChildren: true,
DisableFlagsInUseLine: true,
RunE: cli.Wrap(runSet),
}

return cmd
}

func runSet(cli *state.State, cmd *cobra.Command, args []string) error {
command := strings.TrimSpace(args[0])
if command == "" {
return errors.New("invalid command")
}

if len(args[1:]) == 0 {
return errors.New("invalid columns")
}

columns := make([]string, len(args[1:]))
for index, columnName := range args[1:] {
columns[index] = strings.TrimSpace(columnName)
}

if cli.Config.SubcommandDefaults == nil {
cli.Config.SubcommandDefaults = make(map[string]*state.SubcommandDefaults)
}

defaults := cli.Config.SubcommandDefaults[command]
if defaults == nil {
defaults = &state.SubcommandDefaults{
DefaultColumns: columns,
}
} else {
defaults.DefaultColumns = columns
}

cli.Config.SubcommandDefaults[command] = defaults

if err := cli.WriteConfig(); err != nil {
return err
}

fmt.Printf("Displaying columns '%s' for command '%s list'\n", strings.Join(columns, ", "), command)

return nil
}
5 changes: 4 additions & 1 deletion internal/state/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type RawConfigContext struct {

type RAWSubcommandDefaults struct {
Sorting []string `toml:"sort,omitempty"`
Columns []string `toml:"columns,omitempty"`
}

func MarshalConfig(c *Config) ([]byte, error) {
Expand All @@ -90,6 +91,7 @@ func MarshalConfig(c *Config) ([]byte, error) {
for command, defaults := range c.SubcommandDefaults {
raw.SubcommandDefaults[command] = &RAWSubcommandDefaults{
Sorting: defaults.Sorting,
Columns: defaults.DefaultColumns,
}
}
}
Expand Down Expand Up @@ -122,7 +124,8 @@ func UnmarshalConfig(config *Config, data []byte) error {
config.SubcommandDefaults = make(map[string]*SubcommandDefaults)
for command, defaults := range raw.SubcommandDefaults {
config.SubcommandDefaults[command] = &SubcommandDefaults{
Sorting: defaults.Sorting,
Sorting: defaults.Sorting,
DefaultColumns: defaults.Columns,
}
}
}
Expand Down

0 comments on commit 45de449

Please sign in to comment.