Class: PinkSpoon::DocExtractor
- Inherits:
-
Object
- Object
- PinkSpoon::DocExtractor
- Defined in:
- lib/pink_spoon/doc_extractor.rb
Overview
Fetches YARD/RDoc comments from installed gem source files for a given type + method. Handles both regular ‘def` and DSL-style definitions like `define_example_method :it` or `define_example_group_method :describe`.
Gem lookup uses the downcased first namespace component so that ‘RSpec::Core::ExampleGroup` correctly finds the `rspec-core` gem rather than trying the broken underscore form `r_spec`.
Instance Method Summary collapse
-
#extract(type, method_name) ⇒ Object
Returns a markdown string with the doc comment, or nil.
-
#extract_for_constant(type) ⇒ Object
Returns markdown docs for a class/module/constant.
-
#find_constant_source(type) ⇒ Object
Returns { file: absolute_path, line: integer } for a class/module definition.
-
#find_ivar_in_type(type, ivar_name) ⇒ Object
Returns { file:, line: } for the first assignment of ivar_name (@foo = …) in any source file belonging to the given type’s gem or project.
-
#find_source(type, method_name) ⇒ Object
Returns { file: absolute_path, line: integer } or nil.
-
#initialize(root_path) ⇒ DocExtractor
constructor
A new instance of DocExtractor.
Constructor Details
#initialize(root_path) ⇒ DocExtractor
Returns a new instance of DocExtractor.
12 13 14 15 |
# File 'lib/pink_spoon/doc_extractor.rb', line 12 def initialize(root_path) @root_path = root_path @cache = {} end |
Instance Method Details
#extract(type, method_name) ⇒ Object
Returns a markdown string with the doc comment, or nil.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/pink_spoon/doc_extractor.rb', line 95 def extract(type, method_name) cache_key = "doc:#{type}##{method_name}" return @cache[cache_key] if @cache.key?(cache_key) @cache[cache_key] = begin loc = find_location(type, method_name) if loc raw = read_comments(loc[:file], loc[:line]) raw.empty? ? nil : render(raw) end end rescue nil end |
#extract_for_constant(type) ⇒ Object
Returns markdown docs for a class/module/constant. When there is a YARD comment above the definition, renders it. When there is no comment, falls back to showing the declaration line itself.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/pink_spoon/doc_extractor.rb', line 63 def extract_for_constant(type) cache_key = "const_doc:#{type}" return @cache[cache_key] if @cache.key?(cache_key) @cache[cache_key] = begin loc = find_constant_location(type) if loc raw = read_comments(loc[:file], loc[:line]) if raw.empty? decl = declaration_line(loc[:file], loc[:line]) decl ? "```ruby\n#{decl}\n```" : nil else render(raw) end end end rescue nil end |
#find_constant_source(type) ⇒ Object
Returns { file: absolute_path, line: integer } for a class/module definition.
51 52 53 54 55 56 57 58 |
# File 'lib/pink_spoon/doc_extractor.rb', line 51 def find_constant_source(type) cache_key = "const_loc:#{type}" return @cache[cache_key] if @cache.key?(cache_key) @cache[cache_key] = find_constant_location(type) rescue nil end |
#find_ivar_in_type(type, ivar_name) ⇒ Object
Returns { file:, line: } for the first assignment of ivar_name (@foo = …) in any source file belonging to the given type’s gem or project.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pink_spoon/doc_extractor.rb', line 19 def find_ivar_in_type(type, ivar_name) cache_key = "ivar:#{type}##{ivar_name}" return @cache[cache_key] if @cache.key?(cache_key) @cache[cache_key] = begin escaped = Regexp.escape(ivar_name) pattern = /#{escaped}\s*=/ hint = type.split("::").first.to_s.downcase gem_dirs_for(hint).each do |gem_dir| Dir.glob("#{gem_dir}/lib/**/*.rb").sort.each do |file| line = first_line_matching(file, pattern) return { file: file, line: line } if line end end %w[lib app].each do |subdir| dir = File.join(@root_path, subdir) next unless File.directory?(dir) Dir.glob("#{dir}/**/*.rb").sort.each do |file| line = first_line_matching(file, pattern) return { file: file, line: line } if line end end nil end rescue nil end |
#find_source(type, method_name) ⇒ Object
Returns { file: absolute_path, line: integer } or nil.
85 86 87 88 89 90 91 92 |
# File 'lib/pink_spoon/doc_extractor.rb', line 85 def find_source(type, method_name) cache_key = "loc:#{type}##{method_name}" return @cache[cache_key] if @cache.key?(cache_key) @cache[cache_key] = find_location(type, method_name) rescue nil end |