lib/danger/plugin_support/plugin_parser.rb in danger-0.8.5 vs lib/danger/plugin_support/plugin_parser.rb in danger-0.9.0
- old
+ new
@@ -1,10 +1,10 @@
require 'json'
-=begin
+=begin
- So you want to improve this? Great. Hard thing is getting yourself into a position where you
+ So you want to improve this? Great. Hard thing is getting yourself into a position where you
have access to all the tokens, so here's something you should run in `bundle exec pry` to dig in:
require 'danger'
require 'yard'
parser = Danger::PluginParser.new "spec/fixtures/plugins/example_fully_documented.rb"
@@ -13,35 +13,33 @@
git = plugins.first
klass = git
parser.to_dict(plugins)
Then some helpers
-
+
attribute_meths = klass.attributes[:instance].values.map(&:values).flatten
methods = klass.meths - klass.inherited_meths - attribute_meths
usable_methods = methods.select { |m| m.visibility == :public }.reject { |m| m.name == :initialize }
-
the alternative, is to add
require 'pry'
binding.pry
anywhere inside the source code below.
=end
-
module Danger
class PluginParser
attr_accessor :registry
def initialize(paths)
raise "Path cannot be empty" if paths.empty?
- if paths.is_a? String
+ if paths.kind_of? String
@paths = [File.expand_path(paths)]
else
@paths = paths
end
end
@@ -54,11 +52,11 @@
YARD::Tags::Library.define_tag('availablity', :availablity)
files = ["lib/danger/plugin_support/plugin.rb"] + @paths
# This turns on YARD debugging
# $DEBUG = true
-
+
self.registry = YARD::Registry.load(files, true)
end
def classes_in_file
registry.all(:class).select { |klass| @paths.include? klass.file }
@@ -71,33 +69,80 @@
def to_json
plugins = plugins_from_classes(classes_in_file)
to_dict(plugins).to_json
end
- def to_dict(classes)
- d_meth = lambda do |meth|
- return nil if meth.nil?
- {
- name: meth.name,
- body_md: meth.docstring,
- params: meth.parameters,
- tags: meth.tags.map do |t|
- {
- name: t.tag_name,
- types: t.types
- }
- end
- }
+ # rubocop:disable Metrics/AbcSize
+
+ def method_return_string(meth)
+ return "" unless meth[:tags]
+
+ return_value = meth[:tags].find { |t| t[:name] == "return" && t[:types] }
+ return "" if return_value.nil?
+ return "" if return_value[:types].nil?
+ return "" unless return_value[:types].kind_of? Array
+
+ unless return_value.empty?
+ return "" if return_value[:types].first == "void"
+ return return_value[:types].first
end
+ ""
+ end
- d_attr = lambda do |attribute|
- {
- read: d_meth.call(attribute[:read]),
- write: d_meth.call(attribute[:write])
- }
+ def method_params(params)
+ return {} unless params[:params]
+
+ params_names = params[:params].compact.flat_map(&:first)
+ params_values = params[:tags].find { |t| t[:name] == "param" }
+
+ return {} if params_values.nil?
+ return {} if params_values[:types].nil?
+
+ return params_names.map.with_index do |name, index|
+ { name => params_values[:types][index] }
end
+ end
+ def method_parser(meth)
+ return nil if meth.nil?
+ method = {
+ name: meth.name,
+ body_md: meth.docstring,
+ params: meth.parameters,
+ tags: meth.tags.map { |t| { name: t.tag_name, types: t.types } }
+ }
+
+ return_v = method_return_string(method)
+ params_v = method_params(method)
+
+ # Pull out some derived data
+ method[:param_couplets] = params_v
+ method[:return] = return_v
+
+ # Create the center params, `thing: OK, other: Thing`
+ string_params = params_v.map do |param|
+ name = param.keys.first
+ param[name].nil? ? name : name + ": " + param[name]
+ end.join ", "
+
+ # Wrap it in () if there _are_ params
+ string_params = "(" + string_params + ")" unless string_params.empty?
+ # Append the return type if we have one
+ suffix = return_v.empty? ? "" : " -> #{return_v}"
+
+ method[:one_liner] = meth.name.to_s + string_params + suffix
+ method
+ end
+
+ def attribute_parser(attribute)
+ {
+ read: method_parser(attribute[:read]),
+ write: method_parser(attribute[:write])
+ }
+ end
+
+ def to_dict(classes)
classes.map do |klass|
# Adds the class being parsed into the ruby runtime, so that we can access it's instance_name
require klass.file
real_klass = Danger.const_get klass.name
attribute_meths = klass.attributes[:instance].values.map(&:values).flatten
@@ -107,18 +152,17 @@
{
name: klass.name.to_s,
body_md: klass.docstring,
instance_name: real_klass.instance_name,
- example_code: klass.tags.select { |t| t.tag_name == "example" }.map { |tag| {:title => tag.name, :text => tag.text} }.compact,
- attributes: klass.attributes[:instance].map do |pair|
- { pair.first => d_attr.call(pair.last) }
- end,
- methods: usable_methods.map { |m| d_meth.call(m) },
+ example_code: klass.tags.select { |t| t.tag_name == "example" }.map { |tag| { title: tag.name, text: tag.text } }.compact,
+ attributes: klass.attributes[:instance].map { |pair| { pair.first => attribute_parser(pair.last) } },
+ methods: usable_methods.map { |m| method_parser(m) },
tags: klass.tags.select { |t| t.tag_name == "tags" }.map(&:text).compact,
see: klass.tags.select { |t| t.tag_name == "see" }.map(&:name).map(&:split).flatten.compact,
file: klass.file.gsub(File.expand_path("."), "")
}
end
end
+ # rubocop:enable Metrics/AbcSize
end
end