Update deps to Kube 1.11.3

This updates the dependencies to Kube 1.11.3 to pull in a fix allowing
requestheader auth to be used without normal client auth (which makes
things work on clusters that don't enable client auth normally, like
EKS).
This commit is contained in:
Solly Ross 2018-09-14 16:32:45 -04:00
parent 262493780f
commit c916572aca
474 changed files with 40067 additions and 18326 deletions

21
vendor/github.com/go-openapi/spec/.golangci.yml generated vendored Normal file
View file

@ -0,0 +1,21 @@
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0
gocyclo:
min-complexity: 25
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
min-len: 2
min-occurrences: 2
linters:
enable-all: true
disable:
- maligned
- unparam
- lll

View file

@ -1,6 +1,8 @@
language: go
go:
- 1.7
- 1.8
- 1.9
install:
- go get -u github.com/stretchr/testify
- go get -u github.com/go-openapi/swag

View file

@ -1,5 +1,10 @@
# OAI object model [![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec) [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec)
[![GolangCI](https://golangci.com/badges/github.com/go-openapi/spec.svg)](https://golangci.com)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/spec)](https://goreportcard.com/report/github.com/go-openapi/spec)
The object model for OpenAPI specification documents
The object model for OpenAPI specification documents.
Currently supports Swagger 2.0.

View file

@ -162,7 +162,7 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"jsonschema-draft-04.json": jsonschemaDraft04JSON,
"v2/schema.json": v2SchemaJSON,
"v2/schema.json": v2SchemaJSON,
}
// AssetDir returns the file names below a certain
@ -204,6 +204,7 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
"jsonschema-draft-04.json": &bintree{jsonschemaDraft04JSON, map[string]*bintree{}},
"v2": &bintree{nil, map[string]*bintree{
@ -257,4 +258,3 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

47
vendor/github.com/go-openapi/spec/debug.go generated vendored Normal file
View file

@ -0,0 +1,47 @@
// Copyright 2015 go-swagger maintainers
//
// 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 spec
import (
"fmt"
"log"
"os"
"path/filepath"
"runtime"
)
var (
// Debug is true when the SWAGGER_DEBUG env var is not empty.
// It enables a more verbose logging of validators.
Debug = os.Getenv("SWAGGER_DEBUG") != ""
// validateLogger is a debug logger for this package
specLogger *log.Logger
)
func init() {
debugOptions()
}
func debugOptions() {
specLogger = log.New(os.Stdout, "spec:", log.LstdFlags)
}
func debugLog(msg string, args ...interface{}) {
// A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog()
if Debug {
_, file1, pos1, _ := runtime.Caller(1)
specLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
}
}

View file

@ -30,16 +30,12 @@ import (
"github.com/go-openapi/swag"
)
var (
// Debug enables logging when SWAGGER_DEBUG env var is not empty
Debug = os.Getenv("SWAGGER_DEBUG") != ""
)
// ExpandOptions provides options for expand.
type ExpandOptions struct {
RelativeBase string
SkipSchemas bool
ContinueOnError bool
RelativeBase string
SkipSchemas bool
ContinueOnError bool
AbsoluteCircularRef bool
}
// ResolutionCache a cache for resolving urls
@ -49,7 +45,7 @@ type ResolutionCache interface {
}
type simpleCache struct {
lock sync.Mutex
lock sync.RWMutex
store map[string]interface{}
}
@ -59,6 +55,7 @@ func init() {
resCache = initResolutionCache()
}
// initResolutionCache initializes the URI resolution cache
func initResolutionCache() ResolutionCache {
return &simpleCache{store: map[string]interface{}{
"http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(),
@ -66,16 +63,37 @@ func initResolutionCache() ResolutionCache {
}}
}
// resolverContext allows to share a context during spec processing.
// At the moment, it just holds the index of circular references found.
type resolverContext struct {
// circulars holds all visited circular references, which allows shortcuts.
// NOTE: this is not just a performance improvement: it is required to figure out
// circular references which participate several cycles.
// This structure is privately instantiated and needs not be locked against
// concurrent access, unless we chose to implement a parallel spec walking.
circulars map[string]bool
basePath string
}
func newResolverContext(originalBasePath string) *resolverContext {
return &resolverContext{
circulars: make(map[string]bool),
basePath: originalBasePath, // keep the root base path in context
}
}
// Get retrieves a cached URI
func (s *simpleCache) Get(uri string) (interface{}, bool) {
debugLog("getting %q from resolution cache", uri)
s.lock.Lock()
s.lock.RLock()
v, ok := s.store[uri]
debugLog("got %q from resolution cache: %t", uri, ok)
s.lock.Unlock()
s.lock.RUnlock()
return v, ok
}
// Set caches a URI
func (s *simpleCache) Set(uri string, data interface{}) {
s.lock.Lock()
s.store[uri] = data
@ -84,7 +102,7 @@ func (s *simpleCache) Set(uri string, data interface{}) {
// ResolveRefWithBase resolves a reference against a context root with preservation of base path
func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) {
resolver, err := defaultSchemaLoader(root, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return nil, err
}
@ -116,21 +134,21 @@ func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
case map[string]interface{}:
b, _ := json.Marshal(sch)
newSch := new(Schema)
json.Unmarshal(b, newSch)
_ = json.Unmarshal(b, newSch)
return newSch, nil
default:
return nil, fmt.Errorf("unknown type for the resolved reference")
}
}
// ResolveParameter resolves a paramter reference against a context root
// ResolveParameter resolves a parameter reference against a context root
func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
return ResolveParameterWithBase(root, ref, nil)
}
// ResolveParameterWithBase resolves a paramter reference against a context root and base path
// ResolveParameterWithBase resolves a parameter reference against a context root and base path
func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) {
resolver, err := defaultSchemaLoader(root, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return nil, err
}
@ -149,7 +167,7 @@ func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
// ResolveResponseWithBase resolves response a reference against a context root and base path
func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) {
resolver, err := defaultSchemaLoader(root, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return nil, err
}
@ -163,7 +181,7 @@ func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*R
// ResolveItems resolves header and parameter items reference against a context root and base path
func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) {
resolver, err := defaultSchemaLoader(root, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return nil, err
}
@ -180,7 +198,7 @@ func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error
// ResolvePathItem resolves response a path item against a context root and base path
func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) {
resolver, err := defaultSchemaLoader(root, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return nil, err
}
@ -199,6 +217,7 @@ type schemaLoader struct {
root interface{}
options *ExpandOptions
cache ResolutionCache
context *resolverContext
loadDoc func(string) (json.RawMessage, error)
}
@ -221,7 +240,8 @@ func init() {
func defaultSchemaLoader(
root interface{},
expandOptions *ExpandOptions,
cache ResolutionCache) (*schemaLoader, error) {
cache ResolutionCache,
context *resolverContext) (*schemaLoader, error) {
if cache == nil {
cache = resCache
@ -229,11 +249,15 @@ func defaultSchemaLoader(
if expandOptions == nil {
expandOptions = &ExpandOptions{}
}
absBase, _ := absPath(expandOptions.RelativeBase)
if context == nil {
context = newResolverContext(absBase)
}
return &schemaLoader{
root: root,
options: expandOptions,
cache: cache,
context: context,
loadDoc: func(path string) (json.RawMessage, error) {
debugLog("fetching document at %q", path)
return PathLoader(path)
@ -312,12 +336,6 @@ func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointe
return ret
}
func debugLog(msg string, args ...interface{}) {
if Debug {
log.Printf(msg, args...)
}
}
// normalize absolute path for cache.
// on Windows, drive letters should be converted to lower as scheme in net/url.URL
func normalizeAbsPath(path string) string {
@ -366,6 +384,59 @@ func normalizePaths(refPath, base string) string {
return baseURL.String()
}
// denormalizePaths returns to simplest notation on file $ref,
// i.e. strips the absolute path and sets a path relative to the base path.
//
// This is currently used when we rewrite ref after a circular ref has been detected
func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref {
debugLog("denormalizeFileRef for: %s", ref.String())
if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly {
return ref
}
// strip relativeBase from URI
relativeBaseURL, _ := url.Parse(relativeBase)
relativeBaseURL.Fragment = ""
if relativeBaseURL.IsAbs() && strings.HasPrefix(ref.String(), relativeBase) {
// this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix
r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase))
return &r
}
if relativeBaseURL.IsAbs() {
// other absolute URL get unchanged (i.e. with a non-empty scheme)
return ref
}
// for relative file URIs:
originalRelativeBaseURL, _ := url.Parse(originalRelativeBase)
originalRelativeBaseURL.Fragment = ""
if strings.HasPrefix(ref.String(), originalRelativeBaseURL.String()) {
// the resulting ref is in the expanded spec: return a local ref
r, _ := NewRef(strings.TrimPrefix(ref.String(), originalRelativeBaseURL.String()))
return &r
}
// check if we may set a relative path, considering the original base path for this spec.
// Example:
// spec is located at /mypath/spec.json
// my normalized ref points to: /mypath/item.json#/target
// expected result: item.json#/target
parts := strings.Split(ref.String(), "#")
relativePath, err := filepath.Rel(path.Dir(originalRelativeBaseURL.String()), parts[0])
if err != nil {
// there is no common ancestor (e.g. different drives on windows)
// leaves the ref unchanged
return ref
}
if len(parts) == 2 {
relativePath += "#" + parts[1]
}
r, _ := NewRef(relativePath)
return &r
}
// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL
func normalizeFileRef(ref *Ref, relativeBase string) *Ref {
// This is important for when the reference is pointing to the root schema
@ -374,8 +445,7 @@ func normalizeFileRef(ref *Ref, relativeBase string) *Ref {
return &r
}
refURL := ref.GetURL()
debugLog("normalizing %s against %s (%s)", ref.String(), relativeBase, refURL.String())
debugLog("normalizing %s against %s", ref.String(), relativeBase)
s := normalizePaths(ref.String(), relativeBase)
r, _ := NewRef(s)
@ -400,7 +470,7 @@ func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string)
// it is pointing somewhere in the root.
root := r.root
if (ref.IsRoot() || ref.HasFragmentOnly) && root == nil && basePath != "" {
if baseRef, err := NewRef(basePath); err == nil {
if baseRef, erb := NewRef(basePath); erb == nil {
root, _, _, _ = r.load(baseRef.GetURL())
}
}
@ -475,7 +545,7 @@ func absPath(fname string) (string, error) {
// ExpandSpec expands the references in a swagger spec
func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
resolver, err := defaultSchemaLoader(spec, options, nil)
resolver, err := defaultSchemaLoader(spec, options, nil, nil)
// Just in case this ever returns an error.
if shouldStopOnError(err, resolver.options) {
return err
@ -538,25 +608,35 @@ func shouldStopOnError(err error, opts *ExpandOptions) bool {
return false
}
// ExpandSchema expands the refs in the schema object with reference to the root object
// go-openapi/validate uses this function
// notice that it is impossible to reference a json scema in a different file other than root
func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error {
// Only save the root to a tmp file if it isn't nil.
var base string
// baseForRoot loads in the cache the root document and produces a fake "root" base path entry
// for further $ref resolution
func baseForRoot(root interface{}, cache ResolutionCache) string {
// cache the root document to resolve $ref's
const rootBase = "root"
if root != nil {
base, _ = absPath("root")
base, _ := absPath(rootBase)
normalizedBase := normalizeAbsPath(base)
debugLog("setting root doc in cache at: %s", normalizedBase)
if cache == nil {
cache = resCache
}
cache.Set(normalizeAbsPath(base), root)
base = "root"
cache.Set(normalizedBase, root)
return rootBase
}
return ""
}
// ExpandSchema expands the refs in the schema object with reference to the root object
// go-openapi/validate uses this function
// notice that it is impossible to reference a json schema in a different file other than root
func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error {
opts := &ExpandOptions{
RelativeBase: base,
// when a root is specified, cache the root as an in-memory document for $ref retrieval
RelativeBase: baseForRoot(root, cache),
SkipSchemas: false,
ContinueOnError: false,
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
AbsoluteCircularRef: true,
}
return ExpandSchemaWithBasePath(schema, cache, opts)
}
@ -572,7 +652,7 @@ func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *Expan
basePath, _ = absPath(opts.RelativeBase)
}
resolver, err := defaultSchemaLoader(nil, opts, cache)
resolver, err := defaultSchemaLoader(nil, opts, cache, nil)
if err != nil {
return err
}
@ -624,8 +704,32 @@ func basePathFromSchemaID(oldBasePath, id string) string {
return u.String()
}
func isCircular(ref *Ref, basePath string, parentRefs ...string) bool {
return basePath != "" && swag.ContainsStringsCI(parentRefs, ref.String())
// isCircular detects cycles in sequences of $ref.
// It relies on a private context (which needs not be locked).
func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...string) (foundCycle bool) {
normalizedRef := normalizePaths(ref.String(), basePath)
if _, ok := r.context.circulars[normalizedRef]; ok {
// circular $ref has been already detected in another explored cycle
foundCycle = true
return
}
foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef)
if foundCycle {
r.context.circulars[normalizedRef] = true
}
return
}
func updateBasePath(transitive *schemaLoader, resolver *schemaLoader, basePath string) string {
if transitive != resolver {
debugLog("got a new resolver")
if transitive.options != nil && transitive.options.RelativeBase != "" {
basePath, _ = absPath(transitive.options.RelativeBase)
debugLog("new basePath = %s", basePath)
}
}
return basePath
}
func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
@ -641,6 +745,7 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
otherwise the basePath should inherit the parent's */
// important: ID can be relative path
if target.ID != "" {
debugLog("schema has ID: %s", target.ID)
// handling the case when id is a folder
// remember that basePath has to be a file
refPath := target.ID
@ -652,7 +757,6 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
}
/* Explain here what this function does */
var t *Schema
/* if Ref is found, everything else doesn't matter */
/* Ref also changes the resolution scope of children expandSchema */
@ -661,14 +765,21 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
normalizedRef := normalizeFileRef(&target.Ref, basePath)
normalizedBasePath := normalizedRef.RemoteURI()
/* this means there is a circle in the recursion tree */
/* return the Ref */
if isCircular(normalizedRef, basePath, parentRefs...) {
target.Ref = *normalizedRef
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
// this means there is a cycle in the recursion tree: return the Ref
// - circular refs cannot be expanded. We leave them as ref.
// - denormalization means that a new local file ref is set relative to the original basePath
debugLog("shortcut circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
basePath, normalizedBasePath, normalizedRef.String())
if !resolver.options.AbsoluteCircularRef {
target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath)
} else {
target.Ref = *normalizedRef
}
return &target, nil
}
debugLog("\nbasePath: %s", basePath)
debugLog("basePath: %s", basePath)
if Debug {
b, _ := json.Marshal(target)
debugLog("calling Resolve with target: %s", string(b))
@ -680,12 +791,14 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
if t != nil {
parentRefs = append(parentRefs, normalizedRef.String())
var err error
resolver, err = transitiveResolver(basePath, target.Ref, resolver)
transitiveResolver, err := transitiveResolver(basePath, target.Ref, resolver)
if shouldStopOnError(err, resolver.options) {
return nil, err
}
return expandSchema(*t, parentRefs, resolver, normalizedBasePath)
basePath = updateBasePath(transitiveResolver, resolver, normalizedBasePath)
return expandSchema(*t, parentRefs, transitiveResolver, basePath)
}
}
@ -794,7 +907,7 @@ func derefPathItem(pathItem *PathItem, parentRefs []string, resolver *schemaLoad
normalizedRef := normalizeFileRef(&pathItem.Ref, basePath)
normalizedBasePath := normalizedRef.RemoteURI()
if isCircular(normalizedRef, basePath, parentRefs...) {
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
return nil
}
@ -829,7 +942,8 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
}
pathItem.Ref = Ref{}
parentRefs = parentRefs[0:]
// Currently unused:
//parentRefs = parentRefs[0:]
for idx := range pathItem.Parameters {
if err := expandParameter(&(pathItem.Parameters[idx]), resolver, basePath); shouldStopOnError(err, resolver.options) {
@ -900,7 +1014,13 @@ func transitiveResolver(basePath string, ref Ref, resolver *schemaLoader) (*sche
rootURL.Fragment = ""
root, _ := resolver.cache.Get(rootURL.String())
var err error
resolver, err = defaultSchemaLoader(root, resolver.options, resolver.cache)
// shallow copy of resolver options to set a new RelativeBase when
// traversing multiple documents
newOptions := resolver.options
newOptions.RelativeBase = rootURL.String()
debugLog("setting new root: %s", newOptions.RelativeBase)
resolver, err = defaultSchemaLoader(root, newOptions, resolver.cache, resolver.context)
if err != nil {
return nil, err
}
@ -909,19 +1029,40 @@ func transitiveResolver(basePath string, ref Ref, resolver *schemaLoader) (*sche
return resolver, nil
}
// ExpandResponse expands a response based on a basepath
// This is the exported version of expandResponse
// all refs inside response will be resolved relative to basePath
func ExpandResponse(response *Response, basePath string) error {
// ExpandResponseWithRoot expands a response based on a root document, not a fetchable document
func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error {
opts := &ExpandOptions{
RelativeBase: basePath,
RelativeBase: baseForRoot(root, cache),
SkipSchemas: false,
ContinueOnError: false,
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
AbsoluteCircularRef: true,
}
resolver, err := defaultSchemaLoader(nil, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return err
}
return expandResponse(response, resolver, basePath)
return expandResponse(response, resolver, opts.RelativeBase)
}
// ExpandResponse expands a response based on a basepath
// This is the exported version of expandResponse
// all refs inside response will be resolved relative to basePath
func ExpandResponse(response *Response, basePath string) error {
var specBasePath string
if basePath != "" {
specBasePath, _ = absPath(basePath)
}
opts := &ExpandOptions{
RelativeBase: specBasePath,
}
resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
if err != nil {
return err
}
return expandResponse(response, resolver, opts.RelativeBase)
}
func derefResponse(response *Response, parentRefs []string, resolver *schemaLoader, basePath string) error {
@ -931,7 +1072,7 @@ func derefResponse(response *Response, parentRefs []string, resolver *schemaLoad
normalizedRef := normalizeFileRef(&response.Ref, basePath)
normalizedBasePath := normalizedRef.RemoteURI()
if isCircular(normalizedRef, basePath, parentRefs...) {
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
return nil
}
@ -952,23 +1093,31 @@ func expandResponse(response *Response, resolver *schemaLoader, basePath string)
if response == nil {
return nil
}
parentRefs := []string{}
if err := derefResponse(response, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) {
return err
}
if response.Ref.String() != "" {
var err error
resolver, err = transitiveResolver(basePath, response.Ref, resolver)
if shouldStopOnError(err, resolver.options) {
transitiveResolver, err := transitiveResolver(basePath, response.Ref, resolver)
if shouldStopOnError(err, transitiveResolver.options) {
return err
}
basePath = updateBasePath(transitiveResolver, resolver, basePath)
resolver = transitiveResolver
}
if response.Schema != nil && response.Schema.Ref.String() != "" {
// schema expanded to a $ref in another root
var ern error
response.Schema.Ref, ern = NewRef(normalizePaths(response.Schema.Ref.String(), response.Ref.RemoteURI()))
if ern != nil {
return ern
}
}
response.Ref = Ref{}
parentRefs = parentRefs[0:]
if !resolver.options.SkipSchemas && response.Schema != nil {
parentRefs = append(parentRefs, response.Schema.Ref.String())
// parentRefs = append(parentRefs, response.Schema.Ref.String())
s, err := expandSchema(*response.Schema, parentRefs, resolver, basePath)
if shouldStopOnError(err, resolver.options) {
return err
@ -979,19 +1128,40 @@ func expandResponse(response *Response, resolver *schemaLoader, basePath string)
return nil
}
// ExpandParameter expands a parameter based on a basepath
// This is the exported version of expandParameter
// all refs inside parameter will be resolved relative to basePath
func ExpandParameter(parameter *Parameter, basePath string) error {
// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document
func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error {
opts := &ExpandOptions{
RelativeBase: basePath,
RelativeBase: baseForRoot(root, cache),
SkipSchemas: false,
ContinueOnError: false,
// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
AbsoluteCircularRef: true,
}
resolver, err := defaultSchemaLoader(nil, opts, nil)
resolver, err := defaultSchemaLoader(root, opts, nil, nil)
if err != nil {
return err
}
return expandParameter(parameter, resolver, basePath)
return expandParameter(parameter, resolver, opts.RelativeBase)
}
// ExpandParameter expands a parameter based on a basepath
// This is the exported version of expandParameter
// all refs inside parameter will be resolved relative to basePath
func ExpandParameter(parameter *Parameter, basePath string) error {
var specBasePath string
if basePath != "" {
specBasePath, _ = absPath(basePath)
}
opts := &ExpandOptions{
RelativeBase: specBasePath,
}
resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
if err != nil {
return err
}
return expandParameter(parameter, resolver, opts.RelativeBase)
}
func derefParameter(parameter *Parameter, parentRefs []string, resolver *schemaLoader, basePath string) error {
@ -1000,7 +1170,7 @@ func derefParameter(parameter *Parameter, parentRefs []string, resolver *schemaL
normalizedRef := normalizeFileRef(&parameter.Ref, basePath)
normalizedBasePath := normalizedRef.RemoteURI()
if isCircular(normalizedRef, basePath, parentRefs...) {
if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
return nil
}
@ -1027,17 +1197,26 @@ func expandParameter(parameter *Parameter, resolver *schemaLoader, basePath stri
return err
}
if parameter.Ref.String() != "" {
var err error
resolver, err = transitiveResolver(basePath, parameter.Ref, resolver)
if shouldStopOnError(err, resolver.options) {
transitiveResolver, err := transitiveResolver(basePath, parameter.Ref, resolver)
if shouldStopOnError(err, transitiveResolver.options) {
return err
}
basePath = updateBasePath(transitiveResolver, resolver, basePath)
resolver = transitiveResolver
}
if parameter.Schema != nil && parameter.Schema.Ref.String() != "" {
// schema expanded to a $ref in another root
var ern error
parameter.Schema.Ref, ern = NewRef(normalizePaths(parameter.Schema.Ref.String(), parameter.Ref.RemoteURI()))
if ern != nil {
return ern
}
}
parameter.Ref = Ref{}
parentRefs = parentRefs[0:]
if !resolver.options.SkipSchemas && parameter.Schema != nil {
parentRefs = append(parentRefs, parameter.Schema.Ref.String())
s, err := expandSchema(*parameter.Schema, parentRefs, resolver, basePath)
if shouldStopOnError(err, resolver.options) {
return err

View file

@ -22,6 +22,7 @@ import (
"github.com/go-openapi/swag"
)
// HeaderProps describes a response header
type HeaderProps struct {
Description string `json:"description,omitempty"`
}
@ -153,7 +154,7 @@ func (h Header) MarshalJSON() ([]byte, error) {
return swag.ConcatJSON(b1, b2, b3), nil
}
// UnmarshalJSON marshal this from JSON
// UnmarshalJSON unmarshals this header from JSON
func (h *Header) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &h.CommonValidations); err != nil {
return err
@ -164,32 +165,29 @@ func (h *Header) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &h.VendorExtensible); err != nil {
return err
}
if err := json.Unmarshal(data, &h.HeaderProps); err != nil {
return err
}
return nil
return json.Unmarshal(data, &h.HeaderProps)
}
// JSONLookup look up a value by the json property name
func (p Header) JSONLookup(token string) (interface{}, error) {
if ex, ok := p.Extensions[token]; ok {
func (h Header) JSONLookup(token string) (interface{}, error) {
if ex, ok := h.Extensions[token]; ok {
return &ex, nil
}
r, _, err := jsonpointer.GetForToken(p.CommonValidations, token)
r, _, err := jsonpointer.GetForToken(h.CommonValidations, token)
if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
return nil, err
}
if r != nil {
return r, nil
}
r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token)
r, _, err = jsonpointer.GetForToken(h.SimpleSchema, token)
if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
return nil, err
}
if r != nil {
return r, nil
}
r, _, err = jsonpointer.GetForToken(p.HeaderProps, token)
r, _, err = jsonpointer.GetForToken(h.HeaderProps, token)
return r, err
}

View file

@ -52,14 +52,14 @@ func (e Extensions) GetBool(key string) (bool, bool) {
// GetStringSlice gets a string value from the extensions
func (e Extensions) GetStringSlice(key string) ([]string, bool) {
if v, ok := e[strings.ToLower(key)]; ok {
arr, ok := v.([]interface{})
if !ok {
arr, isSlice := v.([]interface{})
if !isSlice {
return nil, false
}
var strs []string
for _, iface := range arr {
str, ok := iface.(string)
if !ok {
str, isString := iface.(string)
if !isString {
return nil, false
}
strs = append(strs, str)

View file

@ -22,6 +22,7 @@ import (
"github.com/go-openapi/swag"
)
// SimpleSchema describe swagger simple schemas for parameters and headers
type SimpleSchema struct {
Type string `json:"type,omitempty"`
Format string `json:"format,omitempty"`
@ -31,6 +32,7 @@ type SimpleSchema struct {
Example interface{} `json:"example,omitempty"`
}
// TypeName return the type (or format) of a simple schema
func (s *SimpleSchema) TypeName() string {
if s.Format != "" {
return s.Format
@ -38,6 +40,7 @@ func (s *SimpleSchema) TypeName() string {
return s.Type
}
// ItemsTypeName yields the type of items in a simple schema array
func (s *SimpleSchema) ItemsTypeName() string {
if s.Items == nil {
return ""
@ -45,6 +48,7 @@ func (s *SimpleSchema) ItemsTypeName() string {
return s.Items.TypeName()
}
// CommonValidations describe common JSON-schema validations
type CommonValidations struct {
Maximum *float64 `json:"maximum,omitempty"`
ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
@ -212,18 +216,18 @@ func (i Items) MarshalJSON() ([]byte, error) {
}
// JSONLookup look up a value by the json property name
func (p Items) JSONLookup(token string) (interface{}, error) {
func (i Items) JSONLookup(token string) (interface{}, error) {
if token == "$ref" {
return &p.Ref, nil
return &i.Ref, nil
}
r, _, err := jsonpointer.GetForToken(p.CommonValidations, token)
r, _, err := jsonpointer.GetForToken(i.CommonValidations, token)
if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
return nil, err
}
if r != nil {
return r, nil
}
r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token)
r, _, err = jsonpointer.GetForToken(i.SimpleSchema, token)
return r, err
}

View file

@ -21,6 +21,7 @@ import (
"github.com/go-openapi/swag"
)
// OperationProps describes an operation
type OperationProps struct {
Description string `json:"description,omitempty"`
Consumes []string `json:"consumes,omitempty"`
@ -38,9 +39,9 @@ type OperationProps struct {
// MarshalJSON takes care of serializing operation properties to JSON
//
// We use a custom marhaller here to handle a special cases related
// We use a custom marhaller here to handle a special cases related to
// the Security field. We need to preserve zero length slice
// while omiting the field when the value is nil/unset.
// while omitting the field when the value is nil/unset.
func (op OperationProps) MarshalJSON() ([]byte, error) {
type Alias OperationProps
if op.Security == nil {

View file

@ -64,6 +64,7 @@ func ParamRef(uri string) *Parameter {
return p
}
// ParamProps describes the specific attributes of an operation parameter
type ParamProps struct {
Description string `json:"description,omitempty"`
Name string `json:"name,omitempty"`

View file

@ -21,7 +21,7 @@ import (
"github.com/go-openapi/swag"
)
// pathItemProps the path item specific properties
// PathItemProps the path item specific properties
type PathItemProps struct {
Get *Operation `json:"get,omitempty"`
Put *Operation `json:"put,omitempty"`

View file

@ -39,15 +39,15 @@ type Response struct {
}
// JSONLookup look up a value by the json property name
func (p Response) JSONLookup(token string) (interface{}, error) {
if ex, ok := p.Extensions[token]; ok {
func (r Response) JSONLookup(token string) (interface{}, error) {
if ex, ok := r.Extensions[token]; ok {
return &ex, nil
}
if token == "$ref" {
return &p.Ref, nil
return &r.Ref, nil
}
r, _, err := jsonpointer.GetForToken(p.ResponseProps, token)
return r, err
ptr, _, err := jsonpointer.GetForToken(r.ResponseProps, token)
return ptr, err
}
// UnmarshalJSON hydrates this items instance with the data from JSON

View file

@ -85,11 +85,15 @@ func (r Responses) MarshalJSON() ([]byte, error) {
return concated, nil
}
// ResponsesProps describes all responses for an operation.
// It tells what is the default response and maps all responses with a
// HTTP status code.
type ResponsesProps struct {
Default *Response
StatusCodeResponses map[int]Response
}
// MarshalJSON marshals responses as JSON
func (r ResponsesProps) MarshalJSON() ([]byte, error) {
toser := map[string]Response{}
if r.Default != nil {
@ -101,6 +105,7 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) {
return json.Marshal(toser)
}
// UnmarshalJSON unmarshals responses from JSON
func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
var res map[string]Response
if err := json.Unmarshal(data, &res); err != nil {

View file

@ -203,6 +203,7 @@ func (r *SchemaURL) fromMap(v map[string]interface{}) error {
// return nil
// }
// SchemaProps describes a JSON schema (draft 4)
type SchemaProps struct {
ID string `json:"id,omitempty"`
Ref Ref `json:"-"`
@ -240,6 +241,7 @@ type SchemaProps struct {
Definitions Definitions `json:"definitions,omitempty"`
}
// SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
type SwaggerSchemaProps struct {
Discriminator string `json:"discriminator,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
@ -604,8 +606,8 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
return err
}
sch.Ref.fromMap(d)
sch.Schema.fromMap(d)
_ = sch.Ref.fromMap(d)
_ = sch.Schema.fromMap(d)
delete(d, "$ref")
delete(d, "$schema")

View file

@ -78,6 +78,7 @@ func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme {
}}
}
// SecuritySchemeProps describes a swagger security scheme in the securityDefinitions section
type SecuritySchemeProps struct {
Description string `json:"description,omitempty"`
Type string `json:"type"`

View file

@ -67,6 +67,7 @@ func (s *Swagger) UnmarshalJSON(data []byte) error {
return nil
}
// SwaggerProps captures the top-level properties of an Api specification
type SwaggerProps struct {
ID string `json:"id,omitempty"`
Consumes []string `json:"consumes,omitempty"`

View file

@ -21,6 +21,7 @@ import (
"github.com/go-openapi/swag"
)
// TagProps describe a tag entry in the top level tags section of a swagger spec
type TagProps struct {
Description string `json:"description,omitempty"`
Name string `json:"name,omitempty"`

19
vendor/github.com/go-openapi/swag/.golangci.yml generated vendored Normal file
View file

@ -0,0 +1,19 @@
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0
gocyclo:
min-complexity: 25
maligned:
suggest-new: true
dupl:
threshold: 100
goconst:
min-len: 2
min-occurrences: 2
linters:
enable-all: true
disable:
- maligned

View file

@ -1,6 +1,8 @@
language: go
go:
- 1.8
- 1.9.x
- 1.10.x
install:
- go get -u github.com/stretchr/testify
- go get -u github.com/mailru/easyjson

View file

@ -1,6 +1,9 @@
# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
[![GolangCI](https://golangci.com/badges/github.com/go-openapi/swag.svg)](https://golangci.com)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag)
Contains a bunch of helper functions:
@ -9,4 +12,4 @@ Contains a bunch of helper functions:
* fast json concatenation
* search in path
* load from file or http
* name manglin
* name mangling

View file

@ -22,8 +22,9 @@ import (
// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
const (
maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
epsilon float64 = 1e-9
)
// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive
@ -31,21 +32,35 @@ func IsFloat64AJSONInteger(f float64) bool {
if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat {
return false
}
fa := math.Abs(f)
g := float64(uint64(f))
ga := math.Abs(g)
return f == float64(int64(f)) || f == float64(uint64(f))
diff := math.Abs(f - g)
// more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases
if f == g { // best case
return true
} else if f == float64(int64(f)) || f == float64(uint64(f)) { // optimistic case
return true
} else if f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64 { // very close to 0 values
return diff < (epsilon * math.SmallestNonzeroFloat64)
}
// check the relative error
return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon
}
var evaluatesAsTrue = map[string]struct{}{
"true": struct{}{},
"1": struct{}{},
"yes": struct{}{},
"ok": struct{}{},
"y": struct{}{},
"on": struct{}{},
"selected": struct{}{},
"checked": struct{}{},
"t": struct{}{},
"enabled": struct{}{},
"true": {},
"1": {},
"yes": {},
"ok": {},
"y": {},
"on": {},
"selected": {},
"checked": {},
"t": {},
"enabled": {},
}
// ConvertBool turn a string into a boolean

View file

@ -21,6 +21,7 @@ import (
"reflect"
"strings"
"sync"
"sync/atomic"
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
@ -34,9 +35,14 @@ var DefaultJSONNameProvider = NewNameProvider()
const comma = byte(',')
var closers = map[byte]byte{
'{': '}',
'[': ']',
var atomicClosers atomic.Value
func init() {
atomicClosers.Store(
map[byte]byte{
'{': '}',
'[': ']',
})
}
type ejMarshaler interface {
@ -82,10 +88,7 @@ func DynamicJSONToStruct(data interface{}, target interface{}) error {
if err != nil {
return err
}
if err := ReadJSON(b, target); err != nil {
return err
}
return nil
return ReadJSON(b, target)
}
// ConcatJSON concatenates multiple json objects efficiently
@ -110,6 +113,7 @@ func ConcatJSON(blobs ...[]byte) []byte {
var opening, closing byte
var idx, a int
buf := bytes.NewBuffer(nil)
closers := atomicClosers.Load().(map[byte]byte)
for i, b := range blobs[:last+1] {
if b == nil || bytes.Equal(b, nullJSON) {

53
vendor/github.com/go-openapi/swag/post_go19.go generated vendored Normal file
View file

@ -0,0 +1,53 @@
// +build go1.9
package swag
import (
"sort"
"sync"
)
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
// Since go1.9, this may be implemented with sync.Map.
type indexOfInitialisms struct {
sortMutex *sync.Mutex
index *sync.Map
}
func newIndexOfInitialisms() *indexOfInitialisms {
return &indexOfInitialisms{
sortMutex: new(sync.Mutex),
index: new(sync.Map),
}
}
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
m.sortMutex.Lock()
defer m.sortMutex.Unlock()
for k, v := range initial {
m.index.Store(k, v)
}
return m
}
func (m *indexOfInitialisms) isInitialism(key string) bool {
_, ok := m.index.Load(key)
return ok
}
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
m.index.Store(key, true)
return m
}
func (m *indexOfInitialisms) sorted() (result []string) {
m.sortMutex.Lock()
defer m.sortMutex.Unlock()
m.index.Range(func(key, value interface{}) bool {
k := key.(string)
result = append(result, k)
return true
})
sort.Sort(sort.Reverse(byLength(result)))
return
}

55
vendor/github.com/go-openapi/swag/pre_go19.go generated vendored Normal file
View file

@ -0,0 +1,55 @@
// +build !go1.9
package swag
import (
"sort"
"sync"
)
// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
// Before go1.9, this may be implemented with a mutex on the map.
type indexOfInitialisms struct {
getMutex *sync.Mutex
index map[string]bool
}
func newIndexOfInitialisms() *indexOfInitialisms {
return &indexOfInitialisms{
getMutex: new(sync.Mutex),
index: make(map[string]bool, 50),
}
}
func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
m.getMutex.Lock()
defer m.getMutex.Unlock()
for k, v := range initial {
m.index[k] = v
}
return m
}
func (m *indexOfInitialisms) isInitialism(key string) bool {
m.getMutex.Lock()
defer m.getMutex.Unlock()
_, ok := m.index[key]
return ok
}
func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
m.getMutex.Lock()
defer m.getMutex.Unlock()
m.index[key] = true
return m
}
func (m *indexOfInitialisms) sorted() (result []string) {
m.getMutex.Lock()
defer m.getMutex.Unlock()
for k := range m.index {
result = append(result, k)
}
sort.Sort(sort.Reverse(byLength(result)))
return
}

View file

@ -18,63 +18,74 @@ import (
"math"
"reflect"
"regexp"
"sort"
"strings"
"sync"
"unicode"
)
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTPS": true,
"HTTP": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"OAI": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
// commonInitialisms are common acronyms that are kept as whole uppercased words.
var commonInitialisms *indexOfInitialisms
// initialisms is a slice of sorted initialisms
var initialisms []string
var once sync.Once
func sortInitialisms() {
for k := range commonInitialisms {
initialisms = append(initialisms, k)
var isInitialism func(string) bool
func init() {
// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
var configuredInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTPS": true,
"HTTP": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"OAI": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
sort.Sort(sort.Reverse(byLength(initialisms)))
// a thread-safe index of initialisms
commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
// a test function
isInitialism = commonInitialisms.isInitialism
}
func ensureSorted() {
initialisms = commonInitialisms.sorted()
}
// JoinByFormat joins a string array by a known format:
@ -169,7 +180,7 @@ func split(str string) (words []string) {
str = rex1.ReplaceAllString(str, " $1")
// check if consecutive single char things make up an initialism
once.Do(sortInitialisms)
once.Do(ensureSorted)
for _, k := range initialisms {
str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1)
}
@ -230,7 +241,7 @@ func ToCommandName(name string) string {
func ToHumanNameLower(name string) string {
var out []string
for _, w := range split(name) {
if !commonInitialisms[upper(w)] {
if !isInitialism(upper(w)) {
out = append(out, lower(w))
} else {
out = append(out, w)
@ -244,7 +255,7 @@ func ToHumanNameTitle(name string) string {
var out []string
for _, w := range split(name) {
uw := upper(w)
if !commonInitialisms[uw] {
if !isInitialism(uw) {
out = append(out, upper(w[:1])+lower(w[1:]))
} else {
out = append(out, w)
@ -269,7 +280,7 @@ func ToJSONName(name string) string {
// ToVarName camelcases a name which can be underscored or pascal cased
func ToVarName(name string) string {
res := ToGoName(name)
if _, ok := commonInitialisms[res]; ok {
if isInitialism(res) {
return lower(res)
}
if len(res) <= 1 {
@ -284,7 +295,7 @@ func ToGoName(name string) string {
for _, w := range split(name) {
uw := upper(w)
mod := int(math.Min(float64(len(uw)), 2))
if !commonInitialisms[uw] && !commonInitialisms[uw[:len(uw)-mod]] {
if !isInitialism(uw) && !isInitialism(uw[:len(uw)-mod]) {
uw = upper(w[:1]) + lower(w[1:])
}
out = append(out, uw)
@ -350,8 +361,11 @@ func IsZero(data interface{}) bool {
// AddInitialisms add additional initialisms
func AddInitialisms(words ...string) {
for _, word := range words {
commonInitialisms[upper(word)] = true
//commonInitialisms[upper(word)] = true
commonInitialisms.add(upper(word))
}
// sort again
initialisms = commonInitialisms.sorted()
}
// CommandLineOptionsGroup represents a group of user-defined command line options

View file

@ -56,14 +56,17 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) {
return document, nil
}
// JSONMapSlice represent a JSON object, with the order of keys maintained
type JSONMapSlice []JSONMapItem
// MarshalJSON renders a JSONMapSlice as JSON
func (s JSONMapSlice) MarshalJSON() ([]byte, error) {
w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
s.MarshalEasyJSON(w)
return w.BuildBytes()
}
// MarshalEasyJSON renders a JSONMapSlice as JSON, using easyJSON
func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) {
w.RawByte('{')
@ -79,11 +82,14 @@ func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) {
w.RawByte('}')
}
// UnmarshalJSON makes a JSONMapSlice from JSON
func (s *JSONMapSlice) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{Data: data}
s.UnmarshalEasyJSON(&l)
return l.Error()
}
// UnmarshalEasyJSON makes a JSONMapSlice from JSON, using easyJSON
func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
if in.IsNull() {
in.Skip()
@ -100,23 +106,34 @@ func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
*s = result
}
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
type JSONMapItem struct {
Key string
Value interface{}
}
// MarshalJSON renders a JSONMapItem as JSON
func (s JSONMapItem) MarshalJSON() ([]byte, error) {
w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
s.MarshalEasyJSON(w)
return w.BuildBytes()
}
// MarshalEasyJSON renders a JSONMapItem as JSON, using easyJSON
func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) {
w.String(s.Key)
w.RawByte(':')
w.Raw(WriteJSON(s.Value))
}
// UnmarshalJSON makes a JSONMapItem from JSON
func (s *JSONMapItem) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{Data: data}
s.UnmarshalEasyJSON(&l)
return l.Error()
}
// UnmarshalEasyJSON makes a JSONMapItem from JSON, using easyJSON
func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
key := in.UnsafeString()
in.WantColon()
@ -125,11 +142,6 @@ func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
s.Key = key
s.Value = value
}
func (s *JSONMapItem) UnmarshalJSON(data []byte) error {
l := jlexer.Lexer{Data: data}
s.UnmarshalEasyJSON(&l)
return l.Error()
}
func transformData(input interface{}) (out interface{}, err error) {
switch in := input.(type) {
@ -147,9 +159,9 @@ func transformData(input interface{}) (out interface{}, err error) {
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key)
}
v, err := transformData(mi.Value)
if err != nil {
return nil, err
v, ert := transformData(mi.Value)
if ert != nil {
return nil, ert
}
nmi.Value = v
o[i] = nmi
@ -168,9 +180,9 @@ func transformData(input interface{}) (out interface{}, err error) {
return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke)
}
v, err := transformData(va)
if err != nil {
return nil, err
v, ert := transformData(va)
if ert != nil {
return nil, ert
}
nmi.Value = v
o = append(o, nmi)
@ -202,7 +214,7 @@ func YAMLDoc(path string) (json.RawMessage, error) {
return nil, err
}
return json.RawMessage(data), nil
return data, nil
}
// YAMLData loads a yaml document from either http or a file