main.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2017 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // gnostic_analyze is a tool for analyzing OpenAPI descriptions.
  15. //
  16. // It scans an API description and evaluates properties
  17. // that influence the ease and quality of code generation.
  18. // - The number of HTTP operations of each method (GET, POST, etc).
  19. // - The number of HTTP operations with no OperationId value.
  20. // - The parameter types used and their frequencies.
  21. // - The response types used and their frequencies.
  22. // - The types used in definition objects and arrays and their frequencies.
  23. // Results are returned in a JSON structure.
  24. package main
  25. import (
  26. "encoding/json"
  27. "fmt"
  28. "io/ioutil"
  29. "os"
  30. "path"
  31. "strings"
  32. "github.com/golang/protobuf/proto"
  33. "github.com/googleapis/gnostic/plugins/gnostic-analyze/statistics"
  34. openapi "github.com/googleapis/gnostic/OpenAPIv2"
  35. plugins "github.com/googleapis/gnostic/plugins"
  36. )
  37. // Record an error, then serialize and return a response.
  38. func sendAndExitIfError(err error, response *plugins.Response) {
  39. if err != nil {
  40. response.Errors = append(response.Errors, err.Error())
  41. sendAndExit(response)
  42. }
  43. }
  44. // Serialize and return a response.
  45. func sendAndExit(response *plugins.Response) {
  46. responseBytes, _ := proto.Marshal(response)
  47. os.Stdout.Write(responseBytes)
  48. os.Exit(0)
  49. }
  50. func main() {
  51. // Initialize the response.
  52. response := &plugins.Response{}
  53. // Read the request.
  54. data, err := ioutil.ReadAll(os.Stdin)
  55. sendAndExitIfError(err, response)
  56. if len(data) == 0 {
  57. sendAndExitIfError(fmt.Errorf("no input data"), response)
  58. }
  59. // Unmarshal the request.
  60. request := &plugins.Request{}
  61. err = proto.Unmarshal(data, request)
  62. sendAndExitIfError(err, response)
  63. // Verify that the passed-in description is supported.
  64. wrapper := request.Wrapper
  65. if wrapper.Version != "v2" {
  66. err = fmt.Errorf("%s requires an OpenAPI v2 description.",
  67. os.Args[0])
  68. sendAndExitIfError(err, response)
  69. }
  70. // Unmarshal the description.
  71. document := &openapi.Document{}
  72. err = proto.Unmarshal(wrapper.Value, document)
  73. sendAndExitIfError(err, response)
  74. // Analyze the API document.
  75. stats := statistics.NewDocumentStatistics(wrapper.Name, document)
  76. // Return the analysis results with an appropriate filename.
  77. // Results are in files named "summary.json" in the same relative
  78. // locations as the description source files.
  79. file := &plugins.File{}
  80. file.Name = strings.Replace(stats.Name, path.Base(stats.Name), "summary.json", -1)
  81. file.Data, err = json.MarshalIndent(stats, "", " ")
  82. file.Data = append(file.Data, []byte("\n")...)
  83. sendAndExitIfError(err, response)
  84. response.Files = append(response.Files, file)
  85. // Send the final results. Success!
  86. sendAndExit(response)
  87. }