cli icon indicating copy to clipboard operation
cli copied to clipboard

feat: allow configuring default sort columns for each resource

Open phm07 opened this issue 1 year ago • 7 comments

This PR adds options to configure the default sorting column for each resource that supports the list command. See #418 and #434

phm07 avatar Jun 26 '24 13:06 phm07

This is how the table that shows different options when using hcloud help config looks now:

┌───────────────────────┬──────────────────────┬─────────────┬───────────────────────┬──────────────────────────────┬─────────────────┐
│ OPTION                │ DESCRIPTION          │ TYPE        │ CONFIG KEY            │ ENVIRONMENT VARIABLE         │ FLAG            │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ debug                 │ Enable debug output  │ boolean     │ debug                 │ HCLOUD_DEBUG                 │ --debug         │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ debug-file            │ File to write debug  │ string      │ debug_file            │ HCLOUD_DEBUG_FILE            │ --debug-file    │
│                       │ output to            │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ default-ssh-keys      │ Default SSH keys for │ string list │ default_ssh_keys      │ HCLOUD_DEFAULT_SSH_KEYS      │                 │
│                       │ new servers          │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ endpoint              │ Hetzner Cloud API    │ string      │ endpoint              │ HCLOUD_ENDPOINT              │ --endpoint      │
│                       │ endpoint             │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ poll-interval         │ Interval at which to │ duration    │ poll_interval         │ HCLOUD_POLL_INTERVAL         │ --poll-interval │
│                       │ poll information,    │             │                       │                              │                 │
│                       │ for example action   │             │                       │                              │                 │
│                       │ progress             │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ quiet                 │ If true, only print  │ boolean     │ quiet                 │ HCLOUD_QUIET                 │ --quiet         │
│                       │ error messages       │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.certificate      │ Default sorting for  │ string list │ sort.certificate      │ HCLOUD_SORT.CERTIFICATE      │                 │
│                       │ Certificate resource │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.datacenter       │ Default sorting for  │ string list │ sort.datacenter       │ HCLOUD_SORT.DATACENTER       │                 │
│                       │ Datacenter resource  │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.firewall         │ Default sorting for  │ string list │ sort.firewall         │ HCLOUD_SORT.FIREWALL         │                 │
│                       │ Firewall resource    │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.floatingip       │ Default sorting for  │ string list │ sort.floatingip       │ HCLOUD_SORT.FLOATINGIP       │                 │
│                       │ Floating IP resource │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.image            │ Default sorting for  │ string list │ sort.image            │ HCLOUD_SORT.IMAGE            │                 │
│                       │ Image resource       │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.iso              │ Default sorting for  │ string list │ sort.iso              │ HCLOUD_SORT.ISO              │                 │
│                       │ ISO resource         │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.loadbalancer     │ Default sorting for  │ string list │ sort.loadbalancer     │ HCLOUD_SORT.LOADBALANCER     │                 │
│                       │ Load Balancer        │             │                       │                              │                 │
│                       │ resource             │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.loadbalancertype │ Default sorting for  │ string list │ sort.loadbalancertype │ HCLOUD_SORT.LOADBALANCERTYPE │                 │
│                       │ Load Balancer Type   │             │                       │                              │                 │
│                       │ resource             │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.location         │ Default sorting for  │ string list │ sort.location         │ HCLOUD_SORT.LOCATION         │                 │
│                       │ Location resource    │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.network          │ Default sorting for  │ string list │ sort.network          │ HCLOUD_SORT.NETWORK          │                 │
│                       │ Network resource     │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.placementgroup   │ Default sorting for  │ string list │ sort.placementgroup   │ HCLOUD_SORT.PLACEMENTGROUP   │                 │
│                       │ Placement Group      │             │                       │                              │                 │
│                       │ resource             │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.primaryip        │ Default sorting for  │ string list │ sort.primaryip        │ HCLOUD_SORT.PRIMARYIP        │                 │
│                       │ Primary IP resource  │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.server           │ Default sorting for  │ string list │ sort.server           │ HCLOUD_SORT.SERVER           │                 │
│                       │ Server resource      │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.servertype       │ Default sorting for  │ string list │ sort.servertype       │ HCLOUD_SORT.SERVERTYPE       │                 │
│                       │ Server Type resource │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.sshkey           │ Default sorting for  │ string list │ sort.sshkey           │ HCLOUD_SORT.SSHKEY           │                 │
│                       │ SSH Key resource     │             │                       │                              │                 │
├───────────────────────┼──────────────────────┼─────────────┼───────────────────────┼──────────────────────────────┼─────────────────┤
│ sort.volume           │ Default sorting for  │ string list │ sort.volume           │ HCLOUD_SORT.VOLUME           │                 │
│                       │ Volume resource      │             │                       │                              │                 │
└───────────────────────┴──────────────────────┴─────────────┴───────────────────────┴──────────────────────────────┴─────────────────┘

Is this too much? Or should we keep all the entries fort sort.[resource]?

phm07 avatar Jun 26 '24 13:06 phm07

Codecov Report

Attention: Patch coverage is 50.00000% with 7 lines in your changes missing coverage. Please review.

Project coverage is 59.47%. Comparing base (320300c) to head (c5f5823).

Files Patch % Lines
internal/cmd/base/list.go 58.33% 2 Missing and 3 partials :warning:
internal/state/config/options.go 0.00% 2 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #795      +/-   ##
==========================================
- Coverage   59.60%   59.47%   -0.14%     
==========================================
  Files         210      210              
  Lines        7655     7667      +12     
==========================================
- Hits         4563     4560       -3     
- Misses       2450     2458       +8     
- Partials      642      649       +7     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Jun 26 '24 13:06 codecov[bot]

~~Do you think it's possible to decouple the SortOption and the per resource sort arguments? Similar to the tables columns?~~

EDIT: Scratch that.

jooola avatar Jun 26 '24 13:06 jooola

Is this too much? Or should we keep all the entries fort sort.[resource]?

I'd rather keep it explicit, unless we have a clear list of resource names.

sort.loadbalancertype │ HCLOUD_SORT.LOADBALANCERTYPE

Could we keep the _ or - in the names? The env variable name is not the final ones right?

jooola avatar Jun 26 '24 15:06 jooola

sort.loadbalancertype │ HCLOUD_SORT.LOADBALANCERTYPE

Could we keep the _ or - in the names? The env variable name is not the final ones right?

We could either:

  • Create an override for the environment variable names (which would introduce inconsistency)
  • Or just rename the options to include dashes, for example sort.servertype -> sort.server-type. This would lead to the config key name being sort.server_type and the environment variable being HCLOUD_SORT_SERVER_TYPE.

It's a style question, I don't like mixing dots and dashes for the key, but I think it would be best for consistency and readability if we did.

Edit: I just noticed that the environment variables contain dots. That's a bug/oversight. I don't think env vars support dots in their names.

phm07 avatar Jun 27 '24 09:06 phm07

Nope, env vars cannot have dots:

Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2017 consist solely of uppercase letters, digits, and the ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase and lowercase letters shall retain their unique identities and shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.

https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html

jooola avatar Jun 27 '24 09:06 jooola

Without taking a look at the code:

  • I think the options should be the same as the subcommands: hcloud load-balancer -> sort.load-balancer
  • In the docs I would prefer to have a single element sort.<resource> to keep this reasonably small.
  • I would add a section in hcloud config --help that describes these options in general

apricote avatar Jun 27 '24 14:06 apricote

Without taking a look at the code:

  • I think the options should be the same as the subcommands: hcloud load-balancer -> sort.load-balancer
  • In the docs I would prefer to have a single element sort.<resource> to keep this reasonably small.
  • I would add a section in hcloud config --help that describes these options in general

Agreed. Done in 02615665647b142bad6a450c520e1bccb30beb16 and 9b23dfc10eae63ca9f39f1faa1d33c9a85150aa4

phm07 avatar Jul 03 '24 13:07 phm07

While testing this, I found that hcloud config add adds to the front of the list. I found this counterintuitive. I wanted to set a default for hcloud image list --sort name:asc --sort created:asc so I ran:

$ hcloud config add sort.image name:asc
$ hcloud config add sort.image created:asc

Thinking it would end us as [name:asc created:asc]. Turned out it was the other way around, and running hcloud image list now orders the other way around.

$ hcloud config get sort.image
[created:asc name:asc]

So feature works technically, but the UX was unexpected

apricote avatar Jul 04 '24 12:07 apricote

Even with hcloud config set sort.image name:asc created:asc its being saved in the wrong order.

apricote avatar Jul 04 '24 12:07 apricote

Good catch! #805 fixes this. We should wait for #805 before we merge this PR.

phm07 avatar Jul 04 '24 16:07 phm07