131 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.7 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 docs/spec/api.md.tmpl > docs/spec/api.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/registry/api/errcode"
 | 
						|
	"github.com/docker/distribution/registry/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))
 | 
						|
 | 
						|
	data := struct {
 | 
						|
		RouteDescriptors []v2.RouteDescriptor
 | 
						|
		ErrorDescriptors []errcode.ErrorDescriptor
 | 
						|
	}{
 | 
						|
		RouteDescriptors: v2.APIDescriptor.RouteDescriptors,
 | 
						|
		ErrorDescriptors: append(errcode.GetErrorCodeGroup("registry.api.v2"),
 | 
						|
			// The following are part of the specification but provided by errcode default.
 | 
						|
			errcode.ErrorCodeUnauthorized.Descriptor(),
 | 
						|
			errcode.ErrorCodeUnsupported.Descriptor()),
 | 
						|
	}
 | 
						|
 | 
						|
	if err := tmpl.Execute(os.Stdout, data); 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
 | 
						|
 | 
						|
}
 |