elasticsearch-api 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -0
  3. data/Rakefile +3 -3
  4. data/elasticsearch-api.gemspec +4 -1
  5. data/lib/elasticsearch/api.rb +19 -0
  6. data/lib/elasticsearch/api/actions/abort_benchmark.rb +1 -1
  7. data/lib/elasticsearch/api/actions/benchmark.rb +1 -1
  8. data/lib/elasticsearch/api/actions/bulk.rb +1 -1
  9. data/lib/elasticsearch/api/actions/cat/aliases.rb +1 -1
  10. data/lib/elasticsearch/api/actions/cat/allocation.rb +1 -1
  11. data/lib/elasticsearch/api/actions/cat/count.rb +1 -1
  12. data/lib/elasticsearch/api/actions/cat/fielddata.rb +1 -1
  13. data/lib/elasticsearch/api/actions/cat/health.rb +1 -1
  14. data/lib/elasticsearch/api/actions/cat/help.rb +1 -1
  15. data/lib/elasticsearch/api/actions/cat/indices.rb +1 -1
  16. data/lib/elasticsearch/api/actions/cat/master.rb +1 -1
  17. data/lib/elasticsearch/api/actions/cat/nodes.rb +1 -1
  18. data/lib/elasticsearch/api/actions/cat/pending_tasks.rb +1 -1
  19. data/lib/elasticsearch/api/actions/cat/recovery.rb +1 -1
  20. data/lib/elasticsearch/api/actions/cat/segments.rb +34 -0
  21. data/lib/elasticsearch/api/actions/cat/shards.rb +1 -1
  22. data/lib/elasticsearch/api/actions/cat/thread_pool.rb +1 -1
  23. data/lib/elasticsearch/api/actions/clear_scroll.rb +12 -3
  24. data/lib/elasticsearch/api/actions/cluster/get_settings.rb +1 -1
  25. data/lib/elasticsearch/api/actions/cluster/health.rb +1 -1
  26. data/lib/elasticsearch/api/actions/cluster/pending_tasks.rb +1 -1
  27. data/lib/elasticsearch/api/actions/cluster/put_settings.rb +1 -1
  28. data/lib/elasticsearch/api/actions/cluster/reroute.rb +1 -1
  29. data/lib/elasticsearch/api/actions/cluster/state.rb +8 -2
  30. data/lib/elasticsearch/api/actions/count.rb +1 -1
  31. data/lib/elasticsearch/api/actions/count_percolate.rb +1 -1
  32. data/lib/elasticsearch/api/actions/delete.rb +1 -1
  33. data/lib/elasticsearch/api/actions/delete_by_query.rb +1 -1
  34. data/lib/elasticsearch/api/actions/delete_script.rb +1 -1
  35. data/lib/elasticsearch/api/actions/delete_template.rb +1 -1
  36. data/lib/elasticsearch/api/actions/exists.rb +4 -2
  37. data/lib/elasticsearch/api/actions/explain.rb +1 -1
  38. data/lib/elasticsearch/api/actions/get.rb +2 -2
  39. data/lib/elasticsearch/api/actions/get_script.rb +1 -1
  40. data/lib/elasticsearch/api/actions/get_source.rb +2 -2
  41. data/lib/elasticsearch/api/actions/get_template.rb +1 -1
  42. data/lib/elasticsearch/api/actions/index.rb +1 -1
  43. data/lib/elasticsearch/api/actions/indices/analyze.rb +5 -3
  44. data/lib/elasticsearch/api/actions/indices/clear_cache.rb +1 -1
  45. data/lib/elasticsearch/api/actions/indices/close.rb +1 -1
  46. data/lib/elasticsearch/api/actions/indices/create.rb +1 -1
  47. data/lib/elasticsearch/api/actions/indices/delete.rb +7 -1
  48. data/lib/elasticsearch/api/actions/indices/delete_alias.rb +1 -1
  49. data/lib/elasticsearch/api/actions/indices/delete_mapping.rb +1 -1
  50. data/lib/elasticsearch/api/actions/indices/delete_template.rb +1 -1
  51. data/lib/elasticsearch/api/actions/indices/delete_warmer.rb +1 -1
  52. data/lib/elasticsearch/api/actions/indices/exists.rb +3 -1
  53. data/lib/elasticsearch/api/actions/indices/exists_alias.rb +3 -1
  54. data/lib/elasticsearch/api/actions/indices/exists_template.rb +3 -2
  55. data/lib/elasticsearch/api/actions/indices/exists_type.rb +3 -1
  56. data/lib/elasticsearch/api/actions/indices/flush.rb +1 -1
  57. data/lib/elasticsearch/api/actions/indices/get.rb +1 -1
  58. data/lib/elasticsearch/api/actions/indices/get_alias.rb +1 -1
  59. data/lib/elasticsearch/api/actions/indices/get_aliases.rb +1 -1
  60. data/lib/elasticsearch/api/actions/indices/get_field_mapping.rb +1 -1
  61. data/lib/elasticsearch/api/actions/indices/get_mapping.rb +1 -1
  62. data/lib/elasticsearch/api/actions/indices/get_settings.rb +1 -1
  63. data/lib/elasticsearch/api/actions/indices/get_template.rb +3 -2
  64. data/lib/elasticsearch/api/actions/indices/get_warmer.rb +1 -1
  65. data/lib/elasticsearch/api/actions/indices/open.rb +1 -1
  66. data/lib/elasticsearch/api/actions/indices/optimize.rb +1 -1
  67. data/lib/elasticsearch/api/actions/indices/put_alias.rb +2 -2
  68. data/lib/elasticsearch/api/actions/indices/put_mapping.rb +1 -1
  69. data/lib/elasticsearch/api/actions/indices/put_settings.rb +1 -1
  70. data/lib/elasticsearch/api/actions/indices/put_template.rb +1 -1
  71. data/lib/elasticsearch/api/actions/indices/put_warmer.rb +1 -1
  72. data/lib/elasticsearch/api/actions/indices/recovery.rb +1 -1
  73. data/lib/elasticsearch/api/actions/indices/refresh.rb +1 -1
  74. data/lib/elasticsearch/api/actions/indices/segments.rb +1 -1
  75. data/lib/elasticsearch/api/actions/indices/snapshot_index.rb +1 -1
  76. data/lib/elasticsearch/api/actions/indices/stats.rb +1 -1
  77. data/lib/elasticsearch/api/actions/indices/status.rb +1 -1
  78. data/lib/elasticsearch/api/actions/indices/update_aliases.rb +1 -1
  79. data/lib/elasticsearch/api/actions/indices/upgrade.rb +1 -1
  80. data/lib/elasticsearch/api/actions/indices/validate_query.rb +1 -1
  81. data/lib/elasticsearch/api/actions/info.rb +1 -1
  82. data/lib/elasticsearch/api/actions/list_benchmarks.rb +1 -1
  83. data/lib/elasticsearch/api/actions/mget.rb +1 -1
  84. data/lib/elasticsearch/api/actions/mlt.rb +1 -1
  85. data/lib/elasticsearch/api/actions/mpercolate.rb +1 -1
  86. data/lib/elasticsearch/api/actions/msearch.rb +1 -1
  87. data/lib/elasticsearch/api/actions/mtermvectors.rb +1 -1
  88. data/lib/elasticsearch/api/actions/nodes/hot_threads.rb +1 -1
  89. data/lib/elasticsearch/api/actions/nodes/info.rb +18 -2
  90. data/lib/elasticsearch/api/actions/nodes/shutdown.rb +1 -1
  91. data/lib/elasticsearch/api/actions/nodes/stats.rb +1 -1
  92. data/lib/elasticsearch/api/actions/percolate.rb +4 -5
  93. data/lib/elasticsearch/api/actions/ping.rb +1 -1
  94. data/lib/elasticsearch/api/actions/put_script.rb +1 -1
  95. data/lib/elasticsearch/api/actions/put_template.rb +1 -1
  96. data/lib/elasticsearch/api/actions/scroll.rb +2 -2
  97. data/lib/elasticsearch/api/actions/search.rb +4 -3
  98. data/lib/elasticsearch/api/actions/search_shards.rb +1 -1
  99. data/lib/elasticsearch/api/actions/search_template.rb +1 -1
  100. data/lib/elasticsearch/api/actions/snapshot/create.rb +1 -1
  101. data/lib/elasticsearch/api/actions/snapshot/create_repository.rb +1 -1
  102. data/lib/elasticsearch/api/actions/snapshot/delete.rb +1 -1
  103. data/lib/elasticsearch/api/actions/snapshot/delete_repository.rb +1 -1
  104. data/lib/elasticsearch/api/actions/snapshot/get.rb +1 -1
  105. data/lib/elasticsearch/api/actions/snapshot/get_repository.rb +1 -1
  106. data/lib/elasticsearch/api/actions/snapshot/restore.rb +1 -1
  107. data/lib/elasticsearch/api/actions/snapshot/status.rb +1 -1
  108. data/lib/elasticsearch/api/actions/snapshot/verify_repository.rb +1 -1
  109. data/lib/elasticsearch/api/actions/suggest.rb +1 -1
  110. data/lib/elasticsearch/api/actions/{termvector.rb → termvectors.rb} +24 -7
  111. data/lib/elasticsearch/api/actions/update.rb +1 -1
  112. data/lib/elasticsearch/api/utils.rb +27 -6
  113. data/lib/elasticsearch/api/version.rb +1 -1
  114. data/test/integration/yaml_test_runner.rb +3 -2
  115. data/test/unit/api_test.rb +24 -0
  116. data/test/unit/cat/segments_test.rb +26 -0
  117. data/test/unit/clear_scroll_test.rb +4 -4
  118. data/test/unit/exists_document_test.rb +5 -0
  119. data/test/unit/indices/delete_test.rb +7 -0
  120. data/test/unit/indices/exists_alias_test.rb +5 -0
  121. data/test/unit/indices/exists_test.rb +5 -0
  122. data/test/unit/indices/exists_type_test.rb +5 -0
  123. data/test/unit/indices/put_alias_test.rb +9 -0
  124. data/test/unit/nodes/info_test.rb +9 -0
  125. data/test/unit/scroll_test.rb +1 -2
  126. data/test/unit/{termvector_test.rb → termvectors_test.rb} +15 -12
  127. data/test/unit/utils_test.rb +22 -0
  128. data/utils/Gemfile +9 -0
  129. data/utils/Thorfile +3 -0
  130. data/utils/thor/generate_api.rb +189 -0
  131. data/utils/thor/generate_source.rb +122 -0
  132. data/utils/thor/lister.rb +41 -0
  133. data/utils/thor/templates/ruby/method.erb +62 -0
  134. data/utils/thor/templates/ruby/test.erb +26 -0
  135. data/utils/thor/templates/ruby/test_helper.rb +71 -0
  136. metadata +18 -5
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activesupport'
4
+ gem 'rest-client'
5
+ gem 'coderay'
6
+ gem 'multi_json'
7
+ gem 'thor'
8
+ gem 'json'
9
+ gem 'pry'
@@ -0,0 +1,3 @@
1
+ require File.expand_path('./thor/generate_api')
2
+ require File.expand_path('./thor/generate_source')
3
+ require File.expand_path('./thor/lister')
@@ -0,0 +1,189 @@
1
+ require 'thor'
2
+
3
+ require 'pathname'
4
+ require 'active_support/core_ext/hash/deep_merge'
5
+ require 'active_support/inflector/methods'
6
+ require 'rest_client'
7
+ require 'json'
8
+ require 'pry'
9
+
10
+ module Elasticsearch
11
+
12
+ module API
13
+ module Utils
14
+ # controller.registerHandler(RestRequest.Method.GET, "/_cluster/health", this);
15
+ PATTERN_REST = /.*controller.registerHandler\(.*(?<method>GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH)\s*,\s*"(?<url>.*)"\s*,\s*.+\);/
16
+ # request.param("index"), request.paramAsBoolean("docs", indicesStatsRequest.docs()), etc
17
+ PATTERN_URL_PARAMS = /request.param.*\("(?<param>[a-z_]+)".*/
18
+ # controller.registerHandler(GET, "/{index}/_refresh", this)
19
+ PATTERN_URL_PARTS = /\{(?<part>[a-zA-Z0-9\_\-]+)\}/
20
+ # request.hasContent()
21
+ PATTERN_HAS_BODY = /request\.hasContent()/
22
+
23
+ # Parses the Elasticsearch source code and returns a Hash of REST API information/specs.
24
+ #
25
+ # Example:
26
+ #
27
+ # {
28
+ # "cluster.health" => [
29
+ # { "method" => "GET",
30
+ # "path" => "/_cluster/health",
31
+ # "parts" => ["index"],
32
+ # "params" => ["index", "local", ... ],
33
+ # "body" => false
34
+ # }
35
+ #
36
+ def __parse_java_source(path)
37
+ path += '/' unless path =~ /\/$/ # Add trailing slash if missing
38
+ prefix = "src/main/java/org/elasticsearch/rest/action"
39
+
40
+ java_rest_files = Dir["#{path}#{prefix}/**/*.java"]
41
+
42
+ map = {}
43
+
44
+ java_rest_files.sort.each do |file|
45
+ content = File.read(file)
46
+ parts = file.gsub(path+prefix, '').split('/')
47
+ name = parts[0, parts.size-1].reject { |p| p =~ /^\s*$/ }.join('.')
48
+
49
+ # Remove the `admin` namespace
50
+ name.gsub! /admin\./, ''
51
+
52
+ # Extract params
53
+ url_params = content.scan(PATTERN_URL_PARAMS).map { |n| n.first }.sort
54
+
55
+ # Extract parts
56
+ url_parts = content.scan(PATTERN_URL_PARTS).map { |n| n.first }.sort
57
+
58
+ # Extract if body allowed
59
+ has_body = !!content.match(PATTERN_HAS_BODY)
60
+
61
+ # Extract HTTP method and path
62
+ content.scan(PATTERN_REST) do |method, path|
63
+ (map[name] ||= []) << { 'method' => method,
64
+ 'path' => path,
65
+ 'parts' => url_parts,
66
+ 'params' => url_params,
67
+ 'body' => has_body }
68
+ end
69
+
70
+ end
71
+
72
+ map
73
+ end
74
+
75
+ extend self
76
+ end
77
+
78
+ # Contains a generator which will parse the Elasticsearch *.java source files,
79
+ # extract information about REST API endpoints (URLs, HTTP methods, URL parameters, etc),
80
+ # and create a skeleton of the JSON API specification file for each endpoint.
81
+ #
82
+ # Usage:
83
+ #
84
+ # $ thor help api:generate:spec
85
+ #
86
+ # Example:
87
+ #
88
+ # time thor api:generate:spec \
89
+ # --force \
90
+ # --verbose \
91
+ # --crawl \
92
+ # --elasticsearch=/path/to/elasticsearch/source/code
93
+ #
94
+ # Features:
95
+ #
96
+ # * Extract the API name from the source filename (eg. `admin/cluster/health/RestClusterHealthAction.java` -> `cluster.health`)
97
+ # * Extract the URLs from the `registerHandler` statements
98
+ # * Extract the URL parts (eg. `{index}`) from the URLs
99
+ # * Extract the URL parameters (eg. `{timeout}`) from the `request.param("ABC")` statements
100
+ # * Detect whether HTTP body is allowed for the API from `request.hasContent()` statements
101
+ # * Search the <http://elasticsearch.org> website to get proper documentation URLs
102
+ # * Assemble the JSON format for the API spec
103
+ #
104
+ class JsonGenerator < Thor
105
+ namespace 'api:spec'
106
+
107
+ include Thor::Actions
108
+
109
+ __root = Pathname( File.expand_path('../../..', __FILE__) )
110
+
111
+ # Usage: thor help api:generate:spec
112
+ #
113
+ desc "generate", "Generate JSON API spec files from Elasticsearch source code"
114
+ method_option :force, type: :boolean, default: false, desc: 'Overwrite the output'
115
+ method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
116
+ method_option :output, default: __root.join('tmp/out'), desc: 'Path to output directory'
117
+ method_option :elasticsearch, default: __root.join('tmp/elasticsearch'), desc: 'Path to directory with Elasticsearch source code'
118
+ method_option :crawl, type: :boolean, default: false, desc: 'Extract URLs from Elasticsearch website'
119
+
120
+ def generate
121
+ self.class.source_root File.expand_path('../', __FILE__)
122
+
123
+ @output = Pathname(options[:output])
124
+
125
+ rest_actions = Utils.__parse_java_source(options[:elasticsearch].to_s)
126
+
127
+ if rest_actions.empty?
128
+ say_status 'ERROR', 'Cannot find Elasticsearch source in ' + options[:elasticsearch].to_s, :red
129
+ exit(1)
130
+ end
131
+
132
+ rest_actions.each do |name, info|
133
+ doc_url = ""
134
+ parts = info.reduce([]) { |sum, n| sum |= n['parts']; sum }.reduce({}) { |sum, n| sum[n] = {}; sum }
135
+ params = info.reduce([]) { |sum, n| sum |= n['params']; sum }.reduce({}) { |sum, n| sum[n] = {}; sum }
136
+
137
+ if options[:crawl]
138
+ begin
139
+ response = RestClient.get "http://search.elasticsearch.org/elastic-search-website/guide/_search?q=#{URI.escape(name.gsub(/\./, ' '))}"
140
+ hits = JSON.load(response)['hits']['hits']
141
+ if hit = hits.first
142
+ if hit['_score'] > 0.2
143
+ doc_title = hit['fields']['title']
144
+ doc_url = "http://elasticsearch.org" + hit['fields']['url']
145
+ end
146
+ end
147
+ rescue Exception => e
148
+ puts "[!] ERROR: #{e.inspect}"
149
+ end
150
+ end
151
+
152
+ spec = {
153
+ name => {
154
+ 'documentation' => doc_url,
155
+
156
+ 'methods' => info.map { |n| n['method'] }.uniq,
157
+
158
+ 'url' => {
159
+ 'path' => info.first['path'],
160
+ 'paths' => info.map { |n| n['path'] }.uniq,
161
+ 'parts' => parts,
162
+ 'params' => params
163
+ },
164
+
165
+ 'body' => info.first['body'] ? {} : nil
166
+ }
167
+ }
168
+
169
+ json = JSON.pretty_generate(spec, indent: ' ', array_nl: '', object_nl: "\n", space: ' ', space_before: ' ')
170
+
171
+ # Fix JSON array formatting
172
+ json.gsub!(/\[\s+/, '[')
173
+ json.gsub!(/, {2,}"/, ', "')
174
+
175
+ create_file @output.join( "#{name}.json" ), json + "\n"
176
+
177
+ if options[:verbose]
178
+ lines = json.split("\n")
179
+ say_status 'JSON',
180
+ lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n")
181
+ end
182
+ end
183
+ end
184
+
185
+ private
186
+
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,122 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thor'
4
+
5
+ require 'pathname'
6
+ require 'active_support/core_ext/hash/deep_merge'
7
+ require 'active_support/inflector'
8
+ require 'multi_json'
9
+ require 'coderay'
10
+ require 'pry'
11
+
12
+ module Elasticsearch
13
+
14
+ module API
15
+
16
+ # A command line application based on [Thor](https://github.com/wycats/thor),
17
+ # which will read the JSON API spec file(s), and generate
18
+ # the Ruby source code (one file per API endpoint) with correct
19
+ # module namespace, method names, and RDoc documentation,
20
+ # as well as test files for each endpoint.
21
+ #
22
+ # Currently it only generates Ruby source, but can easily be
23
+ # extended and adapted to generate source code for other
24
+ # programming languages.
25
+ #
26
+ class SourceGenerator < Thor
27
+ namespace 'api:code'
28
+
29
+ include Thor::Actions
30
+
31
+ __root = Pathname( File.expand_path('../../..', __FILE__) )
32
+
33
+ desc "generate <PATH TO JSON SPEC FILES>", "Generate source code and tests from the REST API JSON specification"
34
+ method_option :language, default: 'ruby', desc: 'Programming language'
35
+ method_option :force, type: :boolean, default: false, desc: 'Overwrite the output'
36
+ method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
37
+ method_option :input, default: File.expand_path('../../../../tmp/elasticsearch/rest-api-spec/api/**/*.json', __FILE__), desc: 'Path to directory with JSON API specs'
38
+ method_option :output, default: File.expand_path('../../../tmp/out', __FILE__), desc: 'Path to output directory'
39
+
40
+ def generate(*files)
41
+ self.class.source_root File.expand_path('../', __FILE__)
42
+
43
+ @input = Pathname(options[:input])
44
+ @output = Pathname(options[:output])
45
+
46
+ # -- Test helper
47
+ copy_file "templates/ruby/test_helper.rb", @output.join('test').join('test_helper.rb') if options[:language] == 'ruby'
48
+
49
+ Dir[@input].each do |file|
50
+ @path = Pathname(file)
51
+ @json = MultiJson.load( File.read(@path) )
52
+ @spec = @json.values.first
53
+ say_status 'json', @path, :yellow
54
+
55
+ @spec['url'] ||= {}
56
+ @spec['url']['parts'] ||= []
57
+ @spec['url']['params'] ||= {}
58
+
59
+ # say_status 'JSON', @spec.inspect, options[:verbose]
60
+
61
+ @full_namespace = @json.keys.first.split('.')
62
+ @namespace_depth = @full_namespace.size > 0 ? @full_namespace.size-1 : 0
63
+ @module_namespace = @full_namespace[0, @namespace_depth]
64
+ @method_name = @full_namespace.last
65
+
66
+ # -- Ruby files
67
+
68
+ @path_to_file = @output.join('api').join( @module_namespace.join('/') ).join("#{@method_name}.rb")
69
+
70
+ empty_directory @output.join('api').join( @module_namespace.join('/') )
71
+
72
+ template "templates/#{options[:language]}/method.erb", @path_to_file
73
+
74
+ if options[:verbose]
75
+ colorized_output = CodeRay.scan_file(@path_to_file, :ruby).terminal
76
+ lines = colorized_output.split("\n")
77
+ say_status options[:language].downcase,
78
+ lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n"),
79
+ :yellow
80
+ end
81
+
82
+ # --- Test files
83
+
84
+ @test_directory = @output.join('test/api').join( @module_namespace.join('/') )
85
+ @test_file = @test_directory.join("#{@method_name}_test.rb")
86
+
87
+ empty_directory @test_directory
88
+ template "templates/#{options[:language]}/test.erb", @test_file
89
+
90
+ if options[:verbose]
91
+ colorized_output = colorized_output = CodeRay.scan_file(@test_file, :ruby).terminal
92
+ lines = colorized_output.split("\n")
93
+ say_status options[:language].downcase,
94
+ lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n"),
95
+ :yellow
96
+ say '▬'*terminal_width
97
+ end
98
+ end
99
+
100
+ # -- Tree output
101
+
102
+ if options[:verbose] && `which tree > /dev/null 2>&1`
103
+ lines = `tree #{@output}`.split("\n")
104
+ say_status 'tree',
105
+ lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n")
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ # Create the hierarchy of directories based on API namespaces
112
+ #
113
+ def __create_directories(key, value)
114
+ unless value['documentation']
115
+ empty_directory @output.join(key)
116
+ create_directory_hierarchy *value.to_a.first
117
+ end
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'thor'
4
+
5
+ require 'pathname'
6
+
7
+ module Elasticsearch
8
+
9
+ module API
10
+
11
+ class Lister < Thor
12
+ namespace 'api'
13
+
14
+ desc "list <PATH DIRECTORY WITH JSON SPEC FILES>", "List all the REST API endpoints from the JSON specification"
15
+ method_option :verbose, type: :boolean, default: false, desc: 'Output more information'
16
+ method_option :format, default: 'text', desc: 'Output format (text, json)'
17
+ def list(directory)
18
+ input = Pathname(directory).join('*.json')
19
+ apis = Dir[input.to_s].map do |f|
20
+ File.basename(f, '.json')
21
+ end.sort
22
+
23
+ if options[:verbose]
24
+ say_status 'Count', apis.size
25
+ say '▬'*terminal_width
26
+ end
27
+
28
+ case options[:format]
29
+ when 'text'
30
+ apis.each { |a| puts "* #{a}" }
31
+ when 'json'
32
+ puts apis.inspect
33
+ else
34
+ puts "[!] ERROR: Unknown output format '#{options[:format]}'"
35
+ exit(1)
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,62 @@
1
+ module Elasticsearch
2
+ module API
3
+ <%- @module_namespace.each_with_index do |name, i| -%>
4
+ <%= ' '*i %>module <%= name.capitalize %>
5
+ <%- end -%>
6
+ <%= ' '*@namespace_depth %>module Actions
7
+
8
+ <%= ' '*@namespace_depth %># <%= @spec['description'] || 'TODO: Description' %>
9
+ <%= ' '*@namespace_depth %>#
10
+ <%# URL parts -%>
11
+ <%- @spec['url']['parts'].each do |name,info| -%>
12
+ <%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
13
+ <%= ' '*@namespace_depth + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description']}" + ( info['required'] ? ' (*Required*)' : '' ) -%><%= " (options: #{info['options'].join(', ')})" if info['options'] -%>
14
+ <%= "\n" -%>
15
+ <%- end -%>
16
+ <%# Body -%>
17
+ <%= ' '*(@namespace_depth+3) + '# @option arguments [Hash] :body ' + (@spec['body']['description'] || 'TODO: Description') + (@spec['body']['required'] ? ' (*Required*)' : '') + "\n" if @spec['body'] -%>
18
+ <%# URL parameters -%>
19
+ <%- @spec['url']['params'].each do |name,info| -%>
20
+ <%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
21
+ <%= ' '*@namespace_depth + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description']}" -%><%= " (options: #{info['options'].join(', ')})" if info['options'] -%>
22
+ <%= "\n" -%>
23
+ <%- end if @spec['url']['parts'] -%>
24
+ <%= ' '*@namespace_depth -%>#
25
+ <%# Documentation link -%>
26
+ <%= ' '*@namespace_depth %># @see <%= @spec['documentation'] %>
27
+ <%= ' '*@namespace_depth %>#
28
+ <%# Method definition -%>
29
+ <%= ' '*@namespace_depth -%>def <%= @method_name %>(arguments={})
30
+ <%# Required arguments -%>
31
+ <%- @spec['url']['parts'].select { |name, info| info['required'] }.each do |name, info| -%>
32
+ <%= ' '*(@namespace_depth+1) + "raise ArgumentError, \"Required argument '#{name}' missing\" unless arguments[:#{name}]" + "\n" -%>
33
+ <%- end -%>
34
+ <%- if @spec['body'] && @spec['body']['required'] -%>
35
+ <%= ' '*(@namespace_depth+1) + "raise ArgumentError, \"Required argument 'body' missing\" unless arguments[:body]" + "\n" -%>
36
+ <%- end -%>
37
+ <%# Method, path, params, body -%>
38
+ <%= ' '*@namespace_depth %> valid_params = [
39
+ <%= ' '*(@namespace_depth+2) %><%= @spec['url']['params'].keys.map { |k| ":#{k}" }.join(",\n#{' '*(@namespace_depth+5)}") %> ]
40
+ <%= ' '*@namespace_depth %> method = '<%= @spec['methods'].first %>'
41
+ <%- unless @spec['url']['parts'].empty? -%>
42
+ <%= ' '*@namespace_depth %> path = "<%= @spec['url']['path'].split('/').compact.reject {|p| p =~ /^\s*$/}.map do |p|
43
+ p =~ /\{/ ? "\#\{arguments[:#{p.tr('{}', '')}]\}" : p
44
+ end.join('/') %>"
45
+ <%- else -%>
46
+ <%= ' '*@namespace_depth %> path = "<%= @spec['url']['path'] %>"
47
+ <%- end -%>
48
+ <%- unless @spec['url']['params'].keys.empty? -%>
49
+ <%= ' '*@namespace_depth %> params = Utils.__validate_and_extract_params arguments, valid_params
50
+ <%- else -%>
51
+ <%= ' '*@namespace_depth %> params = {}
52
+ <%- end -%>
53
+ <%= ' '*@namespace_depth %> body = <%= @spec['body'].nil? ? 'nil' : 'arguments[:body]' %>
54
+ <%# Perform request %>
55
+ <%= ' '*@namespace_depth %> perform_request(method, path, params, body).body
56
+ <%= ' '*@namespace_depth %>end
57
+ <%- @namespace_depth.downto(1) do |i| -%>
58
+ <%= ' '*(i-1) %>end
59
+ <%- end if @namespace_depth > 0 -%>
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ module Elasticsearch
4
+ module Test
5
+ class <%= @module_namespace.empty? ? @method_name.camelize : @module_namespace.map {|n| n.capitalize}.join + @method_name.camelize %>Test < ::Test::Unit::TestCase
6
+
7
+ context "<%= @module_namespace.empty? ? '' : @module_namespace.map {|n| n.capitalize}.join + ': ' %><%= @method_name.humanize %>" do
8
+ subject { FakeClient.new }
9
+
10
+ should "perform correct request" do
11
+ subject.expects(:perform_request).with do |method, url, params, body|
12
+ assert_equal 'FAKE', method
13
+ assert_equal 'test', url
14
+ assert_equal Hash.new, params
15
+ <%= @spec['body'].nil? ? 'assert_nil body' : 'assert_equal Hash.new, body' %>
16
+ true
17
+ end.returns(FakeResponse.new)
18
+
19
+ subject.<%= @full_namespace.join('.') %>
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
26
+ end