flay 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a86b433cd154d84be7076b6172db4ef1cc399472
4
+ data.tar.gz: d5443415472f22efc31f9fc91c5c40d144f8aedc
5
+ SHA512:
6
+ metadata.gz: d258e0487193665da980125c5245ed86415dfdaf4f51f4453044a3e851d0ee619ddf65a607debd07f4f7cd48af0d62697556c53620aa4060de5ce91be806c320
7
+ data.tar.gz: e578e44ec8118ce4e3dac841910356ed5e344259f47dd08c094734a2d8a1676c4ba2d04b2e9fbf391371ad7ddefc9f5602391b343722f50fc7c2e688ec8ccfe3
checksums.yaml.gz.sig ADDED
@@ -0,0 +1 @@
1
+ q}���y`��)s I� �f�ٟw�n��T ƍW�$�%�M�w�/]x�� �Ԗ�q�o�
data.tar.gz.sig CHANGED
Binary file
data/History.txt CHANGED
@@ -1,3 +1,14 @@
1
+ === 2.5.0 / 2014-05-29
2
+
3
+ * 6 minor enhancements:
4
+
5
+ * Added Flay::Item and Flay::Location to encapsulate analysis.
6
+ * Added `--only nodetype` filter flag.
7
+ * Flay#analyze now returns a nice data structure you can walk over.
8
+ * Flay#report is now much more dumb. :)
9
+ * Flay#report now takes an optional IO object.
10
+ * Removed unused prune arg in Flay#report.
11
+
1
12
  === 2.4.0 / 2013-07-24
2
13
 
3
14
  * 1 minor enhancement:
data/README.txt CHANGED
@@ -30,6 +30,7 @@ braces vs do/end, etc are all ignored. Making this totally rad.
30
30
  == KNOWN EXTENSIONS:
31
31
 
32
32
  * flay-actionpack :: Use Rails ERB handler.
33
+ * flay-js :: Process JavaScript files.
33
34
  * flay-haml :: Flay your HAML source.
34
35
  * flay-persistence :: Persist results across runs. Great for multi-project analysis.
35
36
 
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- ruby -*-
2
2
 
3
- require 'rubygems'
4
- require 'hoe'
3
+ require "rubygems"
4
+ require "hoe"
5
5
 
6
6
  Hoe::add_include_dirs("../../sexp_processor/dev/lib",
7
7
  "../../ruby_parser/dev/lib",
@@ -11,14 +11,14 @@ Hoe::add_include_dirs("../../sexp_processor/dev/lib",
11
11
 
12
12
  Hoe.plugin :seattlerb
13
13
 
14
- Hoe.spec 'flay' do
15
- developer 'Ryan Davis', 'ryand-ruby@zenspider.com'
14
+ Hoe.spec "flay" do
15
+ developer "Ryan Davis", "ryand-ruby@zenspider.com"
16
+ license "MIT"
16
17
 
17
- self.rubyforge_name = 'seattlerb'
18
- self.flay_threshold = 250
18
+ dependency "sexp_processor", "~> 4.0"
19
+ dependency "ruby_parser", "~> 3.0"
19
20
 
20
- dependency 'sexp_processor', '~> 4.0'
21
- dependency 'ruby_parser', '~> 3.0'
21
+ self.flay_threshold = 250
22
22
  end
23
23
 
24
24
  task :debug do
data/lib/flay.rb CHANGED
@@ -15,7 +15,15 @@ class File
15
15
  end
16
16
 
17
17
  class Flay
18
- VERSION = "2.4.0" # :nodoc:
18
+ VERSION = "2.5.0" # :nodoc:
19
+
20
+ class Item < Struct.new(:structural_hash, :name, :bonus, :mass, :locations)
21
+ alias identical? bonus
22
+ end
23
+
24
+ class Location < Struct.new(:file, :line, :fuzzy)
25
+ alias fuzzy? fuzzy
26
+ end
19
27
 
20
28
  ##
21
29
  # Returns the default options.
@@ -30,6 +38,7 @@ class Flay
30
38
  :timeout => 10,
31
39
  :liberal => false,
32
40
  :fuzzy => false,
41
+ :only => nil,
33
42
  }
34
43
  end
35
44
 
@@ -74,6 +83,10 @@ class Flay
74
83
  options[:verbose] = true
75
84
  end
76
85
 
86
+ opts.on('-o', '--only NODE', String, "Only show matches on NODE type.") do |s|
87
+ options[:only] = s.to_sym
88
+ end
89
+
77
90
  opts.on('-d', '--diff', "Diff Mode. Display N-Way diff for ruby.") do
78
91
  options[:diff] = true
79
92
  end
@@ -204,7 +217,7 @@ class Flay
204
217
  ##
205
218
  # Prune, find identical nodes, and update masses.
206
219
 
207
- def analyze
220
+ def analyze filter = nil
208
221
  self.prune
209
222
 
210
223
  self.hashes.each do |hash,nodes|
@@ -212,6 +225,31 @@ class Flay
212
225
  end
213
226
 
214
227
  update_masses
228
+
229
+ sorted = masses.sort_by { |h,m|
230
+ [-m,
231
+ hashes[h].first.file,
232
+ hashes[h].first.line,
233
+ hashes[h].first.first.to_s]
234
+ }
235
+
236
+ sorted.map { |hash, mass|
237
+ nodes = hashes[hash]
238
+
239
+ next unless nodes.first.first == filter if filter
240
+
241
+ same = identical[hash]
242
+ node = nodes.first
243
+ n = nodes.size
244
+ bonus = "*#{n}" if same
245
+
246
+ locs = nodes.sort_by { |x| [x.file, x.line] }.each_with_index.map { |x, i|
247
+ extra = :fuzzy if x.modified?
248
+ Location[x.file, x.line, extra]
249
+ }
250
+
251
+ Item[hash, node.first, bonus, mass, locs]
252
+ }.compact
215
253
  end
216
254
 
217
255
  ##
@@ -427,70 +465,49 @@ class Flay
427
465
  ##
428
466
  # Output the report. Duh.
429
467
 
430
- def report prune = nil
431
- analyze
468
+ def report io = $stdout
469
+ only = option[:only]
470
+
471
+ data = analyze only
432
472
 
433
- puts "Total score (lower is better) = #{self.total}"
473
+ io.puts "Total score (lower is better) = #{self.total}"
434
474
 
435
475
  if option[:summary] then
436
- puts
476
+ io.puts
437
477
 
438
478
  self.summary.sort_by { |_,v| -v }.each do |file, score|
439
- puts "%8.2f: %s" % [score, file]
479
+ io.puts "%8.2f: %s" % [score, file]
440
480
  end
441
481
 
442
482
  return
443
483
  end
444
484
 
445
- count = 0
446
- sorted = masses.sort_by { |h,m|
447
- [-m,
448
- hashes[h].first.file,
449
- hashes[h].first.line,
450
- hashes[h].first.first.to_s]
451
- }
452
- sorted.each do |hash, mass|
453
- nodes = hashes[hash]
454
- next unless nodes.first.first == prune if prune
455
- puts
456
-
457
- same = identical[hash]
458
- node = nodes.first
459
- n = nodes.size
460
- match, bonus = if same then
461
- ["IDENTICAL", "*#{n}"]
462
- else
463
- ["Similar", ""]
464
- end
465
-
466
- if option[:number] then
467
- count += 1
468
-
469
- puts "%d) %s code found in %p (mass%s = %d)" %
470
- [count, match, node.first, bonus, mass]
471
- else
472
- puts "%s code found in %p (mass%s = %d)" %
473
- [match, node.first, bonus, mass]
474
- end
485
+ data.each_with_index do |item, count|
486
+ prefix = "%d) " % (count + 1) if option[:number]
475
487
 
476
- nodes.sort_by { |x| [x.file, x.line] }.each_with_index do |x, i|
477
- if option[:diff] then
478
- c = (?A.ord + i).chr
479
- extra = " (FUZZY)" if x.modified?
480
- puts " #{c}: #{x.file}:#{x.line}#{extra}"
481
- else
482
- extra = " (FUZZY)" if x.modified?
483
- puts " #{x.file}:#{x.line}#{extra}"
484
- end
488
+ match = item.identical? ? "IDENTICAL" : "Similar"
489
+
490
+ io.puts
491
+ io.puts "%s%s code found in %p (mass%s = %d)" %
492
+ [prefix, match, item.name, item.bonus, item.mass]
493
+
494
+ item.locations.each_with_index do |loc, i|
495
+ loc_prefix = "%s: " % (?A.ord + i).chr if option[:diff]
496
+ extra = " (FUZZY)" if loc.fuzzy?
497
+ io.puts " %s%s:%d%s" % [loc_prefix, loc.file, loc.line, extra]
485
498
  end
486
499
 
487
500
  if option[:diff] then
488
- puts
501
+ io.puts
502
+
503
+ nodes = hashes[item.structural_hash]
504
+
489
505
  sources = nodes.map do |s|
490
506
  msg = "sexp_to_#{File.extname(s.file).sub(/./, '')}"
491
507
  self.respond_to?(msg) ? self.send(msg, s) : sexp_to_rb(s)
492
508
  end
493
- puts n_way_diff(*sources)
509
+
510
+ io.puts n_way_diff(*sources)
494
511
  end
495
512
  end
496
513
  end
data/test/test_flay.rb CHANGED
@@ -20,8 +20,8 @@ class TestSexp < Minitest::Test
20
20
  s(:lasgn),
21
21
  s(:call, s(:arglist))).hash
22
22
 
23
- assert_equal hash, @s.structural_hash
24
23
  assert_equal hash, @s.deep_clone.structural_hash
24
+ assert_equal hash, @s.structural_hash
25
25
  end
26
26
 
27
27
  def test_delete_eql
@@ -208,23 +208,13 @@ class TestSexp < Minitest::Test
208
208
  end
209
209
 
210
210
  def test_report
211
- # make sure we run through options parser
212
- $*.clear
213
- $* << "--mass=1"
214
- $* << "-v"
215
-
216
- opts = nil
217
- capture_io do # ignored
218
- opts = Flay.parse_options
219
- end
220
-
221
- flay = Flay.new opts
211
+ flay = Flay.new Flay.parse_options %w[--mass=1 -v]
222
212
 
223
213
  flay.process_sexp DOG_AND_CAT.deep_clone
224
214
  flay.analyze
225
215
 
226
216
  out, err = capture_io do
227
- flay.report nil
217
+ flay.report
228
218
  end
229
219
 
230
220
  exp = <<-END.gsub(/\d+/, "N").gsub(/^ {6}/, "")
@@ -239,25 +229,33 @@ class TestSexp < Minitest::Test
239
229
  assert_equal exp, out.gsub(/\d+/, "N")
240
230
  end
241
231
 
242
- def test_report_diff
243
- # make sure we run through options parser
244
- $*.clear
245
- $* << "-d"
246
- $* << "--mass=1"
247
- $* << "-v"
248
-
249
- opts = nil
250
- capture_io do # ignored
251
- opts = Flay.parse_options
252
- end
232
+ def test_report_io
233
+ out = StringIO.new
234
+ flay = Flay.new Flay.parse_options %w[--mass=1 -v]
253
235
 
254
- flay = Flay.new opts
236
+ flay.process_sexp DOG_AND_CAT.deep_clone
237
+ flay.analyze
238
+ flay.report out
239
+
240
+ exp = <<-END.gsub(/\d+/, "N").gsub(/^ {6}/, "")
241
+ Total score (lower is better) = 16
242
+
243
+ 1) Similar code found in :class (mass = 16)
244
+ (string):1
245
+ (string):6
246
+ END
247
+
248
+ assert_equal exp, out.string.gsub(/\d+/, "N")
249
+ end
250
+
251
+ def test_report_diff
252
+ flay = Flay.new Flay.parse_options %w[-d --mass=1 -v]
255
253
 
256
254
  flay.process_sexp DOG_AND_CAT.deep_clone
257
255
  flay.analyze
258
256
 
259
257
  out, err = capture_io do
260
- flay.report nil
258
+ flay.report
261
259
  end
262
260
 
263
261
  exp = <<-END.gsub(/\d+/, "N").gsub(/^ {6}/, "")
@@ -288,18 +286,7 @@ class TestSexp < Minitest::Test
288
286
  end
289
287
 
290
288
  def test_report_diff_plugin_converter
291
- # make sure we run through options parser
292
- $*.clear
293
- $* << "-d"
294
- $* << "--mass=1"
295
- $* << "-v"
296
-
297
- opts = nil
298
- capture_io do # ignored
299
- opts = Flay.parse_options
300
- end
301
-
302
- flay = Flay.new opts
289
+ flay = Flay.new Flay.parse_options %w[-d --mass=1 -v]
303
290
 
304
291
  flay.process_sexp DOG_AND_CAT.deep_clone
305
292
  flay.analyze
@@ -308,7 +295,7 @@ class TestSexp < Minitest::Test
308
295
  Flay.send(:define_method, :sexp_to_){|s| "source code #{s.line}"}
309
296
 
310
297
  out, err = capture_io do
311
- flay.report nil
298
+ flay.report
312
299
  end
313
300
 
314
301
  Flay.send(:remove_method, :sexp_to_)
metadata CHANGED
@@ -1,24 +1,18 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: flay
3
- version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease:
6
- segments:
7
- - 2
8
- - 4
9
- - 0
10
- version: 2.4.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.5.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Ryan Davis
14
8
  autorequire:
15
9
  bindir: bin
16
- cert_chain:
10
+ cert_chain:
17
11
  - |
18
12
  -----BEGIN CERTIFICATE-----
19
- MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
13
+ MIIDPjCCAiagAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
20
14
  ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
21
- GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE
15
+ GRYDY29tMB4XDTEzMDkxNjIzMDQxMloXDTE0MDkxNjIzMDQxMlowRTETMBEGA1UE
22
16
  AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
23
17
  JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
24
18
  b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
@@ -28,106 +22,100 @@ cert_chain:
28
22
  qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
29
23
  gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
30
24
  HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
31
- AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m
32
- vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/
33
- w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0
34
- l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl
35
- n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T
36
- FBHgymkyj/AOSqKRIpXPhjC6
25
+ AQCFZ7JTzoy1gcG4d8A6dmOJy7ygtO5MFpRIz8HuKCF5566nOvpy7aHhDDzFmQuu
26
+ FX3zDU6ghx5cQIueDhf2SGOncyBmmJRRYawm3wI0o1MeN6LZJ/3cRaOTjSFy6+S6
27
+ zqDmHBp8fVA2TGJtO0BLNkbGVrBJjh0UPmSoGzWlRhEVnYC33TpDAbNA+u39UrQI
28
+ ynwhNN7YbnmSR7+JU2cUjBFv2iPBO+TGuWC+9L2zn3NHjuc6tnmSYipA9y8Hv+As
29
+ Y4evBVezr3SjXz08vPqRO5YRdO3zfeMT8gBjRqZjWJGMZ2lD4XNfrs7eky74CyZw
30
+ xx3n58i0lQkBE1EpKE0lFu/y
37
31
  -----END CERTIFICATE-----
38
-
39
- date: 2013-07-24 00:00:00 Z
40
- dependencies:
41
- - !ruby/object:Gem::Dependency
32
+ date: 2014-05-30 00:00:00.000000000 Z
33
+ dependencies:
34
+ - !ruby/object:Gem::Dependency
42
35
  name: sexp_processor
43
- prerelease: false
44
- requirement: &id001 !ruby/object:Gem::Requirement
45
- none: false
46
- requirements:
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
47
38
  - - ~>
48
- - !ruby/object:Gem::Version
49
- hash: 27
50
- segments:
51
- - 4
52
- - 0
53
- version: "4.0"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
54
41
  type: :runtime
55
- version_requirements: *id001
56
- - !ruby/object:Gem::Dependency
57
- name: ruby_parser
58
42
  prerelease: false
59
- requirement: &id002 !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
62
45
  - - ~>
63
- - !ruby/object:Gem::Version
64
- hash: 7
65
- segments:
66
- - 3
67
- - 0
68
- version: "3.0"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: ruby_parser
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
69
55
  type: :runtime
70
- version_requirements: *id002
71
- - !ruby/object:Gem::Dependency
72
- name: minitest
73
56
  prerelease: false
74
- requirement: &id003 !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
77
59
  - - ~>
78
- - !ruby/object:Gem::Version
79
- hash: 31
80
- segments:
81
- - 5
82
- - 0
83
- version: "5.0"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '5.3'
84
69
  type: :development
85
- version_requirements: *id003
86
- - !ruby/object:Gem::Dependency
87
- name: rdoc
88
70
  prerelease: false
89
- requirement: &id004 !ruby/object:Gem::Requirement
90
- none: false
91
- requirements:
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
92
73
  - - ~>
93
- - !ruby/object:Gem::Version
94
- hash: 27
95
- segments:
96
- - 4
97
- - 0
98
- version: "4.0"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.3'
76
+ - !ruby/object:Gem::Dependency
77
+ name: rdoc
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
99
83
  type: :development
100
- version_requirements: *id004
101
- - !ruby/object:Gem::Dependency
102
- name: hoe
103
84
  prerelease: false
104
- requirement: &id005 !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: hoe
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
107
94
  - - ~>
108
- - !ruby/object:Gem::Version
109
- hash: 9
110
- segments:
111
- - 3
112
- - 7
113
- version: "3.7"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.12'
114
97
  type: :development
115
- version_requirements: *id005
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '3.12'
116
104
  description: |-
117
105
  Flay analyzes code for structural similarities. Differences in literal
118
106
  values, variable, class, method names, whitespace, programming style,
119
107
  braces vs do/end, etc are all ignored. Making this totally rad.
120
- email:
108
+ email:
121
109
  - ryand-ruby@zenspider.com
122
- executables:
110
+ executables:
123
111
  - flay
124
112
  extensions: []
125
-
126
- extra_rdoc_files:
113
+ extra_rdoc_files:
127
114
  - History.txt
128
115
  - Manifest.txt
129
116
  - README.txt
130
- files:
117
+ files:
118
+ - .gemtest
131
119
  - History.txt
132
120
  - Manifest.txt
133
121
  - README.txt
@@ -138,40 +126,31 @@ files:
138
126
  - lib/flay_task.rb
139
127
  - lib/gauntlet_flay.rb
140
128
  - test/test_flay.rb
141
- - .gemtest
142
129
  homepage: http://ruby.sadi.st/
143
- licenses:
130
+ licenses:
144
131
  - MIT
132
+ metadata: {}
145
133
  post_install_message:
146
- rdoc_options:
134
+ rdoc_options:
147
135
  - --main
148
136
  - README.txt
149
- require_paths:
137
+ require_paths:
150
138
  - lib
151
- required_ruby_version: !ruby/object:Gem::Requirement
152
- none: false
153
- requirements:
154
- - - ">="
155
- - !ruby/object:Gem::Version
156
- hash: 3
157
- segments:
158
- - 0
159
- version: "0"
160
- required_rubygems_version: !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ">="
164
- - !ruby/object:Gem::Version
165
- hash: 3
166
- segments:
167
- - 0
168
- version: "0"
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
169
149
  requirements: []
170
-
171
- rubyforge_project: seattlerb
172
- rubygems_version: 1.8.25
150
+ rubyforge_project:
151
+ rubygems_version: 2.2.1
173
152
  signing_key:
174
- specification_version: 3
153
+ specification_version: 4
175
154
  summary: Flay analyzes code for structural similarities
176
- test_files:
155
+ test_files:
177
156
  - test/test_flay.rb
metadata.gz.sig CHANGED
Binary file