summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames O'Doherty <james@theodohertyfamily.com>2026-06-04 23:16:07 -0400
committerJames O'Doherty <james@theodohertyfamily.com>2026-06-04 23:16:07 -0400
commit184deac4efe2062db6ecd2285ec8db1e919f9441 (patch)
tree1c77b35e4ebaec5edf887106e40d4b2f62bf8b69
parent78059b43e3d00a0f2b75677461692745cce34a63 (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.go39
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)
}
}