Switch to github.com/golang/dep for vendoring

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
This commit is contained in:
Mrunal Patel 2017-01-31 16:45:59 -08:00
parent d6ab91be27
commit 8e5b17cf13
15431 changed files with 3971413 additions and 8881 deletions

View file

@ -0,0 +1,15 @@
{
"Rules": [
{
"SelectorRegexp": "k8s[.]io",
"AllowedPrefixes": [
"k8s.io/kubernetes/cmd/libs/go2idl",
"k8s.io/apimachinery/pkg/openapi",
"k8s.io/gengo",
"k8s.io/kubernetes/third_party",
"k8s.io/apimachinery/third_party",
"k8s.io/apimachinery/pkg/util/sets"
]
}
]
}

View file

@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "openapi-gen",
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
tags = ["automanaged"],
deps = [
"//cmd/libs/go2idl/openapi-gen/generators:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/gengo/args",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/libs/go2idl/openapi-gen/generators:all-srcs",
],
tags = ["automanaged"],
)

View file

@ -0,0 +1,4 @@
# Generate OpenAPI definitions
- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines.
- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines.

View file

@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["openapi.go"],
tags = ["automanaged"],
deps = [
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/openapi",
"//vendor:k8s.io/gengo/args",
"//vendor:k8s.io/gengo/generator",
"//vendor:k8s.io/gengo/namer",
"//vendor:k8s.io/gengo/types",
],
)
go_test(
name = "go_default_test",
srcs = ["openapi_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//vendor:github.com/stretchr/testify/assert",
"//vendor:k8s.io/gengo/generator",
"//vendor:k8s.io/gengo/namer",
"//vendor:k8s.io/gengo/parser",
"//vendor:k8s.io/gengo/types",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View file

@ -0,0 +1,514 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package generators
import (
"bytes"
"fmt"
"io"
"path/filepath"
"reflect"
"sort"
"strings"
"k8s.io/apimachinery/pkg/openapi"
"k8s.io/gengo/args"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/types"
"github.com/golang/glog"
)
// This is the comment tag that carries parameters for open API generation.
const tagName = "k8s:openapi-gen"
const tagOptional = "optional"
// Known values for the tag.
const (
tagValueTrue = "true"
tagValueFalse = "false"
)
func hasOpenAPITagValue(comments []string, value string) bool {
tagValues := types.ExtractCommentTags("+", comments)[tagName]
if tagValues == nil {
return false
}
for _, val := range tagValues {
if val == value {
return true
}
}
return false
}
// hasOptionalTag returns true if the member has +optional in its comments or
// omitempty in its json tags.
func hasOptionalTag(m *types.Member) bool {
hasOptionalCommentTag := types.ExtractCommentTags(
"+", m.CommentLines)[tagOptional] != nil
hasOptionalJsonTag := strings.Contains(
reflect.StructTag(m.Tags).Get("json"), "omitempty")
return hasOptionalCommentTag || hasOptionalJsonTag
}
// NameSystems returns the name system used by the generators in this package.
func NameSystems() namer.NameSystems {
return namer.NameSystems{
"raw": namer.NewRawNamer("", nil),
}
}
// DefaultNameSystem returns the default name system for ordering the types to be
// processed by the generators in this package.
func DefaultNameSystem() string {
return "raw"
}
func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
boilerplate, err := arguments.LoadGoBoilerplate()
if err != nil {
glog.Fatalf("Failed loading boilerplate: %v", err)
}
header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
header = append(header, []byte(
`
// This file was autogenerated by openapi-gen. Do not edit it manually!
`)...)
if err := context.AddDir(arguments.OutputPackagePath); err != nil {
glog.Fatalf("Failed to load output package: %v", err)
}
pkg := context.Universe[arguments.OutputPackagePath]
if pkg == nil {
glog.Fatalf("Got nil output package: %v", err)
}
return generator.Packages{
&generator.DefaultPackage{
PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
PackagePath: pkg.Path,
HeaderText: header,
GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
return []generator.Generator{NewOpenAPIGen(arguments.OutputFileBaseName, pkg, context)}
},
FilterFunc: func(c *generator.Context, t *types.Type) bool {
// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
if strings.HasPrefix(t.Name.Name, "codecSelfer") {
return false
}
pkg := context.Universe.Package(t.Name.Package)
if hasOpenAPITagValue(pkg.Comments, tagValueTrue) {
return !hasOpenAPITagValue(t.CommentLines, tagValueFalse)
}
if hasOpenAPITagValue(t.CommentLines, tagValueTrue) {
return true
}
return false
},
},
}
}
const (
specPackagePath = "github.com/go-openapi/spec"
openAPICommonPackagePath = "k8s.io/apimachinery/pkg/openapi"
)
// openApiGen produces a file with auto-generated OpenAPI functions.
type openAPIGen struct {
generator.DefaultGen
// TargetPackage is the package that will get OpenAPIDefinitions variable contains all open API definitions.
targetPackage *types.Package
imports namer.ImportTracker
context *generator.Context
}
func NewOpenAPIGen(sanitizedName string, targetPackage *types.Package, context *generator.Context) generator.Generator {
return &openAPIGen{
DefaultGen: generator.DefaultGen{
OptionalName: sanitizedName,
},
imports: generator.NewImportTracker(),
targetPackage: targetPackage,
context: context,
}
}
func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems {
// Have the raw namer for this file track what it imports.
return namer.NameSystems{
"raw": namer.NewRawNamer(g.targetPackage.Path, g.imports),
}
}
func (g *openAPIGen) Filter(c *generator.Context, t *types.Type) bool {
// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
if strings.HasPrefix(t.Name.Name, "codecSelfer") {
return false
}
return true
}
func (g *openAPIGen) isOtherPackage(pkg string) bool {
if pkg == g.targetPackage.Path {
return false
}
if strings.HasSuffix(pkg, "\""+g.targetPackage.Path+"\"") {
return false
}
return true
}
func (g *openAPIGen) Imports(c *generator.Context) []string {
importLines := []string{}
for _, singleImport := range g.imports.ImportLines() {
importLines = append(importLines, singleImport)
}
return importLines
}
func argsFromType(t *types.Type) generator.Args {
return generator.Args{
"type": t,
"OpenAPIDefinitions": types.Ref(openAPICommonPackagePath, "OpenAPIDefinitions"),
"OpenAPIDefinition": types.Ref(openAPICommonPackagePath, "OpenAPIDefinition"),
"SpecSchemaType": types.Ref(specPackagePath, "Schema"),
}
}
func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$")
sw.Do("var OpenAPIDefinitions *$.OpenAPIDefinitions|raw$ = ", argsFromType(nil))
sw.Do("&$.OpenAPIDefinitions|raw${\n", argsFromType(nil))
return sw.Error()
}
func (g *openAPIGen) Finalize(c *generator.Context, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$")
sw.Do("}\n", nil)
return sw.Error()
}
func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
glog.V(5).Infof("generating for type %v", t)
sw := generator.NewSnippetWriter(w, c, "$", "$")
err := newOpenAPITypeWriter(sw).generate(t)
if err != nil {
return err
}
return sw.Error()
}
func getJsonTags(m *types.Member) []string {
jsonTag := reflect.StructTag(m.Tags).Get("json")
if jsonTag == "" {
return []string{}
}
return strings.Split(jsonTag, ",")
}
func getReferableName(m *types.Member) string {
jsonTags := getJsonTags(m)
if len(jsonTags) > 0 {
if jsonTags[0] == "-" {
return ""
} else {
return jsonTags[0]
}
} else {
return m.Name
}
}
func shouldInlineMembers(m *types.Member) bool {
jsonTags := getJsonTags(m)
return len(jsonTags) > 1 && jsonTags[1] == "inline"
}
type openAPITypeWriter struct {
*generator.SnippetWriter
refTypes map[string]*types.Type
GetDefinitionInterface *types.Type
}
func newOpenAPITypeWriter(sw *generator.SnippetWriter) openAPITypeWriter {
return openAPITypeWriter{
SnippetWriter: sw,
refTypes: map[string]*types.Type{},
}
}
func hasOpenAPIDefinitionMethod(t *types.Type) bool {
for mn, mt := range t.Methods {
if mn != "OpenAPIDefinition" {
continue
}
if len(mt.Signature.Parameters) != 0 || len(mt.Signature.Results) != 1 {
return false
}
r := mt.Signature.Results[0]
if r.Name.Name != "OpenAPIDefinition" || r.Name.Package != openAPICommonPackagePath {
return false
}
return true
}
return false
}
// typeShortName returns short package name (e.g. the name x appears in package x definition) dot type name.
func typeShortName(t *types.Type) string {
return filepath.Base(t.Name.Package) + "." + t.Name.Name
}
func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]string, error) {
var err error
for _, m := range t.Members {
if hasOpenAPITagValue(m.CommentLines, tagValueFalse) {
continue
}
if shouldInlineMembers(&m) {
required, err = g.generateMembers(m.Type, required)
if err != nil {
return required, err
}
continue
}
name := getReferableName(&m)
if name == "" {
continue
}
if !hasOptionalTag(&m) {
required = append(required, name)
}
if err = g.generateProperty(&m); err != nil {
return required, err
}
}
return required, nil
}
func (g openAPITypeWriter) generate(t *types.Type) error {
// Only generate for struct type and ignore the rest
switch t.Kind {
case types.Struct:
args := argsFromType(t)
g.Do("\"$.$\": ", typeShortName(t))
if hasOpenAPIDefinitionMethod(t) {
g.Do("$.type|raw${}.OpenAPIDefinition(),", args)
return nil
}
g.Do("{\nSchema: spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
g.generateDescription(t.CommentLines)
g.Do("Properties: map[string]$.SpecSchemaType|raw${\n", args)
required, err := g.generateMembers(t, []string{})
if err != nil {
return err
}
g.Do("},\n", nil)
if len(required) > 0 {
g.Do("Required: []string{\"$.$\"},\n", strings.Join(required, "\",\""))
}
g.Do("},\n},\n", nil)
g.Do("Dependencies: []string{\n", args)
// Map order is undefined, sort them or we may get a different file generated each time.
keys := []string{}
for k := range g.refTypes {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := g.refTypes[k]
if t, _ := openapi.GetOpenAPITypeFormat(v.String()); t != "" {
// This is a known type, we do not need a reference to it
// Will eliminate special case of time.Time
continue
}
g.Do("\"$.$\",", k)
}
g.Do("},\n},\n", nil)
}
return nil
}
func (g openAPITypeWriter) generateDescription(CommentLines []string) {
var buffer bytes.Buffer
delPrevChar := func() {
if buffer.Len() > 0 {
buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n"
}
}
for _, line := range CommentLines {
// Ignore all lines after ---
if line == "---" {
break
}
line = strings.TrimRight(line, " ")
leading := strings.TrimLeft(line, " ")
switch {
case len(line) == 0: // Keep paragraphs
delPrevChar()
buffer.WriteString("\n\n")
case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs
case strings.HasPrefix(leading, "+"): // Ignore instructions to go2idl
default:
if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
delPrevChar()
line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..."
} else {
line += " "
}
buffer.WriteString(line)
}
}
postDoc := strings.TrimRight(buffer.String(), "\n")
postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to "
postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape "
postDoc = strings.Replace(postDoc, "\n", "\\n", -1)
postDoc = strings.Replace(postDoc, "\t", "\\t", -1)
postDoc = strings.Trim(postDoc, " ")
if postDoc != "" {
g.Do("Description: \"$.$\",\n", postDoc)
}
}
func (g openAPITypeWriter) generateProperty(m *types.Member) error {
name := getReferableName(m)
if name == "" {
return nil
}
g.Do("\"$.$\": {\n", name)
g.Do("SchemaProps: spec.SchemaProps{\n", nil)
g.generateDescription(m.CommentLines)
jsonTags := getJsonTags(m)
if len(jsonTags) > 1 && jsonTags[1] == "string" {
g.generateSimpleProperty("string", "")
g.Do("},\n},\n", nil)
return nil
}
t := resolveAliasAndPtrType(m.Type)
// If we can get a openAPI type and format for this type, we consider it to be simple property
typeString, format := openapi.GetOpenAPITypeFormat(t.String())
if typeString != "" {
g.generateSimpleProperty(typeString, format)
g.Do("},\n},\n", nil)
return nil
}
switch t.Kind {
case types.Builtin:
return fmt.Errorf("please add type %v to getOpenAPITypeFormat function.", t)
case types.Map:
if err := g.generateMapProperty(t); err != nil {
return err
}
case types.Slice, types.Array:
if err := g.generateSliceProperty(t); err != nil {
return err
}
case types.Struct, types.Interface:
g.generateReferenceProperty(t)
default:
return fmt.Errorf("cannot generate spec for type %v.", t)
}
g.Do("},\n},\n", nil)
return g.Error()
}
func (g openAPITypeWriter) generateSimpleProperty(typeString, format string) {
g.Do("Type: []string{\"$.$\"},\n", typeString)
g.Do("Format: \"$.$\",\n", format)
}
func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) {
var name string
if t.Name.Package == "" {
name = t.Name.Name
} else {
name = filepath.Base(t.Name.Package) + "." + t.Name.Name
}
g.refTypes[name] = t
g.Do("Ref: spec.MustCreateRef(\"#/definitions/$.$\"),\n", name)
}
func resolveAliasAndPtrType(t *types.Type) *types.Type {
var prev *types.Type
for prev != t {
prev = t
if t.Kind == types.Alias {
t = t.Underlying
}
if t.Kind == types.Pointer {
t = t.Elem
}
}
return t
}
func (g openAPITypeWriter) generateMapProperty(t *types.Type) error {
keyType := resolveAliasAndPtrType(t.Key)
elemType := resolveAliasAndPtrType(t.Elem)
// According to OpenAPI examples, only map from string is supported
if keyType.Name.Name != "string" {
return fmt.Errorf("map with non-string keys are not supported by OpenAPI in %v", t)
}
g.Do("Type: []string{\"object\"},\n", nil)
g.Do("AdditionalProperties: &spec.SchemaOrBool{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
if typeString != "" {
g.generateSimpleProperty(typeString, format)
g.Do("},\n},\n},\n", nil)
return nil
}
switch elemType.Kind {
case types.Builtin:
return fmt.Errorf("please add type %v to getOpenAPITypeFormat function.", elemType)
case types.Struct:
g.generateReferenceProperty(t.Elem)
case types.Slice, types.Array:
g.generateSliceProperty(elemType)
default:
return fmt.Errorf("map Element kind %v is not supported in %v", elemType.Kind, t.Name)
}
g.Do("},\n},\n},\n", nil)
return nil
}
func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error {
elemType := resolveAliasAndPtrType(t.Elem)
g.Do("Type: []string{\"array\"},\n", nil)
g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
if typeString != "" {
g.generateSimpleProperty(typeString, format)
g.Do("},\n},\n},\n", nil)
return nil
}
switch elemType.Kind {
case types.Builtin:
return fmt.Errorf("please add type %v to getOpenAPITypeFormat function.", elemType)
case types.Struct:
g.generateReferenceProperty(t.Elem)
default:
return fmt.Errorf("slice Element kind %v is not supported in %v", elemType.Kind, t)
}
g.Do("},\n},\n},\n", nil)
return nil
}

View file

@ -0,0 +1,337 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package generators
import (
"bytes"
"fmt"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/gengo/generator"
"k8s.io/gengo/namer"
"k8s.io/gengo/parser"
"k8s.io/gengo/types"
)
func construct(t *testing.T, files map[string]string, testNamer namer.Namer) (*parser.Builder, types.Universe, []*types.Type) {
b := parser.New()
for name, src := range files {
if err := b.AddFileForTest(filepath.Dir(name), name, []byte(src)); err != nil {
t.Fatal(err)
}
}
u, err := b.FindTypes()
if err != nil {
t.Fatal(err)
}
orderer := namer.Orderer{Namer: testNamer}
o := orderer.OrderUniverse(u)
return b, u, o
}
func testOpenAPITypeWritter(t *testing.T, code string) (error, *assert.Assertions, *bytes.Buffer) {
assert := assert.New(t)
var testFiles = map[string]string{
"base/foo/bar.go": code,
}
rawNamer := namer.NewRawNamer("o", nil)
namers := namer.NameSystems{
"raw": namer.NewRawNamer("", nil),
}
builder, universe, _ := construct(t, testFiles, rawNamer)
context, err := generator.NewContext(builder, namers, "raw")
if err != nil {
t.Fatal(err)
}
buffer := &bytes.Buffer{}
sw := generator.NewSnippetWriter(buffer, context, "$", "$")
blahT := universe.Type(types.Name{Package: "base/foo", Name: "Blah"})
return newOpenAPITypeWriter(sw).generate(blahT), assert, buffer
}
func TestSimple(t *testing.T) {
err, assert, buffer := testOpenAPITypeWritter(t, `
package foo
// Blah is a test.
// +k8s:openapi=true
type Blah struct {
// A simple string
String string
// A simple int
Int int `+"`"+`json:",omitempty"`+"`"+`
// An int considered string simple int
IntString int `+"`"+`json:",string"`+"`"+`
// A simple int64
Int64 int64
// A simple int32
Int32 int32
// A simple int16
Int16 int16
// A simple int8
Int8 int8
// A simple int
Uint uint
// A simple int64
Uint64 uint64
// A simple int32
Uint32 uint32
// A simple int16
Uint16 uint16
// A simple int8
Uint8 uint8
// A simple byte
Byte byte
// A simple boolean
Bool bool
// A simple float64
Float64 float64
// A simple float32
Float32 float32
// a base64 encoded characters
ByteArray []byte
}
`)
if err != nil {
t.Fatal(err)
}
assert.Equal(`"foo.Blah": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "Blah is a test.",
Properties: map[string]spec.Schema{
"String": {
SchemaProps: spec.SchemaProps{
Description: "A simple string",
Type: []string{"string"},
Format: "",
},
},
"Int64": {
SchemaProps: spec.SchemaProps{
Description: "A simple int64",
Type: []string{"integer"},
Format: "int64",
},
},
"Int32": {
SchemaProps: spec.SchemaProps{
Description: "A simple int32",
Type: []string{"integer"},
Format: "int32",
},
},
"Int16": {
SchemaProps: spec.SchemaProps{
Description: "A simple int16",
Type: []string{"integer"},
Format: "int32",
},
},
"Int8": {
SchemaProps: spec.SchemaProps{
Description: "A simple int8",
Type: []string{"integer"},
Format: "byte",
},
},
"Uint": {
SchemaProps: spec.SchemaProps{
Description: "A simple int",
Type: []string{"integer"},
Format: "int32",
},
},
"Uint64": {
SchemaProps: spec.SchemaProps{
Description: "A simple int64",
Type: []string{"integer"},
Format: "int64",
},
},
"Uint32": {
SchemaProps: spec.SchemaProps{
Description: "A simple int32",
Type: []string{"integer"},
Format: "int64",
},
},
"Uint16": {
SchemaProps: spec.SchemaProps{
Description: "A simple int16",
Type: []string{"integer"},
Format: "int32",
},
},
"Uint8": {
SchemaProps: spec.SchemaProps{
Description: "A simple int8",
Type: []string{"integer"},
Format: "byte",
},
},
"Byte": {
SchemaProps: spec.SchemaProps{
Description: "A simple byte",
Type: []string{"integer"},
Format: "byte",
},
},
"Bool": {
SchemaProps: spec.SchemaProps{
Description: "A simple boolean",
Type: []string{"boolean"},
Format: "",
},
},
"Float64": {
SchemaProps: spec.SchemaProps{
Description: "A simple float64",
Type: []string{"number"},
Format: "double",
},
},
"Float32": {
SchemaProps: spec.SchemaProps{
Description: "A simple float32",
Type: []string{"number"},
Format: "float",
},
},
"ByteArray": {
SchemaProps: spec.SchemaProps{
Description: "a base64 encoded characters",
Type: []string{"string"},
Format: "byte",
},
},
},
Required: []string{"String","Int64","Int32","Int16","Int8","Uint","Uint64","Uint32","Uint16","Uint8","Byte","Bool","Float64","Float32","ByteArray"},
},
},
Dependencies: []string{
},
},
`, buffer.String())
}
func TestFailingSample1(t *testing.T) {
err, assert, _ := testOpenAPITypeWritter(t, `
package foo
// Map sample tests openAPIGen.generateMapProperty method.
type Blah struct {
// A sample String to String map
StringToArray map[string]map[string]string
}
`)
if assert.Error(err, "An error was expected") {
assert.Equal(err, fmt.Errorf("map Element kind Map is not supported in map[string]map[string]string"))
}
}
func TestFailingSample2(t *testing.T) {
err, assert, _ := testOpenAPITypeWritter(t, `
package foo
// Map sample tests openAPIGen.generateMapProperty method.
type Blah struct {
// A sample String to String map
StringToArray map[int]string
} `)
if assert.Error(err, "An error was expected") {
assert.Equal(err, fmt.Errorf("map with non-string keys are not supported by OpenAPI in map[int]string"))
}
}
func TestPointer(t *testing.T) {
err, assert, buffer := testOpenAPITypeWritter(t, `
package foo
// PointerSample demonstrate pointer's properties
type Blah struct {
// A string pointer
StringPointer *string
// A struct pointer
StructPointer *Blah
// A slice pointer
SlicePointer *[]string
// A map pointer
MapPointer *map[string]string
}
`)
if err != nil {
t.Fatal(err)
}
assert.Equal(`"foo.Blah": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "PointerSample demonstrate pointer's properties",
Properties: map[string]spec.Schema{
"StringPointer": {
SchemaProps: spec.SchemaProps{
Description: "A string pointer",
Type: []string{"string"},
Format: "",
},
},
"StructPointer": {
SchemaProps: spec.SchemaProps{
Description: "A struct pointer",
Ref: spec.MustCreateRef("#/definitions/foo.Blah"),
},
},
"SlicePointer": {
SchemaProps: spec.SchemaProps{
Description: "A slice pointer",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
"MapPointer": {
SchemaProps: spec.SchemaProps{
Description: "A map pointer",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
},
},
},
},
Required: []string{"StringPointer","StructPointer","SlicePointer","MapPointer"},
},
},
Dependencies: []string{
"foo.Blah",},
},
`, buffer.String())
}

View file

@ -0,0 +1,47 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This package generates openAPI definition file to be used in open API spec generation on API servers. To generate
// definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines. To
// exclude a type from a tagged package, add "+k8s:openapi-gen=false" tag to the type comment lines.
package main
import (
"path/filepath"
"k8s.io/gengo/args"
"k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen/generators"
"github.com/golang/glog"
)
func main() {
arguments := args.Default()
// Override defaults.
arguments.OutputFileBaseName = "openapi_generated"
arguments.GoHeaderFilePath = filepath.Join(args.DefaultSourceTree(), "k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt")
// Run it.
if err := arguments.Execute(
generators.NameSystems(),
generators.DefaultNameSystem(),
generators.Packages,
); err != nil {
glog.Fatalf("Error: %v", err)
}
glog.V(2).Info("Completed successfully.")
}