github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/cmd/registry-api-descriptor-template/main.go (about) 1 // registry-api-descriptor-template uses the APIDescriptor defined in the 2 // api/v2 package to execute templates passed to the command line. 3 // 4 // For example, to generate a new API specification, one would execute the 5 // following command from the repo root: 6 // 7 // $ registry-api-descriptor-template docs/spec/api.md.tmpl > docs/spec/api.md 8 // 9 // The templates are passed in the api/v2.APIDescriptor object. Please see the 10 // package documentation for fields available on that object. The template 11 // syntax is from Go's standard library text/template package. For information 12 // on Go's template syntax, please see golang.org/pkg/text/template. 13 package main 14 15 import ( 16 "log" 17 "net/http" 18 "os" 19 "path/filepath" 20 "regexp" 21 "text/template" 22 23 "github.com/docker/distribution/registry/api/errcode" 24 "github.com/docker/distribution/registry/api/v2" 25 ) 26 27 var spaceRegex = regexp.MustCompile(`\n\s*`) 28 29 func main() { 30 31 if len(os.Args) != 2 { 32 log.Fatalln("please specify a template to execute.") 33 } 34 35 path := os.Args[1] 36 filename := filepath.Base(path) 37 38 funcMap := template.FuncMap{ 39 "removenewlines": func(s string) string { 40 return spaceRegex.ReplaceAllString(s, " ") 41 }, 42 "statustext": http.StatusText, 43 "prettygorilla": prettyGorillaMuxPath, 44 } 45 46 tmpl := template.Must(template.New(filename).Funcs(funcMap).ParseFiles(path)) 47 48 data := struct { 49 RouteDescriptors []v2.RouteDescriptor 50 ErrorDescriptors []errcode.ErrorDescriptor 51 }{ 52 RouteDescriptors: v2.APIDescriptor.RouteDescriptors, 53 ErrorDescriptors: append(errcode.GetErrorCodeGroup("registry.api.v2"), 54 // The following are part of the specification but provided by errcode default. 55 errcode.ErrorCodeUnauthorized.Descriptor(), 56 errcode.ErrorCodeDenied.Descriptor(), 57 errcode.ErrorCodeUnsupported.Descriptor()), 58 } 59 60 if err := tmpl.Execute(os.Stdout, data); err != nil { 61 log.Fatalln(err) 62 } 63 } 64 65 // prettyGorillaMuxPath removes the regular expressions from a gorilla/mux 66 // route string, making it suitable for documentation. 67 func prettyGorillaMuxPath(s string) string { 68 // Stateful parser that removes regular expressions from gorilla 69 // routes. It correctly handles balanced bracket pairs. 70 71 var output string 72 var label string 73 var level int 74 75 start: 76 if s[0] == '{' { 77 s = s[1:] 78 level++ 79 goto capture 80 } 81 82 output += string(s[0]) 83 s = s[1:] 84 85 goto end 86 capture: 87 switch s[0] { 88 case '{': 89 level++ 90 case '}': 91 level-- 92 93 if level == 0 { 94 s = s[1:] 95 goto label 96 } 97 case ':': 98 s = s[1:] 99 goto skip 100 default: 101 label += string(s[0]) 102 } 103 s = s[1:] 104 goto capture 105 skip: 106 switch s[0] { 107 case '{': 108 level++ 109 case '}': 110 level-- 111 } 112 s = s[1:] 113 114 if level == 0 { 115 goto label 116 } 117 118 goto skip 119 label: 120 if label != "" { 121 output += "<" + label + ">" 122 label = "" 123 } 124 end: 125 if s != "" { 126 goto start 127 } 128 129 return output 130 131 }