changeset 10:44c07eb8ef08

Add man subcommand to display the user manual Generate the manual from the documentation in godoc format.
author Guido Berhoerster <guido+sievemgr@berhoerster.name>
date Thu, 03 Dec 2020 13:52:28 +0100
parents 7ce77ceeaccc
children 29769b9e2f09
files cmd/sievemgr/doc.go cmd/sievemgr/gendocstr.go cmd/sievemgr/main.go cmd/sievemgr/man.go
diffstat 4 files changed, 150 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/cmd/sievemgr/doc.go	Sat Nov 28 23:44:45 2020 +0100
+++ b/cmd/sievemgr/doc.go	Thu Dec 03 13:52:28 2020 +0100
@@ -14,6 +14,7 @@
 	sievemgr [-f config] checkspace [-a account] script [file]
 	sievemgr [-f config] rename [-a account] old new
 	sievemgr [-f config] edit [-a account] script
+	sievemgr [-f config] man
 
 Description:
 
@@ -152,5 +153,9 @@
 exits with a non-zero exit status the local copy of script will not be
 submitted to the server.  In case of errors the local copy of the script will
 be preserved.
+
+	sievemgr [-f config] man
+
+Display the user manual.
 */
 package main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/sievemgr/gendocstr.go	Thu Dec 03 13:52:28 2020 +0100
@@ -0,0 +1,101 @@
+// Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// +build ignore
+
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/doc"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func newDocPkg(dir, importPath, outputName string) (*doc.Package, error) {
+	fset := token.NewFileSet()
+	var files []*ast.File
+
+	filelist, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	for _, d := range filelist {
+		if !strings.HasSuffix(d.Name(), ".go") ||
+			strings.HasSuffix(d.Name(), "_test.go") ||
+			d.Name() == outputName {
+			continue
+		}
+		if ok, err := build.Default.MatchFile(dir, d.Name()); err != nil || !ok {
+			continue
+		}
+
+		filename := filepath.Join(dir, d.Name())
+		f, err := parser.ParseFile(fset, filename, nil,
+			parser.ParseComments)
+		if err != nil {
+			return nil, err
+		}
+		files = append(files, f)
+	}
+
+	return doc.NewFromFiles(fset, files, importPath)
+}
+
+func main() {
+	if len(os.Args) != 5 {
+		fmt.Fprintf(os.Stderr,
+			"usage: genhelp dir import_path var file\n")
+		os.Exit(1)
+	}
+
+	dir := os.Args[1]
+	importPath := os.Args[2]
+	varName := os.Args[3]
+	outputName := os.Args[4]
+
+	w, err := os.OpenFile(filepath.Join(dir, outputName),
+		os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "failed to open output file: %s\n", err)
+		os.Exit(1)
+	}
+	defer w.Close()
+
+	pkg, err := newDocPkg(dir, importPath, outputName)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "failed to parse files: %s\n", err)
+		os.Exit(1)
+	}
+
+	var b strings.Builder
+	doc.ToText(&b, pkg.Doc, "", "    ", 78)
+
+	fmt.Fprintf(w, "// Code generated by \"gendocstr\"; DO NOT EDIT.\n\n")
+	fmt.Fprintf(w, "package %s\n\n", pkg.Name)
+	fmt.Fprintf(w, "const %s = %q", varName, b.String())
+}
--- a/cmd/sievemgr/main.go	Sat Nov 28 23:44:45 2020 +0100
+++ b/cmd/sievemgr/main.go	Thu Dec 03 13:52:28 2020 +0100
@@ -19,6 +19,8 @@
 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+//go:generate go run gendocstr.go . code.guido-berhoerster.org/go/sievemgr docText docstr.go
+
 package main
 
 import (
@@ -71,6 +73,7 @@
 	cmdCheckSpace,
 	cmdRename,
 	cmdEdit,
+	cmdMan,
 }
 
 func usage() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/sievemgr/man.go	Thu Dec 03 13:52:28 2020 +0100
@@ -0,0 +1,41 @@
+// Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+package main
+
+import (
+	"fmt"
+)
+
+var cmdMan = &command{
+	UsageLine: "man [options]",
+	Run:       runMan,
+}
+
+func runMan(cmd *command, args []string) error {
+	if len(args) != 0 {
+		return usageError("invalid number of arguments")
+	}
+
+	fmt.Println(docText)
+
+	return nil
+}