DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Ruby Rake::todo

04.02.2009
| 3358 views |
  • submit to reddit
        Simply reads the set directories, and scans the .rb files for @todo, will report the line before and line after @todo 
Needs console coloring to work: http://snippets.dzone.com/posts/show/7148

EDIT: After readind Michals comment i decided to change it, i hope it all works a bit faster now and doesnt have to give in on functionalities.

  # A probably controversial way of achieving different task effects
  @task_captures = @legend =  ""
  {:todo => :green, :fixme => :blue, :bug => "red blink"}.each do |task, eff|
    @task_captures += "#{task}|"
    
    methods = eff.to_s.split(/[\.\s]/).map{|e| ".console_#{e}" }.join().to_a.map {|e| 
      "def #{task}; self#{e}; end; "
    }.join()
    eval(%{class String; #{methods} end})
    
    @legend += eval(%{"#{task.to_s.upcase} ".#{task}})
  end
  @task_captures.gsub!(/(.)$/, "")
  puts ("Legend:".console_bold)+" #{@legend}"
  puts ""
  
  tasks = files = 0
  %w{. app config test lib}.each do |dir|
    Dir.entries(dir).each do |entry|
      next unless entry =~ /\.rb$/i
      files   += 1
      f_tasks  = 0
      
      (lines = IO.readlines("#{dir}/#{entry}")).each_with_index do |line, i|
        next if i==0 || i==(lines.size-1) || line.empty?
        
        next unless line.match(/^[\s]*\#.*?(#{@task_captures})[\s\:]*(.+?)$/i)
        
        puts eval(%{'#{$2}'.#{$1.downcase}()}).to_s + " on line: #{i}"
        puts "   \e[1mline before: \e[0m#{lines[i-1].chomp}" if (lines[i-1].match(/[^\s]/) || []).size > 0
        puts "   \e[1mline after: \e[0m#{lines[i+1].gsub!(/^[\s\#]*/, "")}"
        tasks   += 1
        f_tasks += 1
      end
      puts "#{f_tasks} task(s) in total for #{dir}/#{entry}\n".console_bold if f_tasks > 0
    end
  end
  puts "#{tasks} tasks over #{files} files".console_dark_yellow
    

Comments

Snippets Manager replied on Tue, 2009/03/31 - 7:43pm

each_line seems fine but it wouldn't allow me to look ahead in the file. Looking ahead and backwards was something that i wanted to achieve in this task, it gives me a quick peek at what is going on. So to get rid of the probably to big of a regexp i came up with following. It will allow to set the matching tags and effects on it simply by feeding it a hash. It also has the ability to look back and forward. I must say i have no idea how this will hold on large amount of files. # A probably controversial way of achieving different task effects @task_captures = @legend = "" {:todo => :green, :fixme => :blue, :bug => "red blink"}.each do |task, eff| @task_captures += "#{task}|" methods = eff.to_s.split(/[\.\s]/).map{|e| ".console_#{e}" }.join().to_a.map {|e| "def #{task}; self#{e}; end; " }.join() eval(%{class String; #{methods} end}) @legend += eval(%{"#{task.to_s.upcase} ".#{task}}) end @task_captures.gsub!(/(.)$/, "") puts ("Legend:".console_bold)+" #{@legend}" puts "" tasks = files = 0 %w{. app config test lib}.each do |dir| Dir.entries(dir).each do |entry| next unless entry =~ /\.rb$/i files += 1 f_tasks = 0 (lines = IO.readlines("#{dir}/#{entry}")).each_with_index do |line, i| next if i==0 || i==(lines.size-1) || line.empty? next unless line.match(/^[\s]*\#.*?(#{@task_captures})[\s\:]*(.+?)$/i) puts eval(%{'#{$2}'.#{$1.downcase}()}).to_s + " on line: #{i}" puts " \e[1mline before: \e[0m#{lines[i-1].chomp}" if (lines[i-1].match(/[^\s]/) || []).size > 0 puts " \e[1mline after: \e[0m#{lines[i+1].gsub!(/^[\s\#]*/, "")}" tasks += 1 f_tasks += 1 end puts "#{f_tasks} task(s) in total for #{dir}/#{entry}\n".console_bold if f_tasks > 0 end end puts "#{tasks} tasks over #{files} files".console_dark_yellow

Snippets Manager replied on Fri, 2009/01/02 - 3:33pm

How about using each_line on the file? I wanted to use TODO and FIXME and with them the original regexp was very slow on many files. So i simplified it. I also wanted to see the number of the line and file, so here is my version. ... files += 1 open(file) do |f| i = 0 f.each_line do |line| i+=1 if m = line.match(/\s*\#\s*(@todo|TODO|FIXME)(.*)/i) puts "\n#{m[1]} #{m[2]}" puts File.expand_path(file)+':'+i.to_s todos += 1 end end end ...