mirror of
https://github.com/coredns/coredns.git
synced 2025-11-15 16:32:23 -05:00
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:
21
vendor/github.com/googleapis/gnostic/.gitignore
generated
vendored
21
vendor/github.com/googleapis/gnostic/.gitignore
generated
vendored
@@ -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
|
||||
29
vendor/github.com/googleapis/gnostic/.travis-install.sh
generated
vendored
29
vendor/github.com/googleapis/gnostic/.travis-install.sh
generated
vendored
@@ -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
|
||||
49
vendor/github.com/googleapis/gnostic/.travis.yml
generated
vendored
49
vendor/github.com/googleapis/gnostic/.travis.yml
generated
vendored
@@ -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
|
||||
|
||||
35
vendor/github.com/googleapis/gnostic/COMPILE-PROTOS.sh
generated
vendored
35
vendor/github.com/googleapis/gnostic/COMPILE-PROTOS.sh
generated
vendored
@@ -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
|
||||
35
vendor/github.com/googleapis/gnostic/CONTRIBUTING.md
generated
vendored
35
vendor/github.com/googleapis/gnostic/CONTRIBUTING.md
generated
vendored
@@ -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.
|
||||
16
vendor/github.com/googleapis/gnostic/Makefile
generated
vendored
16
vendor/github.com/googleapis/gnostic/Makefile
generated
vendored
@@ -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
|
||||
|
||||
663
vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.proto
generated
vendored
663
vendor/github.com/googleapis/gnostic/OpenAPIv2/OpenAPIv2.proto
generated
vendored
@@ -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;
|
||||
}
|
||||
|
||||
16
vendor/github.com/googleapis/gnostic/OpenAPIv2/README.md
generated
vendored
16
vendor/github.com/googleapis/gnostic/OpenAPIv2/README.md
generated
vendored
@@ -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.
|
||||
1610
vendor/github.com/googleapis/gnostic/OpenAPIv2/openapi-2.0.json
generated
vendored
1610
vendor/github.com/googleapis/gnostic/OpenAPIv2/openapi-2.0.json
generated
vendored
File diff suppressed because it is too large
Load Diff
109
vendor/github.com/googleapis/gnostic/README.md
generated
vendored
109
vendor/github.com/googleapis/gnostic/README.md
generated
vendored
@@ -1,109 +0,0 @@
|
||||
[](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.
|
||||
3
vendor/github.com/googleapis/gnostic/compiler/README.md
generated
vendored
3
vendor/github.com/googleapis/gnostic/compiler/README.md
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# Compiler support code
|
||||
|
||||
This directory contains compiler support code used by Gnostic and Gnostic extensions.
|
||||
5
vendor/github.com/googleapis/gnostic/extensions/COMPILE-EXTENSION.sh
generated
vendored
5
vendor/github.com/googleapis/gnostic/extensions/COMPILE-EXTENSION.sh
generated
vendored
@@ -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
|
||||
|
||||
5
vendor/github.com/googleapis/gnostic/extensions/README.md
generated
vendored
5
vendor/github.com/googleapis/gnostic/extensions/README.md
generated
vendored
@@ -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.
|
||||
93
vendor/github.com/googleapis/gnostic/extensions/extension.proto
generated
vendored
93
vendor/github.com/googleapis/gnostic/extensions/extension.proto
generated
vendored
@@ -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;
|
||||
}
|
||||
610
vendor/github.com/googleapis/gnostic/gnostic.go
generated
vendored
610
vendor/github.com/googleapis/gnostic/gnostic.go
generated
vendored
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user