118 lines
2.2 KiB
Go
118 lines
2.2 KiB
Go
// 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:
|
|
//
|
|
// $ registry-api-descriptor-template doc/SPEC.md.tmpl > doc/SPEC.md
|
|
//
|
|
// 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"
|
|
|
|
"github.com/docker/distribution/api/v2"
|
|
)
|
|
|
|
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))
|
|
|
|
if err := tmpl.Execute(os.Stdout, v2.APIDescriptor); err != nil {
|
|
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
|
|
|
|
}
|