flog 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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