flay 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a86b433cd154d84be7076b6172db4ef1cc399472
4
- data.tar.gz: d5443415472f22efc31f9fc91c5c40d144f8aedc
3
+ metadata.gz: f618784f99890722c0400a5d9bb2724fd2b07758
4
+ data.tar.gz: 40359e7d4fb354939fb424d03b90ae16f8b2624a
5
5
  SHA512:
6
- metadata.gz: d258e0487193665da980125c5245ed86415dfdaf4f51f4453044a3e851d0ee619ddf65a607debd07f4f7cd48af0d62697556c53620aa4060de5ce91be806c320
7
- data.tar.gz: e578e44ec8118ce4e3dac841910356ed5e344259f47dd08c094734a2d8a1676c4ba2d04b2e9fbf391371ad7ddefc9f5602391b343722f50fc7c2e688ec8ccfe3
6
+ metadata.gz: 3bc71abbe2ed73ec4ef380e8441587fe601560a88571330500db0bda26e786708abedb8aa376cde0b977a87ab71d71fb7bf839d7d7aac877f4675c3f55f928e8
7
+ data.tar.gz: 5962022a8e28b9fbd06455663c34dd8973e1d1c87c7ac4e3282dd4edf178b5bdd3f4cf2cfbfd27cadfc4184bc13f8610c6fca5ce904dba89d56213c60ea8cc0c
@@ -1 +1,2 @@
1
- q}���y`��)s I�f�ٟw�n��T ƍW�$�%�Mw�/]x�� �Ԗ�q�o�
1
+ �,v��e���2No'L㵵�� �@4!z���ʘ���фu2㤂G��SYCi��0r��H[F
2
+ R��IwjH��?��jQ�����Eh �h�H�����رy�k��;V���vP�V?>s3]ˇ+™Wm�*8N��Ql2���v�6X �H������<Y�==t�M���<,�(3JM��]Ah�TVp͖X�_���?�?_�o0�o~����8�޹�B�N�t��~ \�U|�����/Ys�ѯ�~A�z���F�����
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,10 @@
1
+ === 2.6.0 / 2015-01-09
2
+
3
+ * 2 minor enhancements:
4
+
5
+ * Added support for .flayignore files. (kcdragon)
6
+ * Added Flay.filter_files(files, ignore_path_or_io).
7
+
1
8
  === 2.5.0 / 2014-05-29
2
9
 
3
10
  * 6 minor enhancements:
data/README.txt CHANGED
@@ -25,6 +25,7 @@ braces vs do/end, etc are all ignored. Making this totally rad.
25
25
  * Ships with .rb and .erb.
26
26
  * javascript and others will be available separately.
27
27
  * Includes FlayTask for Rakefiles.
28
+ * Skips files matched via patterns in .flayignore (subset format of .gitignore).
28
29
  * Totally rad.
29
30
 
30
31
  == KNOWN EXTENSIONS:
@@ -38,6 +39,9 @@ braces vs do/end, etc are all ignored. Making this totally rad.
38
39
 
39
40
  * Editor integration (emacs, textmate, other contributions welcome).
40
41
 
42
+ * Vim integration started (https://github.com/prophittcorey/vim-flay)
43
+ - Flays the current file on save, load, or on command
44
+
41
45
  == SYNOPSIS:
42
46
 
43
47
  % flay -v --diff ~/Work/svn/ruby/ruby_1_8/lib/cgi.rb
data/Rakefile CHANGED
@@ -28,11 +28,13 @@ task :debug do
28
28
  mass = ENV["M"]
29
29
  diff = ENV["D"]
30
30
  libr = ENV["L"]
31
+ ver = ENV["V"]
31
32
 
32
33
  opts = Flay.parse_options
33
34
  opts[:mass] = mass.to_i if mass
34
35
  opts[:diff] = diff.to_i if diff
35
36
  opts[:liberal] = true if libr
37
+ opts[:verbose] = true if ver
36
38
 
37
39
  flay = Flay.new opts
38
40
  flay.process(*Flay.expand_dirs_to_files(file))
data/bin/flay CHANGED
@@ -4,7 +4,7 @@ require 'flay'
4
4
 
5
5
  flay = Flay.new Flay.parse_options
6
6
 
7
- files = Flay.expand_dirs_to_files(*ARGV)
7
+ files = Flay.filter_files Flay.expand_dirs_to_files(*ARGV)
8
8
 
9
9
  flay.process(*files)
10
10
  flay.report
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby -w
2
2
 
3
- require 'optparse'
4
- require 'rubygems'
5
- require 'sexp_processor'
6
- require 'ruby_parser'
7
- require 'timeout'
3
+ require "optparse"
4
+ require "rubygems"
5
+ require "sexp_processor"
6
+ require "ruby_parser"
7
+ require "timeout"
8
8
 
9
9
  class File
10
10
  RUBY19 = "<3".respond_to? :encoding unless defined? RUBY19 # :nodoc:
@@ -15,7 +15,7 @@ class File
15
15
  end
16
16
 
17
17
  class Flay
18
- VERSION = "2.5.0" # :nodoc:
18
+ VERSION = "2.6.0" # :nodoc:
19
19
 
20
20
  class Item < Struct.new(:structural_hash, :name, :bonus, :mass, :locations)
21
21
  alias identical? bonus
@@ -49,61 +49,61 @@ class Flay
49
49
  options = self.default_options
50
50
 
51
51
  OptionParser.new do |opts|
52
- opts.banner = 'flay [options] files_or_dirs'
52
+ opts.banner = "flay [options] files_or_dirs"
53
53
  opts.version = Flay::VERSION
54
54
 
55
55
  opts.separator ""
56
56
  opts.separator "Specific options:"
57
57
  opts.separator ""
58
58
 
59
- opts.on('-h', '--help', 'Display this help.') do
59
+ opts.on("-h", "--help", "Display this help.") do
60
60
  puts opts
61
61
  exit
62
62
  end
63
63
 
64
- opts.on('-f', '--fuzzy [DIFF]', Integer,
64
+ opts.on("-f", "--fuzzy [DIFF]", Integer,
65
65
  "Detect fuzzy (copy & paste) duplication (default 1).") do |n|
66
66
  options[:fuzzy] = n || 1
67
67
  end
68
68
 
69
- opts.on('-l', '--liberal', "Use a more liberal detection method.") do
69
+ opts.on("-l", "--liberal", "Use a more liberal detection method.") do
70
70
  options[:liberal] = true
71
71
  end
72
72
 
73
- opts.on('-m', '--mass MASS', Integer,
73
+ opts.on("-m", "--mass MASS", Integer,
74
74
  "Sets mass threshold (default = #{options[:mass]})") do |m|
75
75
  options[:mass] = m.to_i
76
76
  end
77
77
 
78
- opts.on('-#', "Don't number output (helps with diffs)") do |m|
78
+ opts.on("-#", "Don't number output (helps with diffs)") do |m|
79
79
  options[:number] = false
80
80
  end
81
81
 
82
- opts.on('-v', '--verbose', "Verbose. Show progress processing files.") do
82
+ opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
83
83
  options[:verbose] = true
84
84
  end
85
85
 
86
- opts.on('-o', '--only NODE', String, "Only show matches on NODE type.") do |s|
86
+ opts.on("-o", "--only NODE", String, "Only show matches on NODE type.") do |s|
87
87
  options[:only] = s.to_sym
88
88
  end
89
89
 
90
- opts.on('-d', '--diff', "Diff Mode. Display N-Way diff for ruby.") do
90
+ opts.on("-d", "--diff", "Diff Mode. Display N-Way diff for ruby.") do
91
91
  options[:diff] = true
92
92
  end
93
93
 
94
- opts.on('-s', '--summary', "Summarize. Show flay score per file only.") do
94
+ opts.on("-s", "--summary", "Summarize. Show flay score per file only.") do
95
95
  options[:summary] = true
96
96
  end
97
97
 
98
- opts.on('-t', '--timeout TIME', Integer,
98
+ opts.on("-t", "--timeout TIME", Integer,
99
99
  "Set the timeout. (default = #{options[:timeout]})") do |t|
100
100
  options[:timeout] = t.to_i
101
101
  end
102
102
 
103
- extensions = ['rb'] + Flay.load_plugins
103
+ extensions = ["rb"] + Flay.load_plugins
104
104
 
105
105
  opts.separator ""
106
- opts.separator "Known extensions: #{extensions.join(', ')}"
106
+ opts.separator "Known extensions: #{extensions.join(", ")}"
107
107
 
108
108
  extensions.each do |meth|
109
109
  msg = "options_#{meth}"
@@ -126,15 +126,51 @@ class Flay
126
126
  # REFACTOR: from flog
127
127
 
128
128
  def self.expand_dirs_to_files *dirs
129
- extensions = ['rb'] + Flay.load_plugins
129
+ extensions = ["rb"] + Flay.load_plugins
130
130
 
131
131
  dirs.flatten.map { |p|
132
132
  if File.directory? p then
133
- Dir[File.join(p, '**', "*.{#{extensions.join(',')}}")]
133
+ Dir[File.join(p, "**", "*.{#{extensions.join(",")}}")]
134
134
  else
135
135
  p
136
136
  end
137
- }.flatten
137
+ }.flatten.map { |s| s[/^(\.\/)?/] = ""; s } # strip "./" from paths
138
+ end
139
+
140
+ # so I can move this to flog wholesale
141
+ DEFAULT_IGNORE = ".flayignore" # :nodoc:
142
+
143
+ ##
144
+ # A file filter mechanism similar to, but not as extensive as,
145
+ # .gitignore files:
146
+ #
147
+ # + If a pattern does not contain a slash, it is treated as a shell glob.
148
+ # + If a pattern ends in a slash, it matches on directories (and contents).
149
+ # + Otherwise, it matches on relative paths.
150
+ #
151
+ # File.fnmatch is used throughout, so glob patterns work for all 3 types.
152
+
153
+ def self.filter_files files, ignore = DEFAULT_IGNORE
154
+ ignore_paths = if ignore.respond_to? :read then
155
+ ignore.read
156
+ elsif File.exists? ignore then
157
+ File.read ignore
158
+ end
159
+
160
+ if ignore_paths then
161
+ nonglobs, globs = ignore_paths.split("\n").partition { |p| p.include? "/" }
162
+ dirs, ifiles = nonglobs.partition { |p| p.end_with? "/" }
163
+ dirs = dirs.map { |s| s.chomp "/" }
164
+
165
+ only_paths = File::FNM_PATHNAME
166
+ files = files.reject { |f|
167
+ dirs.any? { |i| File.fnmatch?(i, File.dirname(f), only_paths) } ||
168
+ globs.any? { |i| File.fnmatch?(i, f) } ||
169
+ ifiles.any? { |i| File.fnmatch?(i, f, only_paths) }
170
+ }
171
+ end
172
+
173
+ files
138
174
  end
139
175
 
140
176
  ##
@@ -147,7 +183,7 @@ class Flay
147
183
  plugins = Gem.find_files("flay_*.rb").reject { |p| p =~ /flay_task/ }
148
184
 
149
185
  plugins.each do |plugin|
150
- plugin_name = File.basename(plugin, '.rb').sub(/^flay_/, '')
186
+ plugin_name = File.basename(plugin, ".rb").sub(/^flay_/, "")
151
187
  next if @@plugins.include? plugin_name
152
188
  begin
153
189
  load plugin
@@ -187,7 +223,7 @@ class Flay
187
223
  files.each do |file|
188
224
  warn "Processing #{file}" if option[:verbose]
189
225
 
190
- ext = File.extname(file).sub(/^\./, '')
226
+ ext = File.extname(file).sub(/^\./, "")
191
227
  ext = "rb" if ext.nil? || ext.empty?
192
228
  msg = "process_#{ext}"
193
229
 
@@ -318,7 +354,7 @@ class Flay
318
354
  next unless new_node.any? { |sub| Sexp === sub }
319
355
  next if new_node.mass < self.mass_threshold
320
356
 
321
- # they're already structurally similar, don't bother adding another
357
+ # they're already structurally similar, don"t bother adding another
322
358
  next if self.hashes[new_node.structural_hash].any? { |sub|
323
359
  sub.file == new_node.file and sub.line == new_node.line
324
360
  }
@@ -503,7 +539,7 @@ class Flay
503
539
  nodes = hashes[item.structural_hash]
504
540
 
505
541
  sources = nodes.map do |s|
506
- msg = "sexp_to_#{File.extname(s.file).sub(/./, '')}"
542
+ msg = "sexp_to_#{File.extname(s.file).sub(/./, "")}"
507
543
  self.respond_to?(msg) ? self.send(msg, s) : sexp_to_rb(s)
508
544
  end
509
545
 
@@ -514,9 +550,9 @@ class Flay
514
550
 
515
551
  def sexp_to_rb sexp
516
552
  begin
517
- require 'ruby2ruby'
553
+ require "ruby2ruby"
518
554
  rescue LoadError
519
- return 'ruby2ruby is required for diff'
555
+ return "ruby2ruby is required for diff"
520
556
  end
521
557
  @r2r ||= Ruby2Ruby.new
522
558
  @r2r.process sexp.deep_clone
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- require 'rubygems'
4
- require 'flay'
5
- require 'erb'
3
+ require "rubygems"
4
+ require "flay"
5
+ require "erb"
6
6
 
7
7
  class Flay
8
8
 
@@ -40,11 +40,12 @@ class FlayTask < Rake::TaskLib
40
40
  # Defines the flay task.
41
41
 
42
42
  def define
43
- desc "Analyze for code duplication in: #{dirs.join(', ')}"
43
+ desc "Analyze for code duplication in: #{dirs.join(", ")}"
44
44
  task name do
45
45
  require "flay"
46
46
  flay = Flay.new
47
- flay.process(*Flay.expand_dirs_to_files(dirs))
47
+ files = Flay.filter_files Flay.expand_dirs_to_files dirs
48
+ flay.process(*files)
48
49
  flay.report if verbose
49
50
 
50
51
  raise "Flay total too high! #{flay.total} > #{threshold}" if
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/ruby -ws
2
2
 
3
- $: << 'lib' << '../../ParseTree/dev/lib' << '../../flay/dev/lib'
3
+ $: << "lib" << "../../ParseTree/dev/lib" << "../../flay/dev/lib"
4
4
 
5
5
  $v ||= false # HACK
6
6
 
7
- require 'rubygems'
8
- require 'flay'
7
+ require "rubygems"
8
+ require "flay"
9
9
 
10
- require 'gauntlet'
11
- require 'pp'
10
+ require "gauntlet"
11
+ require "pp"
12
12
 
13
13
  # :stopdoc:
14
14
  class FlayGauntlet < Gauntlet
15
15
  $owners = {}
16
- $score_file = 'flay-scores.yml'
16
+ $score_file = "flay-scores.yml"
17
17
  $misc_error = {:total => -1, :average => -1, :methods => {}}
18
18
  $syntax_error = {:total => -2, :average => -2, :methods => {}}
19
19
  $no_gem = {:total => -4, :average => -4, :methods => {}}
20
20
 
21
- # copied straight from hoedown.rb
21
+ # copied straight from hoedown.rb
22
22
  my_projects = %w[InlineFortran ParseTree RubyInline RubyToC
23
23
  ZenHacks ZenTest bfts box_layout
24
24
  change_class flay flog gauntlet heckle
@@ -31,7 +31,7 @@ class FlayGauntlet < Gauntlet
31
31
 
32
32
  def run name
33
33
  warn name
34
- self.data[name] = score_for '.'
34
+ self.data[name] = score_for "."
35
35
  self.dirty = true
36
36
  end
37
37
 
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/ruby -w
2
2
 
3
- require 'minitest/autorun'
4
- require 'flay'
3
+ require "minitest/autorun"
4
+ require "flay"
5
+ require "tmpdir"
5
6
 
6
7
  $: << "../../sexp_processor/dev/lib"
7
8
 
@@ -225,7 +226,7 @@ class TestSexp < Minitest::Test
225
226
  (string):6
226
227
  END
227
228
 
228
- assert_equal '', err
229
+ assert_equal "", err
229
230
  assert_equal exp, out.gsub(/\d+/, "N")
230
231
  end
231
232
 
@@ -281,7 +282,7 @@ class TestSexp < Minitest::Test
281
282
  end
282
283
  END
283
284
 
284
- assert_equal '', err
285
+ assert_equal "", err
285
286
  assert_equal exp, out.gsub(/\d+/, "N").gsub(/^ {3}$/, "")
286
287
  end
287
288
 
@@ -311,7 +312,7 @@ class TestSexp < Minitest::Test
311
312
  B: source code 6
312
313
  END
313
314
 
314
- assert_equal '', err
315
+ assert_equal "", err
315
316
  assert_equal exp, out.gsub(/\d+/, "N").gsub(/^ {3}$/, "")
316
317
  end
317
318
 
@@ -435,4 +436,46 @@ class TestSexp < Minitest::Test
435
436
 
436
437
  assert_equal exp, flay.n_way_diff(*dog_and_cat).gsub(/^ {3}$/, "")
437
438
  end
439
+
440
+ def test_cls_expand_dirs_to_files
441
+ Dir.mktmpdir do |dir|
442
+ Dir.chdir dir do
443
+ FileUtils.touch "dog_and_cat.rb"
444
+
445
+ files = Flay.expand_dirs_to_files "."
446
+ assert_equal %w[dog_and_cat.rb], files
447
+ end
448
+ end
449
+ end
450
+
451
+ def assert_filter_files exp, filter, files = %w[test/dog_and_cat.rb]
452
+ ignore = StringIO.new filter
453
+ act = Flay.filter_files files, ignore
454
+ assert_equal exp, act
455
+ end
456
+
457
+ def test_cls_filter_files_dir
458
+ assert_filter_files [], "test/"
459
+ end
460
+
461
+ def test_cls_filter_files_files
462
+ assert_filter_files [], "test/*.rb"
463
+
464
+ example = %w[test/file.rb test/sub/file.rb top/test/perf.rb]
465
+
466
+ assert_filter_files example[1..-1], "test/*.rb", example
467
+ end
468
+
469
+ def test_cls_filter_files_glob
470
+ assert_filter_files [], "test*"
471
+ assert_filter_files [], "test*", ["test/lib/woot.rb"]
472
+ assert_filter_files [], "*.rb"
473
+ assert_filter_files [], "*dog*.rb"
474
+ end
475
+
476
+ def test_cls_filter_files_glob_miss
477
+ miss = %w[test/dog_and_cat.rb]
478
+ assert_filter_files miss, "test"
479
+ assert_filter_files miss, "nope"
480
+ end
438
481
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flay
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Davis
@@ -10,9 +10,9 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDPjCCAiagAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
13
+ MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
14
14
  ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
- GRYDY29tMB4XDTEzMDkxNjIzMDQxMloXDTE0MDkxNjIzMDQxMlowRTETMBEGA1UE
15
+ GRYDY29tMB4XDTE0MDkxNzIzMDcwN1oXDTE1MDkxNzIzMDcwN1owRTETMBEGA1UE
16
16
  AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
17
17
  JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
18
18
  b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
@@ -22,14 +22,14 @@ cert_chain:
22
22
  qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
23
23
  gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
24
24
  HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
25
- AQCFZ7JTzoy1gcG4d8A6dmOJy7ygtO5MFpRIz8HuKCF5566nOvpy7aHhDDzFmQuu
26
- FX3zDU6ghx5cQIueDhf2SGOncyBmmJRRYawm3wI0o1MeN6LZJ/3cRaOTjSFy6+S6
27
- zqDmHBp8fVA2TGJtO0BLNkbGVrBJjh0UPmSoGzWlRhEVnYC33TpDAbNA+u39UrQI
28
- ynwhNN7YbnmSR7+JU2cUjBFv2iPBO+TGuWC+9L2zn3NHjuc6tnmSYipA9y8Hv+As
29
- Y4evBVezr3SjXz08vPqRO5YRdO3zfeMT8gBjRqZjWJGMZ2lD4XNfrs7eky74CyZw
30
- xx3n58i0lQkBE1EpKE0lFu/y
25
+ AQAFoDJRokCQdxFfOrmsKX41KOFlU/zjrbDVM9hgB/Ur999M6OXGSi8FitXNtMwY
26
+ FVjsiAPeU7HaWVVcZkj6IhINelTkXsxgGz/qCzjHy3iUMuZWw36cS0fiWJ5rvH+e
27
+ hD7uXxJSFuyf1riDGI1aeWbQ74WMwvNstOxLUMiV5a1fzBhlxPqb537ubDjq/M/h
28
+ zPUFPVYeL5KjDHLCqI2FwIk2sEMOQgjpXHzl+3NlD2LUgUhHDMevmgVua0e2GT1B
29
+ xJcC6UN6NHMOVMyAXsr2HR0gRRx4ofN1LoP2KhXzSr8UMvQYlwPmE0N5GQv1b5AO
30
+ VpzF30vNaJK6ZT7xlIsIlwmH
31
31
  -----END CERTIFICATE-----
32
- date: 2014-05-30 00:00:00.000000000 Z
32
+ date: 2015-01-10 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: sexp_processor
@@ -65,14 +65,14 @@ dependencies:
65
65
  requirements:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: '5.3'
68
+ version: '5.5'
69
69
  type: :development
70
70
  prerelease: false
71
71
  version_requirements: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ~>
74
74
  - !ruby/object:Gem::Version
75
- version: '5.3'
75
+ version: '5.5'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: rdoc
78
78
  requirement: !ruby/object:Gem::Requirement
@@ -93,14 +93,14 @@ dependencies:
93
93
  requirements:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
- version: '3.12'
96
+ version: '3.13'
97
97
  type: :development
98
98
  prerelease: false
99
99
  version_requirements: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ~>
102
102
  - !ruby/object:Gem::Version
103
- version: '3.12'
103
+ version: '3.13'
104
104
  description: |-
105
105
  Flay analyzes code for structural similarities. Differences in literal
106
106
  values, variable, class, method names, whitespace, programming style,
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  version: '0'
149
149
  requirements: []
150
150
  rubyforge_project:
151
- rubygems_version: 2.2.1
151
+ rubygems_version: 2.4.1
152
152
  signing_key:
153
153
  specification_version: 4
154
154
  summary: Flay analyzes code for structural similarities
metadata.gz.sig CHANGED
Binary file