跳至内容 跳至搜索

实现 Rails::Command::NotesCommand 背后的逻辑。有关使用方法信息,请参见 rails notes --help

Annotation 对象是三元组 :line:tag:text,分别表示注释所在的行、其标签及其文本。请注意,文件名未存储。

在注释和模数空白处查找注释,它们必须以标签开头,可选地后跟冒号。从行尾(或关闭 ERB 注释标记)到行的结尾处的所有内容都被视为其文本。

命名空间
方法
D
E
F
N

属性

[R] tag

类公有方法

enumerate(tag = nil, options = {})

打印根目录 appconfigdblibtest(递归)下带有标签 tag 的所有注释。

如果 tagnil,则打印带有默认标签或已注册标签的注释。

可以使用 options 中的 :dirs 键显式设置特定目录。

Rails::SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true

如果 options 具有 :tag 标志,它将传递给每个注释的 to_s

有关将考虑在内文件扩展名的列表,请参见 SourceAnnotationExtractor#find_in

此类方法是 rails notes 命令的单个入口点。

# File railties/lib/rails/source_annotation_extractor.rb, line 145
def self.enumerate(tag = nil, options = {})
  tag ||= Annotation.tags.join("|")
  extractor = new(tag)
  dirs = options.delete(:dirs) || Annotation.directories
  extractor.display(extractor.find(dirs), options)
end

new(tag)

# File railties/lib/rails/source_annotation_extractor.rb, line 154
def initialize(tag)
  @tag = tag
end

实例公有方法

display(results, options = {})

以文件名顺序打印从文件名到 results 中注释的映射。options 哈希传递给每个注释的 to_s

# File railties/lib/rails/source_annotation_extractor.rb, line 203
def display(results, options = {})
  options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
  results.keys.sort.each do |file|
    puts "#{file}:"
    results[file].each do |note|
      puts "  * #{note.to_s(options)}"
    end
    puts
  end
end

find(dirs)

返回一个哈希,该哈希将 dirs 下的文件名(递归)映射到具有其注释的数组。

# File railties/lib/rails/source_annotation_extractor.rb, line 160
def find(dirs)
  dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
end

find_in(dir)

返回一个哈希,该哈希将 dir 下的文件名(递归)映射到具有其注释的数组。考虑在 Rails::SourceAnnotationExtractor::Annotation.extensions 中注册扩展名的文件。仅包含具有注释的文件。

# File railties/lib/rails/source_annotation_extractor.rb, line 168
def find_in(dir)
  results = {}

  Dir.glob("#{dir}/*") do |item|
    next if File.basename(item).start_with?(".")

    if File.directory?(item)
      results.update(find_in(item))
    else
      extension = Annotation.extensions.detect do |regexp, _block|
        regexp.match(item)
      end

      if extension
        pattern = extension.last.call(tag)

        # In case a user-defined pattern returns nothing for the given set
        # of tags, we exit early.
        next unless pattern

        # If a user-defined pattern returns a regular expression, we will
        # wrap it in a PatternExtractor to keep the same API.
        pattern = PatternExtractor.new(pattern) if pattern.is_a?(Regexp)

        annotations = pattern.annotations(item)
        results.update(item => annotations) if annotations.any?
      end
    end
  end

  results
end