diff --git a/rest-api-spec/README.markdown b/rest-api-spec/README.markdown index b3583f70850..469855d935b 100644 --- a/rest-api-spec/README.markdown +++ b/rest-api-spec/README.markdown @@ -47,7 +47,8 @@ The `methods` and `url.paths` elements list all possible HTTP methods and URLs f it is the responsibility of the developer to use this information for a sensible API on the target platform. The repository contains a utility script in Ruby which will scan and parse the Elasticsearch source code -to extract the information from the Java source files. Run `bundle install` and then `thor help api:generate:spec`. +to extract the information from the Java source files. Run `bundle install` and then `thor help api:generate:spec` +in the _utils_ folder. ## License diff --git a/rest-api-spec/Gemfile b/rest-api-spec/utils/Gemfile similarity index 100% rename from rest-api-spec/Gemfile rename to rest-api-spec/utils/Gemfile diff --git a/rest-api-spec/utils/Thorfile b/rest-api-spec/utils/Thorfile new file mode 100644 index 00000000000..887db65b6b2 --- /dev/null +++ b/rest-api-spec/utils/Thorfile @@ -0,0 +1 @@ +require File.expand_path('./thor/generate_api') diff --git a/rest-api-spec/Thorfile b/rest-api-spec/utils/thor/generate_api.rb similarity index 76% rename from rest-api-spec/Thorfile rename to rest-api-spec/utils/thor/generate_api.rb index c06451f085c..4122892775a 100644 --- a/rest-api-spec/Thorfile +++ b/rest-api-spec/utils/thor/generate_api.rb @@ -1,3 +1,5 @@ +require 'thor' + require 'pathname' require 'active_support/core_ext/hash/deep_merge' require 'active_support/inflector/methods' @@ -7,34 +9,8 @@ require 'pry' module Elasticsearch - # Contains a generator which will parse the Elasticsearch *.java source files, - # extract information about REST API endpoints (URLs, HTTP methods, URL parameters, etc), - # and create a skeleton of the JSON API specification file for each endpoint. - # - # Usage: - # - # $ thor help api:generate:spec - # - # Example: - # - # time thor api:generate:spec \ - # --force \ - # --verbose \ - # --crawl \ - # --elasticsearch=/path/to/elasticsearch/source/code - # - # Features: - # - # * Extract the API name from the source filename (eg. `admin/cluster/health/RestClusterHealthAction.java` -> `cluster.health`) - # * Extract the URLs from the `registerHandler` statements - # * Extract the URL parts (eg. `{index}`) from the URLs - # * Extract the URL parameters (eg. `{timeout}`) from the `request.param("ABC")` statements - # * Detect whether HTTP body is allowed for the API from `request.hasContent()` statements - # * Search the website to get proper documentation URLs - # * Assemble the JSON format for the API spec - # module API - module Utils + module Utils # controller.registerHandler(RestRequest.Method.GET, "/_cluster/health", this); PATTERN_REST = /.*controller.registerHandler\(.*(?GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)\s*,\s*"(?.*)"\s*,\s*.+\);/ # request.param("index"), request.paramAsBoolean("docs", indicesStatsRequest.docs()), etc @@ -57,8 +33,7 @@ module Elasticsearch # "body" => false # } # - def __parse_java_source(path=nil) - path ||= Dir.pwd + '/elasticsearch' + def __parse_java_source(path) path += '/' unless path =~ /\/$/ # Add trailing slash if missing prefix = "src/main/java/org/elasticsearch/rest/action" @@ -100,29 +75,57 @@ module Elasticsearch extend self end + # Contains a generator which will parse the Elasticsearch *.java source files, + # extract information about REST API endpoints (URLs, HTTP methods, URL parameters, etc), + # and create a skeleton of the JSON API specification file for each endpoint. + # + # Usage: + # + # $ thor help api:generate:spec + # + # Example: + # + # time thor api:generate:spec \ + # --force \ + # --verbose \ + # --crawl \ + # --elasticsearch=/path/to/elasticsearch/source/code + # + # Features: + # + # * Extract the API name from the source filename (eg. `admin/cluster/health/RestClusterHealthAction.java` -> `cluster.health`) + # * Extract the URLs from the `registerHandler` statements + # * Extract the URL parts (eg. `{index}`) from the URLs + # * Extract the URL parameters (eg. `{timeout}`) from the `request.param("ABC")` statements + # * Detect whether HTTP body is allowed for the API from `request.hasContent()` statements + # * Search the website to get proper documentation URLs + # * Assemble the JSON format for the API spec + # class JsonGenerator < Thor namespace 'api:generate' include Thor::Actions + __root = Pathname( File.expand_path('../../..', __FILE__) ) + # Usage: thor help api:generate:spec # desc "spec", "Generate JSON API spec files from Elasticsearch source code" method_option :force, type: :boolean, default: false, desc: 'Overwrite the output' method_option :verbose, type: :boolean, default: false, desc: 'Output more information' - method_option :output, default: Dir.pwd+'/tmp/out', desc: 'Path to output directory' - method_option :elasticsearch, default: Dir.pwd+'/tmp/elasticsearch', desc: 'Path to directory with Elasticsearch source code' + method_option :output, default: __root.join('tmp/out'), desc: 'Path to output directory' + method_option :elasticsearch, default: __root.join('tmp/elasticsearch'), desc: 'Path to directory with Elasticsearch source code' method_option :crawl, type: :boolean, default: false, desc: 'Extract URLs from Elasticsearch website' def spec self.class.source_root File.expand_path('../', __FILE__) - @output = Pathname(options[:output]) + @output = options[:output] - rest_actions = Utils.__parse_java_source(options[:elasticsearch]) + rest_actions = Utils.__parse_java_source(options[:elasticsearch].to_s) if rest_actions.empty? - say_status 'ERROR', 'Cannot find Elasticsearch source in ' + options[:elasticsearch], :red + say_status 'ERROR', 'Cannot find Elasticsearch source in ' + options[:elasticsearch].to_s, :red exit(1) end