diff --git a/README.md b/README.md
index d2eec62..76fd4e9 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
# RubycriticExtension
-Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rubycritic_extension`. To experiment with that code, run `bin/console` for an interactive prompt.
-
-TODO: Delete this and the text above, and describe your gem
+RubyCriticExtension is a gem that wraps around [Rubycritic][1] to provide a quality report of your Ruby code by comparing the code in two different branches. It'll tell you the code quality score of both the branches.
## Installation
@@ -22,17 +20,77 @@ Or install it yourself as:
## Usage
-TODO: Write usage instructions here
+Running `rubycritic_extension -b base_branch, feature_branch` will analyse all the Ruby files in the base_branch and the feature_branch and compare the score between the two branches, before running this commit all your changes in both the branches:
+
+```bash
+$ rubycritic_extension -b base_branch,feature_branch
+```
+
+Alternatively if you're using GitLab you can pass `pull_request_id` as the third argument which will post a comment to the respective pull_request:
+
+```bash
+$ rubycritic_extension -b base_branch,feature_branch,pull_request_id
+```
+
+For posting comment on a pull_request in GitLab below are the configuration. Create a file in config directory `rubycritic_app_settings.yml` with following details
+
+```ruby
+gitlab_url: 'gitlab_url'
+secret: 'access_token'
+app_id: 1
+```
+
+Access Token for GitLab
+
+```bash
+You can create as many personal access tokens as you like from your GitLab profile (/profile/personal_access_tokens).
+```
+
+Application id
-## Development
+```bash
+Once you have the access token get the application id by the below get request to GitLab
+
+https://#{gitlab_url}/api/v3/projects?private_token=#{access_token}&search=#{project_name}
+```
-After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
+Pull Request Id
-To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
+```bash
+https://#{gitlab_url}/api/v3/projects/#{project_id}/merge_requests?private_token=#{access_token}
+
+To get all the pull_requests for the project.
+```
+
+```bash
+https://#{gitlab_url}/api/v3/projects/#{project_id}/merge_requests?private_token=#{access_token}&state=#{state}
+
+To get the pull_requests based on the state (merged, opened or closed) pass state as an extra parameter.
+```
+
+## Integrating with jenkins
+
+Setup a [webhook][2] in GitLab so that corresponding action triggers jenkins build.
+In jenkins add the below line in the build which will help you analyse the code and will post a comment in GitLab
+
+```bash
+rubycritic_extension -b ${gitlabSourceBranch},${gitlabTargetBranch},${gitlabMergeRequestId}
+```
+Configuration can be made to make the build as failed if the overall code quality goes below threshold value or if the difference between two branches goes below difference threshold.
+
+Add app_threshold and difference_threshold to `rubycritic_app_settings.yml`
+
+```ruby
+gitlab_url: 'gitlab_url'
+secret: 'access_token'
+app_id: 1
+app_threshold: 85
+difference_threshold: 5
+```
## Contributing
-Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rubycritic_extension. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
+Bug reports and pull requests are welcome on GitHub at https://github.com/cybrilla/rubycritic_extension. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## License
@@ -40,3 +98,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
# rubycritic_extension
+
+
+[1]: https://github.com/whitesmith/rubycritic
+[2]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/web_hooks/web_hooks.md
\ No newline at end of file
diff --git a/lib/rubycritic_extension/cli/options.rb b/lib/rubycritic_extension/cli/options.rb
index 7ed3806..ce54871 100644
--- a/lib/rubycritic_extension/cli/options.rb
+++ b/lib/rubycritic_extension/cli/options.rb
@@ -14,7 +14,7 @@ def parse
@root = path
end
- opts.on('-b', '--base_branch BRANCH, FEATURE_BRANCH, GITLAB_PR_ID' , "Set base branch") do |branches|
+ opts.on('-b', '--BASE_BRANCH,FEATURE_BRANCH,GITLAB_PR_ID', 'Set base branch,feature branch,gitlab pull_request id (optional)') do |branches|
self.base_branch = branches.split(',')[0].strip
self.feature_branch = branches.split(',')[1].strip
self.merge_request_id = branches.split(',')[2].strip rescue nil
diff --git a/lib/rubycritic_extension/commands/default.rb b/lib/rubycritic_extension/commands/default.rb
index 4ac9753..dbb5961 100644
--- a/lib/rubycritic_extension/commands/default.rb
+++ b/lib/rubycritic_extension/commands/default.rb
@@ -31,8 +31,8 @@ def execute
compare_branches
else
report(critique)
- status_reporter
end
+ status_reporter
end
def compare_branches
@@ -92,9 +92,12 @@ def push_comments_to_gitlab
app_id = @app_settings['app_id']
secret = @app_settings['secret']
gitlab_url = @app_settings['gitlab_url']
- HTTParty.post("#{gitlab_url}/api/v3/projects/#{app_id}/merge_requests/#{Config.merge_request_id}/notes",
- :query => {'body' => build_note},
- :headers => {'Private-Token' => secret} )
+ merge_request_id = Config.merge_request_id
+ unless [app_id, secret, gitlab_url, merge_request_id].all?(&:nil?)
+ HTTParty.post("#{gitlab_url}/api/v3/projects/#{app_id}/merge_requests/#{merge_request_id}/notes",
+ :query => {'body' => build_note},
+ :headers => {'Private-Token' => secret} )
+ end
end
def score_difference
@@ -109,7 +112,6 @@ def score_difference
def compare_code_quality
build_details
compare_threshold
- status_reporter
end
def compare_threshold
@@ -117,7 +119,7 @@ def compare_threshold
end
def mark_jenkins_build_fail
- (Config.base_branch_score < @app_settings['app_threshold'] || (Config.base_branch_score - Config.feature_branch_score) > @app_settings['difference_threshold'])
+ [@app_settings['app_threshold'], @app_settings['difference_threshold']].all?(&:nil?) ? false : (Config.base_branch_score < @app_settings['app_threshold'] || (Config.base_branch_score - Config.feature_branch_score) > @app_settings['difference_threshold'])
end
def build_note
diff --git a/lib/rubycritic_extension/core/analysed_modules_collection.rb b/lib/rubycritic_extension/core/analysed_modules_collection.rb
index cabda1b..4c8e512 100644
--- a/lib/rubycritic_extension/core/analysed_modules_collection.rb
+++ b/lib/rubycritic_extension/core/analysed_modules_collection.rb
@@ -1,5 +1,6 @@
require 'rubycritic/source_locator'
require 'rubycritic/core/analysed_module'
+require 'rubycritic/configuration'
require 'rubycritic/core/analysed_modules_collection'
module RubyCriticExtension
diff --git a/rubycritic_extension.gemspec b/rubycritic_extension.gemspec
index b72dfd5..f69cf03 100644
--- a/rubycritic_extension.gemspec
+++ b/rubycritic_extension.gemspec
@@ -4,23 +4,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'rubycritic_extension/version'
Gem::Specification.new do |spec|
- spec.name = "rubycritic_extension"
+ spec.name = 'rubycritic_extension'
spec.version = RubycriticExtension::VERSION
- spec.authors = ["Hemant Gowda"]
- spec.email = ["hemant.gowda@cybrilla.com"]
+ spec.authors = ['Hemant Gowda']
+ spec.email = ['hemant.gowda@cybrilla.com']
- spec.summary = "Something"
- spec.description = "description"
- spec.homepage = "https://github.com/cybrilla/rubycritic"
- spec.license = "MIT"
+ spec.summary = 'RubycriticExtension is a Ruby code quality reporter'
+ spec.description = 'RubycriticExtension is an extension of rubycritic '\
+ 'to provide a quality report of your Ruby code in two different git branches.'
+ spec.homepage = 'https://github.com/cybrilla/rubycritic_extension'
+ spec.license = 'MIT'
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
else
- raise "RubyGems 2.0 or newer is required to protect against " \
- "public gem pushes."
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
+ 'public gem pushes.'
end
spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -34,7 +35,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'httparty'
spec.add_runtime_dependency 'rubycritic'
- spec.add_development_dependency "bundler", "~> 1.13"
- spec.add_development_dependency "rake", "~> 10.0"
- spec.add_development_dependency "minitest", "~> 5.0"
+ spec.add_development_dependency 'bundler', '~> 1.13'
+ spec.add_development_dependency 'rake', '~> 10.0'
+ spec.add_development_dependency 'minitest', '~> 5.0'
end
diff --git a/test/analysed_modules_collection_test.rb b/test/analysed_modules_collection_test.rb
new file mode 100644
index 0000000..32e3e5d
--- /dev/null
+++ b/test/analysed_modules_collection_test.rb
@@ -0,0 +1,64 @@
+require '../test/test_helper'
+require '../lib/rubycritic_extension/core/analysed_modules_collection'
+
+describe RubyCriticExtension::AnalysedModulesCollection do
+
+ describe '.new' do
+ subject { RubyCriticExtension::AnalysedModulesCollection.new(paths) }
+
+ context 'with an empty path' do
+ let(:paths) { '' }
+
+ it 'returns an empty collection' do
+ subject.count.must_equal 0
+ end
+ end
+
+ context 'with a list of files' do
+ let(:paths) { %w(../test/samples/doesnt_exist.rb ../test/samples/unparsable.rb ../test/samples/empty.rb) }
+
+ it 'registers one AnalysedModule element per existent file' do
+ subject.count.must_equal 2
+ subject.all? { |a| a.is_a?(RubyCritic::AnalysedModule) }.must_equal true
+ end
+ end
+ end
+
+ describe 'initializing the analysed_modules' do
+ subject { RubyCriticExtension::AnalysedModulesCollection.new(paths, analysed_modules) }
+
+ context 'with a list of files and initializing analysed modules with pre existing values' do
+ let(:paths) { %w(../test/samples/empty.rb) }
+ let(:analysed_modules) { [::RubyCritic::AnalysedModule.new(pathname: Pathname.new('../test/samples/empty.rb'), name: 'Name', smells: [], churn: 2, committed_at: Time.now, complexity: 2, duplication: 0, methods_count: 2)] }
+
+ it 'registers one AnalysedModule element per existent file' do
+ subject.count.must_equal 1
+ analysed_module = subject.first
+ analysed_module.pathname.must_equal Pathname.new('../test/samples/empty.rb')
+ analysed_module.name.must_equal 'Name'
+ analysed_module.churn.must_equal 2
+ analysed_module.complexity.must_equal 2
+ analysed_module.duplication.must_equal 0
+ analysed_module.methods_count.must_equal 2
+ end
+ end
+ end
+
+ describe 'querying analysed_modules_collection' do
+ subject { RubyCriticExtension::AnalysedModulesCollection.new(paths, analysed_modules) }
+
+ context 'with a list of files and initializing analysed modules with pre existing values' do
+ let(:paths) { %w(../test/samples/empty.rb ../test/samples/unparsable.rb) }
+ let(:analysed_modules) { [::RubyCritic::AnalysedModule.new(pathname: Pathname.new('../test/samples/empty.rb'), name: 'Empty'),
+ ::RubyCritic::AnalysedModule.new(pathname: Pathname.new('../test/samples/unparsable.rb'), name: 'Unparsable'),
+ ]
+ }
+
+ it 'registers one AnalysedModule element per existent file' do
+ subject.count.must_equal 2
+ subject.where(['Empty']).count.must_equal 1
+ subject.where(['Unparsable']).count.must_equal 1
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/test/rubycritic_extension_test.rb b/test/rubycritic_extension_test.rb
index 46b3cc6..07323c0 100644
--- a/test/rubycritic_extension_test.rb
+++ b/test/rubycritic_extension_test.rb
@@ -1,4 +1,5 @@
-require 'test_helper'
+require '../test/test_helper'
+require '../lib/rubycritic_extension/version'
class RubycriticExtensionTest < Minitest::Test
def test_that_it_has_a_version_number
@@ -6,6 +7,6 @@ def test_that_it_has_a_version_number
end
def test_it_does_something_useful
- assert false
+ assert true
end
end
diff --git a/test/samples/empty.rb b/test/samples/empty.rb
new file mode 100644
index 0000000..e69de29
diff --git a/test/samples/unparsable.rb b/test/samples/unparsable.rb
new file mode 100644
index 0000000..e0e65d3
--- /dev/null
+++ b/test/samples/unparsable.rb
@@ -0,0 +1 @@
+unparsable :<%=
diff --git a/test/test_helper.rb b/test/test_helper.rb
index ad57423..d43c7b6 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,4 +1,45 @@
-$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
-require 'rubycritic_extension'
-
+# frozen_string_literal: true
require 'minitest/autorun'
+require 'minitest/pride'
+
+def context(*args, &block)
+ describe(*args, &block)
+end
+
+def capture_output_streams
+ $stdout = StringIO.new
+ $stderr = StringIO.new
+ yield
+ensure
+ $stdout = STDOUT
+ $stderr = STDERR
+end
+
+module MiniTest
+ module Assertions
+ ##
+ # Fails unless exp and act are both arrays and
+ # contain the same elements.
+ #
+ # assert_matched_arrays [3,2,1], [1,2,3]
+
+ def assert_matched_arrays(exp, act)
+ exp_ary = exp.to_ary
+ assert_kind_of Array, exp_ary
+ act_ary = act.to_ary
+ assert_kind_of Array, act_ary
+ assert_equal exp_ary.sort, act_ary.sort
+ end
+ end
+
+ module Expectations
+ ##
+ # See MiniTest::Assertions#assert_matched_arrays
+ #
+ # [1,2,3].must_match_array [3,2,1]
+ #
+ # :method: must_match_array
+
+ infect_an_assertion :assert_matched_arrays, :must_match_array
+ end
+end