github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/docs/error-kinds.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/doc" 7 "go/parser" 8 "go/token" 9 "os" 10 "sort" 11 "strconv" 12 "strings" 13 ) 14 15 const ( 16 errorKindsHdr = `## <h3 id='heading--errors'>Error kinds</h3>` 17 maintErrorKindsHdr = `## <h4 id='heading--maint-errors'>Maintenance error kinds</h4> 18 19 These are used only inside the ` + "`maintenance` field of responses." 20 ) 21 22 func fail(err error) { 23 fmt.Fprintf(os.Stderr, "error: %v", err) 24 os.Exit(1) 25 } 26 27 func main() { 28 fset := token.NewFileSet() 29 pkgs, err := parser.ParseDir(fset, "../client", nil, parser.ParseComments) 30 if err != nil { 31 fail(err) 32 } 33 34 p := doc.New(pkgs["client"], "github.com/snapcore/snapd/client", 0) 35 var errorKindT *doc.Type 36 for _, t := range p.Types { 37 if t.Name == "ErrorKind" { 38 errorKindT = t 39 break 40 } 41 } 42 if errorKindT == nil { 43 fail(fmt.Errorf("expected ErrorKind type not defined")) 44 } 45 for _, c := range errorKindT.Consts { 46 if strings.HasPrefix(c.Doc, "Error kinds.") { 47 fmt.Println(errorKindsHdr) 48 } else if strings.HasPrefix(c.Doc, "Maintenance error kinds") { 49 fmt.Println() 50 fmt.Println(maintErrorKindsHdr) 51 } else { 52 fmt.Fprintf(os.Stderr, "unexpected error kind group: %v\n", c.Doc) 53 continue 54 } 55 fmt.Println() 56 57 kinds := make([]string, 0, len(c.Decl.Specs)) 58 docs := make(map[string]string, len(c.Decl.Specs)) 59 for _, spec := range c.Decl.Specs { 60 vs, ok := spec.(*ast.ValueSpec) 61 if !ok { 62 fmt.Printf("%#v\n", spec) 63 continue 64 } 65 kind, err := strconv.Unquote(vs.Values[0].(*ast.BasicLit).Value) 66 if err != nil { 67 // unexpected 68 fail(err) 69 } 70 doc := vs.Doc.Text() 71 name := vs.Names[0] 72 pfx := name.String() + ":" 73 if !strings.HasPrefix(doc, pfx) { 74 fmt.Fprintf(os.Stderr, "expected %s: doc string prefix, got %q\n", name, doc) 75 } else { 76 doc = doc[len(pfx):] 77 } 78 doc = strings.Replace(doc, "\n", " ", -1) 79 doc = strings.Replace(doc, " ", " ", -1) 80 doc = strings.TrimSpace(doc) 81 if !strings.HasSuffix(doc, ".") { 82 fmt.Fprintf(os.Stderr, "expected dot at the end %q for %s\n", doc, name) 83 } 84 if strings.HasPrefix(doc, "deprecated") { 85 // skip 86 continue 87 } 88 if doc == "" { 89 doc = name.String() + "..." 90 } 91 kinds = append(kinds, kind) 92 docs[kind] = doc 93 } 94 95 sort.Strings(kinds) 96 for _, kind := range kinds { 97 fmt.Printf("* `%s`: %s\n", kind, docs[kind]) 98 } 99 } 100 }