flog 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ ����!�������K�4+5՞��d�l=yT�n�6\�aU���dq���>�'x�\�웍{ᷰеf[ɠlW���'�T�vV�h�|��s���o4�<"�8���15��Lʴ��n�����QO/�*ώ��To�tʲ�I'ߨ�tW<z$i���Kìă���V�� ��G�I�ۗei
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+ require 'autotest/rcov'
5
+
6
+ Autotest.add_hook :initialize do |at|
7
+ at.order = :random
8
+
9
+ at.add_mapping(/^spec\/.*_spec\.rb$/) do |filename, _|
10
+ filename
11
+ end
12
+
13
+ at.libs << ':../../minitest/dev/lib'
14
+ at.testlib = "minitest/autorun"
15
+ end
@@ -1,3 +1,25 @@
1
+ === 2.3.0 / 2009-12-09
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Added file:line info to the flog report (Marty Andrews)
6
+
7
+ * 13 minor enhancements:
8
+
9
+ * Added .autotest.
10
+ * Deleted pre-gauntlet scripts.
11
+ * Flog#method_name now at least tries show when it is a class method.
12
+ * Flog.parse_options now takes args directly.
13
+ * Removed Flog#increment_total_score_by.
14
+ * Removed Flog#output_summary.
15
+ * Removed Flog#process_attrset.
16
+ * Removed Flog#record_method_score.
17
+ * Removed Flog#summarize_method.
18
+ * Removed Flog::default_options.
19
+ * Renamed Flog#analyze_list to process_until_empty.
20
+ * Renamed Flog#options to #option
21
+ * Rewrote entire test suite (3100 lines down!). Cleaner and less brittle.
22
+
1
23
  === 2.2.0 / 2009-08-14
2
24
 
3
25
  * 1 minor enhancement:
@@ -1,26 +1,10 @@
1
+ .autotest
1
2
  History.txt
2
3
  Manifest.txt
3
4
  README.txt
4
5
  Rakefile
5
6
  bin/flog
6
- gem_updater.rb
7
7
  lib/flog.rb
8
8
  lib/flog_task.rb
9
9
  lib/gauntlet_flog.rb
10
- unpack.rb
11
- update_scores.rb
12
- spec_fixtures/collection/bigger_example/acts/date_range.rb
13
- spec_fixtures/collection/bigger_example/acts/range.rb
14
- spec_fixtures/collection/bigger_example/association_extensions/date_ranged.rb
15
- spec_fixtures/collection/bigger_example/association_extensions/ranged.rb
16
- spec_fixtures/collection/bigger_example/reflection_extensions/ranged.rb
17
- spec_fixtures/directory/bot_filter.rb
18
- spec_fixtures/directory/bot_parser.rb
19
- spec_fixtures/directory/bot_parser_format.rb
20
- spec_fixtures/directory/bot_sender.rb
21
- spec_fixtures/empty/empty.rb
22
- spec_fixtures/simple/simple.rb
23
10
  test/test_flog.rb
24
- test/test_flog_command.rb
25
- test/test_flog_integration.rb
26
- test/test_helper.rb
data/bin/flog CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'optparse'
4
4
  require 'flog'
5
5
 
6
- options = Flog.parse_options
6
+ options = Flog.parse_options ARGV
7
7
 
8
8
  ARGV << "-" if ARGV.empty?
9
9
 
@@ -4,7 +4,7 @@ require 'ruby_parser'
4
4
  require 'optparse'
5
5
 
6
6
  class Flog < SexpProcessor
7
- VERSION = '2.2.0'
7
+ VERSION = '2.3.0'
8
8
 
9
9
  THRESHOLD = 0.60
10
10
  SCORES = Hash.new 1
@@ -69,14 +69,8 @@ class Flog < SexpProcessor
69
69
  @@no_method = :none
70
70
 
71
71
  attr_accessor :multiplier
72
- attr_reader :calls, :options, :class_stack, :method_stack, :mass
73
-
74
- def self.default_options
75
- {
76
- :quiet => true,
77
- :continue => false,
78
- }
79
- end
72
+ attr_reader :calls, :option, :class_stack, :method_stack, :mass
73
+ attr_reader :method_locations
80
74
 
81
75
  # REFACTOR: from flay
82
76
  def self.expand_dirs_to_files *dirs
@@ -91,27 +85,31 @@ class Flog < SexpProcessor
91
85
  }.flatten.sort
92
86
  end
93
87
 
94
- def self.parse_options
95
- options = self.default_options
96
- op = OptionParser.new do |opts|
88
+ def self.parse_options args = ARGV
89
+ option = {
90
+ :quiet => true,
91
+ :continue => false,
92
+ }
93
+
94
+ OptionParser.new do |opts|
97
95
  opts.on("-a", "--all", "Display all flog results, not top 60%.") do
98
- options[:all] = true
96
+ option[:all] = true
99
97
  end
100
98
 
101
99
  opts.on("-b", "--blame", "Include blame information for methods.") do
102
- options[:blame] = true
100
+ option[:blame] = true
103
101
  end
104
102
 
105
103
  opts.on("-c", "--continue", "Continue despite syntax errors.") do
106
- options[:continue] = true
104
+ option[:continue] = true
107
105
  end
108
106
 
109
107
  opts.on("-d", "--details", "Show method details.") do
110
- options[:details] = true
108
+ option[:details] = true
111
109
  end
112
110
 
113
111
  opts.on("-g", "--group", "Group and sort by class.") do
114
- options[:group] = true
112
+ option[:group] = true
115
113
  end
116
114
 
117
115
  opts.on("-h", "--help", "Show this message.") do
@@ -125,37 +123,34 @@ class Flog < SexpProcessor
125
123
  end
126
124
  end
127
125
 
128
- opts.on("-m", "--methods-only", "Skip code outside of methods.") do |m|
129
- options[:methods] = m
126
+ opts.on("-m", "--methods-only", "Skip code outside of methods.") do
127
+ option[:methods] = true
130
128
  end
131
129
 
132
- opts.on("-q", "--quiet", "Don't show method details. [default]") do |v|
133
- options[:quiet] = v
130
+ opts.on("-q", "--quiet", "Don't show method details. [default]") do
131
+ option[:quiet] = true
134
132
  end
135
133
 
136
- opts.on("-s", "--score", "Display total score only.") do |s|
137
- options[:score] = s
134
+ opts.on("-s", "--score", "Display total score only.") do
135
+ option[:score] = true
138
136
  end
139
137
 
140
- opts.on("-v", "--verbose", "Display progress during processing.") do |v|
141
- options[:verbose] = v
138
+ opts.on("-v", "--verbose", "Display progress during processing.") do
139
+ option[:verbose] = true
142
140
  end
143
- end.parse!
141
+ end.parse! Array(args)
144
142
 
145
- options
143
+ option
146
144
  end
147
145
 
148
- # TODO: rename options to option, you only deal with them one at a time...
149
-
150
146
  def add_to_score name, score = OTHER_SCORES[name]
151
- @calls["#{klass_name}##{method_name}"][name] += score * @multiplier
147
+ @calls[signature][name] += score * @multiplier
152
148
  end
153
149
 
154
150
  ##
155
151
  # Process each element of #exp in turn.
156
- # TODO: rename, bleed wasn't good, but this is actually worse
157
152
 
158
- def analyze_list exp
153
+ def process_until_empty exp
159
154
  process exp.shift until exp.empty?
160
155
  end
161
156
 
@@ -171,7 +166,7 @@ class Flog < SexpProcessor
171
166
  begin
172
167
  # TODO: replace File.open to deal with "-"
173
168
  ruby = file == '-' ? $stdin.read : File.read(file)
174
- warn "** flogging #{file}" if options[:verbose]
169
+ warn "** flogging #{file}" if option[:verbose]
175
170
 
176
171
  ast = @parser.process(ruby, file)
177
172
  next unless ast
@@ -182,7 +177,7 @@ class Flog < SexpProcessor
182
177
  warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
183
178
  warn "\n...stupid lemmings and their bad erb templates... skipping"
184
179
  else
185
- raise e unless options[:continue]
180
+ raise e unless option[:continue]
186
181
  warn file
187
182
  warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
188
183
  end
@@ -190,6 +185,9 @@ class Flog < SexpProcessor
190
185
  end
191
186
  end
192
187
 
188
+ ##
189
+ # Adds name to the class stack, for the duration of the block
190
+
193
191
  def in_klass name
194
192
  @class_stack.unshift name
195
193
  yield
@@ -197,33 +195,30 @@ class Flog < SexpProcessor
197
195
  end
198
196
 
199
197
  ##
200
- # Adds name to the list of methods, for the duration of the block
198
+ # Adds name to the method stack, for the duration of the block
201
199
 
202
- def in_method name
200
+ def in_method(name, file, line)
203
201
  @method_stack.unshift name
202
+ # "#{klass_name}##{name}"
203
+ @method_locations[signature] = "#{file}:#{line}"
204
204
  yield
205
205
  @method_stack.shift
206
206
  end
207
207
 
208
- def increment_total_score_by amount
209
- raise "@total_score isn't even set yet... dumbass" unless @total_score
210
- @total_score += amount
211
- end
212
-
213
- def initialize options = {}
208
+ def initialize option = {}
214
209
  super()
215
- @options = options
210
+ @option = option
216
211
  @class_stack = []
217
212
  @method_stack = []
213
+ @method_locations = {}
218
214
  @mass = {}
219
215
  @parser = RubyParser.new
220
216
  self.auto_shift_type = true
221
- self.require_empty = false # HACK
222
217
  self.reset
223
218
  end
224
219
 
225
220
  ##
226
- # returns the first class in the list, or @@no_class if there are
221
+ # Returns the first class in the list, or @@no_class if there are
227
222
  # none.
228
223
 
229
224
  def klass_name
@@ -236,7 +231,7 @@ class Flog < SexpProcessor
236
231
  name.delete :colon2
237
232
  name.join("::")
238
233
  when :colon3 then
239
- name.last
234
+ name.last.to_s
240
235
  else
241
236
  name
242
237
  end
@@ -245,18 +240,20 @@ class Flog < SexpProcessor
245
240
  end
246
241
 
247
242
  ##
248
- # returns the first method in the list, or @@no_method if there are
243
+ # Returns the first method in the list, or @@no_method if there are
249
244
  # none.
250
245
 
251
246
  def method_name
252
- @method_stack.first || @@no_method
247
+ m = @method_stack.first || @@no_method
248
+ m = "##{m}" unless m =~ /::/ unless m == @@no_method # FIX
249
+ m
253
250
  end
254
251
 
255
252
  def output_details(io, max = nil)
256
253
  my_totals = totals
257
254
  current = 0
258
255
 
259
- if options[:group] then
256
+ if option[:group] then
260
257
  scores = Hash.new 0
261
258
  methods = Hash.new { |h,k| h[k] = [] }
262
259
 
@@ -273,7 +270,12 @@ class Flog < SexpProcessor
273
270
  io.puts
274
271
  io.puts "%8.1f: %s" % [total, "#{klass} total"]
275
272
  methods[klass].each do |name, score|
276
- io.puts "%8.1f: %s" % [score, name]
273
+ location = @method_locations[name]
274
+ if location then
275
+ io.puts "%8.1f: %-32s %s" % [score, name, location]
276
+ else
277
+ io.puts "%8.1f: %s" % [score, name]
278
+ end
277
279
  end
278
280
  end
279
281
  else
@@ -286,21 +288,25 @@ class Flog < SexpProcessor
286
288
  end
287
289
 
288
290
  def output_method_details(io, class_method, call_list)
289
- return 0 if options[:methods] and class_method =~ /##{@@no_method}/
291
+ return 0 if option[:methods] and class_method =~ /##{@@no_method}/
290
292
 
291
293
  total = totals[class_method]
292
- io.puts "%8.1f: %s" % [total, class_method]
293
294
 
294
- call_list.sort_by { |k,v| -v }.each do |call, count|
295
- io.puts " %6.1f: %s" % [count, call]
296
- end if options[:details]
295
+ location = @method_locations[class_method]
296
+ if location then
297
+ io.puts "%8.1f: %-32s %s" % [total, class_method, location]
298
+ else
299
+ io.puts "%8.1f: %s" % [total, class_method]
300
+ end
297
301
 
298
- total
299
- end
302
+ if option[:details] then
303
+ call_list.sort_by { |k,v| -v }.each do |call, count|
304
+ io.puts " %6.1f: %s" % [count, call]
305
+ end
306
+ io.puts
307
+ end
300
308
 
301
- def output_summary(io)
302
- io.puts "%8.1f: %s" % [total, "flog total"]
303
- io.puts "%8.1f: %s" % [average, "flog/method average"]
309
+ total
304
310
  end
305
311
 
306
312
  ##
@@ -315,19 +321,16 @@ class Flog < SexpProcessor
315
321
  @multiplier -= bonus
316
322
  end
317
323
 
318
- def record_method_score(method, score)
319
- @totals ||= Hash.new(0)
320
- @totals[method] = score
321
- end
322
-
323
324
  ##
324
325
  # Report results to #io, STDOUT by default.
325
326
 
326
327
  def report(io = $stdout)
327
- output_summary(io)
328
- return if options[:score]
328
+ io.puts "%8.1f: %s" % [total, "flog total"]
329
+ io.puts "%8.1f: %s" % [average, "flog/method average"]
330
+
331
+ return if option[:score]
329
332
 
330
- if options[:all] then # TODO: fix - use option[:all] and THRESHOLD directly
333
+ if option[:all] then
331
334
  output_details(io)
332
335
  else
333
336
  output_details(io, total * THRESHOLD)
@@ -354,14 +357,13 @@ class Flog < SexpProcessor
354
357
  Math.sqrt(a*a + b*b + c*c)
355
358
  end
356
359
 
357
- def summarize_method(meth, tally)
358
- return if options[:methods] and meth =~ /##{@@no_method}$/
359
- score = score_method(tally)
360
- record_method_score(meth, score)
361
- increment_total_score_by score
360
+ def signature
361
+ m = method_name
362
+ m = "#none" if m == @@no_method
363
+ "#{klass_name}#{m}" # FIX: ugly
362
364
  end
363
365
 
364
- def total
366
+ def total # FIX: I hate this indirectness
365
367
  totals unless @total_score # calculates total_score as well
366
368
 
367
369
  @total_score
@@ -374,10 +376,16 @@ class Flog < SexpProcessor
374
376
  unless @totals then
375
377
  @total_score = 0
376
378
  @totals = Hash.new(0)
379
+
377
380
  calls.each do |meth, tally|
378
- summarize_method(meth, tally)
381
+ next if option[:methods] and meth =~ /##{@@no_method}$/
382
+ score = score_method(tally)
383
+
384
+ @totals[meth] = score
385
+ @total_score += score
379
386
  end
380
387
  end
388
+
381
389
  @totals
382
390
  end
383
391
 
@@ -409,15 +417,9 @@ class Flog < SexpProcessor
409
417
  s()
410
418
  end
411
419
 
412
- def process_attrset(exp)
413
- add_to_score :assignment
414
- raise exp.inspect
415
- s()
416
- end
417
-
418
420
  def process_block(exp)
419
421
  penalize_by 0.1 do
420
- analyze_list exp
422
+ process_until_empty exp
421
423
  end
422
424
  s()
423
425
  end
@@ -461,7 +463,7 @@ class Flog < SexpProcessor
461
463
  add_to_score :branch
462
464
  process exp.shift # recv
463
465
  penalize_by 0.1 do
464
- analyze_list exp
466
+ process_until_empty exp
465
467
  end
466
468
  s()
467
469
  end
@@ -469,14 +471,14 @@ class Flog < SexpProcessor
469
471
  def process_class(exp)
470
472
  in_klass exp.shift do
471
473
  penalize_by 1.0 do
472
- supr = process exp.shift
474
+ process exp.shift # superclass expression
473
475
  end
474
- analyze_list exp
476
+ process_until_empty exp
475
477
  end
476
478
  s()
477
479
  end
478
480
 
479
- def process_dasgn_curr(exp)
481
+ def process_dasgn_curr(exp) # FIX: remove
480
482
  add_to_score :assignment
481
483
  exp.shift # name
482
484
  process exp.shift # assigment, if any
@@ -486,16 +488,16 @@ class Flog < SexpProcessor
486
488
  alias :process_lasgn :process_dasgn_curr
487
489
 
488
490
  def process_defn(exp)
489
- in_method exp.shift do
490
- analyze_list exp
491
+ in_method exp.shift, exp.file, exp.line do
492
+ process_until_empty exp
491
493
  end
492
494
  s()
493
495
  end
494
496
 
495
497
  def process_defs(exp)
496
- process exp.shift
497
- in_method exp.shift do
498
- analyze_list exp
498
+ recv = process exp.shift
499
+ in_method "::#{exp.shift}", exp.file, exp.line do
500
+ process_until_empty exp
499
501
  end
500
502
  s()
501
503
  end
@@ -504,7 +506,7 @@ class Flog < SexpProcessor
504
506
  def process_else(exp)
505
507
  add_to_score :branch
506
508
  penalize_by 0.1 do
507
- analyze_list exp
509
+ process_until_empty exp
508
510
  end
509
511
  s()
510
512
  end
@@ -523,15 +525,17 @@ class Flog < SexpProcessor
523
525
 
524
526
  def process_iter(exp)
525
527
  context = (self.context - [:class, :module, :scope])
526
- if context.uniq.sort_by {|s|s.to_s} == [:block, :iter] then
528
+ if context.uniq.sort_by { |s| s.to_s } == [:block, :iter] then
527
529
  recv = exp.first
530
+
531
+ # DSL w/ names. eg task :name do ... end
528
532
  if (recv[0] == :call and recv[1] == nil and recv.arglist[1] and
529
533
  [:lit, :str].include? recv.arglist[1][0]) then
530
534
  msg = recv[2]
531
535
  submsg = recv.arglist[1][1]
532
- in_method submsg do
533
- in_klass msg do
534
- analyze_list exp
536
+ in_klass msg do # :task
537
+ in_method submsg, exp.file, exp.line do # :name
538
+ process_until_empty exp
535
539
  end
536
540
  end
537
541
  return s()
@@ -540,12 +544,12 @@ class Flog < SexpProcessor
540
544
 
541
545
  add_to_score :branch
542
546
 
543
- exp.delete 0
547
+ exp.delete 0 # TODO: what is this?
544
548
 
545
549
  process exp.shift # no penalty for LHS
546
550
 
547
551
  penalize_by 0.1 do
548
- analyze_list exp
552
+ process_until_empty exp
549
553
  end
550
554
 
551
555
  s()
@@ -568,13 +572,13 @@ class Flog < SexpProcessor
568
572
 
569
573
  def process_masgn(exp)
570
574
  add_to_score :assignment
571
- analyze_list exp
575
+ process_until_empty exp
572
576
  s()
573
577
  end
574
578
 
575
579
  def process_module(exp)
576
580
  in_klass exp.shift do
577
- analyze_list exp
581
+ process_until_empty exp
578
582
  end
579
583
  s()
580
584
  end
@@ -582,7 +586,7 @@ class Flog < SexpProcessor
582
586
  def process_sclass(exp)
583
587
  penalize_by 0.5 do
584
588
  recv = process exp.shift
585
- analyze_list exp
589
+ process_until_empty exp
586
590
  end
587
591
 
588
592
  add_to_score :sclass
@@ -591,7 +595,7 @@ class Flog < SexpProcessor
591
595
 
592
596
  def process_super(exp)
593
597
  add_to_score :super
594
- analyze_list exp
598
+ process_until_empty exp
595
599
  s()
596
600
  end
597
601
 
@@ -608,7 +612,7 @@ class Flog < SexpProcessor
608
612
 
609
613
  def process_yield(exp)
610
614
  add_to_score :yield
611
- analyze_list exp
615
+ process_until_empty exp
612
616
  s()
613
617
  end
614
618
  end