class Swagger::Docs::Generator
Constants
- DEFAULT_CONFIG
- DEFAULT_VER
Public Class Methods
generate_doc(api_version, settings, config)
click to toggle source
# File lib/swagger/docs/generator.rb, line 63 def generate_doc(api_version, settings, config) root = { "swagger" => "2.0", # "info" => settings[:info], "host" => settings[:host], "basePath" => settings[:base_path], "schemes" => [ "http" ], :paths => {}, } results = {:processed => [], :skipped => []} resources = [] get_route_paths(settings[:controller_base_path]).each do |path| ret = process_path(path, root, config, settings) results[ret[:action]] << ret if ret[:action] == :processed resources << generate_resource(ret[:path], ret[:apis], ret[:models], settings, root, config, ret[:klass].swagger_config) debased_path = get_debased_path(ret[:path], settings[:controller_base_path]) ret[:apis] && ret[:apis].each do |rea| name = rea[:path].gsub('.json', '') name += '/' if root[:paths].has_key?(name) api_content = rea[:operations][0] description = ret[:klass].swagger_config[:description] resource_api = { # path: "/#{Config.transform_path(trim_leading_slash(debased_path), api_version)}.{format}", "#{name}" => { "#{api_content[:method]}" => { "summary" => api_content[:summary], "description" => description, "parameters" => api_content[:parameters].map{|pr| { "name" => pr[:name], "in" => pr[:param_type], "required" => pr[:required] ? true : false, "description" => pr[:description], "type" => pr[:type] } }, "responses" => { "200" => { "description" => description, "schema" => { # "type": "array", # "items": { # "properties": { # "firstName": { # "type": "string" # }, # "lastName": { # "type": "string" # }, # "username": { # "type": "string" # } # } # } } } } } } }.as_json # root[:apis] << resource_api root[:paths].merge!(resource_api) end end end root['resources'] = resources results[:root] = root results end
generate_docs(apis=nil)
click to toggle source
# File lib/swagger/docs/generator.rb, line 46 def generate_docs(apis=nil) apis ||= Config.registered_apis results = {} set_real_methods apis[DEFAULT_VER] = DEFAULT_CONFIG if apis.empty? apis.each do |api_version, config| settings = get_settings(api_version, config) config.reverse_merge!(DEFAULT_CONFIG) results[api_version] = generate_doc(api_version, settings, config) results[api_version][:settings] = settings results[api_version][:config] = config end results end
set_real_methods()
click to toggle source
# File lib/swagger/docs/generator.rb, line 16 def set_real_methods # replace impotent methods with live ones Config.base_api_controllers.each do |controller| controller.send(:include, Methods) end end
write_doc(result)
click to toggle source
# File lib/swagger/docs/generator.rb, line 28 def write_doc(result) settings = result[:settings] config = result[:config] create_output_paths(settings[:api_file_path]) clean_output_paths(settings[:api_file_path]) if config[:clean_directory] || false root = result[:root] resources = root.delete 'resources' root.merge!(config[:attributes] || {}) # merge custom user attributes like info # write the api-docs file write_to_file("#{settings[:api_file_path]}/#{config[:api_file_name]}", root, config) # write the individual resource files resources.each do |resource| resource_file_path = resource.delete 'resourceFilePath' write_to_file(File.join(settings[:api_file_path], "#{resource_file_path}.json"), resource, config) end result end
write_docs(apis = nil)
click to toggle source
# File lib/swagger/docs/generator.rb, line 23 def write_docs(apis = nil) results = generate_docs(apis) results.each{|api_version, result| write_doc(result) } end
Private Class Methods
camelize_keys_deep!(h)
click to toggle source
# File lib/swagger/docs/generator.rb, line 153 def camelize_keys_deep!(h) h.keys.each do |k| ks = k.to_s.camelize(:lower) h[ks] = h.delete k camelize_keys_deep! h[ks] if h[ks].kind_of? Hash if h[ks].kind_of? Array h[ks].each do |a| next unless a.kind_of? Hash camelize_keys_deep! a end end end end
clean_output_paths(api_file_path)
click to toggle source
# File lib/swagger/docs/generator.rb, line 302 def clean_output_paths(api_file_path) Dir.foreach(api_file_path) do |f| fn = File.join(api_file_path, f) File.delete(fn) if !File.directory?(fn) and File.extname(fn) == '.json' end end
create_output_paths(api_file_path)
click to toggle source
# File lib/swagger/docs/generator.rb, line 298 def create_output_paths(api_file_path) FileUtils.mkdir_p(api_file_path) # recursively create out output path end
filter_path_params(path, params)
click to toggle source
# File lib/swagger/docs/generator.rb, line 318 def filter_path_params(path, params) params.reject do |param| param_as_variable = "{#{param[:name]}}" param[:param_type] == :path && !path.include?(param_as_variable) end end
generate_resource(path, apis, models, settings, root, config, swagger_config)
click to toggle source
# File lib/swagger/docs/generator.rb, line 218 def generate_resource(path, apis, models, settings, root, config, swagger_config) metadata = ApiDeclarationFileMetadata.new( root["apiVersion"], path, root["basePath"], settings[:controller_base_path], camelize_model_properties: config.fetch(:camelize_model_properties, true), swagger_version: root["swaggerVersion"], authorizations: root[:authorizations], resource_path: swagger_config[:resource_path] ) declaration = ApiDeclarationFile.new(metadata, apis, models) declaration.generate_resource end
get_debased_path(path, controller_base_path)
click to toggle source
# File lib/swagger/docs/generator.rb, line 181 def get_debased_path(path, controller_base_path) path.gsub("#{controller_base_path}", "") end
get_klass_models(klass)
click to toggle source
# File lib/swagger/docs/generator.rb, line 257 def get_klass_models(klass) models = {} # Add any declared models to the root of the resource. klass.swagger_models.each do |model_name, model| formatted_model = { id: model[:id], required: model[:required], properties: model[:properties], } formatted_model[:description] = model[:description] if model[:description] models[model[:id]] = formatted_model end models end
get_route_path_apis(path, route, klass, settings, config)
click to toggle source
# File lib/swagger/docs/generator.rb, line 235 def get_route_path_apis(path, route, klass, settings, config) models, apis = {}, [] action = route.defaults[:action] verbs = route_verbs(route) return {apis: apis, models: models, nickname: nil} if !operation = klass.swagger_actions[action.to_sym] operation = Hash[operation.map {|k, v| [k.to_s.gsub("@","").to_sym, v.respond_to?(:deep_dup) ? v.deep_dup : v.dup] }] # rename :@instance hash keys nickname = operation[:nickname] = path_route_nickname(path, route) route_path = if defined?(route.path.spec) then route.path.spec else route.path end api_path = transform_spec_to_api_path(route_path, settings[:controller_base_path], config[:api_extension_type]) operation[:parameters] = filter_path_params(api_path, operation[:parameters]) if operation[:parameters] operations = verbs.collect{|verb| op = operation.dup op[:method] = verb op } apis << {:path => api_path, :operations => operations} models = get_klass_models(klass) {apis: apis, models: models, nickname: nickname} end
get_route_paths(controller_base_path)
click to toggle source
# File lib/swagger/docs/generator.rb, line 293 def get_route_paths(controller_base_path) paths = routes.map{|i| "#{i.defaults[:controller]}" } paths.uniq.select{|i| i.start_with?(controller_base_path)} end
get_settings(api_version, config)
click to toggle source
# File lib/swagger/docs/generator.rb, line 272 def get_settings(api_version, config) base_path = trim_trailing_slash(config[:base_path] || "") controller_base_path = trim_leading_slash(config[:controller_base_path] || "") base_path += "/#{controller_base_path}" unless controller_base_path.empty? api_file_path = config[:api_file_path] authorizations = config[:authorizations] # new version host = config[:host] info = config[:attributes][:info] settings = { base_path: base_path, controller_base_path: controller_base_path, api_file_path: api_file_path, authorizations: authorizations, info: info, host: host }.freeze end
nickname_defined?(defined_nicknames, path, route)
click to toggle source
# File lib/swagger/docs/generator.rb, line 212 def nickname_defined?(defined_nicknames, path, route) target_nickname = path_route_nickname(path, route) defined_nicknames.each{|nickname| return true if nickname == target_nickname } false end
path_route_nickname(path, route)
click to toggle source
# File lib/swagger/docs/generator.rb, line 207 def path_route_nickname(path, route) action = route.defaults[:action] "#{path.camelize}##{action}" end
process_path(path, root, config, settings)
click to toggle source
# File lib/swagger/docs/generator.rb, line 185 def process_path(path, root, config, settings) return {action: :skipped, reason: :empty_path} if path.empty? klass = Config.log_exception { "#{path.to_s.camelize}Controller".constantize } rescue nil return {action: :skipped, path: path, reason: :klass_not_present} if !klass return {action: :skipped, path: path, reason: :not_swagger_resource} if !klass.methods.include?(:swagger_config) or !klass.swagger_config[:controller] return {action: :skipped, path: path, reason: :not_kind_of_parent_controller} if config[:parent_controller] && !(klass < config[:parent_controller]) apis, models, defined_nicknames = [], {}, [] routes.select{|i| i.defaults[:controller] == path}.each do |route| unless nickname_defined?(defined_nicknames, path, route) # only add once for each route once e.g. PATCH, PUT ret = get_route_path_apis(path, route, klass, settings, config) apis = apis + ret[:apis] models.merge!(ret[:models]) defined_nicknames << ret[:nickname] if ret[:nickname].present? end end {action: :processed, path: path, apis: apis, models: models, klass: klass} end
route_verbs(route)
click to toggle source
# File lib/swagger/docs/generator.rb, line 203 def route_verbs(route) if defined?(route.verb.source) then route.verb.source.to_s.delete('$'+'^').split('|') else [route.verb] end.collect{|verb| verb.downcase.to_sym} end
routes()
click to toggle source
# File lib/swagger/docs/generator.rb, line 231 def routes Config.base_applications.map{|app| app.routes.routes.to_a }.flatten end
transform_spec_to_api_path(spec, controller_base_path, extension)
click to toggle source
# File lib/swagger/docs/generator.rb, line 145 def transform_spec_to_api_path(spec, controller_base_path, extension) api_path = spec.to_s.dup api_path.gsub!('(.:format)', extension ? ".#{extension}" : '') api_path.gsub!(/:(\w+)/, '{\1}') api_path.gsub!(controller_base_path, '') "/" + trim_slashes(api_path) end
trim_leading_slash(str)
click to toggle source
# File lib/swagger/docs/generator.rb, line 167 def trim_leading_slash(str) return str if !str str.gsub(/\A\/+/, '') end
trim_slashes(str)
click to toggle source
# File lib/swagger/docs/generator.rb, line 177 def trim_slashes(str) trim_leading_slash(trim_trailing_slash(str)) end
trim_trailing_slash(str)
click to toggle source
# File lib/swagger/docs/generator.rb, line 172 def trim_trailing_slash(str) return str if !str str.gsub(/\/+\z/, '') end
write_to_file(path, structure, config={})
click to toggle source
# File lib/swagger/docs/generator.rb, line 309 def write_to_file(path, structure, config={}) content = case config[:formatting] when :pretty; JSON.pretty_generate structure else; structure.to_json end FileUtils.mkdir_p File.dirname(path) File.open(path, 'w') { |file| file.write content } end