Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6836dd9
This commit will have changes in rubycritic where you can compare two…
Oct 10, 2016
6e691f1
This commit has changes where we can decide which of the file changes…
Oct 13, 2016
675a08a
Comparing the diff with the whole branch for duplication analysis
Oct 17, 2016
c34ae94
Configuring smell link to point to feature branch code
Oct 20, 2016
3b77fd1
Changes in the content of the build details
Oct 20, 2016
a694137
Gitlab Integration
Oct 24, 2016
5560a78
Code cleanup
Oct 24, 2016
d52cdc4
Specs and code cleanup
Nov 14, 2016
c1a0938
Fix some ruby warnings thrown on rake test
tejasbubane Nov 14, 2016
bae045b
Merge pull request #183 from tejasbubane/fix-warnings
troessner Nov 14, 2016
de8d037
Code Cleanup & Refactoring
Nov 15, 2016
be7827f
Added specs and threshold option
Nov 16, 2016
879833a
Removing simplecov from dependency
Nov 16, 2016
13502f0
Refactoring compare module
Nov 17, 2016
57257da
Code cleanup
Nov 18, 2016
c251517
Options and compare changes
Nov 21, 2016
f34bf45
Revamp the web UI
rohitcy Nov 13, 2016
b977b62
Merge pull request #184 from cybrilla/new-web-ui
nunosilva800 Nov 23, 2016
0cb3f57
Bump to v3.1.0
nunosilva800 Nov 23, 2016
871a38e
Merge pull request #185 from whitesmith/bump-to-3.1
troessner Nov 23, 2016
86557cc
Add screenshot of new ui [ci skip]
nav16 Nov 23, 2016
b5e532d
Merge pull request #186 from nav16/update-readme
troessner Nov 23, 2016
4f70be6
Fixing the options fetaure spec
Nov 24, 2016
f25a40f
Code cleanup and changes
Nov 25, 2016
112e0a5
Spec fix
Nov 25, 2016
8d0ebe0
Abort message changes
Nov 25, 2016
eb9e54a
This commit will have changes in rubycritic where you can compare two…
Oct 10, 2016
696446c
This commit has changes where we can decide which of the file changes…
Oct 13, 2016
afe93c0
Comparing the diff with the whole branch for duplication analysis
Oct 17, 2016
1a515d7
Configuring smell link to point to feature branch code
Oct 20, 2016
1da67e7
Changes in the content of the build details
Oct 20, 2016
4621e76
Gitlab Integration
Oct 24, 2016
d1b7c8c
Code cleanup
Oct 24, 2016
928e0d5
Specs and code cleanup
Nov 14, 2016
a9c5816
Code Cleanup & Refactoring
Nov 15, 2016
1ffd473
Added specs and threshold option
Nov 16, 2016
e662df3
Refactoring compare module
Nov 17, 2016
920fe15
Code cleanup
Nov 18, 2016
6662c81
Options and compare changes
Nov 21, 2016
7ff1634
Fixing the options fetaure spec
Nov 24, 2016
d0713e2
Code cleanup and changes
Nov 25, 2016
4e32d16
Spec fix
Nov 25, 2016
317a3c9
Abort message changes
Nov 25, 2016
34d57e9
Adding links in the navbar
Nov 25, 2016
58d9ce1
Merge Fixes
Nov 25, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ tmp
.idea/
.ruby-gemset
.ruby-version
.DS_Store
*.DS_Store
10 changes: 10 additions & 0 deletions .todo.reek
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ Attribute:
- RubyCritic::Configuration#open_with
- RubyCritic::Configuration#source_control_system
- RubyCritic::Configuration#suppress_ratings
- RubyCritic::Configuration#base_branch
- RubyCritic::Configuration#base_branch_score
- RubyCritic::Configuration#base_root_directory
- RubyCritic::Configuration#build_root_directory
- RubyCritic::Configuration#feature_branch
- RubyCritic::Configuration#feature_branch_score
- RubyCritic::Configuration#feature_root_directory
- RubyCritic::Configuration#threshold_score
- RubyCritic::Configuration#base_branch_collection
- RubyCritic::Configuration#feature_branch_collection
- RubyCritic::RakeTask#name
- RubyCritic::RakeTask#options
- RubyCritic::RakeTask#paths
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# 3.1.0 / 2016-11-23

* [FEATURE] Support for Perforce source control system (by Loic Gudet)
* [CHANGE] New Web UI (by tejasbubane)
* [CHANGE] Significant improvements to documentation (by olleolleolle)
* [CHANGE] Typo / consistency updates to features and tests (by olleolleolle)
* [CHANGE] Fix test warnings and upgrade 'parser' to '2.3.1.4' (by tejasbubane)
* [BUGFIX] Increase the turboThreshold of Highcharts so that it renders nicely even with lots of data (by Victor Martins)

# 3.0.0 / 2016-11-01

* [CHANGE] Set required ruby version to 2.1 (by Onumis)
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RubyCritic
[![Build Status](https://travis-ci.org/whitesmith/rubycritic.svg?branch=master)](https://travis-ci.org/whitesmith/rubycritic)
[![Code Climate](https://codeclimate.com/github/whitesmith/rubycritic/badges/gpa.svg)](https://codeclimate.com/github/whitesmith/rubycritic)

<img src="http://i.imgur.com/66HACCD.png" alt="RubyCritic Icon" align="right" />
<img src="/images/logo.png" alt="RubyCritic Icon" align="right" />
RubyCritic is a gem that wraps around static analysis gems such as [Reek][1], [Flay][2] and [Flog][3] to provide a quality report of your Ruby code.

**Table of Contents**
Expand All @@ -28,15 +28,15 @@ This gem provides features such as:

1. An overview of your project:

![RubyCritic overview screenshot](http://i.imgur.com/oiE5O3X.png)
![RubyCritic overview screenshot](/images/overview.png)

2. An index of the project files with their respective number of smells:

![RubyCritic code index screenshot](http://i.imgur.com/a0GCn48.png)
![RubyCritic code index screenshot](/images/code.png)

3. An index of the smells detected:

![RubyCritic smells index screenshot](http://i.imgur.com/PvkFEe3.png)
![RubyCritic smells index screenshot](/images/smells.png)

4. When analysing code like the following:

Expand All @@ -52,11 +52,11 @@ This gem provides features such as:

It basically turns something like this:

![Reek output screenshot](http://i.imgur.com/5G2zPIC.png)
![Reek output screenshot](/images/reek.png)

Into something like this:

![RubyCritic file code screenshot](http://i.imgur.com/RNzXewk.png)
![RubyCritic file code screenshot](/images/smell-details.png)

5. It uses your source control system (only Git, Mercurial and Perforce
are currently supported) to compare your currently uncommitted
Expand Down Expand Up @@ -215,7 +215,7 @@ The current core team consists of:

## Credits

![Whitesmith](http://i.imgur.com/Si2l3kd.png)
![Whitesmith](/images/whitesmith.png)

RubyCritic is maintained and funded by [Whitesmith][9]. Tweet your questions or suggestions to [@Whitesmithco][10].

Expand Down
6 changes: 3 additions & 3 deletions docs/core-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RubyCritic wraps around static analysis gems such as [Reek][2], [Flay][3] and [Flog][4] to provide a quality report of your Ruby code.

Each of these gems are internally wrapped as an **Analyser**, with a collection of **AnalysedModule**s, which give us calculations of key metrics.
The most important ones are **churn**, **complexity**, **cost** and **rating**.
The most important ones are **churn**, **complexity**, **cost** and **rating**.

The output of RubyCritic will give you four values to help you judge your code's _odorousness_:

Expand Down Expand Up @@ -40,7 +40,7 @@ Complexity is the output of [Flog][4]. You can [read more about how it works][7]

Both **churn** and **complexity** are presented as a chart:

![RubyCritic overview screenshot](http://i.imgur.com/oiE5O3X.png)
![RubyCritic overview screenshot](/images/churn-vs-complexity.png)

Each file is represented by a dot. **The closer they are to the bottom-left corner, the better.**
But keep in mind that you cannot reduce churn (well... not unless you re-write your repo's history :neckbeard:), so try to keep the dots as close to the bottom as possible.
Expand All @@ -54,7 +54,7 @@ Generally `A`'s & `B`'s are good enough, `C`'s serve as a warning and `D`'s & `F

**Rating** is simply [a conversion][5] from the calculated **cost** to a letter.

![RubyCritic code index screenshot](http://i.imgur.com/a0GCn48.png)
![RubyCritic code index screenshot](/images/rating.png)

### Cost

Expand Down
4 changes: 4 additions & 0 deletions features/command_line_interface/options.feature
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Feature: RubyCritic can be controlled using command-line options
"""
Usage: rubycritic [options] [paths]
-p, --path [PATH] Set path where report will be saved (tmp/rubycritic by default)
-b BASE_BRANCH,FEATURE_BRANCH, Set branches
--branch
-t [THRESHOLD_SCORE], Set a threshold score works only with -b option
--threshold-score
-f, --format [FORMAT] Report smells in the given format:
html (default; will open in a browser)
json
Expand Down
Binary file added images/churn-vs-complexity.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/code.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/rating.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/reek.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/smell-details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/smells.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/whitesmith.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions lib/rubycritic/analysis_summary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

module RubyCritic
class AnalysisSummary
def self.generate(analysed_modules)
new(analysed_modules).generate
end

def initialize(analysed_modules)
@analysed_modules = analysed_modules
end

def generate
%w(A B C D F).each_with_object({}) do |rating, summary|
summary[rating] = generate_for(rating)
end
end

private

attr_reader :analysed_modules, :modules

def generate_for(rating)
@modules = analysed_modules.for_rating(rating)
{
files: modules.count,
churns: churns,
smells: smells
}
end

def churns
modules.inject(0) { |acc, elem| acc + elem.churn }
end

def smells
modules.inject(0) { |acc, elem| acc + elem.smells.count }
end
end
end
17 changes: 15 additions & 2 deletions lib/rubycritic/cli/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ def parse
@root = path
end

opts.on('-b', '--branch BASE_BRANCH,FEATURE_BRANCH', 'Set branches to compare') do |branches|
self.base_branch, self.feature_branch = branches.split(',').map { |branch| String(branch) }
self.mode = :compare_branches
end

opts.on('-t', '--threshold-score [THRESHOLD_SCORE]', 'Set a threshold score works only with -b option') do |threshold_score|
self.threshold_score = Integer(threshold_score)
end

opts.on(
'-f', '--format [FORMAT]',
[:html, :json, :console],
Expand Down Expand Up @@ -71,14 +80,18 @@ def to_h
suppress_ratings: suppress_ratings,
help_text: parser.help,
minimum_score: minimum_score || 0,
no_browser: no_browser
no_browser: no_browser,
base_branch: base_branch,
feature_branch: feature_branch,
threshold_score: threshold_score || 0
}
end

private

attr_accessor :mode, :root, :format, :deduplicate_symlinks,
:suppress_ratings, :minimum_score, :no_browser, :parser
:suppress_ratings, :minimum_score, :no_browser,
:parser, :base_branch, :feature_branch, :threshold_score
def paths
if @argv.empty?
['.']
Expand Down
3 changes: 3 additions & 0 deletions lib/rubycritic/command_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ def self.command_class(mode)
when :ci
require 'rubycritic/commands/ci'
Command::Ci
when :compare_branches
require 'rubycritic/commands/compare'
Command::Compare
else
require 'rubycritic/commands/default'
Command::Default
Expand Down
129 changes: 129 additions & 0 deletions lib/rubycritic/commands/compare.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# frozen_string_literal: true
require 'rubycritic/source_control_systems/base'
require 'rubycritic/analysers_runner'
require 'rubycritic/revision_comparator'
require 'rubycritic/reporter'
require 'rubycritic/commands/base'
require 'rubycritic/commands/default'

module RubyCritic
module Command
class Compare < Default
def initialize(options)
super
end

def execute
Config.no_browser = true
compare_branches
status_reporter.score = Config.feature_branch_score
status_reporter
end

private

attr_reader :paths, :status_reporter

def compare_branches
update_build_number
set_root_paths
analyse_branch(:base_branch)
analyse_branch(:feature_branch)
analyse_modified_files
compare_code_quality
end

# keep track of the number of builds and
# use this build number to create seperate directory for each build
def update_build_number
build_file_location = '/tmp/build_count.txt'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention the use of this count file as a comment above the method.

File.new(build_file_location, 'a') unless File.exist?(build_file_location)
@number = File.open(build_file_location).readlines.first.to_i + 1
File.write(build_file_location, @number)
end

def set_root_paths
Config.base_root_directory = Pathname.new(branch_directory(:base_branch))
Config.feature_root_directory = Pathname.new(branch_directory(:feature_branch))
Config.build_root_directory = Pathname.new(build_directory)
end

# switch branch and analyse files
def analyse_branch(branch)
SourceControlSystem::Git.switch_branch(Config.send(branch))
critic = critique(branch)
Config.send(:"#{branch}_score=", critic.score)
Config.root = branch_directory(branch)
report(critic)
end

# generate report only for modified files
def analyse_modified_files
Config.no_browser = false
defected_modules = Config.feature_branch_collection.where(modified_files)
analysed_modules = AnalysedModulesCollection.new(defected_modules.map(&:path), defected_modules)
Config.root = build_directory
report(analysed_modules)
end

def compare_code_quality
build_details
compare_threshold
end

# mark build as failed if the diff b/w the score of
# two branches is greater than threshold value
def compare_threshold
if mark_build_fail?
print("Threshold: #{Config.threshold_score}\n")
print("Difference: #{(Config.base_branch_score - Config.feature_branch_score).abs}\n")
abort('The score difference between the two branches is over the threshold.')
end
end

def mark_build_fail?
threshold_values_set? && threshold_reached?
end

def threshold_values_set?
Config.threshold_score > 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if threshold is nil this will fail with undefined method>' for nil:NilClass`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix this

end

def threshold_reached?
(Config.base_branch_score - Config.feature_branch_score).abs > Config.threshold_score
end

def branch_directory(branch)
"tmp/rubycritic/compare/#{Config.send(branch)}"
end

def build_directory
"tmp/rubycritic/compare/builds/build_#{@number}"
end

# create a txt file with the branch score details
def build_details
details = "Base branch (#{Config.base_branch}) score: #{Config.base_branch_score.to_s} \n"\
"Feature branch (#{Config.feature_branch}) score: #{Config.feature_branch_score.to_s} \n"
File.open("#{Config.build_root_directory}/build_details.txt", 'w') { |file| file.write(details) }
end

# get the modified files in the feature branch
def modified_files
modified_files = SourceControlSystem::Git.modified_files
modified_files.split("\n").map do |line|
next if line.start_with?('D')
status, file_name = line.split("\t")
file_name
end.compact
end

# store the analysed moduled collection based on the branch
def critique(branch)
module_collection = AnalysersRunner.new(paths).run
Config.send(:"#{branch}_collection=", module_collection)
RevisionComparator.new(paths).set_statuses(module_collection)
end
end
end
end
9 changes: 8 additions & 1 deletion lib/rubycritic/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ module RubyCritic
class Configuration
attr_reader :root
attr_accessor :source_control_system, :mode, :format, :deduplicate_symlinks,
:suppress_ratings, :open_with, :no_browser
:suppress_ratings, :open_with, :no_browser, :base_branch,
:feature_branch, :base_branch_score, :feature_branch_score,
:base_root_directory, :feature_root_directory,
:build_root_directory, :threshold_score, :base_branch_collection,
:feature_branch_collection

def set(options)
self.mode = options[:mode] || :default
Expand All @@ -13,6 +17,9 @@ def set(options)
self.suppress_ratings = options[:suppress_ratings] || false
self.open_with = options[:open_with]
self.no_browser = options[:no_browser]
self.base_branch = options[:base_branch]
self.feature_branch = options[:feature_branch]
self.threshold_score = options[:threshold_score]
end

def root=(path)
Expand Down
Loading