X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;ds=sidebyside;f=vendor%2Frails%2Frailties%2Flib%2Fsource_annotation_extractor.rb;fp=vendor%2Frails%2Frailties%2Flib%2Fsource_annotation_extractor.rb;h=591fd6f6bd33ca6b250ddf3bba83b7e49931c030;hb=d115f2e23823271635bad69229a42cd8ac68debe;hp=0000000000000000000000000000000000000000;hpb=37cb670bf3ddde90b214e591f100ed4446469484;p=depot.git diff --git a/vendor/rails/railties/lib/source_annotation_extractor.rb b/vendor/rails/railties/lib/source_annotation_extractor.rb new file mode 100644 index 0000000..591fd6f --- /dev/null +++ b/vendor/rails/railties/lib/source_annotation_extractor.rb @@ -0,0 +1,102 @@ +# Implements the logic behind the rake tasks for annotations like +# +# rake notes +# rake notes:optimize +# +# and friends. See rake -T notes and railties/lib/tasks/annotations.rake. +# +# Annotation objects are triplets :line, :tag, :text that +# represent the line where the annotation lives, its tag, and its text. Note +# the filename is not stored. +# +# Annotations are looked for in comments and modulus whitespace they have to +# start with the tag optionally followed by a colon. Everything up to the end +# of the line (or closing ERb comment tag) is considered to be their text. +class SourceAnnotationExtractor + class Annotation < Struct.new(:line, :tag, :text) + + # Returns a representation of the annotation that looks like this: + # + # [126] [TODO] This algorithm is simple and clearly correct, make it faster. + # + # If +options+ has a flag :tag the tag is shown as in the example above. + # Otherwise the string contains just line and text. + def to_s(options={}) + s = "[%3d] " % line + s << "[#{tag}] " if options[:tag] + s << text + end + end + + # Prints all annotations with tag +tag+ under the root directories +app+, +lib+, + # and +test+ (recursively). Only filenames with extension +.builder+, +.rb+, + # +.rxml+, +.rjs+, +.rhtml+, or +.erb+ are taken into account. The +options+ + # hash is passed to each annotation's +to_s+. + # + # This class method is the single entry point for the rake tasks. + def self.enumerate(tag, options={}) + extractor = new(tag) + extractor.display(extractor.find, options) + end + + attr_reader :tag + + def initialize(tag) + @tag = tag + end + + # Returns a hash that maps filenames under +dirs+ (recursively) to arrays + # with their annotations. Only files with annotations are included, and only + # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ + # are taken into account. + def find(dirs=%w(app lib test)) + dirs.inject({}) { |h, dir| h.update(find_in(dir)) } + end + + # Returns a hash that maps filenames under +dir+ (recursively) to arrays + # with their annotations. Only files with annotations are included, and only + # those with extension +.builder+, +.rb+, +.rxml+, +.rjs+, +.rhtml+, and +.erb+ + # are taken into account. + def find_in(dir) + results = {} + + Dir.glob("#{dir}/*") do |item| + next if File.basename(item)[0] == ?. + + if File.directory?(item) + results.update(find_in(item)) + elsif item =~ /\.(builder|(r(?:b|xml|js)))$/ + results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/)) + elsif item =~ /\.(rhtml|erb)$/ + results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/)) + end + end + + results + end + + # If +file+ is the filename of a file that contains annotations this method returns + # a hash with a single entry that maps +file+ to an array of its annotations. + # Otherwise it returns an empty hash. + def extract_annotations_from(file, pattern) + lineno = 0 + result = File.readlines(file).inject([]) do |list, line| + lineno += 1 + next list unless line =~ pattern + list << Annotation.new(lineno, $1, $2) + end + result.empty? ? {} : { file => result } + end + + # Prints the mapping from filenames to annotations in +results+ ordered by filename. + # The +options+ hash is passed to each annotation's +to_s+. + def display(results, options={}) + results.keys.sort.each do |file| + puts "#{file}:" + results[file].each do |note| + puts " * #{note.to_s(options)}" + end + puts + end + end +end \ No newline at end of file