Skip to content

Commit

Permalink
Refactor manpage generator as external module
Browse files Browse the repository at this point in the history
  • Loading branch information
pymnh committed Aug 31, 2021
1 parent 522f169 commit b7a1e86
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 31 deletions.
2 changes: 1 addition & 1 deletion cmd/commandfuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ func cmdReload(fl Flags) (int, error) {
}

func cmdVersion(_ Flags) (int, error) {
fmt.Println(caddyVersion())
fmt.Println(CaddyVersion())
return caddy.ExitCodeSuccess, nil
}

Expand Down
6 changes: 6 additions & 0 deletions cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ type Command struct {
// any error that occurred.
type CommandFunc func(Flags) (int, error)

// Commands returns a list of registered commands as type
// map[string]Command
func Commands() map[string]Command {
return commands
}

var commands = make(map[string]Command)

func init() {
Expand Down
6 changes: 3 additions & 3 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ func printEnvironment() {
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
fmt.Printf("caddy.AppConfigDir=%s\n", caddy.AppConfigDir())
fmt.Printf("caddy.ConfigAutosavePath=%s\n", caddy.ConfigAutosavePath)
fmt.Printf("caddy.Version=%s\n", caddyVersion())
fmt.Printf("caddy.Version=%s\n", CaddyVersion())
fmt.Printf("runtime.GOOS=%s\n", runtime.GOOS)
fmt.Printf("runtime.GOARCH=%s\n", runtime.GOARCH)
fmt.Printf("runtime.Compiler=%s\n", runtime.Compiler)
Expand All @@ -437,8 +437,8 @@ func printEnvironment() {
}
}

// caddyVersion returns a detailed version string, if available.
func caddyVersion() string {
// CaddyVersion returns a detailed version string, if available.
func CaddyVersion() string {
goModule := caddy.GoModule()
ver := goModule.Version
if goModule.Sum != "" {
Expand Down
87 changes: 60 additions & 27 deletions cmd/man.go → modules/doc/manpages.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package caddycmd
package doc

import (
"errors"
Expand All @@ -12,10 +12,14 @@ import (
"time"

"github.com/caddyserver/caddy/v2"
caddycmd "github.com/caddyserver/caddy/v2/cmd"
)

func init() {
RegisterCommand(Command{

caddy.RegisterModule(Manpages{})

caddycmd.RegisterCommand(caddycmd.Command{
Name: "man",
Func: cmdMan,
Short: "Print manual pages for Caddy",
Expand All @@ -25,7 +29,17 @@ Creates subfolder "man" in current directory and prints manual pages for Caddy a
})
}

func cmdMan(fl Flags) (int, error) {
type Manpages struct {
}

func (Manpages) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: "caddy.doc.manpages",
New: func() caddy.Module { return new(Manpages) },
}
}

func cmdMan(fl caddycmd.Flags) (int, error) {

type Makro struct {
App string
Expand All @@ -37,67 +51,72 @@ func cmdMan(fl Flags) (int, error) {
Usage string
Version string
Flags []*flag.Flag
Other []Command
Other []caddycmd.Command
}

const DateFormat = "January 2021"
const DateFormat = "January 2006"

const manpageTemplate = `.TH "{{ toUpper .Title }}" "1" "{{ .Date }}"
.SH NAME
.HP
{{ .Title }} \- {{ .Short }}
.SH SYNOPSIS
.HP
{{ .App }} {{if ne .Name .App}}{{ .Name }} {{ end }}{{ .Usage }}
{{ if .Long }}.SH DESCRIPTION
{{ .App }} {{if ne .Name .App}}{{ .Name }} {{ end }}{{ .Usage }}{{ if .Long }}
.SH DESCRIPTION
.PP
{{ .Long }}{{ end }}
{{ if .Flags}}.SH OPTIONS{{ range .Flags }}
.HP
\fB-{{ .Name }}\fR <string>
.RS
{{ .Usage }}
.RE {{ end }} {{ end }}
{{ if eq .Name .App }}.SH COMMANDS
.RE{{ end }}{{ end }}{{ if eq .Name .App }}
.SH COMMANDS
.PP
These are available commands to use with caddy. See their manpages
for usage and available flags.{{ range .Other }}
These are available commands to use with caddy.
See their manpages for usage and available flags.{{ range .Other }}
.HP
\fB{{ .Name }}\fR
.RS
{{ .Short }}. See \fBcaddy-{{ .Name }}\fR(1)
.RE{{ end }}{{ end }}
{{if ne .Name .App}}.SH SEE ALSO
.RE{{ end }}{{ end }}{{if ne .Name .App}}
.SH SEE ALSO
.PP
{{ range .Other }}\fBcaddy-{{ .Name }}\fR(1), {{ end }}\fBcaddy\fR(1){{ end }}
.HP
.SH DOCUMENTATION
.PP
Full documentation is available at:
https://caddyserver.com/docs/
.HP
Full documentation is available at: https://caddyserver.com/docs/
.SH VERSION
.HP
{{ .Version }}
.SH BUGS
.HP
Report Bugs to https://github.com/caddyserver/caddy
Report Bugs to: https://github.com/caddyserver/caddy
.SH COPYRIGHT
.HP
(c) Matthew Holt and The Caddy Authors`

// create dummy commands list and append dummy function for os.Args[0]
cmdCaddy := Command{
// Get list of subcommands
commands := caddycmd.Commands()

// Create dummy function for os.Args[0]
cmdCaddy := caddycmd.Command{
Name: os.Args[0],
Short: "an extensible server platform",
Usage: "<command> [<args...>]",
}
// abort if os.Args[0] matches name of registered subcommand

// Abort if os.Args[0] matches name of a registered subcommand
if _, exists := commands[cmdCaddy.Name]; exists {
return caddy.ExitCodeFailedStartup,
errors.New("Main command is named similar as subcommand: " + cmdCaddy.Name + "\nAborting")
}
// Create dummy commands list and append dummy function for os.Args[0]
all := commands
all[cmdCaddy.Name] = cmdCaddy

// Create "man" subdirectory in current directory
curDir, err := os.Getwd()
if err != nil {
return caddy.ExitCodeFailedStartup, err
Expand All @@ -107,29 +126,37 @@ Report Bugs to https://github.com/caddyserver/caddy
if err != nil {
return caddy.ExitCodeFailedStartup, err
}

fmt.Printf("Printing manual pages for " + os.Args[0] + " into " + manDir + "...\n")

for _, cmd := range all {
// Allocate Makrose to be passed to the template parser
m := Makro{
App: os.Args[0],
Name: cmd.Name,
Date: time.Now().Format(DateFormat),
Long: strings.TrimSuffix(strings.TrimPrefix(cmd.Long, "\n"), "\n"),
Short: strings.TrimSuffix(cmd.Short, "."),
Usage: cmd.Usage,
Version: caddyVersion(),
Version: caddycmd.CaddyVersion(),
}

// Title of man page will be be os.Args[0]-subcommand
// except for os.Args[0] itself
if m.Name == m.App {
m.Title = m.App
} else {
m.Title = m.App + "-" + m.Name
}

// Allocate available cli flags
if cmd.Flags != nil {
cmd.Flags.VisitAll(func(f *flag.Flag) {
m.Flags = append(m.Flags, f)
})
}

// Allocate list of "other" subcommands then itself
keys := make([]string, 0, len(commands))
for k := range commands {
keys = append(keys, k)
Expand All @@ -141,25 +168,31 @@ Report Bugs to https://github.com/caddyserver/caddy
}
}

// Create file
output := m.Title + ".1"
f, err := os.Create(filepath.Join(manDir, output))
if err != nil {
return caddy.ExitCodeFailedStartup, err
}

// Initialize template
t := template.New(output)
t = t.Funcs(template.FuncMap{
"toUpper": strings.ToUpper,
})

// Make toUpper function available to template parser
t = t.Funcs(template.FuncMap{"toUpper": strings.ToUpper})

// Parse template
t, err = t.Parse(manpageTemplate)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}

// Write template into file
err = t.Execute(f, m)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
}
fmt.Printf(`Done.
To inspect a files content as rendered manual page, use 'nroff -man <manpage>.1' or similar command`)
fmt.Printf("Done.\nTo inspect a files content as rendered manual page, use 'nroff -man <manpage>.1' or a similar text formatter\n")
return caddy.ExitCodeSuccess, nil
}

0 comments on commit b7a1e86

Please sign in to comment.