Skip to content

Commit c2b1fb5

Browse files
committed
[API] Refactor Generator and required parameters
1 parent 0fd7cfb commit c2b1fb5

File tree

2 files changed

+82
-53
lines changed

2 files changed

+82
-53
lines changed

elasticsearch-api/utils/thor/generate_source.rb

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
require 'pry'
1515

1616
module Elasticsearch
17-
1817
module API
19-
2018
# A command line application based on [Thor](https://github.com/wycats/thor),
2119
# which will read the JSON API spec file(s), and generate
2220
# the Ruby source code (one file per API endpoint) with correct
@@ -55,40 +53,28 @@ def generate(*files)
5553

5654
files.each do |filepath|
5755
file = @input.join(filepath)
58-
5956
@path = Pathname(file)
6057
@json = MultiJson.load( File.read(@path) )
61-
6258
@spec = @json.values.first
6359
say_status 'json', @path, :yellow
6460

6561
@spec['url'] ||= {}
6662

67-
# say_status 'JSON', @spec.inspect, options[:verbose]
68-
6963
@full_namespace = @json.keys.first.split('.')
70-
@namespace_depth = @full_namespace.size > 0 ? @full_namespace.size-1 : 0
64+
@namespace_depth = @full_namespace.size > 0 ? @full_namespace.size - 1 : 0
7165
@module_namespace = @full_namespace[0, @namespace_depth]
7266
@method_name = @full_namespace.last
7367

7468
@parts = __endpoint_parts
7569
@params = @spec['params'] || {}
76-
7770
method = @spec['url']['paths'].map { |a| a['methods'] }.flatten.first
7871
@http_method = "HTTP_#{method}"
79-
@http_path_params = __path_params
80-
@http_path = unless false
81-
@spec['url']['paths'].first['path']
82-
.split('/')
83-
.compact
84-
.reject { |p| p =~ /^\s*$/ }
85-
.map { |p| p =~ /\{/ ? "\#\{arguments[:#{p.tr('{}', '')}]\}" : p }
86-
.join('/')
87-
.gsub(/^\//, '')
88-
else
89-
@spec['url']['paths'].first.gsub(/^\//, '')
90-
end
91-
# -- Ruby files
72+
@paths = @spec['url']['paths'].reject { |p| p['path'].include? 'type' }.map { |b| b['path'] }
73+
# TODO : Temporary Hack for deprecated method
74+
next if @method_name == 'exists_type'
75+
76+
@http_path = __http_path
77+
@required_parts = __required_parts
9278

9379
@path_to_file = @output.join('api').join( @module_namespace.join('/') ).join("#{@method_name}.rb")
9480

@@ -98,7 +84,7 @@ def generate(*files)
9884

9985
if options[:verbose]
10086
colorized_output = CodeRay.scan_file(@path_to_file, :ruby).terminal
101-
lines = colorized_output.split("\n")
87+
lines = colorized_output.split("\n")
10288
say_status 'ruby',
10389
lines.first + "\n" + lines[1, lines.size].map { |l| ' '*14 + l }.join("\n"),
10490
:yellow
@@ -142,6 +128,8 @@ def __create_directories(key, value)
142128
end
143129
end
144130

131+
# Extract parts from each path
132+
#
145133
def __endpoint_parts
146134
parts = @spec['url']['paths'].select do |a|
147135
a.keys.include?('parts')
@@ -151,15 +139,55 @@ def __endpoint_parts
151139
(parts.first || [])
152140
end
153141

154-
def __path_params
155-
return nil if @parts.empty? || @parts.nil?
156-
params = []
157-
@parts.each do |name, _|
158-
params << "Utils.__listify(_#{name})"
142+
def __http_path
143+
return "\"#{__parse_path(@paths.first)}\"" if @paths.size == 1
144+
result = ''
145+
146+
@paths.sort { |a, b| b.length <=> a.length }.each_with_index do |path, i|
147+
var_string = __extract_path_variables(path).map { |var| "_#{var}" }.join(' && ')
148+
result += if i == 0
149+
"if #{var_string}\n"
150+
elsif i == @paths.size - 1
151+
"else\n"
152+
else
153+
"elsif #{var_string}\n"
154+
end
155+
result += "\"#{__parse_path(path)}\"\n"
159156
end
160-
', ' + params.join(', ')
157+
result += 'end'
158+
result
161159
end
162160

161+
def __parse_path(path)
162+
path.gsub(/^\//, '')
163+
.gsub('{', '#{Utils.__listify(_')
164+
.gsub('}', ')}')
165+
end
166+
167+
def __path_variables
168+
@paths.map do |path|
169+
__extract_path_variables(path)
170+
end
171+
end
172+
173+
# extract values that are in the {var} format:
174+
def __extract_path_variables(path)
175+
path.scan(/{(\w+)}/).flatten
176+
end
177+
178+
# Find parts that are definitely required and should raise an error if
179+
# they're not present
180+
#
181+
def __required_parts
182+
required = []
183+
# TODO Looks like this is not right:
184+
required << 'body' if (@spec['body'] && @spec['body']['required'])
185+
186+
# Get required variables from paths:
187+
req_variables = __path_variables.inject(:&) # find intersection
188+
required << req_variables unless req_variables.empty?
189+
required.flatten
190+
end
163191
end
164192
end
165193
end

elasticsearch-api/utils/thor/templates/method.erb

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,57 @@ module Elasticsearch
99
<%- end -%>
1010
<%= ' '*(@namespace_depth+2) %>module Actions
1111
<%- if @spec['documentation']['description'] %>
12-
<%= ' '*(@namespace_depth+3) %># <%= @spec['documentation']['description'].gsub("\n", "\n#{' '*(@namespace_depth+3)}# ") %>
12+
<%= ' '*(@namespace_depth+3) %># <%= @spec['documentation']['description'].gsub("\n", "\n#{' '*(@namespace_depth+3)}# ") %>
1313
<%- else %>
14-
<%= ' '*(@namespace_depth+3) %># TODO: Description %>
14+
<%= ' '*(@namespace_depth+3) %># TODO: Description
1515
<%- end %>
1616
<%= ' '*(@namespace_depth+3) %>#
1717
<%- unless @parts.nil? || @parts.empty? %><%# URL parts -%>
18-
<%- @parts.each do |name, info| -%>
19-
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
20-
<%= ' '*(@namespace_depth+3) + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description'] ? info['description'].strip : '[TODO]'}" + ( info['required'] ? ' (*Required*)' : '' ) -%>
21-
<%= " (options: #{info['options'].join(', '.strip)})" if info['options'] -%>
22-
<%= "\n" -%>
23-
<%- end -%>
18+
<%- @parts.each do |name, info| -%>
19+
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
20+
<%= ' '*(@namespace_depth+3) + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description'] ? info['description'].strip : '[TODO]'}" + ( info['required'] ? ' (*Required*)' : '' ) -%>
21+
<%= " (options: #{info['options'].join(', '.strip)})" if info['options'] -%>
22+
<%= "\n" -%>
23+
<%- end -%>
2424
<%- end -%><%# Body -%>
2525
<%= ' '*(@namespace_depth+3) + '# @option arguments [Hash] :body ' + (@spec['body']['description'] ? @spec['body']['description'].strip : 'TODO: Description') + (@spec['body']['required'] ? ' (*Required*)' : '') + "\n" if @spec['body'] -%>
2626

2727
<%# URL parameters -%>
2828
<%- @params.each do |name,info| -%>
29-
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
30-
<%= ' '*(@namespace_depth+5) + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description'] ? info['description'].strip : '[TODO]'}" -%>
31-
<%= ' '*(@namespace_depth+5) +" (options: #{info['options'].join(', ')})" if info['options'] -%>
32-
<%= "\n" -%>
29+
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
30+
<%= ' '*(@namespace_depth+5) + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description'] ? info['description'].strip : '[TODO]'}" -%>
31+
<%= ' '*(@namespace_depth+5) +" (options: #{info['options'].join(', ')})" if info['options'] -%>
32+
<%= "\n" -%>
3333
<%- end if @spec['url']['parts'] -%>
3434
<%= ' '*(@namespace_depth+3) -%>#
3535
<%# Documentation link -%>
3636
<%= ' '*(@namespace_depth+3) %># @see <%= @spec['documentation']['url'] ? @spec['documentation']['url'] : "[TODO]" %>
3737
<%= ' '*(@namespace_depth+3) %>#
3838
<%# Method definition -%>
3939
<%= ' '*(@namespace_depth+3) -%>def <%= @method_name %>(arguments={})
40-
<%# Arguments -%>
40+
<%- @required_parts.each do |required| %><%# Arguments -%>
41+
<%= ' '*(@namespace_depth+4) + "raise ArgumentError, \"Required argument '#{required}' missing\" unless arguments[:#{required}]" + "\n" -%>
42+
<%- end -%>
4143
<%= ' '*(@namespace_depth+4) %>arguments = arguments.clone
4244
<%- @parts.each do |name, info| %>
43-
<%- if info['required'] %>
44-
<%= ' '*(@namespace_depth+3) + "raise ArgumentError, \"Required argument '#{name}' missing\" unless arguments[:#{name}]" + "\n" -%>
45-
<%- end -%>
46-
<%= ' '*(@namespace_depth+4) + "_#{name}" %> = arguments.delete(:<%=name %>)
47-
<%- end -%>
48-
<%- if @spec['body'] && @spec['body']['required'] -%>
49-
<%= ' '*(@namespace_depth+3) + "raise ArgumentError, \"Required argument 'body' missing\" unless arguments[:body]" + "\n" -%>
45+
<%= ' '*(@namespace_depth+3) + "_#{name}" %> = arguments.delete(:<%=name %>)
5046
<%- end -%>
5147

48+
<%# This is where I need to check what's available %>
5249
<%= ' '*(@namespace_depth+4) %>method = <%= @http_method %>
53-
<%= ' '*(@namespace_depth+4) %>path = Utils.__pathify "<%= @http_path %>"<%= @http_path_params %>
50+
<%= ' '*(@namespace_depth+4) %>path = <%= @http_path %>
5451
<%- unless @params.empty? -%>
55-
<%= ' '*(@namespace_depth+4) %>params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__)
52+
<%= ' '*(@namespace_depth+4) %>params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__)
5653
<%- else -%>
57-
<%= ' '*(@namespace_depth+4) %>params = {}
54+
<%= ' '*(@namespace_depth+4) %>params = {}
5855
<%- end -%>
5956
<%= ' '*(@namespace_depth+4) %>body = <%= @spec['body'].nil? ? 'nil' : 'arguments[:body]' %>
6057
<%# Perform request %>
61-
<%= ' '*(@namespace_depth+4) %>perform_request(method, path, params, body).body
58+
<% if ['bulk', 'msearch', 'msearch_template'].include? @method_name %>
59+
<%= ' '*(@namespace_depth+3) %> perform_request(method, path, params, body, {"Content-Type" => "application/x-ndjson"}).body
60+
<% else %>
61+
<%= ' '*(@namespace_depth+3) %>perform_request(method, path, params, body).body
62+
<% end %>
6263
<%= ' '*(@namespace_depth+3) %>end
6364
6465
<%# Method, path, params, body -%>
@@ -68,7 +69,7 @@ module Elasticsearch
6869
<%= ' '*(@namespace_depth+3) %># @since 6.2.0
6970
<%- unless @params.empty? -%>
7071
<%= ' '*(@namespace_depth+3) %>ParamsRegistry.register(:<%= @method_name %>, [
71-
<%= ' '*(@namespace_depth+4) %><%= @params.keys.map { |k| ":#{k}" }.join(",\n#{' '*(@namespace_depth+5)}") %>
72+
<%= ' '*(@namespace_depth+4) %><%= @params.keys.map { |k| ":#{k}" }.join(",\n#{' '*(@namespace_depth+4)}") %>
7273
<%= ' '*(@namespace_depth+3) %>].freeze)
7374
<%- end -%>
7475

0 commit comments

Comments
 (0)