Karel Minarik faa0ee14bd [UTIL] Added a source code generator using the JSON API specs
The generator is based on [Thor](https://github.com/wycats/thor),
a library/framework for command line applications.

The generator will read the JSON API spec file(s), and generate
the Ruby source code (one file per API endpoint) with correct
module namespace, method names, and RDoc documentation.

It will generate a test file for each API endpoint as well.

Currently it only generates Ruby source, but can easily be
extended and adapted to generate source code for other
programming languages.

Usage example:

    $ thor api:code:generate ../../api-spec/*.json --force --verbose
2013-06-16 23:25:08 +02:00

60 lines
3.2 KiB
Plaintext

module Elasticsearch
module API
<%- @module_namespace.each_with_index do |name, i| -%>
<%= ' '*i %>module <%= name.capitalize %>
<%- end -%>
<%= ' '*@namespace_depth %>module Actions
<%= ' '*@namespace_depth %># <%= @spec['description'] || 'TODO: Description' %>
<%= ' '*@namespace_depth %>#
<%# URL parts -%>
<%- @spec['url']['parts'].each do |name,info| -%>
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
<%= ' '*@namespace_depth + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description']}" + ( info['required'] ? ' (*Required*)' : '' ) -%><%= " (options: #{info['options'].join(', ')})" if info['options'] -%>
<%= "\n" -%>
<%- end -%>
<%# Body -%>
<%= ' '*(@namespace_depth+3) + '# @option arguments [Hash] :body ' + (@spec['body']['description'] || 'TODO: Description') + "\n" if @spec['body'] -%>
<%# URL parameters -%>
<%- @spec['url']['params'].each do |name,info| -%>
<%- info['type'] = 'String' if info['type'] == 'enum' # Rename 'enums' to 'strings' -%>
<%= ' '*@namespace_depth + "# @option arguments [#{info['type'] ? info['type'].capitalize : 'String'}] :#{name} #{info['description']}" -%><%= " (options: #{info['options'].join(', ')})" if info['options'] -%>
<%= "\n" -%>
<%- end -%>
<%= ' '*@namespace_depth -%>#
<%# Documentation link -%>
<%= ' '*@namespace_depth %># @see <%= @spec['documentation'] %>
<%= ' '*@namespace_depth %>#
<%# Method definition -%>
<%= ' '*@namespace_depth -%>def <%= @method_name %>(arguments={})
<%# Required arguments -%>
<%- @spec['url']['parts'].select { |name, info| info['required'] }.each do |name, info| -%>
<%= ' '*(@namespace_depth+1) + "raise ArgumentError, \"Required argument '#{name}' missing\" unless arguments[:#{name}]" + "\n" -%>
<%- end -%>
<%# Method, path, params, body -%>
<%= ' '*@namespace_depth %> method = '<%= @spec['methods'].first %>'
<%- unless @spec['url']['parts'].empty? -%>
<%= ' '*@namespace_depth %> path = "<%= @spec['url']['path'].split('/').compact.reject {|p| p =~ /^\s*$/}.map do |p|
p =~ /\{/ ? "\#\{arguments[:#{p.tr('{}', '')}]\}" : p
end.join('/') %>"
<%- else -%>
<%= ' '*@namespace_depth %> path = "<%= @spec['url']['path'] %>"
<%- end -%>
<%- unless @spec['url']['params'].keys.empty? -%>
<%= ' '*@namespace_depth %> params = arguments.select do |k,v|
<%= ' '*@namespace_depth %> [ :<%= @spec['url']['params'].keys.join(",\n#{' '*(@namespace_depth+6)}:") %> ].include?(k)
<%= ' '*@namespace_depth %> end
<%= ' '*@namespace_depth %> # Normalize Ruby 1.8 and Ruby 1.9 Hash#select behaviour
<%= ' '*@namespace_depth %> params = Hash[params] unless params.is_a?(Hash)
<%- end -%>
<%= ' '*@namespace_depth %> body = <%= @spec['body'].nil? ? 'nil' : '"TODO: Body specification missing"' %>
<%# Perform request %>
<%= ' '*@namespace_depth %> perform_request(method, path, params, body).body
<%= ' '*@namespace_depth %>end
<%- @namespace_depth.downto(1) do |i| -%>
<%= ' '*(i-1) %>end
<%- end if @namespace_depth > 0 -%>
end
end
end