projects/sievemgr

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 Dec 03 13:52:28 2020 +0100 (9 months ago)
parents 7ce77ceeaccc
children 29769b9e2f09
files cmd/sievemgr/doc.go cmd/sievemgr/gendocstr.go cmd/sievemgr/main.go cmd/sievemgr/man.go
line diff
     1.1 --- a/cmd/sievemgr/doc.go	Sat Nov 28 23:44:45 2020 +0100
     1.2 +++ b/cmd/sievemgr/doc.go	Thu Dec 03 13:52:28 2020 +0100
     1.3 @@ -14,6 +14,7 @@
     1.4  	sievemgr [-f config] checkspace [-a account] script [file]
     1.5  	sievemgr [-f config] rename [-a account] old new
     1.6  	sievemgr [-f config] edit [-a account] script
     1.7 +	sievemgr [-f config] man
     1.8  
     1.9  Description:
    1.10  
    1.11 @@ -152,5 +153,9 @@
    1.12  exits with a non-zero exit status the local copy of script will not be
    1.13  submitted to the server.  In case of errors the local copy of the script will
    1.14  be preserved.
    1.15 +
    1.16 +	sievemgr [-f config] man
    1.17 +
    1.18 +Display the user manual.
    1.19  */
    1.20  package main
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/cmd/sievemgr/gendocstr.go	Thu Dec 03 13:52:28 2020 +0100
     2.3 @@ -0,0 +1,101 @@
     2.4 +// Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
     2.5 +//
     2.6 +// Permission is hereby granted, free of charge, to any person obtaining
     2.7 +// a copy of this software and associated documentation files (the
     2.8 +// "Software"), to deal in the Software without restriction, including
     2.9 +// without limitation the rights to use, copy, modify, merge, publish,
    2.10 +// distribute, sublicense, and/or sell copies of the Software, and to
    2.11 +// permit persons to whom the Software is furnished to do so, subject to
    2.12 +// the following conditions:
    2.13 +//
    2.14 +// The above copyright notice and this permission notice shall be included
    2.15 +// in all copies or substantial portions of the Software.
    2.16 +//
    2.17 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    2.18 +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    2.19 +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    2.20 +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    2.21 +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    2.22 +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    2.23 +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    2.24 +
    2.25 +// +build ignore
    2.26 +
    2.27 +package main
    2.28 +
    2.29 +import (
    2.30 +	"fmt"
    2.31 +	"go/ast"
    2.32 +	"go/build"
    2.33 +	"go/doc"
    2.34 +	"go/parser"
    2.35 +	"go/token"
    2.36 +	"io/ioutil"
    2.37 +	"os"
    2.38 +	"path/filepath"
    2.39 +	"strings"
    2.40 +)
    2.41 +
    2.42 +func newDocPkg(dir, importPath, outputName string) (*doc.Package, error) {
    2.43 +	fset := token.NewFileSet()
    2.44 +	var files []*ast.File
    2.45 +
    2.46 +	filelist, err := ioutil.ReadDir(dir)
    2.47 +	if err != nil {
    2.48 +		return nil, err
    2.49 +	}
    2.50 +	for _, d := range filelist {
    2.51 +		if !strings.HasSuffix(d.Name(), ".go") ||
    2.52 +			strings.HasSuffix(d.Name(), "_test.go") ||
    2.53 +			d.Name() == outputName {
    2.54 +			continue
    2.55 +		}
    2.56 +		if ok, err := build.Default.MatchFile(dir, d.Name()); err != nil || !ok {
    2.57 +			continue
    2.58 +		}
    2.59 +
    2.60 +		filename := filepath.Join(dir, d.Name())
    2.61 +		f, err := parser.ParseFile(fset, filename, nil,
    2.62 +			parser.ParseComments)
    2.63 +		if err != nil {
    2.64 +			return nil, err
    2.65 +		}
    2.66 +		files = append(files, f)
    2.67 +	}
    2.68 +
    2.69 +	return doc.NewFromFiles(fset, files, importPath)
    2.70 +}
    2.71 +
    2.72 +func main() {
    2.73 +	if len(os.Args) != 5 {
    2.74 +		fmt.Fprintf(os.Stderr,
    2.75 +			"usage: genhelp dir import_path var file\n")
    2.76 +		os.Exit(1)
    2.77 +	}
    2.78 +
    2.79 +	dir := os.Args[1]
    2.80 +	importPath := os.Args[2]
    2.81 +	varName := os.Args[3]
    2.82 +	outputName := os.Args[4]
    2.83 +
    2.84 +	w, err := os.OpenFile(filepath.Join(dir, outputName),
    2.85 +		os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
    2.86 +	if err != nil {
    2.87 +		fmt.Fprintf(os.Stderr, "failed to open output file: %s\n", err)
    2.88 +		os.Exit(1)
    2.89 +	}
    2.90 +	defer w.Close()
    2.91 +
    2.92 +	pkg, err := newDocPkg(dir, importPath, outputName)
    2.93 +	if err != nil {
    2.94 +		fmt.Fprintf(os.Stderr, "failed to parse files: %s\n", err)
    2.95 +		os.Exit(1)
    2.96 +	}
    2.97 +
    2.98 +	var b strings.Builder
    2.99 +	doc.ToText(&b, pkg.Doc, "", "    ", 78)
   2.100 +
   2.101 +	fmt.Fprintf(w, "// Code generated by \"gendocstr\"; DO NOT EDIT.\n\n")
   2.102 +	fmt.Fprintf(w, "package %s\n\n", pkg.Name)
   2.103 +	fmt.Fprintf(w, "const %s = %q", varName, b.String())
   2.104 +}
     3.1 --- a/cmd/sievemgr/main.go	Sat Nov 28 23:44:45 2020 +0100
     3.2 +++ b/cmd/sievemgr/main.go	Thu Dec 03 13:52:28 2020 +0100
     3.3 @@ -19,6 +19,8 @@
     3.4  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     3.5  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     3.6  
     3.7 +//go:generate go run gendocstr.go . code.guido-berhoerster.org/go/sievemgr docText docstr.go
     3.8 +
     3.9  package main
    3.10  
    3.11  import (
    3.12 @@ -71,6 +73,7 @@
    3.13  	cmdCheckSpace,
    3.14  	cmdRename,
    3.15  	cmdEdit,
    3.16 +	cmdMan,
    3.17  }
    3.18  
    3.19  func usage() {
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/cmd/sievemgr/man.go	Thu Dec 03 13:52:28 2020 +0100
     4.3 @@ -0,0 +1,41 @@
     4.4 +// Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
     4.5 +//
     4.6 +// Permission is hereby granted, free of charge, to any person obtaining
     4.7 +// a copy of this software and associated documentation files (the
     4.8 +// "Software"), to deal in the Software without restriction, including
     4.9 +// without limitation the rights to use, copy, modify, merge, publish,
    4.10 +// distribute, sublicense, and/or sell copies of the Software, and to
    4.11 +// permit persons to whom the Software is furnished to do so, subject to
    4.12 +// the following conditions:
    4.13 +//
    4.14 +// The above copyright notice and this permission notice shall be included
    4.15 +// in all copies or substantial portions of the Software.
    4.16 +//
    4.17 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    4.18 +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    4.19 +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    4.20 +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    4.21 +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    4.22 +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    4.23 +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    4.24 +
    4.25 +package main
    4.26 +
    4.27 +import (
    4.28 +	"fmt"
    4.29 +)
    4.30 +
    4.31 +var cmdMan = &command{
    4.32 +	UsageLine: "man [options]",
    4.33 +	Run:       runMan,
    4.34 +}
    4.35 +
    4.36 +func runMan(cmd *command, args []string) error {
    4.37 +	if len(args) != 0 {
    4.38 +		return usageError("invalid number of arguments")
    4.39 +	}
    4.40 +
    4.41 +	fmt.Println(docText)
    4.42 +
    4.43 +	return nil
    4.44 +}