Class: FlogCLI

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/flog_cli.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ FlogCLI

Creates a new Flog instance with options.



176
177
178
# File 'lib/flog_cli.rb', line 176

def initialize options = {}
  @flog = Flog.new options
end

Class Method Details

.load_pluginsObject

Loads all flog plugins. Files must be named “flog/*.rb”.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/flog_cli.rb', line 35

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

.parse_options(args = ARGV) ⇒ Object

Parse options in args (defaults to ARGV).



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/flog_cli.rb', line 69

def self.parse_options args = ARGV
  option = {
    :quiet    => false,
    :continue => false,
    :parser   => RubyParser,
  }

  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

    opts.on("--18", "Use a ruby 1.8 parser.") do
      option[:parser] = Ruby18Parser
    end

    opts.on("--19", "Use a ruby 1.9 parser.") do
      option[:parser] = Ruby19Parser
    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

.pluginsObject

The known plugins for Flog. See Flog.load_plugins.



159
160
161
# File 'lib/flog_cli.rb', line 159

def self.plugins
  @plugins ||= {}
end

.run(args = ARGV) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/flog_cli.rb', line 16

def self.run args = ARGV
  load_plugins

  expander = PathExpander.new args, "**/*.{rb,rake}"
  files = expander.process

  abort "no files or stdin (-) to process, aborting." if
    files.empty? and args.empty?

  options = parse_options args

  flogger = new options
  flogger.flog(*files)
  flogger.report
end

Instance Method Details

#flog(*files) ⇒ Object

Flog the given files. Deals with “-”, syntax errors, and traversing subdirectories intelligently. Use PathExpander to process dirs into files.



168
169
170
171
# File 'lib/flog_cli.rb', line 168

def flog(*files)
  files << "-" if files.empty?
  @flog.flog(*files)
end

#output_details(io, max = nil) ⇒ Object

Output the report up to a given max or report everything, if nil.



183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/flog_cli.rb', line 183

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

#output_details_grouped(io, threshold = nil) ⇒ Object

Output the report, grouped by class/module, up to a given max or report everything, if nil.



202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/flog_cli.rb', line 202

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

Print out one formatted score.



219
220
221
222
223
224
225
226
227
228
# File 'lib/flog_cli.rb', line 219

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

#report(io = $stdout) ⇒ Object

Report results to #io, STDOUT by default.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/flog_cli.rb', line 233

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