Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: group subcommands in command help #675

Merged
merged 9 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 107 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,130 @@
# Developing hcloud-cli

## Generated files

This repository contains generated files, mainly for testing purposes. These files are generated by running

```sh
go generate ./...
```

in the root directory of this repository. Make sure to keep generated files up-to-date
when making changes to the code.

## Unit tests
Unit tests are located in the `internal` directory. Run them with

Unit tests are located in the `internal` directory. Run them with:

```sh
go test ./...
```

## Build
To build the binary, run

To build the binary, run:

```sh
go build -o hcloud-cli ./cmd/hcloud
```

To include version information in the resulting binary and build for all targets, use GoReleaser:
To include version information in the resulting binary and build for all targets, use GoReleaser:

```sh
goreleaser --snapshot --skip-publish --rm-dist
```

## Conventions

### Subcommand groups

Cobra offers the functionality to group subcommands. The conventions on when and how to group commands are as follows:

1. Use the following Categories:
- **General** (CRUD operations such as `create`, `delete`, `describe`, `list`, `update` + Label
commands `add-`/`remove-label`)
- Groups based on actions (e.g. `enable`, `disable`, `attach`, `detach`), for example `enable-`/`disable-protection`
or `poweron`/`poweroff`/`shutdown`/`reset`/`reboot`
- **Additional commands** that don't fit into the other categories (`Group.ID` is empty). These should be
utility commands, for example ones that perform client-side actions.
2. Groups are only needed if more than the "General" group commands are present.
3. `Group.ID` formatting:
1. If the `ID` is a noun, it should be singular.
2. If the `ID` is a verb, it should be in the infinitive form.
3. The `ID` should be in kebab-case.
4. `Group.Title` formatting:
1. Should be the `ID` but capitalized and with spaces instead of dashes.
2. If a single resource is managed, the `Title` should be singular. Otherwise, it should be plural.

Example: Multiple network can be attached to server -> `Networks`, but only one ISO can be attached to a server -> `ISO`

Here is how to create a group:

```go
// General
util.AddGroup(cmd, "general", "General",
SomeGeneralCommand.CobraCommand(s),
// ...
)

// Additional commands
cmd.AddCommand(
SomeUtilCommand.CobraCommand(s),
// ...
)
```

Example of the `hcloud server` command groups:

```
General:
add-label Add a label to a server
change-type Change type of a server
create Create a server
create-image Create an image from a server
delete Delete a server
describe Describe a server
list List Servers
rebuild Rebuild a server
remove-label Remove a label from a server
update Update a Server

Protection:
disable-protection Disable resource protection for a server
enable-protection Enable resource protection for a server

Rescue:
disable-rescue Disable rescue for a server
enable-rescue Enable rescue for a server

Power/Reboot:
poweroff Poweroff a server
poweron Poweron a server
reboot Reboot a server
reset Reset a server
shutdown Shutdown a server

Networks:
attach-to-network Attach a server to a network
change-alias-ips Change a server's alias IPs in a network
detach-from-network Detach a server from a network

ISO:
attach-iso Attach an ISO to a server
detach-iso Detach an ISO from a server

Placement Groups:
add-to-placement-group Add a server to a placement group
remove-from-placement-group Removes a server from a placement group

Backup:
disable-backup Disable backup for a server
enable-backup Enable backup for a server

Additional Commands:
ip Print a server's IP address
metrics [ALPHA] Metrics from a Server
request-console Request a WebSocket VNC console for a server
reset-password Reset the root password of a server
set-rdns Change reverse DNS of a Server
ssh Spawn an SSH connection for the server
```
13 changes: 9 additions & 4 deletions cmd/hcloud/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/hetznercloud/cli/internal/cmd/server"
"github.com/hetznercloud/cli/internal/cmd/servertype"
"github.com/hetznercloud/cli/internal/cmd/sshkey"
"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/cmd/version"
"github.com/hetznercloud/cli/internal/cmd/volume"
"github.com/hetznercloud/cli/internal/state"
Expand Down Expand Up @@ -52,16 +53,14 @@ func main() {
}

rootCommand := cli.NewRootCommand(s)
rootCommand.AddCommand(

util.AddGroup(rootCommand, "resource", "Resources",
all.NewCommand(s),
floatingip.NewCommand(s),
image.NewCommand(s),
server.NewCommand(s),
sshkey.NewCommand(s),
version.NewCommand(s),
completion.NewCommand(s),
servertype.NewCommand(s),
context.NewCommand(s),
datacenter.NewCommand(s),
location.NewCommand(s),
iso.NewCommand(s),
Expand All @@ -75,6 +74,12 @@ func main() {
primaryip.NewCommand(s),
)

rootCommand.AddCommand(
version.NewCommand(s),
completion.NewCommand(s),
context.NewCommand(s),
)

if err := rootCommand.Execute(); err != nil {
log.Fatalln(err)
}
Expand Down
16 changes: 12 additions & 4 deletions internal/cmd/firewall/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package firewall
import (
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/state"
)

Expand All @@ -14,19 +15,26 @@ func NewCommand(s state.State) *cobra.Command {
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.AddCommand(

util.AddGroup(cmd, "general", "General",
ListCmd.CobraCommand(s),
DescribeCmd.CobraCommand(s),
CreateCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
UpdateCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
)

util.AddGroup(cmd, "rule", "Rules",
ReplaceRulesCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
AddRuleCmd.CobraCommand(s),
DeleteRuleCmd.CobraCommand(s),
)

util.AddGroup(cmd, "resource", "Resources",
ApplyToResourceCmd.CobraCommand(s),
RemoveFromResourceCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
)
return cmd
}
25 changes: 17 additions & 8 deletions internal/cmd/floatingip/floatingip.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package floatingip
import (
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/state"
)

Expand All @@ -14,19 +15,27 @@ func NewCommand(s state.State) *cobra.Command {
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
UpdateCmd.CobraCommand(s),

util.AddGroup(cmd, "general", "General",
ListCmd.CobraCommand(s),
CreateCmd.CobraCommand(s),
DescribeCmd.CobraCommand(s),
AssignCmd.CobraCommand(s),
UnassignCmd.CobraCommand(s),
CreateCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
UpdateCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
SetRDNSCmd.CobraCommand(s),
)

util.AddGroup(cmd, "protection", "Protection",
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
)

util.AddGroup(cmd, "assign", "Assign",
AssignCmd.CobraCommand(s),
UnassignCmd.CobraCommand(s),
)

cmd.AddCommand(SetRDNSCmd.CobraCommand(s))
return cmd
}
13 changes: 9 additions & 4 deletions internal/cmd/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package image
import (
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/state"
)

Expand All @@ -14,15 +15,19 @@ func NewCommand(s state.State) *cobra.Command {
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.AddCommand(

util.AddGroup(cmd, "general", "General",
ListCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
DescribeCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
UpdateCmd.CobraCommand(s),
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
)

util.AddGroup(cmd, "protection", "Protection",
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
)
return cmd
}
34 changes: 27 additions & 7 deletions internal/cmd/loadbalancer/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package loadbalancer
import (
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/state"
)

Expand All @@ -15,27 +16,46 @@ func NewCommand(s state.State) *cobra.Command {
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.AddCommand(
CreateCmd.CobraCommand(s),

util.AddGroup(cmd, "general", "General",
ListCmd.CobraCommand(s),
CreateCmd.CobraCommand(s),
DescribeCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
UpdateCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
ChangeAlgorithmCmd.CobraCommand(s),
ChangeTypeCmd.CobraCommand(s),
)

util.AddGroup(cmd, "protection", "Protection",
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
)

util.AddGroup(cmd, "target", "Targets",
AddTargetCmd.CobraCommand(s),
RemoveTargetCmd.CobraCommand(s),
ChangeAlgorithmCmd.CobraCommand(s),
)

util.AddGroup(cmd, "service", "Services",
AddServiceCmd.CobraCommand(s),
UpdateServiceCmd.CobraCommand(s),
DeleteServiceCmd.CobraCommand(s),
AddServiceCmd.CobraCommand(s),
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
)

util.AddGroup(cmd, "network", "Network",
AttachToNetworkCmd.CobraCommand(s),
DetachFromNetworkCmd.CobraCommand(s),
)

util.AddGroup(cmd, "public-interface", "Public Interface",
EnablePublicInterfaceCmd.CobraCommand(s),
DisablePublicInterfaceCmd.CobraCommand(s),
ChangeTypeCmd.CobraCommand(s),
)

cmd.AddCommand(
MetricsCmd.CobraCommand(s),
SetRDNSCmd.CobraCommand(s),
)
Expand Down
25 changes: 18 additions & 7 deletions internal/cmd/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package network
import (
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/state"
)

Expand All @@ -14,22 +15,32 @@ func NewCommand(s state.State) *cobra.Command {
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.AddCommand(

util.AddGroup(cmd, "general", "General",
ListCmd.CobraCommand(s),
DescribeCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
CreateCmd.CobraCommand(s),
UpdateCmd.CobraCommand(s),
DeleteCmd.CobraCommand(s),
ChangeIPRangeCmd.CobraCommand(s),
AddRouteCmd.CobraCommand(s),
RemoveRouteCmd.CobraCommand(s),
AddSubnetCmd.CobraCommand(s),
RemoveSubnetCmd.CobraCommand(s),
LabelCmds.AddCobraCommand(s),
LabelCmds.RemoveCobraCommand(s),
ChangeIPRangeCmd.CobraCommand(s),
)

util.AddGroup(cmd, "protection", "Protection",
EnableProtectionCmd.CobraCommand(s),
DisableProtectionCmd.CobraCommand(s),
)

util.AddGroup(cmd, "route", "Routes",
AddRouteCmd.CobraCommand(s),
RemoveRouteCmd.CobraCommand(s),
ExposeRoutesToVSwitchCmd.CobraCommand(s),
)

util.AddGroup(cmd, "subnet", "Subnets",
AddSubnetCmd.CobraCommand(s),
RemoveSubnetCmd.CobraCommand(s),
)
return cmd
}
Loading
Loading