diff options
| author | James O'Doherty <james@theodohertyfamily.com> | 2026-06-04 23:16:07 -0400 |
|---|---|---|
| committer | James O'Doherty <james@theodohertyfamily.com> | 2026-06-04 23:16:07 -0400 |
| commit | 184deac4efe2062db6ecd2285ec8db1e919f9441 (patch) | |
| tree | 1c77b35e4ebaec5edf887106e40d4b2f62bf8b69 | |
| parent | 78059b43e3d00a0f2b75677461692745cce34a63 (diff) | |
cli: improve usage and help output
Implement custom usage functions to provide more comprehensive and
discoverable help messages for the top-level tool and profile
management subcommands.
- Add printUsage and printProfileUsage methods to App.
- Override FlagSet.Usage to display professional help messages.
- Ensure profile subcommands are listed in the main help output.
- Trigger profile usage on missing or invalid subcommands.
| -rw-r--r-- | internal/cli/cli.go | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 9041670..a4b9a9a 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -102,6 +102,7 @@ func (a *App) Run() error { cfg := &config.Config{} fs := flag.NewFlagSet("wg-wrap", flag.ExitOnError) + fs.Usage = a.printUsage fs.StringVar(&cfg.Profile, "profile", "", "WireGuard profile to use") fs.StringVar(&cfg.DNSServer, "dns-server", "", "Override DNS server to use") @@ -158,9 +159,32 @@ func (a *App) isVerbose() bool { return os.Getenv("WG_WRAP_VERBOSE") == "1" } +func (a *App) printUsage() { + fmt.Fprintf(os.Stderr, "Usage: wg-wrap [options] [-- command [args]]\n\n") + fmt.Fprintf(os.Stderr, "Options:\n") + fmt.Fprintf(os.Stderr, " -profile string\n\tWireGuard profile to use (default \"default\")\n") + fmt.Fprintf(os.Stderr, " -dns-server string\n\tOverride DNS server to use\n\n") + fmt.Fprintf(os.Stderr, "Commands:\n") + fmt.Fprintf(os.Stderr, " show-config\n\tDisplay the current configuration and environment details\n") + fmt.Fprintf(os.Stderr, " profile <command>\n\tManage WireGuard profiles\n\t\t(list, import, configure, delete, stop)\n\n") + fmt.Fprintf(os.Stderr, "Run the wrapped command:\n") + fmt.Fprintf(os.Stderr, " wg-wrap [options] -- <command> [args]\n") +} + +func (a *App) printProfileUsage() { + fmt.Fprintf(os.Stderr, "Usage: wg-wrap profile <command> [args]\n\n") + fmt.Fprintf(os.Stderr, "Commands:\n") + fmt.Fprintf(os.Stderr, " list\n\tList all available profiles\n") + fmt.Fprintf(os.Stderr, " import <path> [name]\n\tImport a WireGuard .conf file\n") + fmt.Fprintf(os.Stderr, " configure <name>\n\tEdit a profile in the default editor\n") + fmt.Fprintf(os.Stderr, " delete <name>\n\tRemove a profile\n") + fmt.Fprintf(os.Stderr, " stop <name>\n\tStop a running profile and unpin its namespace\n") +} + func (a *App) handleProfileCmd() error { if len(a.Args) < 3 { - return fmt.Errorf("usage: wg-wrap profile <list|import|configure|delete|stop> [args]") + a.printProfileUsage() + return fmt.Errorf("missing profile subcommand") } subCmd := a.Args[2] @@ -169,7 +193,8 @@ func (a *App) handleProfileCmd() error { return a.handleProfileList() case "import": if len(a.Args) < 4 { - return fmt.Errorf("usage: wg-wrap profile import <path> [name]") + a.printProfileUsage() + return fmt.Errorf("missing import path") } var name string if len(a.Args) > 4 { @@ -178,17 +203,20 @@ func (a *App) handleProfileCmd() error { return a.handleProfileImport(a.Args[3], name) case "configure": if len(a.Args) < 4 { - return fmt.Errorf("usage: wg-wrap profile configure <name>") + a.printProfileUsage() + return fmt.Errorf("missing profile name") } return a.handleProfileConfigure(a.Args[3]) case "delete": if len(a.Args) < 4 { - return fmt.Errorf("usage: wg-wrap profile delete <name>") + a.printProfileUsage() + return fmt.Errorf("missing profile name") } return a.handleProfileDelete(a.Args[3]) case "stop": if len(a.Args) < 4 { - return fmt.Errorf("usage: wg-wrap profile stop <name>") + a.printProfileUsage() + return fmt.Errorf("missing profile name") } if !IsValidProfileName(a.Args[3]) { return fmt.Errorf("invalid profile name: %q", a.Args[3]) @@ -200,6 +228,7 @@ func (a *App) handleProfileCmd() error { fmt.Printf("Profile %s stopped and unpinned.\n", a.Args[3]) return nil default: + a.printProfileUsage() return fmt.Errorf("unknown profile subcommand: %s", subCmd) } } |
