class FlogCLI
def self.load_plugins
def self.load_plugins # TODO: I think I want to do this more like hoe's plugin system. Generalize? loaded, found = {}, {} Gem.find_files("flog/*.rb").reverse.each do |path| found[File.basename(path, ".rb").intern] = path end found.each do |name, plugin| next if loaded[name] begin warn "loading #{plugin}" # if $DEBUG loaded[name] = load plugin rescue LoadError => e warn "error loading #{plugin.inspect}: #{e.message}. skipping..." end end self.plugins.merge loaded names = Flog.constants.map {|s| s.to_s}.reject {|n| n =~ /^[A-Z_]+$/} names.each do |name| # next unless Hoe.plugins.include? name.downcase.intern mod = Flog.const_get(name) next if Class === mod warn "extend #{mod}" if $DEBUG # self.extend mod end end
def self.parse_options args = ARGV, extra_options = {}
def self.parse_options args = ARGV, extra_options = {} option = { :quiet => false, :continue => false, :parser => RubyParser, }.merge extra_options OptionParser.new do |opts| opts.separator "Standard options:" opts.on("-a", "--all", "Display all flog results, not top 60%.") do option[:all] = true end opts.on("-b", "--blame", "Include blame information for methods.") do option[:blame] = true end opts.on("-c", "--continue", "Continue despite syntax errors.") do option[:continue] = true end opts.on("-d", "--details", "Show method details.") do option[:details] = true end opts.on("-g", "--group", "Group and sort by class.") do option[:group] = true end opts.on("-h", "--help", "Show this message.") do puts opts exit end opts.on("-I dir1,dir2,dir3", Array, "Add to LOAD_PATH.") do |dirs| dirs.each do |dir| $: << dir end end opts.on("-m", "--methods-only", "Skip code outside of methods.") do option[:methods] = true end opts.on("-q", "--quiet", "Don't show parse errors.") do option[:quiet] = true end opts.on("-e", "--extended", "Put file:line on a separate line (for rubymine & friends).") do option[:extended] = true end opts.on("-s", "--score", "Display total score only.") do option[:score] = true end opts.on("-tN", "--threshold=N", Integer, "Set the report cutoff threshold (def: 60%).") do |n| option[:threshold] = n / 100.0 end opts.on("-v", "--verbose", "Display progress during processing.") do option[:verbose] = true end next if self.plugins.empty? opts.separator "Plugin options:" extra = self.method_scores.grep(/parse_options/) - %w(parse_options) extra.sort.each do |msg| self.send msg, opts, option end end.parse! Array(args) option end
def self.plugins
def self.plugins @plugins ||= {} end
def self.run args = ARGV, extra = {}
def self.run args = ARGV, extra = {} load_plugins expander = PathExpander.new args, "**/*.{rb,rake}" files = expander.process options = parse_options args, extra abort "no files or stdin (-) to process, aborting." if files.empty? and args.empty? flogger = new options flogger.flog(*files) flogger.report end
def flog(*files)
def flog(*files) files << "-" if files.empty? @flog.flog(*files) end
def initialize options = {}
def initialize options = {} @flog = Flog.new options end
def output_details io, max = nil
def output_details io, max = nil io.puts each_by_score max do |class_method, score, call_list| self.print_score io, class_method, score if option[:details] then call_list.sort_by { |k,v| -v }.each do |call, count| io.puts " %6.1f: %s" % [count, call] end io.puts end end end
def output_details_grouped io, threshold = nil
def output_details_grouped io, threshold = nil calculate scores.sort_by { |_, n| -n }.each do |klass, total| io.puts io.puts "%8.1f: %s" % [total, "#{klass} total"] method_scores[klass].each do |name, score| self.print_score io, name, score end end end
def print_score io, name, score
def print_score io, name, score location = method_locations[name] if location then sep = " " sep = "%-11s" % "\n" if option[:extended] io.puts "%8.1f: %-32s%s%s" % [score, name, sep, location] else io.puts "%8.1f: %s" % [score, name] end end
def report(io = $stdout)
def report(io = $stdout) io.puts "%8.1f: %s" % [total_score, "flog total"] io.puts "%8.1f: %s" % [average, "flog/method average"] return if option[:score] if option[:group] then output_details_grouped io, threshold else output_details io, threshold end ensure self.reset end