class Apipie::Extractor::ActionDescriptionUpdater

Public Class Methods

new(controller, action) click to toggle source
# File lib/apipie/extractor/writer.rb, line 235
def initialize(controller, action)
  @controller = controller
  @action = action
end

Public Instance Methods

generated?() click to toggle source
# File lib/apipie/extractor/writer.rb, line 240
def generated?
  old_header.include?(Apipie.configuration.generated_doc_disclaimer)
end
old_header() click to toggle source
# File lib/apipie/extractor/writer.rb, line 266
def old_header
  return @old_header if defined? @old_header
  @old_header = lines_above_method[/^\s*?#{Regexp.escape(Apipie.configuration.generated_doc_disclaimer)}.*/m]
  @old_header ||= lines_above_method[/^\s*?\b(api|params|error|example)\b.*/m]
  @old_header ||= ""
  @old_header.sub!(/\A\s*\n/,"")
  @old_header = align_indented(@old_header)
end
update(new_header) click to toggle source
# File lib/apipie/extractor/writer.rb, line 262
def update(new_header)
  overwrite_header(new_header)
end
update_apis(apis) click to toggle source
# File lib/apipie/extractor/writer.rb, line 244
def update_apis(apis)
  new_header = ""
  new_header << Apipie.configuration.generated_doc_disclaimer << "\n" if generated?
  new_header << generate_apis_code(apis)
  new_header << ensure_line_breaks(old_header.lines).reject do |line|
    line.include?(Apipie.configuration.generated_doc_disclaimer) ||
      line =~ /^api/
  end.join
  overwrite_header(new_header)
end
update_generated_description(desc) click to toggle source
# File lib/apipie/extractor/writer.rb, line 255
def update_generated_description(desc)
  if generated? || old_header.empty?
    new_header = generate_code(desc)
    overwrite_header(new_header)
  end
end
write!() click to toggle source
# File lib/apipie/extractor/writer.rb, line 275
def write!
  File.open(controller_path, "w") { |f| f << @controller_content }
  @changed=false
end

Protected Instance Methods

action_line() click to toggle source
# File lib/apipie/extractor/writer.rb, line 286
def action_line
  return @action_line if defined? @action_line
  @action_line = ensure_line_breaks(controller_content.lines).find_index { |line| line =~ /def \b#{@action}\b/ }
  raise ActionNotFound unless @action_line
  @action_line
end
align_indented(text) click to toggle source
# File lib/apipie/extractor/writer.rb, line 374
def align_indented(text)
  shift_left = ensure_line_breaks(text.lines).map { |l| l[/^\s*/].size }.min
  ensure_line_breaks(text.lines).map { |l| l[shift_left..-1] }.join
end
controller_content() click to toggle source
# File lib/apipie/extractor/writer.rb, line 297
def controller_content
  raise ControllerNotFound.new unless controller_path && File.exist?(controller_path)
  @controller_content ||= File.read(controller_path)
end
controller_content=(new_content) click to toggle source
# File lib/apipie/extractor/writer.rb, line 302
def controller_content=(new_content)
  return if @controller_name == new_content
  remove_instance_variable("@action_line")
  remove_instance_variable("@old_header")
  @controller_content=new_content
  @changed = true
end
controller_path() click to toggle source
# File lib/apipie/extractor/writer.rb, line 293
def controller_path
  @controller_path ||= Apipie::Extractor.controller_path(@controller.controller_path)
end
ensure_line_breaks(lines) click to toggle source

this method would be totally useless unless some clever guy desided that it would be great idea to change a behavior of “”.lines method to not include end of lines.

For more details:

https://github.com/puppetlabs/puppet/blob/0dc44695/lib/puppet/util/monkey_patches.rb
# File lib/apipie/extractor/writer.rb, line 427
def ensure_line_breaks(lines)
  if lines.to_a.size > 1 && lines.first !~ /\n\Z/
    lines.map { |l| l !~ /\n\Z/ ? (l << "\n") : l }.to_enum
  else
    lines
  end
end
generate_apis_code(apis) click to toggle source
# File lib/apipie/extractor/writer.rb, line 318
def generate_apis_code(apis)
  code = ""
  apis.sort_by {|a| a[:path] }.each do |api|
    desc = api[:desc]
    name = @controller.controller_name.gsub("_", " ")
    desc ||= case @action.to_s
             when "show", "create", "update", "destroy"
               name = name.singularize
               "#{@action.capitalize} #{name =~ /^[aeiou]/ ? "an" : "a"} #{name}"
             when "index"
               "List #{name}"
             end

    code << "api :#{api[:method]}, '#{api[:path]}'"
    code << ", '#{desc}'" if desc
    code << "\n"
  end
  return code
end
generate_code(desc) click to toggle source
# File lib/apipie/extractor/writer.rb, line 310
def generate_code(desc)
  code = "#{Apipie.configuration.generated_doc_disclaimer}\n"
  code << generate_apis_code(desc[:api])
  code << generate_params_code(desc[:params])
  code << generate_errors_code(desc[:errors])
  return code
end
generate_errors_code(errors) click to toggle source
# File lib/apipie/extractor/writer.rb, line 366
def generate_errors_code(errors)
  code = ""
  errors.sort_by {|e| e[:code] }.each do |error|
    code << "error code: #{error[:code]}\n"
  end
  code
end
generate_params_code(params, indent = "") click to toggle source
# File lib/apipie/extractor/writer.rb, line 338
def generate_params_code(params, indent = "")
  code = ""
  params.sort_by {|n,_| n }.each do |(name, desc)|
    desc[:type] = (desc[:type] && desc[:type].first) || Object
    code << "#{indent}param"
    if name =~ /\W/
      code << " :'#{name}'"
    else
      code << " :#{name}"
    end
    code << ", #{desc[:type].inspect}"
    if desc[:allow_nil]
      code << ", allow_nil: true"
    end
    if desc[:required]
      code << ", required: true"
    end
    if desc[:nested]
      code << " do\n"
      code << generate_params_code(desc[:nested], indent + "  ")
      code << "#{indent}end"
    else
    end
    code << "\n"
  end
  code
end
lines_above_method() click to toggle source

returns all the lines before the method that might contain the restpi descriptions not bulletproof but working for conventional Ruby code

# File lib/apipie/extractor/writer.rb, line 394
def lines_above_method
  added_lines = []
  lines_to_add = []
  block_level = 0
  ensure_line_breaks(controller_content.lines).first(action_line).reverse_each do |line|
    if line =~ /\s*\bend\b\s*/
      block_level += 1
    end
    if block_level > 0
      lines_to_add << line
    else
      added_lines << line
    end
    if line =~ /\s*\b(module|class|def)\b /
      break
    end
    if line =~ /do\s*(\|.*?\|)?\s*$/
      block_level -= 1
      if block_level == 0
        added_lines.concat(lines_to_add)
        lines_to_add = []
      end
    end
  end
  return added_lines.reverse.join
end
logger() click to toggle source
# File lib/apipie/extractor/writer.rb, line 282
def logger
  Extractor.logger
end
overwrite_header(new_header) click to toggle source
# File lib/apipie/extractor/writer.rb, line 379
def overwrite_header(new_header)
  overwrite_line_from = action_line
  overwrite_line_to = action_line
  unless old_header.empty?
    overwrite_line_from -= ensure_line_breaks(old_header.lines).count
  end
  lines = ensure_line_breaks(controller_content.lines).to_a
  indentation = lines[action_line][/^\s*/]
  self.controller_content= (lines[0...overwrite_line_from] +
                        [new_header.gsub(/^/,indentation)] +
                        lines[overwrite_line_to..-1]).join
end