File: error-kinds.go

package info (click to toggle)
snapd 2.71-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 79,536 kB
  • sloc: ansic: 16,114; sh: 16,105; python: 9,941; makefile: 1,890; exp: 190; awk: 40; xml: 22
file content (100 lines) | stat: -rw-r--r-- 2,337 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main

import (
	"fmt"
	"go/ast"
	"go/doc"
	"go/parser"
	"go/token"
	"os"
	"sort"
	"strconv"
	"strings"
)

const (
	errorKindsHdr      = `## <h3 id='heading--errors'>Error kinds</h3>`
	maintErrorKindsHdr = `## <h4 id='heading--maint-errors'>Maintenance error kinds</h4>

These are used only inside the ` + "`maintenance` field of responses."
)

func fail(err error) {
	fmt.Fprintf(os.Stderr, "error: %v", err)
	os.Exit(1)
}

func main() {
	fset := token.NewFileSet()
	pkgs, err := parser.ParseDir(fset, "../client", nil, parser.ParseComments)
	if err != nil {
		fail(err)
	}

	p := doc.New(pkgs["client"], "github.com/snapcore/snapd/client", 0)
	var errorKindT *doc.Type
	for _, t := range p.Types {
		if t.Name == "ErrorKind" {
			errorKindT = t
			break
		}
	}
	if errorKindT == nil {
		fail(fmt.Errorf("expected ErrorKind type not defined"))
	}
	for _, c := range errorKindT.Consts {
		if strings.HasPrefix(c.Doc, "Error kinds.") {
			fmt.Println(errorKindsHdr)
		} else if strings.HasPrefix(c.Doc, "Maintenance error kinds") {
			fmt.Println()
			fmt.Println(maintErrorKindsHdr)
		} else {
			fmt.Fprintf(os.Stderr, "unexpected error kind group: %v\n", c.Doc)
			continue
		}
		fmt.Println()

		kinds := make([]string, 0, len(c.Decl.Specs))
		docs := make(map[string]string, len(c.Decl.Specs))
		for _, spec := range c.Decl.Specs {
			vs, ok := spec.(*ast.ValueSpec)
			if !ok {
				fmt.Printf("%#v\n", spec)
				continue
			}
			kind, err := strconv.Unquote(vs.Values[0].(*ast.BasicLit).Value)
			if err != nil {
				// unexpected
				fail(err)
			}
			doc := vs.Doc.Text()
			name := vs.Names[0]
			pfx := name.String() + ":"
			if !strings.HasPrefix(doc, pfx) {
				fmt.Fprintf(os.Stderr, "expected %s: doc string prefix, got %q\n", name, doc)
			} else {
				doc = doc[len(pfx):]
			}
			doc = strings.Replace(doc, "\n", " ", -1)
			doc = strings.Replace(doc, "  ", " ", -1)
			doc = strings.TrimSpace(doc)
			if !strings.HasSuffix(doc, ".") {
				fmt.Fprintf(os.Stderr, "expected dot at the end %q for %s\n", doc, name)
			}
			if strings.HasPrefix(doc, "deprecated") {
				// skip
				continue
			}
			if doc == "" {
				doc = name.String() + "..."
			}
			kinds = append(kinds, kind)
			docs[kind] = doc
		}

		sort.Strings(kinds)
		for _, kind := range kinds {
			fmt.Printf("* `%s`: %s\n", kind, docs[kind])
		}
	}
}