skunk 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: ef09af7a1b681dd7ed6c4d647722be36f1f31fb1475127bf7179f74a8387b2b1
4
- data.tar.gz: 02d009e31e053fc944efcff71d87688e9132509fc9911948245a83cc559b4107
3
+ metadata.gz: df70466af9db8ae3849245db231b15bcee039470542d750b54dc27d6cc27f11f
4
+ data.tar.gz: eed948e603c3f94226ed2eb4ede37397f731675401d34d70731069113af233c2
5
5
  SHA512:
6
- metadata.gz: 116a79026c8c16e72012063e5d59b5191f21ca57115fbbe810d44ce03608284ec1090e71e14e0e828411ea779e7593d8408967e80d34851cfc1630f3d7c191d9
7
- data.tar.gz: 546637856b882b66d974110e7dc7756166fdcd194d4ab351888f75664460e25bd4356e3002e3756f0ea6c3614fec992a693b52681f4fe0374339397892cc5ee4
6
+ metadata.gz: 93b44bae842a25cca17a1708bbe2b7ba1a1b4fea072130d9609967fad908f16c0d54b16df3eb8c21e4cf222414a925bb671c9b06782b9aa3576c2893d96db1ee
7
+ data.tar.gz: f7ef68ea2c9b5513183aec2757380e6b62b53def85be94d9e144562d47d9352e30703f81e99f18db7b8b2d8ceb526a5cffb896054f60f049171388d9333dbaa6
data/.reek.yml CHANGED
@@ -4,22 +4,22 @@ detectors:
4
4
  UtilityFunction:
5
5
  exclude:
6
6
  - capture_output_streams
7
+ - Skunk::Command::Compare#analyse_modified_files
8
+ - Skunk::Command::Compare#build_details_path
7
9
  InstanceVariableAssumption:
8
10
  exclude:
9
11
  - Skunk::Cli::Application
10
12
  - Skunk::Cli::Command::Default
11
- IrresponsibleModule:
12
- exclude:
13
- - Skunk::Cli::Application
14
- - Skunk::Cli::Command::Default
15
- - Skunk::Cli::Command::Help
16
- - Skunk::Command::StatusReporter
17
- - Skunk::Cli::Options
18
- - RubyCritic::AnalysedModule
13
+ - RubyCritic::AnalysedModulesCollection
19
14
  TooManyStatements:
20
15
  exclude:
21
16
  - initialize
22
17
  - Skunk::Cli::Application#execute
18
+ IrresponsibleModule:
19
+ exclude:
20
+ - Skunk::Cli::Command::Help
21
+ - Skunk::Cli::Options
22
+ - RubyCritic::AnalysedModulesCollection
23
23
  Attribute:
24
24
  exclude:
25
25
  - Skunk::Command::StatusReporter#analysed_modules
data/.rubocop_todo.yml CHANGED
@@ -1,16 +1,30 @@
1
1
  # This configuration was generated by
2
- # `rubocop --auto-gen-config --exclude-limit 500`
3
- # on 2019-10-15 15:20:00 -0400 using RuboCop version 0.75.1.
2
+ # `rubocop --auto-gen-config`
3
+ # on 2019-11-09 15:45:44 -0500 using RuboCop version 0.75.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
9
  # Offense count: 1
10
+ # Cop supports --auto-correct.
11
+ Layout/ClosingHeredocIndentation:
12
+ Exclude:
13
+ - 'lib/skunk/cli/commands/status_reporter.rb'
14
+
15
+ # Offense count: 1
16
+ # Cop supports --auto-correct.
17
+ # Configuration parameters: EnforcedStyle.
18
+ # SupportedStyles: squiggly, active_support, powerpack, unindent
19
+ Layout/IndentHeredoc:
20
+ Exclude:
21
+ - 'lib/skunk/cli/commands/status_reporter.rb'
22
+
23
+ # Offense count: 2
10
24
  # Configuration parameters: CountComments, ExcludedMethods.
11
25
  # ExcludedMethods: refine
12
26
  Metrics/BlockLength:
13
- Max: 34
27
+ Max: 40
14
28
 
15
29
  # Offense count: 1
16
30
  # Cop supports --auto-correct.
@@ -19,9 +33,9 @@ Naming/RescuedExceptionsVariableName:
19
33
  Exclude:
20
34
  - 'lib/skunk/cli/application.rb'
21
35
 
22
- # Offense count: 8
36
+ # Offense count: 7
23
37
  # Cop supports --auto-correct.
24
38
  # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
25
39
  # URISchemes: http, https
26
40
  Metrics/LineLength:
27
- Max: 107
41
+ Max: 96
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
@@ -0,0 +1,77 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to make participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies within all project spaces, and it also applies when
49
+ an individual is representing the project or its community in public spaces.
50
+ Examples of representing a project or community include using an official
51
+ project e-mail address, posting via an official social media account, or acting
52
+ as an appointed representative at an online or offline event. Representation of
53
+ a project may be further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at oss@ombulabs.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
77
+
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- skunk (0.1.0)
5
- rubycritic-simplecov (~> 4.1.1)
4
+ skunk (0.3.0)
5
+ rubycritic (~> 4.2.1)
6
6
  terminal-table (~> 1.8.0)
7
7
 
8
8
  GEM
@@ -36,7 +36,7 @@ GEM
36
36
  ruby_parser (~> 3.1, > 3.1.0)
37
37
  sexp_processor (~> 4.8)
38
38
  ice_nine (0.11.2)
39
- jaro_winkler (1.5.3)
39
+ jaro_winkler (1.5.4)
40
40
  json (2.2.0)
41
41
  kwalify (0.7.2)
42
42
  launchy (2.4.3)
@@ -44,7 +44,7 @@ GEM
44
44
  minitest (5.8.5)
45
45
  minitest-around (0.5.0)
46
46
  minitest (~> 5.0)
47
- parallel (1.18.0)
47
+ parallel (1.19.0)
48
48
  parser (2.6.5.0)
49
49
  ast (~> 2.4.0)
50
50
  path_expander (1.1.0)
@@ -52,13 +52,13 @@ GEM
52
52
  public_suffix (4.0.1)
53
53
  rainbow (3.0.0)
54
54
  rake (10.5.0)
55
- reek (5.4.0)
55
+ reek (5.4.1)
56
56
  codeclimate-engine-rb (~> 0.4.0)
57
57
  kwalify (~> 0.7.0)
58
58
  parser (>= 2.5.0.0, < 2.7, != 2.5.1.1)
59
59
  psych (~> 3.1.0)
60
60
  rainbow (>= 2.0, < 4.0)
61
- rubocop (0.75.1)
61
+ rubocop (0.76.0)
62
62
  jaro_winkler (~> 1.5.1)
63
63
  parallel (~> 1.10)
64
64
  parser (>= 2.6)
@@ -66,9 +66,9 @@ GEM
66
66
  ruby-progressbar (~> 1.7)
67
67
  unicode-display_width (>= 1.4.0, < 1.7)
68
68
  ruby-progressbar (1.10.1)
69
- ruby_parser (3.14.0)
69
+ ruby_parser (3.14.1)
70
70
  sexp_processor (~> 4.9)
71
- rubycritic-simplecov (4.1.1)
71
+ rubycritic (4.2.2)
72
72
  flay (~> 2.8)
73
73
  flog (~> 4.4)
74
74
  launchy (= 2.4.3)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2019 Ernesto Tagwerker
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 CHANGED
@@ -1,10 +1,12 @@
1
1
  # Skunk
2
2
 
3
+ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](code-of-conduct.md) [![Build Status](https://travis-ci.org/fastruby/skunk.svg?branch=master)](https://travis-ci.org/fastruby/skunk) [![Maintainability](https://api.codeclimate.com/v1/badges/3e33d701ced16eee2420/maintainability)](https://codeclimate.com/github/fastruby/skunk/maintainability)
4
+
3
5
  A RubyCritic extension to calculate StinkScore for a file or project.
4
6
 
5
7
  ## What is the StinkScore?
6
8
 
7
- The StinkScore is a value that assess the quality of a module. It takes into
9
+ The StinkScore is a value that assesses the quality of a module. It takes into
8
10
  account:
9
11
 
10
12
  - Code Quality
@@ -12,7 +14,16 @@ account:
12
14
  - Churn
13
15
  - Code Coverage
14
16
 
15
- The formula is not perfect and it is certainly controversial.
17
+ The main goal of the StinkScore is to serve as a compass in your next
18
+ refactoring adventure. It will help you answer these questions:
19
+
20
+ - What can I do to pay off technical debt?
21
+ - What are the most complicated files with the least code coverage?
22
+ - What are good candidates for your next test-writing efforts?
23
+ - What are good candidates for your nest refactoring efforts?
24
+
25
+ The formula is not perfect and it is certainly controversial, so any feedback is
26
+ welcome as a new issue!
16
27
 
17
28
  ## Installation
18
29
 
@@ -32,7 +43,13 @@ Or install it yourself as:
32
43
 
33
44
  ## Usage
34
45
 
35
- Simply run:
46
+ ### Getting a sorted list of stinkiest files
47
+
48
+ To get the best results, make sure that you have `coverage/.resultset.json` in
49
+ your application directory. That way `skunk` knows what's the status of your
50
+ test suite + code coverage.
51
+
52
+ Then simply run:
36
53
 
37
54
  ```
38
55
  skunk
@@ -84,11 +101,60 @@ StinkScore Average: 0.47100769230769230769230769231e2
84
101
  Worst StinkScore: 166.44 (lib/skunk/cli/commands/default.rb)
85
102
  ```
86
103
 
87
- The command will run `rubycritic`, so that will generate a RubyCritic overview
88
- HTML report as well.
104
+ The command will run `rubycritic` and it will try to load code coverage data
105
+ from your `.resultset.json` file.
89
106
 
90
107
  Skunk's report will be in the console. Use it wisely. :)
91
108
 
109
+ ### Comparing one branch vs. another
110
+
111
+ Simply run:
112
+
113
+ ```
114
+ skunk -b <target-branch-name>
115
+ ```
116
+
117
+ Then get a StinkScore average comparison:
118
+
119
+ ```
120
+ $ skunk -b master
121
+ Switched to branch 'master'
122
+ running flay smells
123
+ ..
124
+ running flog smells
125
+ ..............
126
+ running reek smells
127
+ ..............
128
+ running complexity
129
+ ..............
130
+ running attributes
131
+ ..............
132
+ running churn
133
+ ..............
134
+ running simple_cov
135
+ ..............
136
+ Switched to branch 'feature/compare'
137
+ running flay smells
138
+ ..
139
+ running flog smells
140
+ .................
141
+ running reek smells
142
+ .................
143
+ running complexity
144
+ .................
145
+ running attributes
146
+ .................
147
+ running churn
148
+ .................
149
+ running simple_cov
150
+ .................
151
+ Base branch (master) average stink score: 290.53999999999996
152
+ Feature branch (feature/compare) average stink score: 340.3005882352941
153
+ Score: 340.3
154
+ ```
155
+
156
+ This should give you an idea if you're moving in the right direction or not.
157
+
92
158
  ## Known Issues
93
159
 
94
160
  The StinkScore should be calculated per method. This would provide a more accurate
@@ -113,4 +179,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
113
179
 
114
180
  ## Contributing
115
181
 
116
- Bug reports and pull requests are welcome on GitHub at https://github.com/fastruby/skunk.
182
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fastruby/skunk/issues.
data/bin/console CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #!/usr/bin/env ruby
2
4
 
3
5
  require "bundler/setup"
@@ -13,7 +13,6 @@ module Skunk
13
13
  class Application < RubyCritic::Cli::Application
14
14
  def execute
15
15
  parsed_options = @options.parse.to_h
16
-
17
16
  reporter = Skunk::Cli::CommandFactory.create(parsed_options).execute
18
17
  print(reporter.status_message)
19
18
  reporter.status
@@ -6,7 +6,7 @@ module Skunk
6
6
  module Cli
7
7
  # Knows how to calculate the command that was request by the CLI user
8
8
  class CommandFactory < RubyCritic::CommandFactory
9
- COMMAND_CLASS_MODES = %i[version help default].freeze
9
+ COMMAND_CLASS_MODES = %i[version help default compare].freeze
10
10
 
11
11
  # Returns the command class based on the command that was executed
12
12
  #
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/commands/compare"
4
+ require "skunk/rubycritic/analysed_modules_collection"
5
+
6
+ # nodoc #
7
+ module Skunk
8
+ module Command
9
+ # Knows how to compare two branches and their stink score average
10
+ class Compare < RubyCritic::Command::Compare
11
+ # switch branch and analyse files but don't generate a report
12
+ def analyse_branch(branch)
13
+ ::RubyCritic::SourceControlSystem::Git.switch_branch(::RubyCritic::Config.send(branch))
14
+ critic = critique(branch)
15
+ ::RubyCritic::Config.send(:"#{branch}_score=", critic.stink_score_average)
16
+ ::RubyCritic::Config.root = branch_directory(branch)
17
+ end
18
+
19
+ # generate report only for modified files but don't report it
20
+ def analyse_modified_files
21
+ modified_files = ::RubyCritic::Config
22
+ .feature_branch_collection
23
+ .where(::RubyCritic::SourceControlSystem::Git.modified_files)
24
+ ::RubyCritic::AnalysedModulesCollection.new(modified_files.map(&:path),
25
+ modified_files)
26
+ ::RubyCritic::Config.root = "#{::RubyCritic::Config.root}/compare"
27
+ end
28
+
29
+ # create a txt file with the branch score details
30
+ def build_details
31
+ details = "Base branch (#{::RubyCritic::Config.base_branch}) "\
32
+ "average stink score: #{::RubyCritic::Config.base_branch_score} \n"\
33
+ "Feature branch (#{::RubyCritic::Config.feature_branch}) "\
34
+ "average stink score: #{::RubyCritic::Config.feature_branch_score} \n"
35
+ File.open(build_details_path, "w") { |file| file.write(details) }
36
+ puts details
37
+ end
38
+
39
+ def build_details_path
40
+ "#{::RubyCritic::Config.compare_root_directory}/build_details.txt"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -20,16 +20,13 @@ module Skunk
20
20
  end
21
21
 
22
22
  def execute
23
+ RubyCritic::Config.formats = []
24
+
23
25
  report(critique)
24
26
  status_reporter
25
27
  end
26
28
 
27
- def critique
28
- RubyCritic::AnalysersRunner.new(paths).run
29
- end
30
-
31
29
  def report(analysed_modules)
32
- RubyCritic::Reporter.generate_report(analysed_modules)
33
30
  status_reporter.analysed_modules = analysed_modules
34
31
  status_reporter.score = analysed_modules.score
35
32
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "erb"
3
4
  require "rubycritic/commands/status_reporter"
4
5
  require "terminal-table"
5
6
 
@@ -11,6 +12,15 @@ module Skunk
11
12
 
12
13
  HEADINGS = %w[file stink_score churn_times_cost churn cost coverage].freeze
13
14
 
15
+ TEMPLATE = ERB.new(<<-TEMPL
16
+ <%= ttable %>\n
17
+ StinkScore Total: <%= total_stink_score %>
18
+ Modules Analysed: <%= analysed_modules_count %>
19
+ StinkScore Average: <%= stink_score_average %>
20
+ <% if worst %>Worst StinkScore: <%= worst.stink_score %> (<%= worst.pathname %>)<% end %>
21
+ TEMPL
22
+ )
23
+
14
24
  # Returns a status message with a table of all analysed_modules and
15
25
  # a stink score average
16
26
  def update_status_message
@@ -18,12 +28,7 @@ module Skunk
18
28
 
19
29
  ttable = Terminal::Table.new(opts)
20
30
 
21
- @status_message = "#{ttable}\n\n"
22
-
23
- @status_message += "StinkScore Total: #{total_stink_score}\n"
24
- @status_message += "Modules Analysed: #{analysed_modules_count}\n"
25
- @status_message += "StinkScore Average: #{stink_score}\n"
26
- @status_message += "Worst StinkScore: #{worst.stink_score} (#{worst.pathname})\n" if worst
31
+ @status_message = TEMPLATE.result(binding)
27
32
  end
28
33
 
29
34
  private
@@ -33,7 +38,9 @@ module Skunk
33
38
  end
34
39
 
35
40
  def non_test_modules
36
- @non_test_modules ||= analysed_modules.reject { |x| x.pathname.to_s.start_with?("test", "spec")}
41
+ @non_test_modules ||= analysed_modules.reject do |a_module|
42
+ a_module.pathname.to_s.start_with?("test", "spec")
43
+ end
37
44
  end
38
45
 
39
46
  def worst
@@ -52,10 +59,10 @@ module Skunk
52
59
  non_test_modules.map(&:churn_times_cost).sum
53
60
  end
54
61
 
55
- def stink_score
56
- return 0 if analysed_modules_count == 0
62
+ def stink_score_average
63
+ return 0 if analysed_modules_count.zero?
57
64
 
58
- total_stink_score.to_d / analysed_modules_count
65
+ (total_stink_score.to_d / analysed_modules_count).to_f
59
66
  end
60
67
 
61
68
  def table_options
@@ -40,7 +40,7 @@ module RubyCritic
40
40
  #
41
41
  # @return [Integer]
42
42
  def churn_times_cost
43
- safe_churn = churn > 0 ? churn : 1
43
+ safe_churn = churn.positive? ? churn : 1
44
44
  @churn_times_cost ||= safe_churn * cost
45
45
  end
46
46
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/core/analysed_modules_collection"
4
+
5
+ module RubyCritic
6
+ # nodoc #
7
+ class AnalysedModulesCollection
8
+ def stink_score_average
9
+ num_modules = @modules.size
10
+ if num_modules.positive?
11
+ map(&:stink_score).reduce(:+) / num_modules.to_f
12
+ else
13
+ 0.0
14
+ end
15
+ end
16
+ end
17
+ end
data/lib/skunk/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skunk
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/core/analysed_module"
4
+
5
+ module RubyCritic
6
+ # Monkey-patches RubyCritic::AnalysedModule to add a stink_score method
7
+ class AnalysedModule
8
+ PERFECT_COVERAGE = 100
9
+
10
+ # Returns a numeric value that represents the stink_score of a module:
11
+ #
12
+ # If module is perfectly covered, stink score is the same as the
13
+ # `churn_times_cost`
14
+ #
15
+ # If module has no coverage, stink score is a penalized value of
16
+ # `churn_times_cost`
17
+ #
18
+ # For now the stink_score is calculated by multiplying `churn_times_cost`
19
+ # times the lack of coverage.
20
+ #
21
+ # For example:
22
+ #
23
+ # When `churn_times_cost` is 100 and module is perfectly covered:
24
+ # stink_score => 100
25
+ #
26
+ # When `churn_times_cost` is 100 and module is not covered at all:
27
+ # stink_score => 100 * 100 = 10_000
28
+ #
29
+ # When `churn_times_cost` is 100 and module is covered at 75%:
30
+ # stink_score => 100 * 25 (percentage uncovered) = 2_500
31
+ #
32
+ # @return [Float]
33
+ def stink_score
34
+ return churn_times_cost.round(2) if coverage == PERFECT_COVERAGE
35
+
36
+ (churn_times_cost * (PERFECT_COVERAGE - coverage.to_i)).round(2)
37
+ end
38
+
39
+ # Returns the value of churn times cost.
40
+ #
41
+ # @return [Integer]
42
+ def churn_times_cost
43
+ safe_churn = churn.positive? ? churn : 1
44
+ @churn_times_cost ||= safe_churn * cost
45
+ end
46
+ end
47
+ end
data/skunk.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.version = Skunk::VERSION
10
10
  spec.authors = ["Ernesto Tagwerker"]
11
11
  spec.email = ["ernesto+github@ombulabs.com"]
12
-
12
+ spec.licenses = ['MIT']
13
13
  spec.summary = "A library to assess code quality vs. code coverage"
14
14
  spec.description = "Knows how to calculate the StinkScore for a Ruby file"
15
15
  spec.homepage = "https://github.com/fastruby/skunk"
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
37
  spec.require_paths = ["lib"]
38
38
 
39
- spec.add_dependency "rubycritic-simplecov", "~> 4.1.1"
39
+ spec.add_dependency "rubycritic", "~> 4.2.1"
40
40
  spec.add_dependency "terminal-table", "~> 1.8.0"
41
41
 
42
42
  spec.add_development_dependency "bundler", "~> 2.0"
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernesto Tagwerker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-16 00:00:00.000000000 Z
11
+ date: 2019-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rubycritic-simplecov
14
+ name: rubycritic
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.1
19
+ version: 4.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 4.1.1
26
+ version: 4.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: terminal-table
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -176,9 +176,12 @@ files:
176
176
  - ".reek.yml"
177
177
  - ".rubocop.yml"
178
178
  - ".rubocop_todo.yml"
179
+ - ".travis.yml"
179
180
  - CHANGELOG.md
181
+ - CODE_OF_CONDUCT.md
180
182
  - Gemfile
181
183
  - Gemfile.lock
184
+ - LICENSE.txt
182
185
  - README.md
183
186
  - Rakefile
184
187
  - bin/console
@@ -188,15 +191,19 @@ files:
188
191
  - lib/skunk/cli/application.rb
189
192
  - lib/skunk/cli/command_factory.rb
190
193
  - lib/skunk/cli/commands/base.rb
194
+ - lib/skunk/cli/commands/compare.rb
191
195
  - lib/skunk/cli/commands/default.rb
192
196
  - lib/skunk/cli/commands/help.rb
193
197
  - lib/skunk/cli/commands/status_reporter.rb
194
198
  - lib/skunk/cli/options.rb
195
199
  - lib/skunk/rubycritic/analysed_module.rb
200
+ - lib/skunk/rubycritic/analysed_modules_collection.rb
196
201
  - lib/skunk/version.rb
202
+ - samples/rubycritic/analysed_module.rb
197
203
  - skunk.gemspec
198
204
  homepage: https://github.com/fastruby/skunk
199
- licenses: []
205
+ licenses:
206
+ - MIT
200
207
  metadata:
201
208
  allowed_push_host: https://www.rubygems.org
202
209
  homepage_uri: https://github.com/fastruby/skunk
@@ -217,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
224
  - !ruby/object:Gem::Version
218
225
  version: '0'
219
226
  requirements: []
220
- rubygems_version: 3.0.3
227
+ rubygems_version: 3.0.6
221
228
  signing_key:
222
229
  specification_version: 4
223
230
  summary: A library to assess code quality vs. code coverage