2014-12-19 03:21:57 +01:00
|
|
|
// registry-api-descriptor-template uses the APIDescriptor defined in the
|
|
|
|
// api/v2 package to execute templates passed to the command line.
|
|
|
|
//
|
|
|
|
// For example, to generate a new API specification, one would execute the
|
|
|
|
// following command from the repo root:
|
|
|
|
//
|
2015-05-11 21:24:54 +02:00
|
|
|
// $ registry-api-descriptor-template docs/spec/api.md.tmpl > docs/spec/api.md
|
2014-12-19 03:21:57 +01:00
|
|
|
//
|
|
|
|
// The templates are passed in the api/v2.APIDescriptor object. Please see the
|
|
|
|
// package documentation for fields available on that object. The template
|
|
|
|
// syntax is from Go's standard library text/template package. For information
|
|
|
|
// on Go's template syntax, please see golang.org/pkg/text/template.
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
|
|
|
"text/template"
|
|
|
|
|
2015-06-03 15:52:39 +02:00
|
|
|
"github.com/docker/distribution/registry/api/errcode"
|
2015-02-11 02:32:22 +01:00
|
|
|
"github.com/docker/distribution/registry/api/v2"
|
2014-12-19 03:21:57 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var spaceRegex = regexp.MustCompile(`\n\s*`)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
|
|
if len(os.Args) != 2 {
|
|
|
|
log.Fatalln("please specify a template to execute.")
|
|
|
|
}
|
|
|
|
|
|
|
|
path := os.Args[1]
|
|
|
|
filename := filepath.Base(path)
|
|
|
|
|
|
|
|
funcMap := template.FuncMap{
|
|
|
|
"removenewlines": func(s string) string {
|
|
|
|
return spaceRegex.ReplaceAllString(s, " ")
|
|
|
|
},
|
|
|
|
"statustext": http.StatusText,
|
|
|
|
"prettygorilla": prettyGorillaMuxPath,
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := template.Must(template.New(filename).Funcs(funcMap).ParseFiles(path))
|
|
|
|
|
2015-06-03 15:52:39 +02:00
|
|
|
data := struct {
|
|
|
|
RouteDescriptors []v2.RouteDescriptor
|
|
|
|
ErrorDescriptors []errcode.ErrorDescriptor
|
|
|
|
}{
|
|
|
|
RouteDescriptors: v2.APIDescriptor.RouteDescriptors,
|
2015-08-07 01:25:08 +02:00
|
|
|
ErrorDescriptors: append(errcode.GetErrorCodeGroup("registry.api.v2"),
|
|
|
|
// The following are part of the specification but provided by errcode default.
|
|
|
|
errcode.ErrorCodeUnauthorized.Descriptor(),
|
2015-09-28 19:41:18 +02:00
|
|
|
errcode.ErrorCodeDenied.Descriptor(),
|
2015-08-07 01:25:08 +02:00
|
|
|
errcode.ErrorCodeUnsupported.Descriptor()),
|
2015-06-03 15:52:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := tmpl.Execute(os.Stdout, data); err != nil {
|
2014-12-19 03:21:57 +01:00
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// prettyGorillaMuxPath removes the regular expressions from a gorilla/mux
|
|
|
|
// route string, making it suitable for documentation.
|
|
|
|
func prettyGorillaMuxPath(s string) string {
|
|
|
|
// Stateful parser that removes regular expressions from gorilla
|
|
|
|
// routes. It correctly handles balanced bracket pairs.
|
|
|
|
|
|
|
|
var output string
|
|
|
|
var label string
|
|
|
|
var level int
|
|
|
|
|
|
|
|
start:
|
|
|
|
if s[0] == '{' {
|
|
|
|
s = s[1:]
|
|
|
|
level++
|
|
|
|
goto capture
|
|
|
|
}
|
|
|
|
|
|
|
|
output += string(s[0])
|
|
|
|
s = s[1:]
|
|
|
|
|
|
|
|
goto end
|
|
|
|
capture:
|
|
|
|
switch s[0] {
|
|
|
|
case '{':
|
|
|
|
level++
|
|
|
|
case '}':
|
|
|
|
level--
|
|
|
|
|
|
|
|
if level == 0 {
|
|
|
|
s = s[1:]
|
|
|
|
goto label
|
|
|
|
}
|
|
|
|
case ':':
|
|
|
|
s = s[1:]
|
|
|
|
goto skip
|
|
|
|
default:
|
|
|
|
label += string(s[0])
|
|
|
|
}
|
|
|
|
s = s[1:]
|
|
|
|
goto capture
|
|
|
|
skip:
|
|
|
|
switch s[0] {
|
|
|
|
case '{':
|
|
|
|
level++
|
|
|
|
case '}':
|
|
|
|
level--
|
|
|
|
}
|
|
|
|
s = s[1:]
|
|
|
|
|
|
|
|
if level == 0 {
|
|
|
|
goto label
|
|
|
|
}
|
|
|
|
|
|
|
|
goto skip
|
|
|
|
label:
|
|
|
|
if label != "" {
|
|
|
|
output += "<" + label + ">"
|
|
|
|
label = ""
|
|
|
|
}
|
|
|
|
end:
|
|
|
|
if s != "" {
|
|
|
|
goto start
|
|
|
|
}
|
|
|
|
|
|
|
|
return output
|
|
|
|
|
|
|
|
}
|