5d8ff39816be2b4875f3782631d2b0c62f4e63d2
- Author
- Ayman Bagabas <ayman.bagabas@gmail.com>
- Committer
- Ayman Bagabas <ayman.bagabas@gmail.com>
- Date
Message
Diff
This diff is truncated to protect this page.
1diff --git a/server/cmd/cmd.go b/server/cmd/cmd.go
2index 671b6707ae339f0f70843e960c6413e1c4d23374..d2a369a2ab246f1e79774b1e7e0a237f089c4392 100644
3--- a/server/cmd/cmd.go
4+++ b/server/cmd/cmd.go
5@@ -3,6 +3,10 @@ package cmd
6 import (
7 "context"
8 "fmt"
9+ "net/url"
10+ "strings"
11+ "text/template"
12+ "unicode"
13
14 "github.com/charmbracelet/log"
15 "github.com/charmbracelet/soft-serve/server/backend"
16@@ -44,15 +48,92 @@ var (
17 logger = log.WithPrefix("server.cmd")
18 )
19
20+var templateFuncs = template.FuncMap{
21+ "trim": strings.TrimSpace,
22+ "trimRightSpace": trimRightSpace,
23+ "trimTrailingWhitespaces": trimRightSpace,
24+ "rpad": rpad,
25+ "gt": cobra.Gt,
26+ "eq": cobra.Eq,
27+}
28+
29+const (
30+ usageTmpl = `Usage:{{if .Runnable}}
31+ {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
32+ {{.SSHCommand}}{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
33+
34+Aliases:
35+ {{.NameAndAliases}}{{end}}{{if .HasExample}}
36+
37+Examples:
38+{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}
39+
40+Available Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
41+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}
42+
43+{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name "help")))}}
44+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}
45+
46+Additional Commands:{{range $cmds}}{{if (and (eq .GroupID "") (or .IsAvailableCommand (eq .Name "help")))}}
47+ {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
48+
49+Flags:
50+{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
51+
52+Global Flags:
53+{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
54+
55+Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
56+ {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
57+
58+Use "{{.SSHCommand}}{{.CommandPath}} [command] --help" for more information about a command.{{end}}
59+`
60+)
61+
62+func trimRightSpace(s string) string {
63+ return strings.TrimRightFunc(s, unicode.IsSpace)
64+}
65+
66+// rpad adds padding to the right of a string.
67+func rpad(s string, padding int) string {
68+ template := fmt.Sprintf("%%-%ds", padding)
69+ return fmt.Sprintf(template, s)
70+}
71+
72 // rootCommand is the root command for the server.
73 func rootCommand(cfg *config.Config, s ssh.Session) *cobra.Command {
74 rootCmd := &cobra.Command{
75- Use: "soft",
76 Short: "Soft Serve is a self-hostable Git server for the command line.",
77 SilenceUsage: true,
78 }
79
80- // TODO: use command usage template to include hostname and port
81+ hostname := "localhost"
82+ port := "23231"
83+ url, err := url.Parse(cfg.SSH.PublicURL)
84+ if err == nil {
85+ hostname = url.Hostname()
86+ port = url.Port()
87+ }
88+
89+ sshCmd := "ssh"
90+ if port != "22" {
91+ sshCmd += " -p" + port
92+ }
93+
94+ sshCmd += " " + hostname
95+ rootCmd.SetUsageTemplate(usageTmpl)
96+ rootCmd.SetUsageFunc(func(c *cobra.Command) error {
97+ t := template.New("usage")
98+ t.Funcs(templateFuncs)
99+ template.Must(t.Parse(c.UsageTemplate()))
100+ return t.Execute(c.OutOrStderr(), struct {
101+ *cobra.Command
102+ SSHCommand string
103+ }{
104+ Command: c,