comparison cmd/sievemgr/gendocstr.go @ 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
children
comparison
equal deleted inserted replaced
9:7ce77ceeaccc 10:44c07eb8ef08
1 // Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 // +build ignore
23
24 package main
25
26 import (
27 "fmt"
28 "go/ast"
29 "go/build"
30 "go/doc"
31 "go/parser"
32 "go/token"
33 "io/ioutil"
34 "os"
35 "path/filepath"
36 "strings"
37 )
38
39 func newDocPkg(dir, importPath, outputName string) (*doc.Package, error) {
40 fset := token.NewFileSet()
41 var files []*ast.File
42
43 filelist, err := ioutil.ReadDir(dir)
44 if err != nil {
45 return nil, err
46 }
47 for _, d := range filelist {
48 if !strings.HasSuffix(d.Name(), ".go") ||
49 strings.HasSuffix(d.Name(), "_test.go") ||
50 d.Name() == outputName {
51 continue
52 }
53 if ok, err := build.Default.MatchFile(dir, d.Name()); err != nil || !ok {
54 continue
55 }
56
57 filename := filepath.Join(dir, d.Name())
58 f, err := parser.ParseFile(fset, filename, nil,
59 parser.ParseComments)
60 if err != nil {
61 return nil, err
62 }
63 files = append(files, f)
64 }
65
66 return doc.NewFromFiles(fset, files, importPath)
67 }
68
69 func main() {
70 if len(os.Args) != 5 {
71 fmt.Fprintf(os.Stderr,
72 "usage: genhelp dir import_path var file\n")
73 os.Exit(1)
74 }
75
76 dir := os.Args[1]
77 importPath := os.Args[2]
78 varName := os.Args[3]
79 outputName := os.Args[4]
80
81 w, err := os.OpenFile(filepath.Join(dir, outputName),
82 os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
83 if err != nil {
84 fmt.Fprintf(os.Stderr, "failed to open output file: %s\n", err)
85 os.Exit(1)
86 }
87 defer w.Close()
88
89 pkg, err := newDocPkg(dir, importPath, outputName)
90 if err != nil {
91 fmt.Fprintf(os.Stderr, "failed to parse files: %s\n", err)
92 os.Exit(1)
93 }
94
95 var b strings.Builder
96 doc.ToText(&b, pkg.Doc, "", " ", 78)
97
98 fmt.Fprintf(w, "// Code generated by \"gendocstr\"; DO NOT EDIT.\n\n")
99 fmt.Fprintf(w, "package %s\n\n", pkg.Name)
100 fmt.Fprintf(w, "const %s = %q", varName, b.String())
101 }