Update client-go to v10.0.0 (Kubernetes 1.13) (#2382)

* Update client-go to v10.0.0 (Kubernetes 1.13)

This fix updates client-go to v10.0.0 which matches
Kubernetes 1.13 (released several days ago).

Other changes in Gopkg.yaml:
- Updated apimachinary, api, klog, yaml associated with k8s version
  go dep will not automatically match the version.
- Added [prune] field (otherwise go dep will not prune automatically)

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Updated Gopkg.lock

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

* Updated vendor for client-go v10.0.0

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang
2018-12-16 01:04:41 -08:00
committed by Miek Gieben
parent c8f0e94026
commit 6b8c154441
996 changed files with 29842 additions and 101899 deletions

View File

@@ -1,21 +0,0 @@
# IntelliJ IDEA
.idea
# Eclipse
.checkstyle
.project
.settings
# Swift
.build
Packages
# Node
node_modules
package-lock.json
bundle.json
# vi
*.swp
# vscode
.vscode
.DS_Store
*~
Package.resolved
extensions/sample/generated

View File

@@ -1,29 +0,0 @@
#!/bin/sh
#
# Install dependencies that aren't available as Ubuntu packages.
#
# Everything goes into $HOME/local.
#
# Scripts should add
# - $HOME/local/bin to PATH
# - $HOME/local/lib to LD_LIBRARY_PATH
#
cd
mkdir -p local
# Install swift
SWIFT_URL=https://swift.org/builds/swift-4.0-branch/ubuntu1404/swift-4.0-DEVELOPMENT-SNAPSHOT-2017-09-01-a/swift-4.0-DEVELOPMENT-SNAPSHOT-2017-09-01-a-ubuntu14.04.tar.gz
echo $SWIFT_URL
curl -fSsL $SWIFT_URL -o swift.tar.gz
tar -xzf swift.tar.gz --strip-components=2 --directory=local
# Install protoc
PROTOC_URL=https://github.com/google/protobuf/releases/download/v3.4.0/protoc-3.4.0-linux-x86_64.zip
echo $PROTOC_URL
curl -fSsL $PROTOC_URL -o protoc.zip
unzip protoc.zip -d local
# Verify installation
find local

View File

@@ -1,49 +0,0 @@
# Travis CI build file for OpenAPI Compiler, including Go and Swift plugins
# Use Ubuntu 14.04
dist: trusty
sudo: false
language: go
addons:
apt:
packages:
- clang-3.8
- lldb-3.8
- libicu-dev
- libtool
- libcurl4-openssl-dev
- libbsd-dev
- build-essential
- libssl-dev
- uuid-dev
- curl
- unzip
install:
- ./.travis-install.sh
- export PATH=.:$HOME/local/bin:$PATH
- make
script:
- go test . -v
- pushd plugins/gnostic-go-generator/examples/v2.0/bookstore
- make test
- popd
- pushd plugins/gnostic-go-generator/examples/v2.0/sample
- make test
- popd
- pushd plugins/gnostic-go-generator/examples/v3.0/bookstore
- make test
- popd
- export PATH=.:$HOME/local/bin:$PATH
- export LD_LIBRARY_PATH=$HOME/local/lib
- pushd plugins/gnostic-swift-generator
- make install
- cd examples/bookstore
- make
- .build/debug/Server &
- make test

View File

@@ -1,35 +0,0 @@
#!/bin/sh
#
# Copyright 2016 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.
#
go get github.com/golang/protobuf/protoc-gen-go
protoc \
--go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. \
OpenAPIv2/OpenAPIv2.proto
protoc \
-I.:$GOPATH/src \
--go_out=:. \
plugins/plugin.proto
protoc \
--go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. \
OpenAPIv3/OpenAPIv3.proto
protoc \
--go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. \
discovery/discovery.proto

View File

@@ -1,35 +0,0 @@
# How to become a contributor and submit your own code
## Contributor License Agreements
We'd love to accept your sample apps and patches! Before we can take them, we
have to jump a couple of legal hurdles.
Please fill out either the individual or corporate Contributor License Agreement
(CLA).
* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an [individual CLA]
(https://developers.google.com/open-source/cla/individual).
* If you work for a company that wants to allow you to contribute your work,
then you'll need to sign a [corporate CLA]
(https://developers.google.com/open-source/cla/corporate).
Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.
## Contributing A Patch
1. Submit an issue describing your proposed change to the repo in question.
1. The repo owner will respond to your issue promptly.
1. If your proposed change is accepted, and you haven't already done so, sign a
Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which
you are contributing. Refer to the
[Google Cloud Platform Samples Style Guide]
(https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
recommended coding standards for this organization.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request.

View File

@@ -1,16 +0,0 @@
build:
go get
go install
cd generate-gnostic; go get; go install
cd apps/disco; go get; go install
cd apps/report; go get; go install
cd apps/petstore-builder; go get; go install
cd plugins/gnostic-summary; go get; go install
cd plugins/gnostic-analyze; go get; go install
cd plugins/gnostic-go-generator; go get; go install
rm -f $(GOPATH)/bin/gnostic-go-client $(GOPATH)/bin/gnostic-go-server
ln -s $(GOPATH)/bin/gnostic-go-generator $(GOPATH)/bin/gnostic-go-client
ln -s $(GOPATH)/bin/gnostic-go-generator $(GOPATH)/bin/gnostic-go-server
cd extensions/sample; make

View File

@@ -1,663 +0,0 @@
// 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.
// THIS FILE IS AUTOMATICALLY GENERATED.
syntax = "proto3";
package openapi.v2;
import "google/protobuf/any.proto";
// This option lets the proto compiler generate Java code inside the package
// name (see below) instead of inside an outer class. It creates a simpler
// developer experience by reducing one-level of name nesting and be
// consistent with most programming languages that don't support outer classes.
option java_multiple_files = true;
// The Java outer classname should be the filename in UpperCamelCase. This
// class is only used to hold proto descriptor, so developers don't need to
// work with it directly.
option java_outer_classname = "OpenAPIProto";
// The Java package name must be proto package name with proper prefix.
option java_package = "org.openapi_v2";
// A reasonable prefix for the Objective-C symbols generated from the package.
// It should at a minimum be 3 characters long, all uppercase, and convention
// is to use an abbreviation of the package name. Something short, but
// hopefully unique enough to not conflict with things that may come along in
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
option objc_class_prefix = "OAS";
message AdditionalPropertiesItem {
oneof oneof {
Schema schema = 1;
bool boolean = 2;
}
}
message Any {
google.protobuf.Any value = 1;
string yaml = 2;
}
message ApiKeySecurity {
string type = 1;
string name = 2;
string in = 3;
string description = 4;
repeated NamedAny vendor_extension = 5;
}
message BasicAuthenticationSecurity {
string type = 1;
string description = 2;
repeated NamedAny vendor_extension = 3;
}
message BodyParameter {
// A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed.
string description = 1;
// The name of the parameter.
string name = 2;
// Determines the location of the parameter.
string in = 3;
// Determines whether or not this parameter is required or optional.
bool required = 4;
Schema schema = 5;
repeated NamedAny vendor_extension = 6;
}
// Contact information for the owners of the API.
message Contact {
// The identifying name of the contact person/organization.
string name = 1;
// The URL pointing to the contact information.
string url = 2;
// The email address of the contact person/organization.
string email = 3;
repeated NamedAny vendor_extension = 4;
}
message Default {
repeated NamedAny additional_properties = 1;
}
// One or more JSON objects describing the schemas being consumed and produced by the API.
message Definitions {
repeated NamedSchema additional_properties = 1;
}
message Document {
// The Swagger version of this document.
string swagger = 1;
Info info = 2;
// The host (name or ip) of the API. Example: 'swagger.io'
string host = 3;
// The base path to the API. Example: '/api'.
string base_path = 4;
// The transfer protocol of the API.
repeated string schemes = 5;
// A list of MIME types accepted by the API.
repeated string consumes = 6;
// A list of MIME types the API can produce.
repeated string produces = 7;
Paths paths = 8;
Definitions definitions = 9;
ParameterDefinitions parameters = 10;
ResponseDefinitions responses = 11;
repeated SecurityRequirement security = 12;
SecurityDefinitions security_definitions = 13;
repeated Tag tags = 14;
ExternalDocs external_docs = 15;
repeated NamedAny vendor_extension = 16;
}
message Examples {
repeated NamedAny additional_properties = 1;
}
// information about external documentation
message ExternalDocs {
string description = 1;
string url = 2;
repeated NamedAny vendor_extension = 3;
}
// A deterministic version of a JSON Schema object.
message FileSchema {
string format = 1;
string title = 2;
string description = 3;
Any default = 4;
repeated string required = 5;
string type = 6;
bool read_only = 7;
ExternalDocs external_docs = 8;
Any example = 9;
repeated NamedAny vendor_extension = 10;
}
message FormDataParameterSubSchema {
// Determines whether or not this parameter is required or optional.
bool required = 1;
// Determines the location of the parameter.
string in = 2;
// A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed.
string description = 3;
// The name of the parameter.
string name = 4;
// allows sending a parameter by name only or with an empty value.
bool allow_empty_value = 5;
string type = 6;
string format = 7;
PrimitivesItems items = 8;
string collection_format = 9;
Any default = 10;
double maximum = 11;
bool exclusive_maximum = 12;
double minimum = 13;
bool exclusive_minimum = 14;
int64 max_length = 15;
int64 min_length = 16;
string pattern = 17;
int64 max_items = 18;
int64 min_items = 19;
bool unique_items = 20;
repeated Any enum = 21;
double multiple_of = 22;
repeated NamedAny vendor_extension = 23;
}
message Header {
string type = 1;
string format = 2;
PrimitivesItems items = 3;
string collection_format = 4;
Any default = 5;
double maximum = 6;
bool exclusive_maximum = 7;
double minimum = 8;
bool exclusive_minimum = 9;
int64 max_length = 10;
int64 min_length = 11;
string pattern = 12;
int64 max_items = 13;
int64 min_items = 14;
bool unique_items = 15;
repeated Any enum = 16;
double multiple_of = 17;
string description = 18;
repeated NamedAny vendor_extension = 19;
}
message HeaderParameterSubSchema {
// Determines whether or not this parameter is required or optional.
bool required = 1;
// Determines the location of the parameter.
string in = 2;
// A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed.
string description = 3;
// The name of the parameter.
string name = 4;
string type = 5;
string format = 6;
PrimitivesItems items = 7;
string collection_format = 8;
Any default = 9;
double maximum = 10;
bool exclusive_maximum = 11;
double minimum = 12;
bool exclusive_minimum = 13;
int64 max_length = 14;
int64 min_length = 15;
string pattern = 16;
int64 max_items = 17;
int64 min_items = 18;
bool unique_items = 19;
repeated Any enum = 20;
double multiple_of = 21;
repeated NamedAny vendor_extension = 22;
}
message Headers {
repeated NamedHeader additional_properties = 1;
}
// General information about the API.
message Info {
// A unique and precise title of the API.
string title = 1;
// A semantic version number of the API.
string version = 2;
// A longer description of the API. Should be different from the title. GitHub Flavored Markdown is allowed.
string description = 3;
// The terms of service for the API.
string terms_of_service = 4;
Contact contact = 5;
License license = 6;
repeated NamedAny vendor_extension = 7;
}
message ItemsItem {
repeated Schema schema = 1;
}
message JsonReference {
string _ref = 1;
string description = 2;
}
message License {
// The name of the license type. It's encouraged to use an OSI compatible license.
string name = 1;
// The URL pointing to the license.
string url = 2;
repeated NamedAny vendor_extension = 3;
}
// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.
message NamedAny {
// Map key
string name = 1;
// Mapped value
Any value = 2;
}
// Automatically-generated message used to represent maps of Header as ordered (name,value) pairs.
message NamedHeader {
// Map key
string name = 1;
// Mapped value
Header value = 2;
}
// Automatically-generated message used to represent maps of Parameter as ordered (name,value) pairs.
message NamedParameter {
// Map key
string name = 1;
// Mapped value
Parameter value = 2;
}
// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.
message NamedPathItem {
// Map key
string name = 1;
// Mapped value
PathItem value = 2;
}
// Automatically-generated message used to represent maps of Response as ordered (name,value) pairs.
message NamedResponse {
// Map key
string name = 1;
// Mapped value
Response value = 2;
}
// Automatically-generated message used to represent maps of ResponseValue as ordered (name,value) pairs.
message NamedResponseValue {
// Map key
string name = 1;
// Mapped value
ResponseValue value = 2;
}
// Automatically-generated message used to represent maps of Schema as ordered (name,value) pairs.
message NamedSchema {
// Map key
string name = 1;
// Mapped value
Schema value = 2;
}
// Automatically-generated message used to represent maps of SecurityDefinitionsItem as ordered (name,value) pairs.
message NamedSecurityDefinitionsItem {
// Map key
string name = 1;
// Mapped value
SecurityDefinitionsItem value = 2;
}
// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.
message NamedString {
// Map key
string name = 1;
// Mapped value
string value = 2;
}
// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.
message NamedStringArray {
// Map key
string name = 1;
// Mapped value
StringArray value = 2;
}
message NonBodyParameter {
oneof oneof {
HeaderParameterSubSchema header_parameter_sub_schema = 1;
FormDataParameterSubSchema form_data_parameter_sub_schema = 2;
QueryParameterSubSchema query_parameter_sub_schema = 3;
PathParameterSubSchema path_parameter_sub_schema = 4;
}
}
message Oauth2AccessCodeSecurity {
string type = 1;
string flow = 2;
Oauth2Scopes scopes = 3;
string authorization_url = 4;
string token_url = 5;
string description = 6;
repeated NamedAny vendor_extension = 7;
}
message Oauth2ApplicationSecurity {
string type = 1;
string flow = 2;
Oauth2Scopes scopes = 3;
string token_url = 4;
string description = 5;
repeated NamedAny vendor_extension = 6;
}
message Oauth2ImplicitSecurity {
string type = 1;
string flow = 2;
Oauth2Scopes scopes = 3;
string authorization_url = 4;
string description = 5;
repeated NamedAny vendor_extension = 6;
}
message Oauth2PasswordSecurity {
string type = 1;
string flow = 2;
Oauth2Scopes scopes = 3;
string token_url = 4;
string description = 5;
repeated NamedAny vendor_extension = 6;
}
message Oauth2Scopes {
repeated NamedString additional_properties = 1;
}
message Operation {
repeated string tags = 1;
// A brief summary of the operation.
string summary = 2;
// A longer description of the operation, GitHub Flavored Markdown is allowed.
string description = 3;
ExternalDocs external_docs = 4;
// A unique identifier of the operation.
string operation_id = 5;
// A list of MIME types the API can produce.
repeated string produces = 6;
// A list of MIME types the API can consume.
repeated string consumes = 7;
// The parameters needed to send a valid API call.
repeated ParametersItem parameters = 8;
Responses responses = 9;
// The transfer protocol of the API.
repeated string schemes = 10;
bool deprecated = 11;
repeated SecurityRequirement security = 12;
repeated NamedAny vendor_extension = 13;
}
message Parameter {
oneof oneof {
BodyParameter body_parameter = 1;
NonBodyParameter non_body_parameter = 2;
}
}
// One or more JSON representations for parameters
message ParameterDefinitions {
repeated NamedParameter additional_properties = 1;
}
message ParametersItem {
oneof oneof {
Parameter parameter = 1;
JsonReference json_reference = 2;
}
}
message PathItem {
string _ref = 1;
Operation get = 2;
Operation put = 3;
Operation post = 4;
Operation delete = 5;
Operation options = 6;
Operation head = 7;
Operation patch = 8;
// The parameters needed to send a valid API call.
repeated ParametersItem parameters = 9;
repeated NamedAny vendor_extension = 10;
}
message PathParameterSubSchema {
// Determines whether or not this parameter is required or optional.
bool required = 1;
// Determines the location of the parameter.
string in = 2;
// A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed.
string description = 3;
// The name of the parameter.
string name = 4;
string type = 5;
string format = 6;
PrimitivesItems items = 7;
string collection_format = 8;
Any default = 9;
double maximum = 10;
bool exclusive_maximum = 11;
double minimum = 12;
bool exclusive_minimum = 13;
int64 max_length = 14;
int64 min_length = 15;
string pattern = 16;
int64 max_items = 17;
int64 min_items = 18;
bool unique_items = 19;
repeated Any enum = 20;
double multiple_of = 21;
repeated NamedAny vendor_extension = 22;
}
// Relative paths to the individual endpoints. They must be relative to the 'basePath'.
message Paths {
repeated NamedAny vendor_extension = 1;
repeated NamedPathItem path = 2;
}
message PrimitivesItems {
string type = 1;
string format = 2;
PrimitivesItems items = 3;
string collection_format = 4;
Any default = 5;
double maximum = 6;
bool exclusive_maximum = 7;
double minimum = 8;
bool exclusive_minimum = 9;
int64 max_length = 10;
int64 min_length = 11;
string pattern = 12;
int64 max_items = 13;
int64 min_items = 14;
bool unique_items = 15;
repeated Any enum = 16;
double multiple_of = 17;
repeated NamedAny vendor_extension = 18;
}
message Properties {
repeated NamedSchema additional_properties = 1;
}
message QueryParameterSubSchema {
// Determines whether or not this parameter is required or optional.
bool required = 1;
// Determines the location of the parameter.
string in = 2;
// A brief description of the parameter. This could contain examples of use. GitHub Flavored Markdown is allowed.
string description = 3;
// The name of the parameter.
string name = 4;
// allows sending a parameter by name only or with an empty value.
bool allow_empty_value = 5;
string type = 6;
string format = 7;
PrimitivesItems items = 8;
string collection_format = 9;
Any default = 10;
double maximum = 11;
bool exclusive_maximum = 12;
double minimum = 13;
bool exclusive_minimum = 14;
int64 max_length = 15;
int64 min_length = 16;
string pattern = 17;
int64 max_items = 18;
int64 min_items = 19;
bool unique_items = 20;
repeated Any enum = 21;
double multiple_of = 22;
repeated NamedAny vendor_extension = 23;
}
message Response {
string description = 1;
SchemaItem schema = 2;
Headers headers = 3;
Examples examples = 4;
repeated NamedAny vendor_extension = 5;
}
// One or more JSON representations for parameters
message ResponseDefinitions {
repeated NamedResponse additional_properties = 1;
}
message ResponseValue {
oneof oneof {
Response response = 1;
JsonReference json_reference = 2;
}
}
// Response objects names can either be any valid HTTP status code or 'default'.
message Responses {
repeated NamedResponseValue response_code = 1;
repeated NamedAny vendor_extension = 2;
}
// A deterministic version of a JSON Schema object.
message Schema {
string _ref = 1;
string format = 2;
string title = 3;
string description = 4;
Any default = 5;
double multiple_of = 6;
double maximum = 7;
bool exclusive_maximum = 8;
double minimum = 9;
bool exclusive_minimum = 10;
int64 max_length = 11;
int64 min_length = 12;
string pattern = 13;
int64 max_items = 14;
int64 min_items = 15;
bool unique_items = 16;
int64 max_properties = 17;
int64 min_properties = 18;
repeated string required = 19;
repeated Any enum = 20;
AdditionalPropertiesItem additional_properties = 21;
TypeItem type = 22;
ItemsItem items = 23;
repeated Schema all_of = 24;
Properties properties = 25;
string discriminator = 26;
bool read_only = 27;
Xml xml = 28;
ExternalDocs external_docs = 29;
Any example = 30;
repeated NamedAny vendor_extension = 31;
}
message SchemaItem {
oneof oneof {
Schema schema = 1;
FileSchema file_schema = 2;
}
}
message SecurityDefinitions {
repeated NamedSecurityDefinitionsItem additional_properties = 1;
}
message SecurityDefinitionsItem {
oneof oneof {
BasicAuthenticationSecurity basic_authentication_security = 1;
ApiKeySecurity api_key_security = 2;
Oauth2ImplicitSecurity oauth2_implicit_security = 3;
Oauth2PasswordSecurity oauth2_password_security = 4;
Oauth2ApplicationSecurity oauth2_application_security = 5;
Oauth2AccessCodeSecurity oauth2_access_code_security = 6;
}
}
message SecurityRequirement {
repeated NamedStringArray additional_properties = 1;
}
message StringArray {
repeated string value = 1;
}
message Tag {
string name = 1;
string description = 2;
ExternalDocs external_docs = 3;
repeated NamedAny vendor_extension = 4;
}
message TypeItem {
repeated string value = 1;
}
// Any property starting with x- is valid.
message VendorExtension {
repeated NamedAny additional_properties = 1;
}
message Xml {
string name = 1;
string namespace = 2;
string prefix = 3;
bool attribute = 4;
bool wrapped = 5;
repeated NamedAny vendor_extension = 6;
}

View File

@@ -1,16 +0,0 @@
# OpenAPI v2 Protocol Buffer Models
This directory contains a Protocol Buffer-language model
and related code for supporting OpenAPI v2.
Gnostic applications and plugins can use OpenAPIv2.proto
to generate Protocol Buffer support code for their preferred languages.
OpenAPIv2.go is used by Gnostic to read JSON and YAML OpenAPI
descriptions into the Protocol Buffer-based datastructures
generated from OpenAPIv2.proto.
OpenAPIv2.proto and OpenAPIv2.go are generated by the Gnostic
compiler generator, and OpenAPIv2.pb.go is generated by
protoc, the Protocol Buffer compiler, and protoc-gen-go, the
Protocol Buffer Go code generation plugin.

File diff suppressed because it is too large Load Diff

View File

@@ -1,109 +0,0 @@
[![Build Status](https://travis-ci.org/googleapis/gnostic.svg?branch=master)](https://travis-ci.org/googleapis/gnostic)
# ⨁ gnostic
This repository contains a Go command line tool which converts
JSON and YAML [OpenAPI](https://github.com/OAI/OpenAPI-Specification)
descriptions to and from equivalent Protocol Buffer representations.
[Protocol Buffers](https://developers.google.com/protocol-buffers/)
provide a language-neutral, platform-neutral, extensible mechanism
for serializing structured data.
**gnostic**'s Protocol Buffer models for the OpenAPI Specification
can be used to generate code that includes data structures with
explicit fields for the elements of an OpenAPI description.
This makes it possible for developers to work with OpenAPI
descriptions in type-safe ways, which is particularly useful
in strongly-typed languages like Go and Swift.
**gnostic** reads OpenAPI descriptions into
these generated data structures, reports errors,
resolves internal dependencies, and writes the results
in a binary form that can be used in any language that is
supported by the Protocol Buffer tools.
A plugin interface simplifies integration with API
tools written in a variety of different languages,
and when necessary, Protocol Buffer OpenAPI descriptions
can be reexported as JSON or YAML.
**gnostic** compilation code and OpenAPI Protocol Buffer
models are automatically generated from an
[OpenAPI JSON Schema](https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json).
Source code for the generator is in the [generate-gnostic](generate-gnostic) directory.
## Disclaimer
This is prerelease software and work in progress. Feedback and
contributions are welcome, but we currently make no guarantees of
function or stability.
## Requirements
**gnostic** can be run in any environment that supports [Go](http://golang.org)
and the [Google Protocol Buffer Compiler](https://github.com/google/protobuf).
## Installation
1. Get this package by downloading it with `go get`.
go get github.com/googleapis/gnostic
2. [Optional] Build and run the compiler generator.
This uses the OpenAPI JSON schema to generate a Protocol Buffer language file
that describes the OpenAPI specification and a Go-language file of code that
will read a JSON or YAML OpenAPI representation into the generated protocol
buffers. Pre-generated versions of these files are in the OpenAPIv2 directory.
cd $GOPATH/src/github.com/googleapis/gnostic/generate-gnostic
go install
cd ..
generate-gnostic --v2
3. [Optional] Generate Protocol Buffer support code.
A pre-generated version of this file is checked into the OpenAPIv2 directory.
This step requires a local installation of protoc, the Protocol Buffer Compiler,
and the Go protoc plugin.
You can get protoc [here](https://github.com/google/protobuf).
You can install the plugin with this command:
go get -u github.com/golang/protobuf/protoc-gen-go
Then use the following to recompile the Gnostic Protocol Buffer models:
./COMPILE-PROTOS.sh
4. [Optional] Rebuild **gnostic**. This is only necessary if you've performed steps
2 or 3 above.
go install github.com/googleapis/gnostic
5. Run **gnostic**. This will create a file in the current directory named "petstore.pb" that contains a binary
Protocol Buffer description of a sample API.
gnostic --pb-out=. examples/v2.0/json/petstore.json
6. You can also compile files that you specify with a URL. Here's another way to compile the previous
example. This time we're creating "petstore.text", which contains a textual representation of the
Protocol Buffer description. This is mainly for use in testing and debugging.
gnostic --text-out=petstore.text https://raw.githubusercontent.com/googleapis/gnostic/master/examples/petstore.json
7. For a sample application, see apps/report.
go install github.com/googleapis/gnostic/apps/report
report petstore.pb
8. **gnostic** supports plugins. This builds and runs a sample plugin
that reports some basic information about an API. The "-" causes the plugin to
write its output to stdout.
go install github.com/googleapis/gnostic/plugins/gnostic-go-sample
gnostic examples/v2.0/json/petstore.json --go-sample-out=-
## Copyright
Copyright 2017, Google Inc.
## License
Released under the Apache 2.0 license.

View File

@@ -1,3 +0,0 @@
# Compiler support code
This directory contains compiler support code used by Gnostic and Gnostic extensions.

View File

@@ -1,5 +0,0 @@
go get github.com/golang/protobuf/protoc-gen-go
protoc \
--go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. *.proto

View File

@@ -1,5 +0,0 @@
# Extensions
This directory contains support code for building Gnostic extensions and associated examples.
Extensions are used to compile vendor or specification extensions into protocol buffer structures.

View File

@@ -1,93 +0,0 @@
// 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.
syntax = "proto3";
import "google/protobuf/any.proto";
package openapiextension.v1;
// This option lets the proto compiler generate Java code inside the package
// name (see below) instead of inside an outer class. It creates a simpler
// developer experience by reducing one-level of name nesting and be
// consistent with most programming languages that don't support outer classes.
option java_multiple_files = true;
// The Java outer classname should be the filename in UpperCamelCase. This
// class is only used to hold proto descriptor, so developers don't need to
// work with it directly.
option java_outer_classname = "OpenAPIExtensionV1";
// The Java package name must be proto package name with proper prefix.
option java_package = "org.gnostic.v1";
// A reasonable prefix for the Objective-C symbols generated from the package.
// It should at a minimum be 3 characters long, all uppercase, and convention
// is to use an abbreviation of the package name. Something short, but
// hopefully unique enough to not conflict with things that may come along in
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
//
option objc_class_prefix = "OAE"; // "OpenAPI Extension"
// The version number of OpenAPI compiler.
message Version {
int32 major = 1;
int32 minor = 2;
int32 patch = 3;
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
// be empty for mainline stable releases.
string suffix = 4;
}
// An encoded Request is written to the ExtensionHandler's stdin.
message ExtensionHandlerRequest {
// The OpenAPI descriptions that were explicitly listed on the command line.
// The specifications will appear in the order they are specified to gnostic.
Wrapper wrapper = 1;
// The version number of openapi compiler.
Version compiler_version = 3;
}
// The extensions writes an encoded ExtensionHandlerResponse to stdout.
message ExtensionHandlerResponse {
// true if the extension is handled by the extension handler; false otherwise
bool handled = 1;
// Error message. If non-empty, the extension handling failed.
// The extension handler process should exit with status code zero
// even if it reports an error in this way.
//
// This should be used to indicate errors which prevent the extension from
// operating as intended. Errors which indicate a problem in gnostic
// itself -- such as the input Document being unparseable -- should be
// reported by writing a message to stderr and exiting with a non-zero
// status code.
repeated string error = 2;
// text output
google.protobuf.Any value = 3;
}
message Wrapper {
// version of the OpenAPI specification in which this extension was written.
string version = 1;
// Name of the extension
string extension_name = 2;
// Must be a valid yaml for the proto
string yaml = 3;
}

View File

@@ -1,610 +0,0 @@
// 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.
//go:generate ./COMPILE-PROTOS.sh
// Gnostic is a tool for building better REST APIs through knowledge.
//
// Gnostic reads declarative descriptions of REST APIs that conform
// to the OpenAPI Specification, reports errors, resolves internal
// dependencies, and puts the results in a binary form that can
// be used in any language that is supported by the Protocol Buffer
// tools.
//
// Gnostic models are validated and typed. This allows API tool
// developers to focus on their product and not worry about input
// validation and type checking.
//
// Gnostic calls plugins that implement a variety of API implementation
// and support features including generation of client and server
// support code.
package main
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"
"github.com/golang/protobuf/proto"
"github.com/googleapis/gnostic/OpenAPIv2"
"github.com/googleapis/gnostic/OpenAPIv3"
"github.com/googleapis/gnostic/compiler"
"github.com/googleapis/gnostic/discovery"
"github.com/googleapis/gnostic/jsonwriter"
plugins "github.com/googleapis/gnostic/plugins"
surface "github.com/googleapis/gnostic/surface"
"gopkg.in/yaml.v2"
)
const ( // Source Format
SourceFormatUnknown = 0
SourceFormatOpenAPI2 = 2
SourceFormatOpenAPI3 = 3
SourceFormatDiscovery = 4
)
// Determine the version of an OpenAPI description read from JSON or YAML.
func getOpenAPIVersionFromInfo(info interface{}) int {
m, ok := compiler.UnpackMap(info)
if !ok {
return SourceFormatUnknown
}
swagger, ok := compiler.MapValueForKey(m, "swagger").(string)
if ok && strings.HasPrefix(swagger, "2.0") {
return SourceFormatOpenAPI2
}
openapi, ok := compiler.MapValueForKey(m, "openapi").(string)
if ok && strings.HasPrefix(openapi, "3.0") {
return SourceFormatOpenAPI3
}
kind, ok := compiler.MapValueForKey(m, "kind").(string)
if ok && kind == "discovery#restDescription" {
return SourceFormatDiscovery
}
return SourceFormatUnknown
}
const (
pluginPrefix = "gnostic-"
extensionPrefix = "gnostic-x-"
)
type pluginCall struct {
Name string
Invocation string
}
// Invokes a plugin.
func (p *pluginCall) perform(document proto.Message, sourceFormat int, sourceName string, timePlugins bool) ([]*plugins.Message, error) {
if p.Name != "" {
request := &plugins.Request{}
// Infer the name of the executable by adding the prefix.
executableName := pluginPrefix + p.Name
// Validate invocation string with regular expression.
invocation := p.Invocation
//
// Plugin invocations must consist of
// zero or more comma-separated key=value pairs followed by a path.
// If pairs are present, a colon separates them from the path.
// Keys and values must be alphanumeric strings and may contain
// dashes, underscores, periods, or forward slashes.
// A path can contain any characters other than the separators ',', ':', and '='.
//
invocationRegex := regexp.MustCompile(`^([\w-_\/\.]+=[\w-_\/\.]+(,[\w-_\/\.]+=[\w-_\/\.]+)*:)?[^,:=]+$`)
if !invocationRegex.Match([]byte(p.Invocation)) {
return nil, fmt.Errorf("Invalid invocation of %s: %s", executableName, invocation)
}
invocationParts := strings.Split(p.Invocation, ":")
var outputLocation string
switch len(invocationParts) {
case 1:
outputLocation = invocationParts[0]
case 2:
parameters := strings.Split(invocationParts[0], ",")
for _, keyvalue := range parameters {
pair := strings.Split(keyvalue, "=")
if len(pair) == 2 {
request.Parameters = append(request.Parameters, &plugins.Parameter{Name: pair[0], Value: pair[1]})
}
}
outputLocation = invocationParts[1]
default:
// badly-formed request
outputLocation = invocationParts[len(invocationParts)-1]
}
version := &plugins.Version{}
version.Major = 0
version.Minor = 1
version.Patch = 0
request.CompilerVersion = version
request.OutputPath = outputLocation
request.SourceName = sourceName
switch sourceFormat {
case SourceFormatOpenAPI2:
request.AddModel("openapi.v2.Document", document)
// include experimental API surface model
surfaceModel, err := surface.NewModelFromOpenAPI2(document.(*openapi_v2.Document))
if err == nil {
request.AddModel("surface.v1.Model", surfaceModel)
}
case SourceFormatOpenAPI3:
request.AddModel("openapi.v3.Document", document)
// include experimental API surface model
surfaceModel, err := surface.NewModelFromOpenAPI3(document.(*openapi_v3.Document))
if err == nil {
request.AddModel("surface.v1.Model", surfaceModel)
}
case SourceFormatDiscovery:
request.AddModel("discovery.v1.Document", document)
default:
}
requestBytes, _ := proto.Marshal(request)
cmd := exec.Command(executableName, "-plugin")
cmd.Stdin = bytes.NewReader(requestBytes)
cmd.Stderr = os.Stderr
pluginStartTime := time.Now()
output, err := cmd.Output()
pluginElapsedTime := time.Since(pluginStartTime)
if timePlugins {
fmt.Printf("> %s (%s)\n", executableName, pluginElapsedTime)
}
if err != nil {
return nil, err
}
response := &plugins.Response{}
err = proto.Unmarshal(output, response)
if err != nil {
// Gnostic expects plugins to only write the
// response message to stdout. Be sure that
// any logging messages are written to stderr only.
return nil, errors.New("Invalid plugin response (plugins must write log messages to stderr, not stdout).")
}
plugins.HandleResponse(response, outputLocation)
return response.Messages, nil
}
return nil, nil
}
func isFile(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return !fileInfo.IsDir()
}
func isDirectory(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return fileInfo.IsDir()
}
// Write bytes to a named file.
// Certain names have special meaning:
// ! writes nothing
// - writes to stdout
// = writes to stderr
// If a directory name is given, the file is written there with
// a name derived from the source and extension arguments.
func writeFile(name string, bytes []byte, source string, extension string) {
var writer io.Writer
if name == "!" {
return
} else if name == "-" {
writer = os.Stdout
} else if name == "=" {
writer = os.Stderr
} else if isDirectory(name) {
base := filepath.Base(source)
// Remove the original source extension.
base = base[0 : len(base)-len(filepath.Ext(base))]
// Build the path that puts the result in the passed-in directory.
filename := name + "/" + base + "." + extension
file, _ := os.Create(filename)
defer file.Close()
writer = file
} else {
file, _ := os.Create(name)
defer file.Close()
writer = file
}
writer.Write(bytes)
if name == "-" || name == "=" {
writer.Write([]byte("\n"))
}
}
// The Gnostic structure holds global state information for gnostic.
type Gnostic struct {
usage string
sourceName string
binaryOutputPath string
textOutputPath string
yamlOutputPath string
jsonOutputPath string
errorOutputPath string
messageOutputPath string
resolveReferences bool
pluginCalls []*pluginCall
extensionHandlers []compiler.ExtensionHandler
sourceFormat int
timePlugins bool
}
// Initialize a structure to store global application state.
func newGnostic() *Gnostic {
g := &Gnostic{}
// Option fields initialize to their default values.
g.usage = `
Usage: gnostic SOURCE [OPTIONS]
SOURCE is the filename or URL of an API description.
Options:
--pb-out=PATH Write a binary proto to the specified location.
--text-out=PATH Write a text proto to the specified location.
--json-out=PATH Write a json API description to the specified location.
--yaml-out=PATH Write a yaml API description to the specified location.
--errors-out=PATH Write compilation errors to the specified location.
--messages-out=PATH Write messages generated by plugins to the specified
location. Messages from all plugin invocations are
written to a single common file.
--PLUGIN-out=PATH Run the plugin named gnostic-PLUGIN and write results
to the specified location.
--PLUGIN Run the plugin named gnostic-PLUGIN but don't write any
results. Used for plugins that return messages only.
PLUGIN must not match any other gnostic option.
--x-EXTENSION Use the extension named gnostic-x-EXTENSION
to process OpenAPI specification extensions.
--resolve-refs Explicitly resolve $ref references.
This could have problems with recursive definitions.
--time-plugins Report plugin runtimes.
`
// Initialize internal structures.
g.pluginCalls = make([]*pluginCall, 0)
g.extensionHandlers = make([]compiler.ExtensionHandler, 0)
return g
}
// Parse command-line options.
func (g *Gnostic) readOptions() {
// plugin processing matches patterns of the form "--PLUGIN-out=PATH" and "--PLUGIN_out=PATH"
pluginRegex := regexp.MustCompile("--(.+)[-_]out=(.+)")
// extension processing matches patterns of the form "--x-EXTENSION"
extensionRegex := regexp.MustCompile("--x-(.+)")
for i, arg := range os.Args {
if i == 0 {
continue // skip the tool name
}
var m [][]byte
if m = pluginRegex.FindSubmatch([]byte(arg)); m != nil {
pluginName := string(m[1])
invocation := string(m[2])
switch pluginName {
case "pb":
g.binaryOutputPath = invocation
case "text":
g.textOutputPath = invocation
case "json":
g.jsonOutputPath = invocation
case "yaml":
g.yamlOutputPath = invocation
case "errors":
g.errorOutputPath = invocation
case "messages":
g.messageOutputPath = invocation
default:
p := &pluginCall{Name: pluginName, Invocation: invocation}
g.pluginCalls = append(g.pluginCalls, p)
}
} else if m = extensionRegex.FindSubmatch([]byte(arg)); m != nil {
extensionName := string(m[1])
extensionHandler := compiler.ExtensionHandler{Name: extensionPrefix + extensionName}
g.extensionHandlers = append(g.extensionHandlers, extensionHandler)
} else if arg == "--resolve-refs" {
g.resolveReferences = true
} else if arg == "--time-plugins" {
g.timePlugins = true
} else if arg[0] == '-' && arg[1] == '-' {
// try letting the option specify a plugin with no output files (or unwanted output files)
// this is useful for calling plugins like linters that only return messages
p := &pluginCall{Name: arg[2:len(arg)], Invocation: "!"}
g.pluginCalls = append(g.pluginCalls, p)
} else if arg[0] == '-' {
fmt.Fprintf(os.Stderr, "Unknown option: %s.\n%s\n", arg, g.usage)
os.Exit(-1)
} else {
g.sourceName = arg
}
}
}
// Validate command-line options.
func (g *Gnostic) validateOptions() {
if g.binaryOutputPath == "" &&
g.textOutputPath == "" &&
g.yamlOutputPath == "" &&
g.jsonOutputPath == "" &&
g.errorOutputPath == "" &&
len(g.pluginCalls) == 0 {
fmt.Fprintf(os.Stderr, "Missing output directives.\n%s\n", g.usage)
os.Exit(-1)
}
if g.sourceName == "" {
fmt.Fprintf(os.Stderr, "No input specified.\n%s\n", g.usage)
os.Exit(-1)
}
// If we get here and the error output is unspecified, write errors to stderr.
if g.errorOutputPath == "" {
g.errorOutputPath = "="
}
}
// Generate an error message to be written to stderr or a file.
func (g *Gnostic) errorBytes(err error) []byte {
return []byte("Errors reading " + g.sourceName + "\n" + err.Error())
}
// Read an OpenAPI description from YAML or JSON.
func (g *Gnostic) readOpenAPIText(bytes []byte) (message proto.Message, err error) {
info, err := compiler.ReadInfoFromBytes(g.sourceName, bytes)
if err != nil {
return nil, err
}
// Determine the OpenAPI version.
g.sourceFormat = getOpenAPIVersionFromInfo(info)
if g.sourceFormat == SourceFormatUnknown {
return nil, errors.New("unable to identify OpenAPI version")
}
// Compile to the proto model.
if g.sourceFormat == SourceFormatOpenAPI2 {
document, err := openapi_v2.NewDocument(info, compiler.NewContextWithExtensions("$root", nil, &g.extensionHandlers))
if err != nil {
return nil, err
}
message = document
} else if g.sourceFormat == SourceFormatOpenAPI3 {
document, err := openapi_v3.NewDocument(info, compiler.NewContextWithExtensions("$root", nil, &g.extensionHandlers))
if err != nil {
return nil, err
}
message = document
} else {
document, err := discovery_v1.NewDocument(info, compiler.NewContextWithExtensions("$root", nil, &g.extensionHandlers))
if err != nil {
return nil, err
}
message = document
}
return message, err
}
// Read an OpenAPI binary file.
func (g *Gnostic) readOpenAPIBinary(data []byte) (message proto.Message, err error) {
// try to read an OpenAPI v3 document
documentV3 := &openapi_v3.Document{}
err = proto.Unmarshal(data, documentV3)
if err == nil && strings.HasPrefix(documentV3.Openapi, "3.0") {
g.sourceFormat = SourceFormatOpenAPI3
return documentV3, nil
}
// if that failed, try to read an OpenAPI v2 document
documentV2 := &openapi_v2.Document{}
err = proto.Unmarshal(data, documentV2)
if err == nil && strings.HasPrefix(documentV2.Swagger, "2.0") {
g.sourceFormat = SourceFormatOpenAPI2
return documentV2, nil
}
// if that failed, try to read a Discovery Format document
discoveryDocument := &discovery_v1.Document{}
err = proto.Unmarshal(data, discoveryDocument)
if err == nil { // && strings.HasPrefix(documentV2.Swagger, "2.0") {
g.sourceFormat = SourceFormatDiscovery
return discoveryDocument, nil
}
return nil, err
}
// Write a binary pb representation.
func (g *Gnostic) writeBinaryOutput(message proto.Message) {
protoBytes, err := proto.Marshal(message)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
defer os.Exit(-1)
} else {
writeFile(g.binaryOutputPath, protoBytes, g.sourceName, "pb")
}
}
// Write a text pb representation.
func (g *Gnostic) writeTextOutput(message proto.Message) {
bytes := []byte(proto.MarshalTextString(message))
writeFile(g.textOutputPath, bytes, g.sourceName, "text")
}
// Write JSON/YAML OpenAPI representations.
func (g *Gnostic) writeJSONYAMLOutput(message proto.Message) {
// Convert the OpenAPI document into an exportable MapSlice.
var rawInfo yaml.MapSlice
var ok bool
var err error
if g.sourceFormat == SourceFormatOpenAPI2 {
document := message.(*openapi_v2.Document)
rawInfo, ok = document.ToRawInfo().(yaml.MapSlice)
if !ok {
rawInfo = nil
}
} else if g.sourceFormat == SourceFormatOpenAPI3 {
document := message.(*openapi_v3.Document)
rawInfo, ok = document.ToRawInfo().(yaml.MapSlice)
if !ok {
rawInfo = nil
}
} else if g.sourceFormat == SourceFormatDiscovery {
document := message.(*discovery_v1.Document)
rawInfo, ok = document.ToRawInfo().(yaml.MapSlice)
if !ok {
rawInfo = nil
}
}
// Optionally write description in yaml format.
if g.yamlOutputPath != "" {
var bytes []byte
if rawInfo != nil {
bytes, err = yaml.Marshal(rawInfo)
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating yaml output %s\n", err.Error())
}
writeFile(g.yamlOutputPath, bytes, g.sourceName, "yaml")
} else {
fmt.Fprintf(os.Stderr, "No yaml output available.\n")
}
}
// Optionally write description in json format.
if g.jsonOutputPath != "" {
var bytes []byte
if rawInfo != nil {
bytes, _ = jsonwriter.Marshal(rawInfo)
if err != nil {
fmt.Fprintf(os.Stderr, "Error generating json output %s\n", err.Error())
}
writeFile(g.jsonOutputPath, bytes, g.sourceName, "json")
} else {
fmt.Fprintf(os.Stderr, "No json output available.\n")
}
}
}
// Write messages.
func (g *Gnostic) writeMessagesOutput(message proto.Message) {
protoBytes, err := proto.Marshal(message)
if err != nil {
writeFile(g.messageOutputPath, g.errorBytes(err), g.sourceName, "errors")
defer os.Exit(-1)
} else {
writeFile(g.messageOutputPath, protoBytes, g.sourceName, "messages.pb")
}
}
// Perform all actions specified in the command-line options.
func (g *Gnostic) performActions(message proto.Message) (err error) {
// Optionally resolve internal references.
if g.resolveReferences {
if g.sourceFormat == SourceFormatOpenAPI2 {
document := message.(*openapi_v2.Document)
_, err = document.ResolveReferences(g.sourceName)
} else if g.sourceFormat == SourceFormatOpenAPI3 {
document := message.(*openapi_v3.Document)
_, err = document.ResolveReferences(g.sourceName)
}
if err != nil {
return err
}
}
// Optionally write proto in binary format.
if g.binaryOutputPath != "" {
g.writeBinaryOutput(message)
}
// Optionally write proto in text format.
if g.textOutputPath != "" {
g.writeTextOutput(message)
}
// Optionally write document in yaml and/or json formats.
if g.yamlOutputPath != "" || g.jsonOutputPath != "" {
g.writeJSONYAMLOutput(message)
}
// Call all specified plugins.
messages := make([]*plugins.Message, 0)
for _, p := range g.pluginCalls {
pluginMessages, err := p.perform(message, g.sourceFormat, g.sourceName, g.timePlugins)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
defer os.Exit(-1) // run all plugins, even when some have errors
}
messages = append(messages, pluginMessages...)
}
if g.messageOutputPath != "" {
g.writeMessagesOutput(&plugins.Messages{Messages: messages})
} else {
// Print any messages from the plugins
if len(messages) > 0 {
for _, message := range messages {
fmt.Printf("%+v\n", message)
}
}
}
return nil
}
func (g *Gnostic) main() {
var err error
g.readOptions()
g.validateOptions()
// Read the OpenAPI source.
bytes, err := compiler.ReadBytesForFile(g.sourceName)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
os.Exit(-1)
}
extension := strings.ToLower(filepath.Ext(g.sourceName))
var message proto.Message
if extension == ".json" || extension == ".yaml" {
// Try to read the source as JSON/YAML.
message, err = g.readOpenAPIText(bytes)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
os.Exit(-1)
}
} else if extension == ".pb" {
// Try to read the source as a binary protocol buffer.
message, err = g.readOpenAPIBinary(bytes)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
os.Exit(-1)
}
} else {
err = errors.New("unknown file extension. 'json', 'yaml', and 'pb' are accepted")
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
os.Exit(-1)
}
// Perform actions specified by command options.
err = g.performActions(message)
if err != nil {
writeFile(g.errorOutputPath, g.errorBytes(err), g.sourceName, "errors")
os.Exit(-1)
}
}
func main() {
g := newGnostic()
g.main()
}