Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

20
vendor/github.com/googleapis/gnostic/linters/README.md generated vendored Normal file
View File

@@ -0,0 +1,20 @@
# Linters
This directory contains linters that can be used to check Gnostic models.
Linters are plugins that generate no files but instead return messages
in their responses. Each message can include a level, an identifier, text,
and a key path in an API description associated with that message.
Messages are collected by gnostic and written to a common output file,
allowing multiple linter plugins to be invoked in a single gnostic
run.
The following invocation runs the `gnostic-lint-paths` and
`gnostic-lint-descriptions` plugins and writes their messages
to a file named `lint.pb`.
```
% gnostic examples/v2.0/yaml/petstore.yaml --lint-paths --lint-descriptions --messages-out=lint.pb
```
Message files can be displayed using the `report-messages` tool in the `apps` directory.

View File

@@ -0,0 +1,9 @@
# gnostic-lint-descriptions
This directory contains a `gnostic` plugin that analyzes an OpenAPI
description for factors that might influence code generation and other
API automation.
The plugin can be invoked like this:
gnostic bookstore.json --lint-descriptions

View File

@@ -0,0 +1,180 @@
//
// 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 main
import (
openapi "github.com/googleapis/gnostic/OpenAPIv2"
plugins "github.com/googleapis/gnostic/plugins"
)
// DocumentLinter contains information collected about an API description.
type DocumentLinterV2 struct {
document *openapi.Document `json:"-"`
}
func (d *DocumentLinterV2) Run() []*plugins.Message {
return d.analyzeDocument(d.document)
}
// NewDocumentLinter builds a new DocumentLinter object.
func NewDocumentLinterV2(document *openapi.Document) *DocumentLinterV2 {
return &DocumentLinterV2{document: document}
}
// Analyze an OpenAPI description.
func (s *DocumentLinterV2) analyzeDocument(document *openapi.Document) []*plugins.Message {
messages := make([]*plugins.Message, 0, 0)
for _, pair := range document.Paths.Path {
path := pair.Value
if path.Get != nil {
messages = append(messages, s.analyzeOperation([]string{"paths", pair.Name, "get"}, path.Get)...)
}
if path.Post != nil {
messages = append(messages, s.analyzeOperation([]string{"paths", pair.Name, "post"}, path.Post)...)
}
if path.Put != nil {
messages = append(messages, s.analyzeOperation([]string{"paths", pair.Name, "put"}, path.Put)...)
}
if path.Delete != nil {
messages = append(messages, s.analyzeOperation([]string{"paths", pair.Name, "delete"}, path.Delete)...)
}
}
if document.Definitions != nil {
for _, pair := range document.Definitions.AdditionalProperties {
definition := pair.Value
messages = append(messages, s.analyzeDefinition([]string{"definitions", pair.Name}, definition)...)
}
}
return messages
}
func (s *DocumentLinterV2) analyzeOperation(keys []string, operation *openapi.Operation) []*plugins.Message {
messages := make([]*plugins.Message, 0)
if operation.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Operation has no description.",
Keys: keys})
}
for _, parameter := range operation.Parameters {
p := parameter.GetParameter()
if p != nil {
b := p.GetBodyParameter()
if b != nil && b.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Parameter has no description.",
Keys: append(keys, []string{"responses", b.Name}...)})
}
n := p.GetNonBodyParameter()
if n != nil {
hp := n.GetHeaderParameterSubSchema()
if hp != nil && hp.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Parameter has no description.",
Keys: append(keys, []string{"responses", hp.Name}...)})
}
fp := n.GetFormDataParameterSubSchema()
if fp != nil && fp.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Parameter has no description.",
Keys: append(keys, []string{"responses", fp.Name}...)})
}
qp := n.GetQueryParameterSubSchema()
if qp != nil && qp.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Parameter has no description.",
Keys: append(keys, []string{"responses", qp.Name}...)})
}
pp := n.GetPathParameterSubSchema()
if pp != nil && pp.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Parameter has no description.",
Keys: append(keys, []string{"responses", pp.Name}...)})
}
}
}
}
for _, pair := range operation.Responses.ResponseCode {
value := pair.Value
response := value.GetResponse()
if response != nil {
responseSchema := response.Schema
responseSchemaSchema := responseSchema.GetSchema()
if responseSchemaSchema != nil && responseSchemaSchema.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Response has no description.",
Keys: append(keys, []string{"responses", pair.Name}...)})
}
responseFileSchema := responseSchema.GetFileSchema()
if responseFileSchema != nil && responseFileSchema.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Response has no description.",
Keys: append(keys, []string{"responses", pair.Name}...)})
}
}
}
return messages
}
// Analyze a definition in an OpenAPI description.
func (s *DocumentLinterV2) analyzeDefinition(keys []string, definition *openapi.Schema) []*plugins.Message {
messages := make([]*plugins.Message, 0)
if definition.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Definition has no description.",
Keys: keys})
}
if definition.Properties != nil {
for _, pair := range definition.Properties.AdditionalProperties {
propertySchema := pair.Value
if propertySchema.Description == "" {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_WARNING,
Code: "NODESCRIPTION",
Text: "Property has no description.",
Keys: append(keys, []string{"properties", pair.Name}...)})
}
}
}
return messages
}

View File

@@ -0,0 +1,33 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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 main
import (
openapi "github.com/googleapis/gnostic/OpenAPIv3"
plugins "github.com/googleapis/gnostic/plugins"
)
// DocumentLinter contains information collected about an API description.
type DocumentLinterV3 struct {
}
func (d *DocumentLinterV3) Run() []*plugins.Message {
return nil
}
// NewDocumentLinter builds a new DocumentLinter object.
func NewDocumentLinterV3(document *openapi.Document) *DocumentLinterV3 {
return &DocumentLinterV3{}
}

View File

@@ -0,0 +1,61 @@
// Copyright 2017 Google Inc. All Rights Reserved.
//
// 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.
// gnostic_lint is a tool for analyzing OpenAPI descriptions.
//
// It scans an API description and checks it against a set of
// coding style guidelines.
//
// Results are returned in a JSON structure.
package main
import (
"github.com/golang/protobuf/proto"
openapiv2 "github.com/googleapis/gnostic/OpenAPIv2"
openapiv3 "github.com/googleapis/gnostic/OpenAPIv3"
plugins "github.com/googleapis/gnostic/plugins"
)
type DocumentLinter interface {
Run() []*plugins.Message
}
// This is the main function for the plugin.
func main() {
env, err := plugins.NewEnvironment()
env.RespondAndExitIfError(err)
var linter DocumentLinter
for _, model := range env.Request.Models {
switch model.TypeUrl {
case "openapi.v2.Document":
documentv2 := &openapiv2.Document{}
err = proto.Unmarshal(model.Value, documentv2)
if err == nil {
linter = NewDocumentLinterV2(documentv2)
env.Response.Messages = linter.Run()
}
case "openapi.v3.Document":
documentv3 := &openapiv3.Document{}
err = proto.Unmarshal(model.Value, documentv3)
if err == nil {
linter = NewDocumentLinterV3(documentv3)
env.Response.Messages = linter.Run()
}
}
}
env.RespondAndExit()
}

View File

@@ -0,0 +1,9 @@
# gnostic-lint-paths
This directory contains a `gnostic` plugin that analyzes an OpenAPI
description for factors that might influence code generation and other
API automation.
The plugin can be invoked like this:
gnostic bookstore.json --lint-paths

View File

@@ -0,0 +1,77 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
// gnostic-lint-paths is a tool for analyzing paths in OpenAPI descriptions.
//
// It scans an API description and checks it against a set of coding style guidelines.
package main
import (
"github.com/golang/protobuf/proto"
openapiv2 "github.com/googleapis/gnostic/OpenAPIv2"
openapiv3 "github.com/googleapis/gnostic/OpenAPIv3"
plugins "github.com/googleapis/gnostic/plugins"
)
func checkPathsV2(document *openapiv2.Document, messages []*plugins.Message) []*plugins.Message {
for _, pair := range document.Paths.Path {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_INFO,
Code: "PATH",
Text: pair.Name,
Keys: []string{"paths", pair.Name}})
}
return messages
}
func checkPathsV3(document *openapiv3.Document, messages []*plugins.Message) []*plugins.Message {
for _, pair := range document.Paths.Path {
messages = append(messages,
&plugins.Message{
Level: plugins.Message_INFO,
Code: "PATH",
Text: pair.Name,
Keys: []string{"paths", pair.Name}})
}
return messages
}
func main() {
env, err := plugins.NewEnvironment()
env.RespondAndExitIfError(err)
messages := make([]*plugins.Message, 0, 0)
for _, model := range env.Request.Models {
switch model.TypeUrl {
case "openapi.v2.Document":
documentv2 := &openapiv2.Document{}
err = proto.Unmarshal(model.Value, documentv2)
if err == nil {
messages = checkPathsV2(documentv2, messages)
}
case "openapi.v3.Document":
documentv3 := &openapiv3.Document{}
err = proto.Unmarshal(model.Value, documentv3)
if err == nil {
messages = checkPathsV3(documentv3, messages)
}
}
}
env.RespondAndExitIfError(err)
env.Response.Messages = messages
env.RespondAndExit()
}

View File

@@ -0,0 +1,20 @@
GNOSTIC = $(GOPATH)/src/github.com/googleapis/gnostic
plugin:
node_modules/.bin/pbjs -t json \
$(GNOSTIC)/OpenAPIv2/OpenAPIv2.proto \
$(GNOSTIC)/OpenAPIv3/OpenAPIv3.proto \
$(GNOSTIC)/discovery/discovery.proto \
$(GNOSTIC)/surface/surface.proto \
$(GNOSTIC)/plugins/plugin.proto \
> bundle.json
node_modules/.bin/nexe gnostic-lint-operations.js
run: plugin
gnostic $(GNOSTIC)/examples/v2.0/yaml/petstore.yaml --lint-operations
setup:
npm install protobufjs
npm install get-stdin
npm install nexe

View File

@@ -0,0 +1,15 @@
This directory contains a gnostic linter written with node.
It is built using [dcodeIO/Protobuf.js](https://github.com/dcodeIO/ProtoBuf.js).
### SETUP
- Install node.
- Run `make setup` to install node dependencies.
### TRY IT
- Run `make run` to test-run the plugin.

View File

@@ -0,0 +1,47 @@
// import libraries
const protobuf = require("protobufjs")
const getStdin = require('get-stdin')
// import messages
const root = protobuf.Root.fromJSON(require("./bundle.json"))
const Request = root.lookupType("gnostic.plugin.v1.Request")
const Response = root.lookupType("gnostic.plugin.v1.Response")
const Document = root.lookupType("openapi.v2.Document")
getStdin.buffer().then(buffer => {
const request = Request.decode(buffer)
messages = []
for (var j in request.models) {
const m = request.models[j]
if (m.type_url == "openapi.v2.Document") {
const openapi2 = Document.decode(m.value)
const paths = openapi2.paths.path
for (var i in paths) {
const path = paths[i]
//console.error('path %s\n\n', path.name)
const getOperation = path.value.get
if (getOperation && getOperation.operationId == "") {
messages.push({level:3, code:"NOOPERATIONID", text:"No operation id.", keys:["paths", path.name, "get"]})
}
const postOperation = path.value.post
if (postOperation && postOperation.operationId == "") {
messages.push({level:3, code:"NOOPERATIONID", text:"No operation id.", keys:["paths", path.name, "post"]})
}
//console.error('get %s\n\n', JSON.stringify(getOperation))
}
}
}
const payload = {
messages: messages
}
// Verify the payload if necessary (i.e. when possibly incomplete or invalid)
const errMsg = Response.verify(payload)
if (errMsg)
throw Error(errMsg)
const message = Response.create(payload)
process.stdout.write(Response.encode(message).finish())
}).catch(err => console.error(err))

View File

@@ -0,0 +1,19 @@
GNOSTIC = $(GOPATH)/src/github.com/googleapis/gnostic
plugin:
node_modules/.bin/pbjs -t json \
$(GNOSTIC)/OpenAPIv2/OpenAPIv2.proto \
$(GNOSTIC)/OpenAPIv3/OpenAPIv3.proto \
$(GNOSTIC)/discovery/discovery.proto \
$(GNOSTIC)/surface/surface.proto \
$(GNOSTIC)/plugins/plugin.proto \
> bundle.json
node_modules/.bin/nexe gnostic-lint-responses.js
mv gnostic-lint-responses $(GOPATH)/bin
run: plugin
gnostic $(GNOSTIC)/examples/v2.0/yaml/petstore.yaml --lint-responses
setup:
npm install

View File

@@ -0,0 +1,15 @@
This directory contains a gnostic linter written with node.
It is built using [dcodeIO/Protobuf.js](https://github.com/dcodeIO/ProtoBuf.js).
### SETUP
- Install node.
- Run `make setup` to install node dependencies.
### TRY IT
- Run `make run` to test-run the plugin.

View File

@@ -0,0 +1,83 @@
// import libraries
const protobuf = require("protobufjs");
const getStdin = require("get-stdin");
const find = require("lodash/find");
const forEach = require("lodash/forEach");
const pick = require("lodash/pick");
// import messages
const root = protobuf.Root.fromJSON(require("./bundle.json"));
const Request = root.lookupType("gnostic.plugin.v1.Request");
const Response = root.lookupType("gnostic.plugin.v1.Response");
const Document = root.lookupType("openapi.v2.Document");
getStdin.buffer().then(buffer => {
const request = Request.decode(buffer);
var messages = [];
for (var j in request.models) {
const m = request.models[j];
if (m.type_url == "openapi.v2.Document") {
const openapi2 = Document.decode(m.value);
const paths = openapi2.paths.path;
for (var i in paths) {
const path = paths[i];
// console.error('path %s\n\n', path.name)
// Arrays MUST NOT be returned as the top-level structure in a response body.
let pathOps = pick(path.value, ["get","head","post", "put", "patch", "delete", "options"]);
forEach(pathOps, (op, opKey) => {
if (op != null) {
forEach(op.responses.responseCode, responseObj => {
// console.error('responseObj is %j', responseObj)
name = responseObj.name;
response = responseObj.value.response;
if (response.schema && response.schema.schema) {
if (!response.schema.schema._ref) {
if (
response.schema.schema.type != null &&
response.schema.schema.type.value == "array"
) {
messages.push({
level: 3,
code: "NO_ARRAY_RESPONSES",
text: "Arrays MUST NOT be returned as the top-level structure in a response body.",
keys: ["paths", path.name, opKey, "responses", name, "schema"]
});
}
} else {
let schemaName = response.schema.schema._ref.match(/#\/definitions\/(\w+)/);
if (schemaName) {
const definitions = openapi2.definitions.additionalProperties;
const schemaKvp = find(definitions, {name: schemaName[1]
});
//console.error('schemaKvp.value.type = %s', schemaKvp.value.type.value)
if (schemaKvp && schemaKvp.value.type && schemaKvp.value.type.value.indexOf("array") >= 0) {
messages.push({
level: 3,
code: "NO_ARRAY_RESPONSES",
text: "Arrays MUST NOT be returned as the top-level structure in a response body.",
keys: ["paths", path.name, opKey, "responses", name, "schema" ]
});
}
}
}
}
});
}
});
}
}
}
const payload = {
messages: messages
};
// Verify the payload if necessary (i.e. when possibly incomplete or invalid)
const errMsg = Response.verify(payload);
if (errMsg) throw Error(errMsg);
const message = Response.create(payload);
process.stdout.write(Response.encode(message).finish());
})
.catch(err => console.error(err));

View File

@@ -0,0 +1,19 @@
{
"name": "gnostic-lint-responses",
"version": "1.0.0",
"description": "Gnostic linter plugin to check responses",
"main": "gnostic-lint-responses.js",
"repository": "git@github.com:googleapis/gnostic.git",
"author": "Mike Kistler",
"license": "Apache-2.0",
"dependencies": {
"get-stdin": "^5.0.1",
"lodash": "^4.17.5",
"nexe": "^2.0.0-rc.24",
"protobufjs": "^6.8.4"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}

View File

@@ -0,0 +1,18 @@
TGT=gnostic-lint-responses-swift
BINDIR=.build/debug
all:
swift build
install: all
cp $(BINDIR)/$(TGT) $(GOPATH)/bin/$(TGT)
clean :
rm -rf Packages
rm -rf .build
rm -f Package.pins Package.resolved
run:
gnostic ../../../examples/v2.0/yaml/petstore.yaml --lint-responses-swift

View File

@@ -0,0 +1,26 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
import PackageDescription
let package = Package(
name: "gnostic-lint-responses-swift",
targets: [
Target(name: "gnostic-lint-responses-swift", dependencies: [ "Gnostic" ]),
Target(name: "Gnostic")
],
dependencies: [
.Package(url: "https://github.com/apple/swift-protobuf.git", Version(1,0,2))
]
)

View File

@@ -0,0 +1,12 @@
This directory contains a gnostic linter written with Swift.
### SETUP
- Install protoc (https://github.com/google/protobuf)
- Install the Swift Protocol Buffer plugin (https://github.com/apple/swift-protobuf)
- Run `sh compile-protos` to generate Protocol Buffer support code.
- Run `make install` to build and install the plugin.
### TRY IT
- Run `make run` to test-run the plugin.

View File

@@ -0,0 +1,77 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
import Foundation
// The I/O code below is derived from Apple's swift-protobuf project.
// https://github.com/apple/swift-protobuf
// BEGIN swift-protobuf derivation
#if os(Linux)
import Glibc
#else
import Darwin.C
#endif
enum PluginError: Error {
/// Raised for any errors reading the input
case readFailure
}
// Alias clib's write() so Stdout.write(bytes:) can call it.
private let _write = write
class Stdin {
static func readall() throws -> Data {
let fd: Int32 = 0
let buffSize = 32
var buff = [UInt8]()
while true {
var fragment = [UInt8](repeating: 0, count: buffSize)
let count = read(fd, &fragment, buffSize)
if count < 0 {
throw PluginError.readFailure
}
if count < buffSize {
buff += fragment[0..<count]
return Data(bytes: buff)
}
buff += fragment
}
}
}
class Stdout {
static func write(bytes: Data) {
bytes.withUnsafeBytes { (p: UnsafePointer<UInt8>) -> () in
_ = _write(1, p, bytes.count)
}
}
static func write(_ string: String) {
self.write(bytes:string.data(using:.utf8)!)
}
}
class Stderr {
static func write(bytes: Data) {
bytes.withUnsafeBytes { (p: UnsafePointer<UInt8>) -> () in
_ = _write(2, p, bytes.count)
}
}
static func write(_ string: String) {
self.write(bytes:string.data(using:.utf8)!)
}
}
// END swift-protobuf derivation

View File

@@ -0,0 +1,116 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// 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.
import Foundation
import Gnostic
extension Gnostic_Plugin_V1_Response {
mutating func message(level:Gnostic_Plugin_V1_Message.Level,
code:String,
text:String,
path:[String]=[]) {
var message = Gnostic_Plugin_V1_Message()
message.level = level
message.code = code
message.text = text
message.keys = path
messages.append(message)
}
}
class ResponseLinter {
var document : Openapi_V2_Document = Openapi_V2_Document()
func run(_ request : Gnostic_Plugin_V1_Request,
_ response : inout Gnostic_Plugin_V1_Response) throws {
for model in request.models {
if model.typeURL == "openapi.v2.Document" {
let document = try Openapi_V2_Document(serializedData: model.value)
self.document = document
for pair in document.paths.path {
let path = ["paths", pair.name]
let v = pair.value
if v.hasGet {
checkOperation(v.get, path:path + ["get"], response:&response)
}
if v.hasPost {
checkOperation(v.post, path:path + ["post"], response:&response)
}
if v.hasPut {
checkOperation(v.put, path:path + ["put"], response:&response)
}
if v.hasDelete {
checkOperation(v.delete, path:path + ["delete"], response:&response)
}
}
}
}
}
func checkOperation(_ operation:Openapi_V2_Operation,
path:[String],
response:inout Gnostic_Plugin_V1_Response) {
for responseCode in operation.responses.responseCode {
let code = responseCode.name
if responseCode.value.response.hasSchema {
var schema = responseCode.value.response.schema.schema
if schema.ref != "" {
if let resolvedSchema = resolveReference(schema.ref) {
schema = resolvedSchema
}
}
checkSchemaType(schema, path: path + ["responses", code, "schema"], response: &response)
}
}
}
func checkSchemaType(_ schema:Openapi_V2_Schema,
path:[String],
response:inout Gnostic_Plugin_V1_Response) {
if schema.hasType {
for type in schema.type.value {
if type == "array" {
response.message(
level: .error,
code: "NO_ARRAY_RESPONSES",
text: "Arrays MUST NOT be returned as the top-level structure in a response body.",
path: path)
}
}
}
}
func resolveReference(_ reference:String) -> Openapi_V2_Schema? {
let prefix = "#/definitions/"
if reference.hasPrefix(prefix) {
let schemaName = reference.dropFirst(prefix.count)
for pair in document.definitions.additionalProperties {
if pair.name == schemaName {
return pair.value
}
}
}
return nil
}
}
func main() throws {
let request = try Gnostic_Plugin_V1_Request(serializedData: Stdin.readall())
var response = Gnostic_Plugin_V1_Response()
try ResponseLinter().run(request, &response)
let serializedResponse = try response.serializedData()
Stdout.write(bytes: serializedResponse)
}
try main()

View File

@@ -0,0 +1,54 @@
#!/bin/sh
#
# Copyright 2018 Google Inc. All Rights Reserved.
#
# 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.
# Use this script to run protoc and swift-proto to generate
# support code for gnostic protos.
GNOSTIC=$GOPATH/src/github.com/googleapis/gnostic
PROTOS=(
plugins/plugin.proto
OpenAPIv2/OpenAPIv2.proto
OpenAPIv3/OpenAPIv3.proto
surface/surface.proto
discovery/discovery.proto
)
mkdir -p Sources/Gnostic
# remove old compiled pb files
rm -rf Sources/Gnostic/*.pb.swift
# remove any prior compilations
rm -rf Sources/Gnostic/github.com
# compile protos
for proto in "${PROTOS[@]}"
do
echo "COMPILING $proto"
protoc $GNOSTIC/$proto \
--swift_opt=Visibility=Public \
--swift_out=Sources/Gnostic \
--proto_path=$GOPATH/src
# relocate compiled protos
find Sources/Gnostic/github.com -name "*.pb.swift" -exec mv {} Sources/Gnostic \;
# remove scaffolding of compilation
rm -rf Sources/Gnostic/github.com
done