rubycritic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/CONTRIBUTING.md +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/SPEC.md +58 -0
- data/bin/rubycritic +3 -0
- data/lib/rubycritic.rb +23 -0
- data/lib/rubycritic/analysers/config.reek +18 -0
- data/lib/rubycritic/analysers/flog.rb +20 -0
- data/lib/rubycritic/analysers/reek.rb +15 -0
- data/lib/rubycritic/cli.rb +25 -0
- data/lib/rubycritic/location.rb +40 -0
- data/lib/rubycritic/report_generators/assets/stylesheets/application.css +4 -0
- data/lib/rubycritic/report_generators/file_generator.rb +58 -0
- data/lib/rubycritic/report_generators/line_generator.rb +29 -0
- data/lib/rubycritic/report_generators/report_generator.rb +31 -0
- data/lib/rubycritic/report_generators/templates/file.html.erb +1 -0
- data/lib/rubycritic/report_generators/templates/layouts/application.html.erb +16 -0
- data/lib/rubycritic/report_generators/templates/line.html.erb +1 -0
- data/lib/rubycritic/report_generators/templates/smelly_line.html.erb +1 -0
- data/lib/rubycritic/smell.rb +32 -0
- data/lib/rubycritic/smell_adapters/flog.rb +41 -0
- data/lib/rubycritic/smell_adapters/reek.rb +35 -0
- data/lib/rubycritic/smells_aggregator.rb +29 -0
- data/lib/rubycritic/source_locator.rb +31 -0
- data/lib/rubycritic/version.rb +3 -0
- data/rubycritic.gemspec +31 -0
- data/test/lib/rubycritic/location_test.rb +37 -0
- data/test/lib/rubycritic/metric_adapters/flog_adapter_test.rb +25 -0
- data/test/lib/rubycritic/metric_adapters/reek_adapter_test.rb +34 -0
- data/test/lib/rubycritic/smell_test.rb +57 -0
- data/test/lib/rubycritic/smells_aggregator_test.rb +47 -0
- data/test/lib/rubycritic/source_locator_test.rb +44 -0
- data/test/lib/rubycritic/version_test.rb +7 -0
- data/test/samples/flog/smelly.rb +6 -0
- data/test/samples/location/dir1/file1.rb +0 -0
- data/test/samples/location/file0.rb +0 -0
- data/test/samples/reek/not_smelly.rb +7 -0
- data/test/samples/reek/smelly.rb +5 -0
- data/test/test_helper.rb +7 -0
- metadata +199 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3254c84987373469b8c33271f81794a5495b7a1
|
4
|
+
data.tar.gz: 7face22a8c659ef7fb50c701e2ceaab5925c618a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3f00535b10889d81455894436c7b79d117a085745fcc6e886dfb9aabf7c53bcb47827d4d1d9ca1a6b596a46e2a4f9b4ca0494b555e7552321f8ac76d887e1671
|
7
|
+
data.tar.gz: 5fd94e011dd5c5ae34fab83e23d528ec618307ce801fecb87cdf1971be8b32df281ee1c4ea05e12d338ac483a74f84b7566f9fd0ff7943f46661af8bad859496
|
data/.gitignore
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Contributing
|
2
|
+
============
|
3
|
+
|
4
|
+
1. Fork the project.
|
5
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
6
|
+
3. Stage partial-file changesets (`git -p`).
|
7
|
+
4. Commit your changes (`git commit`).
|
8
|
+
Make exactly as many commits as you need.
|
9
|
+
Too many is confusing. Too few will result in epic diffs. Strive for just the right number.
|
10
|
+
Each commit should do one thing and one thing only.
|
11
|
+
Follow [these guidelines][1] when writing your commit messages.
|
12
|
+
5. [Hide the sausage making][2]. Squash, split and reorder commits if necessary (`git rebase -i`).
|
13
|
+
For a more in-depth look at interactive rebasing, be sure to check [how to rewrite history][3].
|
14
|
+
6. Push to the branch (`git push origin my-new-feature`).
|
15
|
+
7. Create new Pull Request.
|
16
|
+
|
17
|
+
[1]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
18
|
+
[2]: http://sethrobertson.github.io/GitBestPractices/#sausage
|
19
|
+
[3]: http://git-scm.com/book/en/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Guilherme Simoes
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Ruby Critic
|
2
|
+
===========
|
3
|
+
|
4
|
+
Ruby Critic is a tool that detects and reports smells in Ruby code.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem "rubycritic"
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
Or just install it yourself:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ gem install rubycritic
|
25
|
+
```
|
26
|
+
|
27
|
+
Usage
|
28
|
+
-----
|
29
|
+
|
30
|
+
Running `rubycritic` with no arguments will check all Ruby source files in the
|
31
|
+
current directory:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
$ rubycritic
|
35
|
+
```
|
36
|
+
|
37
|
+
Alternatively you can pass `rubycritic` a list of files and directories to check:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ rubycritic app lib/foo.rb
|
41
|
+
```
|
data/Rakefile
ADDED
data/SPEC.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
Ruby Critic
|
2
|
+
===========
|
3
|
+
|
4
|
+
Ruby Critic is a tool that detects and reports smells in Ruby code.
|
5
|
+
|
6
|
+
Inspired by [RuboCop][1], [Rails Best Practices][2] and [Code Climate][3], Ruby Critic aims to better help you refactor your code. By making use of Ruby's rich ecosystem of code metrics tools, Ruby Critic generates high-quality visualizations and insightful code quality reports.
|
7
|
+
|
8
|
+
[1]: https://github.com/bbatsov/rubocop/
|
9
|
+
[2]: https://github.com/railsbp/rails_best_practices
|
10
|
+
[3]: https://codeclimate.com/
|
11
|
+
|
12
|
+
Installation
|
13
|
+
------------
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem "rubycritic"
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ bundle
|
25
|
+
```
|
26
|
+
|
27
|
+
Or just install it yourself:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
$ gem install rubycritic
|
31
|
+
```
|
32
|
+
|
33
|
+
Usage
|
34
|
+
-----
|
35
|
+
|
36
|
+
Running `rubycritic` with no arguments will check all Ruby source files in the
|
37
|
+
current directory:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ rubycritic
|
41
|
+
```
|
42
|
+
|
43
|
+
Alternatively you can pass `rubycritic` a list of files and directories to check:
|
44
|
+
|
45
|
+
```bash
|
46
|
+
$ rubycritic app lib/foo.rb
|
47
|
+
```
|
48
|
+
|
49
|
+
Options
|
50
|
+
-------
|
51
|
+
|
52
|
+
To specify an output file for the results:
|
53
|
+
|
54
|
+
```bash
|
55
|
+
$ rubycritic -o output_file
|
56
|
+
```
|
57
|
+
|
58
|
+
The output format is determined by the file extension or by using the `-f` option. Current options are: `text`, `html`, `yaml` and `json`.
|
data/bin/rubycritic
ADDED
data/lib/rubycritic.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rubycritic/source_locator"
|
2
|
+
require "rubycritic/analysers/reek"
|
3
|
+
require "rubycritic/smell_adapters/reek"
|
4
|
+
require "rubycritic/smells_aggregator"
|
5
|
+
require "rubycritic/report_generators/report_generator"
|
6
|
+
|
7
|
+
module Rubycritic
|
8
|
+
|
9
|
+
class Rubycritic
|
10
|
+
def initialize(paths)
|
11
|
+
@source = SourceLocator.new(paths)
|
12
|
+
|
13
|
+
analyser = Analyser::Reek.new(@source.paths)
|
14
|
+
smell_adapters = [ SmellAdapter::Reek.new(analyser) ]
|
15
|
+
@aggregator = SmellsAggregator.new(smell_adapters)
|
16
|
+
end
|
17
|
+
|
18
|
+
def critique
|
19
|
+
ReportGenerator.new(@source.pathnames, @aggregator.smelly_pathnames).generate_report
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
Attribute:
|
3
|
+
enabled: false
|
4
|
+
IrresponsibleModule:
|
5
|
+
enabled: false
|
6
|
+
UncommunicativeMethodName:
|
7
|
+
reject:
|
8
|
+
- !ruby/regexp /^[a-z]$/
|
9
|
+
- !ruby/regexp /[0-9]$/
|
10
|
+
UncommunicativeParameterName:
|
11
|
+
reject:
|
12
|
+
- !ruby/regexp /^.$/
|
13
|
+
- !ruby/regexp /[0-9]$/
|
14
|
+
- !ruby/regexp /^_/
|
15
|
+
UncommunicativeVariableName:
|
16
|
+
reject:
|
17
|
+
- !ruby/regexp /^.$/
|
18
|
+
- !ruby/regexp /[0-9]$/
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "flog"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
module Analyser
|
5
|
+
|
6
|
+
class Flog < ::Flog
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
:all => true,
|
9
|
+
:continue => true,
|
10
|
+
:methods => true
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize(paths)
|
14
|
+
super(DEFAULT_OPTIONS)
|
15
|
+
flog(*paths)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "reek"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
module Analyser
|
5
|
+
|
6
|
+
class Reek < ::Reek::Examiner
|
7
|
+
DEFAULT_CONFIG_FILES = [File.expand_path("../config.reek", __FILE__)]
|
8
|
+
|
9
|
+
def initialize(paths)
|
10
|
+
super(Array(paths), DEFAULT_CONFIG_FILES)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "rubycritic"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: rubycritic [options] [paths]"
|
8
|
+
|
9
|
+
opts.on_tail("-v", "--version", "Show this version") do
|
10
|
+
require "rubycritic/version"
|
11
|
+
puts VERSION
|
12
|
+
exit 0
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
16
|
+
puts opts
|
17
|
+
exit 0
|
18
|
+
end
|
19
|
+
end.parse!
|
20
|
+
|
21
|
+
ARGV << "." if ARGV.empty?
|
22
|
+
Rubycritic.new(ARGV).critique
|
23
|
+
exit 0
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
|
5
|
+
class Location
|
6
|
+
attr_reader :pathname, :line
|
7
|
+
|
8
|
+
def initialize(path, line)
|
9
|
+
@pathname = Pathname.new(path)
|
10
|
+
@line = line
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
@pathname.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def file
|
18
|
+
@pathname.basename.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"#{path}:#{line}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
self.class == other.class && state == other.state
|
27
|
+
end
|
28
|
+
|
29
|
+
def <=>(other)
|
30
|
+
state <=> other.state
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def state
|
36
|
+
[@pathname, @line]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "rubycritic/report_generators/line_generator"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class FileGenerator
|
7
|
+
LINE_NUMBER_OFFSET = 1
|
8
|
+
REPORT_DIR = File.expand_path("tmp/rubycritic", Dir.getwd)
|
9
|
+
TEMPLATES_DIR = File.expand_path("../templates", __FILE__)
|
10
|
+
FILE_TEMPLATE = ERB.new(File.read(File.join(TEMPLATES_DIR, "file.html.erb")))
|
11
|
+
LAYOUT_TEMPLATE = ERB.new(File.read(File.join(TEMPLATES_DIR, "layouts", "application.html.erb")))
|
12
|
+
|
13
|
+
def initialize(pathname, smells)
|
14
|
+
@pathname = pathname
|
15
|
+
@smells = smells
|
16
|
+
end
|
17
|
+
|
18
|
+
def file_pathname
|
19
|
+
File.join(file_directory, file_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_directory
|
23
|
+
File.join(REPORT_DIR, File.dirname(@pathname))
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_name
|
27
|
+
"#{@pathname.basename.sub_ext('')}.html"
|
28
|
+
end
|
29
|
+
|
30
|
+
def output
|
31
|
+
output ||= file_content
|
32
|
+
end
|
33
|
+
|
34
|
+
def stylesheet_path
|
35
|
+
File.join(REPORT_DIR, "assets/stylesheets/application.css")
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_binding
|
39
|
+
binding
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def file_content
|
45
|
+
file_code = ""
|
46
|
+
File.readlines(@pathname).each.with_index(LINE_NUMBER_OFFSET) do |line_text, line_number|
|
47
|
+
location = Location.new(@pathname, line_number)
|
48
|
+
line_smells = @smells.select { |smell| smell.located_in?(location) }
|
49
|
+
file_code << LineGenerator.new(line_text, line_number, line_smells).output
|
50
|
+
end
|
51
|
+
|
52
|
+
file_body = FILE_TEMPLATE.result(self.get_binding { file_code })
|
53
|
+
|
54
|
+
LAYOUT_TEMPLATE.result(self.get_binding { file_body })
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class LineGenerator
|
7
|
+
LINE_NUMBER_PADDING = 3
|
8
|
+
TEMPLATES_DIR = File.expand_path("../templates", __FILE__)
|
9
|
+
NORMAL_TEMPLATE = ERB.new(File.read(File.join(TEMPLATES_DIR, "line.html.erb")))
|
10
|
+
SMELLY_TEMPLATE = ERB.new(File.read(File.join(TEMPLATES_DIR, "smelly_line.html.erb")))
|
11
|
+
|
12
|
+
def initialize(text, number, smells)
|
13
|
+
@text = CGI::escapeHTML(text.chomp)
|
14
|
+
@number = number.to_s.rjust(LINE_NUMBER_PADDING)
|
15
|
+
@smells = smells
|
16
|
+
@template =
|
17
|
+
if @smells.empty?
|
18
|
+
NORMAL_TEMPLATE
|
19
|
+
else
|
20
|
+
SMELLY_TEMPLATE
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def output
|
25
|
+
@output ||= @template.result(binding).delete("\n") + "\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "rubycritic/report_generators/file_generator"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class ReportGenerator
|
7
|
+
ASSETS_DIR = File.expand_path("../assets", __FILE__)
|
8
|
+
REPORT_DIR = File.expand_path("tmp/rubycritic", Dir.getwd)
|
9
|
+
|
10
|
+
def initialize(source_pathnames, smelly_pathnames)
|
11
|
+
@source_pathnames = source_pathnames
|
12
|
+
@smelly_pathnames = smelly_pathnames
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate_report
|
16
|
+
FileUtils.mkdir_p(REPORT_DIR)
|
17
|
+
FileUtils.cp_r(ASSETS_DIR, REPORT_DIR)
|
18
|
+
|
19
|
+
@source_pathnames.each do |pathname|
|
20
|
+
file_smells = @smelly_pathnames[pathname]
|
21
|
+
file_generator = FileGenerator.new(pathname, file_smells)
|
22
|
+
|
23
|
+
FileUtils.mkdir_p(file_generator.file_directory)
|
24
|
+
File.open(file_generator.file_pathname, "w+") do |report_file|
|
25
|
+
report_file.write(file_generator.output)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<pre><code><%= yield %></code></pre>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
|
+
<title>RubyCritic</title>
|
7
|
+
<link href="<%= stylesheet_path %>" media="screen, projection, print" rel="stylesheet" type="text/css">
|
8
|
+
<meta name="description" content="">
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<h1>RubyCritic</h1>
|
13
|
+
|
14
|
+
<%= yield %>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= @number %>. <%= @text %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<div class='smelly'><%= @number %>. <%= @text %> # <% @smells.each { |smell| %><%= smell %><% } %></div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "virtus"
|
2
|
+
require "rubycritic/location"
|
3
|
+
|
4
|
+
module Rubycritic
|
5
|
+
|
6
|
+
class Smell
|
7
|
+
include Virtus.model
|
8
|
+
|
9
|
+
attribute :context
|
10
|
+
attribute :locations
|
11
|
+
attribute :message
|
12
|
+
attribute :score
|
13
|
+
attribute :type
|
14
|
+
|
15
|
+
def pathnames
|
16
|
+
@pathnames ||= locations.map(&:pathname).uniq
|
17
|
+
end
|
18
|
+
|
19
|
+
def located_in?(other_location)
|
20
|
+
locations.any? { |location| location == other_location }
|
21
|
+
end
|
22
|
+
|
23
|
+
def <=>(other)
|
24
|
+
locations <=> other.locations
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"(#{type}) #{context} #{message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "rubycritic/smell"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
module SmellAdapter
|
5
|
+
|
6
|
+
class Flog
|
7
|
+
def initialize(flog)
|
8
|
+
@flog = flog
|
9
|
+
end
|
10
|
+
|
11
|
+
def smells
|
12
|
+
smells = []
|
13
|
+
@flog.each_by_score do |class_method, score|
|
14
|
+
smells << create_smell(class_method, score)
|
15
|
+
end
|
16
|
+
smells
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def create_smell(context, score)
|
22
|
+
location = method_location(context)
|
23
|
+
message = "has a complexity of #{score.round}"
|
24
|
+
Smell.new(
|
25
|
+
:locations => [location],
|
26
|
+
:context => context,
|
27
|
+
:message => message,
|
28
|
+
:score => score,
|
29
|
+
:type => "Complexity"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_location(context)
|
34
|
+
line = @flog.method_locations[context]
|
35
|
+
file_path, file_line = line.split(':')
|
36
|
+
Location.new(file_path, file_line)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "rubycritic/smell"
|
2
|
+
|
3
|
+
module Rubycritic
|
4
|
+
module SmellAdapter
|
5
|
+
|
6
|
+
class Reek
|
7
|
+
def initialize(reek)
|
8
|
+
@reek = reek
|
9
|
+
end
|
10
|
+
|
11
|
+
def smells
|
12
|
+
@reek.smells.map do |smell|
|
13
|
+
create_smell(smell)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def create_smell(smell)
|
20
|
+
locations = smell_locations(smell.source, smell.lines)
|
21
|
+
message = smell.message
|
22
|
+
context = smell.context
|
23
|
+
type = smell.subclass
|
24
|
+
Smell.new(:locations => locations, :context => context, :message => message, :type => type)
|
25
|
+
end
|
26
|
+
|
27
|
+
def smell_locations(file_path, file_lines)
|
28
|
+
file_lines.uniq.map do |file_line|
|
29
|
+
Location.new(file_path, file_line)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rubycritic
|
2
|
+
|
3
|
+
class SmellsAggregator
|
4
|
+
def initialize(smell_adapters)
|
5
|
+
@smell_adapters = smell_adapters
|
6
|
+
end
|
7
|
+
|
8
|
+
def smells
|
9
|
+
@smells ||= @smell_adapters.map(&:smells).flatten.sort
|
10
|
+
end
|
11
|
+
|
12
|
+
def smelly_pathnames
|
13
|
+
@smelly_pathnames ||= pathnames_to_files_with_smells
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def pathnames_to_files_with_smells
|
19
|
+
pathnames = Hash.new { |hash, key| hash[key] = [] }
|
20
|
+
smells.each do |smell|
|
21
|
+
smell.pathnames.each do |path|
|
22
|
+
pathnames[path] << smell
|
23
|
+
end
|
24
|
+
end
|
25
|
+
pathnames
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rubycritic
|
2
|
+
|
3
|
+
class SourceLocator
|
4
|
+
RUBY_FILES = File.join("**", "*.rb")
|
5
|
+
|
6
|
+
def initialize(dirs)
|
7
|
+
@dirs = dirs
|
8
|
+
end
|
9
|
+
|
10
|
+
def pathnames
|
11
|
+
@pathnames ||= expand_paths
|
12
|
+
end
|
13
|
+
|
14
|
+
def paths
|
15
|
+
@paths ||= pathnames.map(&:to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def expand_paths
|
21
|
+
@dirs.map do |path|
|
22
|
+
if File.directory?(path)
|
23
|
+
Pathname.glob(RUBY_FILES)
|
24
|
+
elsif File.exists?(path)
|
25
|
+
Pathname.new(path)
|
26
|
+
end
|
27
|
+
end.flatten.compact.sort
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/rubycritic.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "rubycritic/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rubycritic"
|
8
|
+
spec.version = Rubycritic::VERSION
|
9
|
+
spec.authors = ["Guilherme Simoes"]
|
10
|
+
spec.email = ["guilherme.rdems@gmail.com"]
|
11
|
+
spec.description = <<-EOF
|
12
|
+
Ruby Critic is a tool that detects and reports smells in Ruby classes, modules and methods.
|
13
|
+
EOF
|
14
|
+
spec.summary = "Ruby code smell detector"
|
15
|
+
spec.homepage = "https://github.com/GuilhermeSimoes/rubycritic"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split("\n")
|
19
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
spec.test_files = `git ls-files -- test/*`.split("\n")
|
21
|
+
spec.require_path = "lib"
|
22
|
+
|
23
|
+
spec.add_runtime_dependency "virtus", "~> 1.0"
|
24
|
+
spec.add_runtime_dependency "flog", "4.2.0"
|
25
|
+
spec.add_runtime_dependency "reek", "1.3.6"
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "minitest", "~> 5.3"
|
30
|
+
spec.add_development_dependency "mocha", "~> 1.0"
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/location"
|
3
|
+
|
4
|
+
describe Rubycritic::Location do
|
5
|
+
describe "attribute readers" do
|
6
|
+
before do
|
7
|
+
@path = "./foo"
|
8
|
+
@line = 42
|
9
|
+
@location = Rubycritic::Location.new(@path, @line)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a file path" do
|
13
|
+
@location.path.must_equal @path
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a file name" do
|
17
|
+
@location.file.must_equal "foo"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has a line number" do
|
21
|
+
@location.line.must_equal @line
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is comparable" do
|
26
|
+
location1 = Rubycritic::Location.new("./foo", 42)
|
27
|
+
location2 = Rubycritic::Location.new("./foo", 42)
|
28
|
+
location1.must_equal location2
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is sortable" do
|
32
|
+
location1 = Rubycritic::Location.new("./foo", 42)
|
33
|
+
location2 = Rubycritic::Location.new("./bar", 23)
|
34
|
+
location3 = Rubycritic::Location.new("./bar", 16)
|
35
|
+
[location1, location2, location3].sort.must_equal [location3, location2, location1]
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/analysers/flog"
|
3
|
+
require "rubycritic/smell_adapters/flog"
|
4
|
+
|
5
|
+
describe Rubycritic::SmellAdapter::Flog do
|
6
|
+
before do
|
7
|
+
@sample_path = "test/samples/flog/smelly.rb"
|
8
|
+
flog = Rubycritic::Analyser::Flog.new([@sample_path])
|
9
|
+
@adapter = Rubycritic::SmellAdapter::Flog.new(flog)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "detects smells" do
|
13
|
+
@adapter.smells.wont_be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has smells with messages" do
|
17
|
+
smell = @adapter.smells.first
|
18
|
+
smell.message.must_equal "has a complexity of 8"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has smells with scores" do
|
22
|
+
smell = @adapter.smells.first
|
23
|
+
smell.score.must_be_kind_of Numeric
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/analysers/reek"
|
3
|
+
require "rubycritic/smell_adapters/reek"
|
4
|
+
|
5
|
+
describe Rubycritic::SmellAdapter::Reek do
|
6
|
+
context "when analysing a smelly file" do
|
7
|
+
before do
|
8
|
+
@sample_path = "test/samples/reek/smelly.rb"
|
9
|
+
reek = Rubycritic::Analyser::Reek.new([@sample_path])
|
10
|
+
@adapter = Rubycritic::SmellAdapter::Reek.new(reek)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "detects smells" do
|
14
|
+
@adapter.smells.wont_be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has smells with messages" do
|
18
|
+
smell = @adapter.smells.first
|
19
|
+
smell.message.must_equal "has boolean parameter 'reek'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when analysing a file with smells ignored in config.reek" do
|
24
|
+
before do
|
25
|
+
sample_path = "test/samples/reek/not_smelly.rb"
|
26
|
+
reek = Rubycritic::Analyser::Reek.new(sample_path)
|
27
|
+
@adapter = Rubycritic::SmellAdapter::Reek.new(reek)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "does not detect smells" do
|
31
|
+
@adapter.smells.must_be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/smell"
|
3
|
+
|
4
|
+
describe Rubycritic::Smell do
|
5
|
+
it "has a context reader" do
|
6
|
+
context = "#bar"
|
7
|
+
smell = Rubycritic::Smell.new(:context => context)
|
8
|
+
smell.context.must_equal context
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a locations reader" do
|
12
|
+
location = Rubycritic::Location.new("./foo", "42")
|
13
|
+
smell = Rubycritic::Smell.new(:locations => [location])
|
14
|
+
smell.locations.must_equal [location]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has a pathnames reader" do
|
18
|
+
path = Pathname.new("./foo")
|
19
|
+
location1 = Rubycritic::Location.new("./foo", "42")
|
20
|
+
location2 = Rubycritic::Location.new("./foo", "23")
|
21
|
+
smell = Rubycritic::Smell.new(:locations => [location1, location2])
|
22
|
+
smell.pathnames.must_equal [path]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has a message reader" do
|
26
|
+
message = "This smells"
|
27
|
+
smell = Rubycritic::Smell.new(:message => message)
|
28
|
+
smell.message.must_equal message
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has a score reader" do
|
32
|
+
score = 0
|
33
|
+
smell = Rubycritic::Smell.new(:score => score)
|
34
|
+
smell.score.must_equal score
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has a type reader" do
|
38
|
+
type = :complexity
|
39
|
+
smell = Rubycritic::Smell.new(:type => type)
|
40
|
+
smell.type.must_equal type
|
41
|
+
end
|
42
|
+
|
43
|
+
it "is sortable" do
|
44
|
+
location1 = Rubycritic::Location.new("./foo", 42)
|
45
|
+
location2 = Rubycritic::Location.new("./bar", 23)
|
46
|
+
location3 = Rubycritic::Location.new("./bar", 16)
|
47
|
+
[location1, location2, location3].sort.must_equal [location3, location2, location1]
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#located_in?" do
|
51
|
+
it "returns true if the smell has a location that matches the location passed as argument" do
|
52
|
+
location = Rubycritic::Location.new("./foo", "42")
|
53
|
+
smell = Rubycritic::Smell.new(:locations => [location])
|
54
|
+
smell.located_in?(location).must_equal true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/smells_aggregator"
|
3
|
+
|
4
|
+
describe Rubycritic::SmellsAggregator do
|
5
|
+
context "when when analysing smelly files" do
|
6
|
+
before do
|
7
|
+
@location1 = Rubycritic::Location.new("./foo", "42")
|
8
|
+
@location2 = Rubycritic::Location.new("./bar", "23")
|
9
|
+
@location3 = Rubycritic::Location.new("./bar", "16")
|
10
|
+
@smell1 = Rubycritic::Smell.new(:locations => [@location1])
|
11
|
+
@smell2 = Rubycritic::Smell.new(:locations => [@location2, @location3])
|
12
|
+
@smell_adapters = [stub(:smells => [@smell1]), stub(:smells => [@smell2])]
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#smells" do
|
16
|
+
it "returns the smells found in those files" do
|
17
|
+
smells = [@smell2, @smell1]
|
18
|
+
Rubycritic::SmellsAggregator.new(@smell_adapters).smells.must_equal smells
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#smelly_pathnames" do
|
23
|
+
it "returns the files where smells were found" do
|
24
|
+
smelly_pathnames = {@location1.pathname => [@smell1], @location2.pathname => [@smell2]}
|
25
|
+
Rubycritic::SmellsAggregator.new(@smell_adapters).smelly_pathnames.must_equal smelly_pathnames
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when analysing files with no smells" do
|
31
|
+
before do
|
32
|
+
@smell_adapters = [stub(:smells => [])]
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#smells" do
|
36
|
+
it "returns an empty array" do
|
37
|
+
Rubycritic::SmellsAggregator.new(@smell_adapters).smells.must_equal []
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#smelly_pathnames" do
|
42
|
+
it "returns an empty hash" do
|
43
|
+
Rubycritic::SmellsAggregator.new(@smell_adapters).smelly_pathnames.must_equal({})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rubycritic/source_locator"
|
3
|
+
|
4
|
+
describe Rubycritic::SourceLocator do
|
5
|
+
before do
|
6
|
+
@original_dir = Dir.pwd
|
7
|
+
Dir.chdir("test/samples/location")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#paths" do
|
11
|
+
it "finds a single path" do
|
12
|
+
paths = ["file0.rb"]
|
13
|
+
Rubycritic::SourceLocator.new(paths).paths.must_equal paths
|
14
|
+
end
|
15
|
+
|
16
|
+
it "finds multiple paths" do
|
17
|
+
paths = ["dir1/file1.rb", "file0.rb"]
|
18
|
+
Rubycritic::SourceLocator.new(paths).paths.must_equal paths
|
19
|
+
end
|
20
|
+
|
21
|
+
it "finds all the paths" do
|
22
|
+
paths = ["dir1/file1.rb", "file0.rb"]
|
23
|
+
Rubycritic::SourceLocator.new(["."]).paths.must_equal paths
|
24
|
+
end
|
25
|
+
|
26
|
+
it "deals with non-existent paths" do
|
27
|
+
paths = ["non_existent_dir1/non_existent_file1.rb", "non_existent_file0.rb"]
|
28
|
+
Rubycritic::SourceLocator.new(paths).paths.must_equal []
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#pathnames" do
|
33
|
+
it "finds a single path" do
|
34
|
+
path = "file0.rb"
|
35
|
+
paths = [path]
|
36
|
+
result = [Pathname.new(path)]
|
37
|
+
Rubycritic::SourceLocator.new(paths).pathnames.must_equal result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
after do
|
42
|
+
Dir.chdir(@original_dir)
|
43
|
+
end
|
44
|
+
end
|
File without changes
|
File without changes
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubycritic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guilherme Simoes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: virtus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: flog
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: reek
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.6
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3.6
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '5.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: mocha
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.0'
|
111
|
+
description: |2
|
112
|
+
Ruby Critic is a tool that detects and reports smells in Ruby classes, modules and methods.
|
113
|
+
email:
|
114
|
+
- guilherme.rdems@gmail.com
|
115
|
+
executables:
|
116
|
+
- rubycritic
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".gitignore"
|
121
|
+
- CONTRIBUTING.md
|
122
|
+
- Gemfile
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- SPEC.md
|
127
|
+
- bin/rubycritic
|
128
|
+
- lib/rubycritic.rb
|
129
|
+
- lib/rubycritic/analysers/config.reek
|
130
|
+
- lib/rubycritic/analysers/flog.rb
|
131
|
+
- lib/rubycritic/analysers/reek.rb
|
132
|
+
- lib/rubycritic/cli.rb
|
133
|
+
- lib/rubycritic/location.rb
|
134
|
+
- lib/rubycritic/report_generators/assets/stylesheets/application.css
|
135
|
+
- lib/rubycritic/report_generators/file_generator.rb
|
136
|
+
- lib/rubycritic/report_generators/line_generator.rb
|
137
|
+
- lib/rubycritic/report_generators/report_generator.rb
|
138
|
+
- lib/rubycritic/report_generators/templates/file.html.erb
|
139
|
+
- lib/rubycritic/report_generators/templates/layouts/application.html.erb
|
140
|
+
- lib/rubycritic/report_generators/templates/line.html.erb
|
141
|
+
- lib/rubycritic/report_generators/templates/smelly_line.html.erb
|
142
|
+
- lib/rubycritic/smell.rb
|
143
|
+
- lib/rubycritic/smell_adapters/flog.rb
|
144
|
+
- lib/rubycritic/smell_adapters/reek.rb
|
145
|
+
- lib/rubycritic/smells_aggregator.rb
|
146
|
+
- lib/rubycritic/source_locator.rb
|
147
|
+
- lib/rubycritic/version.rb
|
148
|
+
- rubycritic.gemspec
|
149
|
+
- test/lib/rubycritic/location_test.rb
|
150
|
+
- test/lib/rubycritic/metric_adapters/flog_adapter_test.rb
|
151
|
+
- test/lib/rubycritic/metric_adapters/reek_adapter_test.rb
|
152
|
+
- test/lib/rubycritic/smell_test.rb
|
153
|
+
- test/lib/rubycritic/smells_aggregator_test.rb
|
154
|
+
- test/lib/rubycritic/source_locator_test.rb
|
155
|
+
- test/lib/rubycritic/version_test.rb
|
156
|
+
- test/samples/flog/smelly.rb
|
157
|
+
- test/samples/location/dir1/file1.rb
|
158
|
+
- test/samples/location/file0.rb
|
159
|
+
- test/samples/reek/not_smelly.rb
|
160
|
+
- test/samples/reek/smelly.rb
|
161
|
+
- test/test_helper.rb
|
162
|
+
homepage: https://github.com/GuilhermeSimoes/rubycritic
|
163
|
+
licenses:
|
164
|
+
- MIT
|
165
|
+
metadata: {}
|
166
|
+
post_install_message:
|
167
|
+
rdoc_options: []
|
168
|
+
require_paths:
|
169
|
+
- lib
|
170
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
requirements: []
|
181
|
+
rubyforge_project:
|
182
|
+
rubygems_version: 2.1.11
|
183
|
+
signing_key:
|
184
|
+
specification_version: 4
|
185
|
+
summary: Ruby code smell detector
|
186
|
+
test_files:
|
187
|
+
- test/lib/rubycritic/location_test.rb
|
188
|
+
- test/lib/rubycritic/metric_adapters/flog_adapter_test.rb
|
189
|
+
- test/lib/rubycritic/metric_adapters/reek_adapter_test.rb
|
190
|
+
- test/lib/rubycritic/smell_test.rb
|
191
|
+
- test/lib/rubycritic/smells_aggregator_test.rb
|
192
|
+
- test/lib/rubycritic/source_locator_test.rb
|
193
|
+
- test/lib/rubycritic/version_test.rb
|
194
|
+
- test/samples/flog/smelly.rb
|
195
|
+
- test/samples/location/dir1/file1.rb
|
196
|
+
- test/samples/location/file0.rb
|
197
|
+
- test/samples/reek/not_smelly.rb
|
198
|
+
- test/samples/reek/smelly.rb
|
199
|
+
- test/test_helper.rb
|