flay 2.5.0 → 2.6.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -1
- data.tar.gz.sig +0 -0
- data/History.txt +7 -0
- data/README.txt +4 -0
- data/Rakefile +2 -0
- data/bin/flay +1 -1
- data/lib/flay.rb +64 -28
- data/lib/flay_erb.rb +3 -3
- data/lib/flay_task.rb +3 -2
- data/lib/gauntlet_flay.rb +8 -8
- data/test/test_flay.rb +48 -5
- metadata +15 -15
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f618784f99890722c0400a5d9bb2724fd2b07758
|
4
|
+
data.tar.gz: 40359e7d4fb354939fb424d03b90ae16f8b2624a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bc71abbe2ed73ec4ef380e8441587fe601560a88571330500db0bda26e786708abedb8aa376cde0b977a87ab71d71fb7bf839d7d7aac877f4675c3f55f928e8
|
7
|
+
data.tar.gz: 5962022a8e28b9fbd06455663c34dd8973e1d1c87c7ac4e3282dd4edf178b5bdd3f4cf2cfbfd27cadfc4184bc13f8610c6fca5ce904dba89d56213c60ea8cc0c
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
�,v��e���2N�o'L㵵�� �@4!z���ʘ���фu2㤂G��SYC�i��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
|
data/History.txt
CHANGED
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
data/lib/flay.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
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.
|
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 =
|
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(
|
59
|
+
opts.on("-h", "--help", "Display this help.") do
|
60
60
|
puts opts
|
61
61
|
exit
|
62
62
|
end
|
63
63
|
|
64
|
-
opts.on(
|
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(
|
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(
|
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(
|
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(
|
82
|
+
opts.on("-v", "--verbose", "Verbose. Show progress processing files.") do
|
83
83
|
options[:verbose] = true
|
84
84
|
end
|
85
85
|
|
86
|
-
opts.on(
|
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(
|
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(
|
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(
|
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 = [
|
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 = [
|
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,
|
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,
|
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
|
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
|
553
|
+
require "ruby2ruby"
|
518
554
|
rescue LoadError
|
519
|
-
return
|
555
|
+
return "ruby2ruby is required for diff"
|
520
556
|
end
|
521
557
|
@r2r ||= Ruby2Ruby.new
|
522
558
|
@r2r.process sexp.deep_clone
|
data/lib/flay_erb.rb
CHANGED
data/lib/flay_task.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/gauntlet_flay.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
#!/usr/bin/ruby -ws
|
2
2
|
|
3
|
-
$: <<
|
3
|
+
$: << "lib" << "../../ParseTree/dev/lib" << "../../flay/dev/lib"
|
4
4
|
|
5
5
|
$v ||= false # HACK
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "rubygems"
|
8
|
+
require "flay"
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "gauntlet"
|
11
|
+
require "pp"
|
12
12
|
|
13
13
|
# :stopdoc:
|
14
14
|
class FlayGauntlet < Gauntlet
|
15
15
|
$owners = {}
|
16
|
-
$score_file =
|
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
|
|
data/test/test_flay.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/ruby -w
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
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
|
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
|
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
|
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.
|
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
|
-
|
13
|
+
MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
|
14
14
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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:
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|