skunk 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +12 -92
  3. data/.github/workflows/skunk.yml +4 -3
  4. data/.gitignore +1 -0
  5. data/.reek.yml +4 -3
  6. data/.rubocop_todo.yml +25 -17
  7. data/CHANGELOG.md +18 -1
  8. data/CONTRIBUTING.md +84 -0
  9. data/Gemfile +4 -0
  10. data/README.md +108 -156
  11. data/lib/skunk/cli/application.rb +3 -3
  12. data/lib/skunk/cli/options/argv.rb +1 -1
  13. data/lib/skunk/command_factory.rb +25 -0
  14. data/lib/skunk/commands/base.rb +21 -0
  15. data/lib/skunk/commands/compare.rb +64 -0
  16. data/lib/skunk/commands/compare_score.rb +39 -0
  17. data/lib/skunk/commands/default.rb +48 -0
  18. data/lib/skunk/commands/help.rb +25 -0
  19. data/lib/skunk/commands/shareable.rb +25 -0
  20. data/lib/skunk/{cli/commands → commands}/status_reporter.rb +1 -1
  21. data/lib/skunk/{cli/commands → commands}/status_sharer.rb +1 -3
  22. data/lib/skunk/commands/version.rb +20 -0
  23. data/lib/skunk/generators/json/simple.rb +58 -0
  24. data/lib/skunk/generators/json_report.rb +23 -0
  25. data/lib/skunk/reporter.rb +25 -0
  26. data/lib/skunk/rubycritic/analysed_module.rb +15 -9
  27. data/lib/skunk/version.rb +1 -1
  28. data/skunk.gemspec +6 -7
  29. metadata +40 -55
  30. data/CODEOWNERS +0 -5
  31. data/Gemfile-Ruby-2-4 +0 -10
  32. data/lib/skunk/cli/command_factory.rb +0 -27
  33. data/lib/skunk/cli/commands/base.rb +0 -22
  34. data/lib/skunk/cli/commands/compare.rb +0 -66
  35. data/lib/skunk/cli/commands/compare_score.rb +0 -41
  36. data/lib/skunk/cli/commands/default.rb +0 -49
  37. data/lib/skunk/cli/commands/help.rb +0 -27
  38. data/lib/skunk/cli/commands/shareable.rb +0 -27
  39. data/lib/skunk/cli/commands/version.rb +0 -22
  40. /data/lib/skunk/{cli/commands → commands}/output.rb +0 -0
data/README.md CHANGED
@@ -4,52 +4,63 @@
4
4
 
5
5
  [![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) [![Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/gems/skunk) [![codecov](https://codecov.io/gh/fastruby/skunk/branch/master/graph/badge.svg)](https://codecov.io/gh/fastruby/skunk)
6
6
 
7
- A RubyCritic extension to calculate SkunkScore for a file or project.
7
+ Skunk is a RubyCritic extension to calculate a SkunkScore for a file or project. The SkunkScore is a value that assesses the technical debt of a module.
8
+
9
+ ## Table of contents
10
+ * [What is the SkunkScore?](#what-is-the-skunkscore)
11
+ * [Getting started](#getting-started)
12
+ * [Running SimpleCov](#running-simplecov)
13
+ * [Usage](#usage)
14
+ * [Help commands](#help-commands)
15
+ * [Generate the SkunkCore for your project](#generate-the-skunkcore-for-your-project)
16
+ * [Comparing Feature Branches](#comparing-feature-branches)
17
+ * [Sharing your SkunkScore](#sharing-your-skunkscore)
18
+ * [Contributing](#contributing)
19
+ * [Sponsorship](#sponsorship)
8
20
 
9
21
  ## What is the SkunkScore?
10
22
 
11
- The SkunkScore is a value that assesses the technical debt of a module. It takes
12
- into account:
13
-
14
- - Code Complexity
15
- - Code Smells
16
- - Code Coverage
17
-
18
- The main goal of the SkunkScore is to serve as a compass in your next
19
- refactoring adventure. It will help you answer these questions:
23
+ The main goal of the SkunkScore is to serve as a compass in your next refactoring adventure. It will help you answer these questions:
20
24
 
21
25
  - What can I do to pay off technical debt?
22
26
  - What are the most complicated files with the least code coverage?
23
- - What are good candidates for your next test-writing efforts?
24
- - What are good candidates for your next refactoring efforts?
27
+ - What are good candidates for my next test-writing efforts?
28
+ - What are good candidates for my next refactoring efforts?
25
29
 
26
- The formula is not perfect and it is certainly controversial, so any feedback is
27
- welcome as a new issue!
30
+ To assess the technical debt of a module, Skunk takes into account:
31
+ - Code Complexity
32
+ - Code Smells
33
+ - Code Coverage
28
34
 
29
- ## Installation
35
+ ## Getting started
30
36
 
31
- Add this line to your application's Gemfile:
37
+ Start by including `skunk` in your Gemfile:
32
38
 
33
39
  ```ruby
34
40
  gem 'skunk'
35
41
  ```
36
42
 
37
- And then execute:
43
+ Then run `bundle`.
44
+
45
+ Or, install it yourself by running: `$ gem install skunk`
46
+
47
+ ### Running SimpleCov to generate your Code Coverage report
48
+ Use SimpleCov to generate a report of how many statements are covered by your test suite (code coverage). That's how `skunk` knows what's the status of your test suite + code coverage.
38
49
 
39
- $ bundle
50
+ Please refer to [SimpleCov's Getting Started Guide](https://github.com/simplecov-ruby/simplecov#getting-started) to install it and generate the coverage report.
40
51
 
41
- Or install it yourself as:
52
+ SimpleCov was successfully installed when it generated a JSON file under `coverage/.resultset.json` in your application directory.
42
53
 
43
- $ gem install skunk
54
+ > :warning: Skunk runs `rubycritic`, which loads code coverage data from your `coverage/.resultset.json` file. Make sure to have this file for best SkunkScore results.
44
55
 
56
+ **Note:** after adding more tests to your application, run SimpleCov again to generate an updated Code Coverage. This way, skunk will generate a new SkunkScore.
45
57
  ## Usage
46
58
 
47
- ### Help details
59
+ ### Help commands
48
60
 
49
- There are not that many options but here they are:
61
+ Run `skunk -h` to check out the help options:
50
62
 
51
63
  ```
52
- skunk -h
53
64
  Usage: skunk [options] [paths]
54
65
  -b, --branch BRANCH Set branch to compare
55
66
  -o, --out FILE Output report to file
@@ -57,185 +68,126 @@ Usage: skunk [options] [paths]
57
68
  -h, --help Show this message
58
69
  ```
59
70
 
60
- ### Getting a sorted list of smelly files
71
+ ### Generating the SkunkCore for your project
61
72
 
62
- To get the best results, make sure that you have `coverage/.resultset.json` in
63
- your application directory. That way `skunk` knows what's the status of your
64
- test suite + code coverage.
65
-
66
- Then simply run:
73
+ The SkunkCore is a sorted list of smelly files. Skunk's report will be in the console. On the Ruby project you want to analyze, run:
67
74
 
68
75
  ```
69
76
  skunk
70
77
  ```
71
78
 
72
- Then get a list of smelly files:
79
+ The result is a list of smelly files and the SkunkScore of the project/files:
73
80
 
74
81
  ```
75
- $ skunk
76
- running flay smells
77
-
78
- running flog smells
79
- .............
80
- running reek smells
81
- .............
82
- running complexity
83
- .............
84
- running attributes
85
- .............
86
- running churn
87
- .............
88
- running simple_cov
89
- .............
90
- New critique at file:////Users/etagwerker/Projects/fastruby/skunk/tmp/rubycritic/overview.html
91
- +-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
92
- | file | skunk_score | churn_times_cost | churn | cost | coverage |
93
- +-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
94
- | lib/skunk/cli/commands/default.rb | 166.44 | 1.6643999999999999 | 3 | 0.5548 | 0 |
95
- | lib/skunk/cli/application.rb | 139.2 | 1.392 | 3 | 0.46399999999999997 | 0 |
96
- | lib/skunk/cli/command_factory.rb | 97.6 | 0.976 | 2 | 0.488 | 0 |
97
- | test/test_helper.rb | 75.2 | 0.752 | 2 | 0.376 | 0 |
98
- | lib/skunk/rubycritic/analysed_module.rb | 48.12 | 1.7184 | 2 | 0.8592 | 72.72727272727273 |
99
- | test/lib/skunk/cli/commands/status_reporter_test.rb | 45.6 | 0.456 | 1 | 0.456 | 0 |
100
- | lib/skunk/cli/commands/base.rb | 29.52 | 0.2952 | 3 | 0.0984 | 0 |
101
- | lib/skunk/cli/commands/status_reporter.rb | 8.0 | 7.9956 | 3 | 2.6652 | 100.0 |
102
- | test/lib/skunk/rubycritic/analysed_module_test.rb | 2.63 | 2.6312 | 2 | 1.3156 | 100.0 |
103
- | lib/skunk.rb | 0.0 | 0.0 | 2 | 0.0 | 0 |
104
- | lib/skunk/cli/options.rb | 0.0 | 0.0 | 2 | 0.0 | 0 |
105
- | lib/skunk/version.rb | 0.0 | 0.0 | 2 | 0.0 | 0 |
106
- | lib/skunk/cli/commands/help.rb | 0.0 | 0.0 | 2 | 0.0 | 0 |
107
- +-----------------------------------------------------+----------------------------+----------------------------+----------------------------+----------------------------+----------------------------+
108
-
109
- SkunkScore Total: 612.31
110
- Modules Analysed: 13
111
- SkunkScore Average: 0.47100769230769230769230769231e2
112
- Worst SkunkScore: 166.44 (lib/skunk/cli/commands/default.rb)
82
+ +-----------------------------------------------------+----------------+------------------+--------------+--------------+--------------+
83
+ | file | skunk_score | churn_times_cost | churn | cost | coverage |
84
+ +-----------------------------------------------------+----------------+------------------+--------------+--------------+--------------+
85
+ | samples/rubycritic/analysed_module.rb | 258.88 | 12.94 | 5 | 2.59 | 0.0 |
86
+ | lib/skunk/commands/compare.rb | 85.41 | 32.32 | 14 | 2.31 | 63.64 |
87
+ | lib/skunk/rubycritic/analysed_modules_collection.rb | 31.76 | 3.18 | 5 | 0.64 | 50.0 |
88
+ | lib/skunk/commands/status_reporter.rb | 11.33 | 68.0 | 18 | 3.78 | 97.5 |
89
+ | lib/skunk/command_factory.rb | 8.3 | 1.95 | 4 | 0.49 | 83.33 |
90
+ | lib/skunk/commands/status_sharer.rb | 8.17 | 10.9 | 4 | 2.72 | 97.67 |
91
+ | lib/skunk/cli/application.rb | 7.06 | 21.19 | 18 | 1.18 | 94.12 |
92
+ | lib/skunk/cli/options/argv.rb | 4.08 | 7.35 | 9 | 0.82 | 95.24 |
93
+ | lib/skunk/commands/compare_score.rb | 3.77 | 2.51 | 4 | 0.63 | 94.74 |
94
+ | lib/skunk/rubycritic/analysed_module.rb | 3.37 | 33.74 | 10 | 3.37 | 100.0 |
95
+ | lib/skunk/commands/version.rb | 2.64 | 0.7 | 8 | 0.09 | 70.0 |
96
+ | lib/skunk/commands/output.rb | 1.86 | 0.09 | 1 | 0.09 | 80.0 |
97
+ | lib/skunk/cli/options.rb | 0.68 | 5.44 | 8 | 0.68 | 100.0 |
98
+ | lib/skunk/commands/default.rb | 0.4 | 3.23 | 8 | 0.4 | 100.0 |
99
+ | lib/skunk/commands/shareable.rb | 0.2 | 0.4 | 2 | 0.2 | 100.0 |
100
+ | lib/skunk/commands/help.rb | 0.2 | 1.2 | 6 | 0.2 | 100.0 |
101
+ | lib/skunk/commands/base.rb | 0.1 | 0.49 | 5 | 0.1 | 100.0 |
102
+ | lib/skunk.rb | 0.0 | 0.0 | 6 | 0.0 | 100.0 |
103
+ | lib/skunk/version.rb | 0.0 | 0.0 | 12 | 0.0 | 0.0 |
104
+ +-----------------------------------------------------+----------------+------------------+--------------+--------------+--------------+
105
+
106
+ SkunkScore Total: 428.21
107
+ Modules Analysed: 19
108
+ SkunkScore Average: 22.54
109
+ Worst SkunkScore: 258.88 (samples/rubycritic/analysed_module.rb)
113
110
  ```
114
111
 
115
- The command will run `rubycritic` and it will try to load code coverage data
116
- from your `coverage/.resultset.json` file.
112
+ With the report, you can answer [these refactoring questions](#what-is-the-skunkscore) with clarity.
113
+
114
+ In this example, the file `samples/rubycritic/analysed_module.rb` has the Worst SkunkScore. It means this file has a high code complexity, with lower code coverage. To decrease its SkunkScore, start by adding tests to it. Then, simplify the code to decrease the code complexity.
115
+
116
+ Other great candidates are the files that have lower code coverage. By adding tests, their SkunkScore will decrease, and refactoring the code will be more achievable.
117
+
118
+ Skunk also gives you a SkunkScore Total value: it shows you the overall code quality of the project. As you decrease the SkunkScore of the files, the total score of the project will decrease.
119
+
120
+ #### Excluding folders from the report
121
+
122
+ To only run skunk on specific folders, pass a list of directories in the command line. For example, if you only want the report for the files under `app` and `lib`, run:
123
+
124
+ `skunk app lib`
125
+
126
+ ### Generate JSON report in background
127
+
128
+ When the Skunk command is run, it will generate a JSON report file in the `RubyCritic::Config.root` location.
117
129
 
118
- Skunk's report will be in the console. Use it wisely. :)
130
+ ### Comparing feature branches
119
131
 
120
- ### Comparing one branch vs. another
132
+ When working on new features, run skunk against your feature branch to check if the changes are improving or decreasing the code quality of the project.
121
133
 
122
- Simply run:
134
+ To generate the SkunkScore of your feature branch, run:
123
135
 
124
136
  ```
125
- skunk -b <target-branch-name>
137
+ skunk -b <your-feature-branch-name>
126
138
  ```
127
139
 
128
- Then get a SkunkScore average comparison:
140
+ Then, get a SkunkScore average comparison with `main` by running:
141
+
142
+ `$ skunk -b main`
129
143
 
130
144
  ```
131
- $ skunk -b master
132
- Switched to branch 'master'
133
- running flay smells
134
- ..
135
- running flog smells
136
- ..............
137
- running reek smells
138
- ..............
139
- running complexity
140
- ..............
141
- running attributes
142
- ..............
143
- running churn
144
- ..............
145
- running simple_cov
146
- ..............
147
- Switched to branch 'feature/compare'
148
- running flay smells
149
- ..
150
- running flog smells
151
- .................
152
- running reek smells
153
- .................
154
- running complexity
155
- .................
156
- running attributes
157
- .................
158
- running churn
159
- .................
160
- running simple_cov
161
- .................
162
- Base branch (master) average skunk score: 290.53999999999996
145
+ Switched to branch 'main'
146
+ ....
147
+
148
+ Base branch (main) average skunk score: 290.53999999999996
163
149
  Feature branch (feature/compare) average skunk score: 340.3005882352941
164
150
  Score: 340.3
165
151
  ```
166
152
 
167
- This should give you an idea if you're moving in the right direction or not.
153
+ This should give you an idea if you're moving in the direction of maintaining the code quality or not. In this case, the feature branch is decreasing the code quality because it has a higher SkunkScore than the main branch.
154
+
155
+ ## Sharing your SkunkScore
168
156
 
169
- ### Sharing results
157
+ If you want to share the results of your Skunk report with the Ruby community, run:
170
158
 
171
- If you want to quickly share the results of your report, you can use an
172
- environment variable:
159
+ `SHARE=true skunk app/`
173
160
 
174
161
  ```
175
- SHARE=true skunk app/
176
- ...
177
162
  SkunkScore Total: 126.99
178
163
  Modules Analysed: 17
179
164
  SkunkScore Average: 7.47
180
- Worst SkunkScore: 41.92 (lib/skunk/cli/commands/status_sharer.rb)
165
+ Worst SkunkScore: 41.92 (lib/skunk/commands/status_sharer.rb)
181
166
 
182
167
  Generated with Skunk v0.5.0
183
- Shared at: https://skunk.fastruby.io/k
168
+ Shared at: https://skunk.fastruby.io/
184
169
  ```
185
170
 
186
- Results will be posted by default to https://skunk.fastruby.io which is a free
187
- and open source Ruby on Rails application sponsored by
188
- [OmbuLabs](https://www.ombulabs.com) ([source code](https://github.com/fastruby/skunk.fyi)).
171
+ Results will be posted by default to https://skunk.fastruby.io which is a free and open source Ruby on Rails application sponsored by [OmbuLabs](https://www.ombulabs.com)([source code](https://github.com/fastruby/skunk.fyi)).
189
172
 
190
- If you prefer to post results to your own server, you can do so:
173
+ If you prefer to post results to your server, set your own `SHARE_URL`:
174
+
175
+ `$ SHARE_URL=https://path.to.your.skunk-fyi-server.example.com skunk app/`
191
176
 
192
177
  ```
193
- SHARE_URL=https://path.to.your.skunk-fyi-server.example.com skunk app/
194
- ...
195
178
  SkunkScore Total: 126.99
196
179
  Modules Analysed: 17
197
180
  SkunkScore Average: 7.47
198
- Worst SkunkScore: 41.92 (lib/skunk/cli/commands/status_sharer.rb)
181
+ Worst SkunkScore: 41.92 (lib/skunk/commands/status_sharer.rb)
199
182
 
200
183
  Generated with Skunk v0.5.0
201
- Shared at: https://path.to.your.skunk-fyi-server.example.com/k
184
+ Shared at: https://path.to.your.skunk-fyi-server.example.com
202
185
  ```
203
186
 
204
- ## Known Issues
205
-
206
- The SkunkScore should be calculated per method. This would provide a more accurate
207
- representation of the average SkunkScore in a module.
208
-
209
- I think that the SkunkScore of a module should be the average of the SkunkScores of
210
- all of its methods.
211
-
212
- Right now the SkunkScore is calculated using the totals for a module:
213
-
214
- - Total Code Coverage Percentage per Module
215
- - Total Churn per Module
216
- - Total Cost per Module
217
-
218
- For more details, feel free to review and improve this method: [RubyCritic::AnalysedModule#skunk_score]
219
-
220
- ## Development
221
-
222
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
223
-
224
- 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).
225
-
226
187
  ## Contributing
188
+ Have a fix for a problem you've been running into or an idea for a new feature you think would be useful? Want to see how you can support Skunk?
227
189
 
228
- Bug reports and pull requests are welcome on GitHub at [https://github.com/fastruby/skunk](https://github.com/fastruby/skunk). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/fastruby/skunk/blob/main/CODE_OF_CONDUCT.md).
229
-
230
- When Submitting a Pull Request:
231
-
232
- * If your PR closes any open GitHub issues, please include `Closes #XXXX` in your comment.
233
-
234
- * Please include a summary of the change and which issue is fixed or which feature is introduced.
235
-
236
- * If changes to the behavior are made, clearly describe what changes.
237
-
238
- * If changes to the UI are made, please include screenshots of the before and after.
190
+ Take a look at the [Contributing document](CONTRIBUTING.md) for instructions to set up the repo on your machine, check the Help Wanted section, and create a good Pull Request.
239
191
 
240
192
  ## Sponsorship
241
193
 
@@ -6,8 +6,8 @@ require "rubycritic/cli/application"
6
6
  require "skunk"
7
7
  require "skunk/rubycritic/analysed_module"
8
8
  require "skunk/cli/options"
9
- require "skunk/cli/command_factory"
10
- require "skunk/cli/commands/status_sharer"
9
+ require "skunk/command_factory"
10
+ require "skunk/commands/status_sharer"
11
11
 
12
12
  module Skunk
13
13
  module Cli
@@ -26,7 +26,7 @@ module Skunk
26
26
 
27
27
  # :reek:NilCheck
28
28
  @parsed_options = @options.parse.to_h
29
- command = Skunk::Cli::CommandFactory.create(@parsed_options)
29
+ command = Skunk::CommandFactory.create(@parsed_options)
30
30
  reporter = command.execute
31
31
 
32
32
  print(reporter.status_message)
@@ -37,7 +37,7 @@ module Skunk
37
37
  end
38
38
 
39
39
  def to_h
40
- super.merge(output_filename: output_filename) # rubocop:disable Style/HashSyntax
40
+ super.merge(output_filename: output_filename)
41
41
  end
42
42
  end
43
43
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/command_factory"
4
+
5
+ module Skunk
6
+ # Knows how to calculate the command that was request by the CLI user
7
+ class CommandFactory < RubyCritic::CommandFactory
8
+ COMMAND_CLASS_MODES = %i[version help default compare].freeze
9
+
10
+ # Returns the command class based on the command that was executed
11
+ #
12
+ # @param mode
13
+ # @return [Class]
14
+ def self.command_class(mode)
15
+ mode = mode.to_s.split("_").first.to_sym
16
+ if COMMAND_CLASS_MODES.include? mode
17
+ require "skunk/commands/#{mode}"
18
+ Command.const_get(mode.capitalize)
19
+ else
20
+ require "skunk/commands/default"
21
+ Command::Default
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/commands/base"
4
+ require "skunk/commands/status_reporter"
5
+
6
+ module Skunk
7
+ module Command
8
+ # Base class for `Skunk` commands. It knows how to build a command with
9
+ # options. It always uses a [Skunk::Command::StatusReporter] as its
10
+ # reporter object.
11
+ class Base < RubyCritic::Command::Base
12
+ def initialize(options)
13
+ super
14
+ @options = options
15
+ @status_reporter = Skunk::Command::StatusReporter.new(@options)
16
+ end
17
+
18
+ def share(_); end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/commands/compare"
4
+ require "skunk/rubycritic/analysed_modules_collection"
5
+ require "skunk/commands/output"
6
+ require "skunk/commands/shareable"
7
+ require "skunk/commands/compare_score"
8
+
9
+ # nodoc #
10
+ module Skunk
11
+ module Command
12
+ # Knows how to compare two branches and their skunk score average
13
+ class Compare < RubyCritic::Command::Compare
14
+ include Skunk::Command::Shareable
15
+
16
+ def initialize(options)
17
+ super
18
+ @options = options
19
+ @status_reporter = Skunk::Command::StatusReporter.new(options)
20
+ end
21
+
22
+ def execute
23
+ compare_branches
24
+ status_reporter
25
+ end
26
+
27
+ # switch branch and analyse files but don't generate a report
28
+ def analyse_branch(branch)
29
+ ::RubyCritic::SourceControlSystem::Git.switch_branch(::RubyCritic::Config.send(branch))
30
+ critic = critique(branch)
31
+ ::RubyCritic::Config.send(:"#{branch}_score=", critic.skunk_score_average)
32
+ ::RubyCritic::Config.root = branch_directory(branch)
33
+ end
34
+
35
+ # generate report only for modified files but don't report it
36
+ def analyse_modified_files
37
+ modified_files = ::RubyCritic::Config
38
+ .feature_branch_collection
39
+ .where(::RubyCritic::SourceControlSystem::Git.modified_files)
40
+ ::RubyCritic::AnalysedModulesCollection.new(modified_files.map(&:path),
41
+ modified_files)
42
+ ::RubyCritic::Config.root = "#{::RubyCritic::Config.root}/compare"
43
+ end
44
+
45
+ # create a txt file with the branch score details
46
+ def build_details
47
+ details = CompareScore.new(
48
+ ::RubyCritic::Config.base_branch,
49
+ ::RubyCritic::Config.feature_branch,
50
+ ::RubyCritic::Config.base_branch_score.to_f.round(2),
51
+ ::RubyCritic::Config.feature_branch_score.to_f.round(2)
52
+ ).message
53
+
54
+ Skunk::Command::Output.create_directory(::RubyCritic::Config.compare_root_directory)
55
+ File.open(build_details_path, "w") { |file| file.write(details) }
56
+ puts details
57
+ end
58
+
59
+ def build_details_path
60
+ "#{::RubyCritic::Config.compare_root_directory}/build_details.txt"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # nodoc #
4
+ module Skunk
5
+ module Command
6
+ # Knows how to describe score evolution between two branches
7
+ class CompareScore
8
+ def initialize(base_branch, feature_branch, base_branch_score, feature_branch_score)
9
+ @base_branch = base_branch
10
+ @feature_branch = feature_branch
11
+ @base_branch_score = base_branch_score
12
+ @feature_branch_score = feature_branch_score
13
+ end
14
+
15
+ def message
16
+ "Base branch (#{@base_branch}) "\
17
+ "average skunk score: #{@base_branch_score} \n"\
18
+ "Feature branch (#{@feature_branch}) "\
19
+ "average skunk score: #{@feature_branch_score} \n"\
20
+ "#{score_evolution_message}"
21
+ end
22
+
23
+ def score_evolution_message
24
+ "Skunk score average is #{score_evolution} #{score_evolution_appreciation} \n"
25
+ end
26
+
27
+ def score_evolution_appreciation
28
+ @feature_branch_score > @base_branch_score ? "worse" : "better"
29
+ end
30
+
31
+ def score_evolution
32
+ return "Infinitely" if @base_branch_score.zero?
33
+
34
+ precentage = (100 * (@base_branch_score - @feature_branch_score) / @base_branch_score)
35
+ "#{precentage.round(0).abs}%"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubycritic/commands/default"
4
+ require "rubycritic/analysers_runner"
5
+ require "rubycritic/revision_comparator"
6
+
7
+ require "skunk/commands/shareable"
8
+ require "skunk/commands/status_reporter"
9
+ require "skunk/reporter"
10
+
11
+ module Skunk
12
+ module Command
13
+ # Default command runs a critique using RubyCritic and uses
14
+ # Skunk::Command::StatusReporter to report status
15
+ class Default < RubyCritic::Command::Default
16
+ include Skunk::Command::Shareable
17
+
18
+ def initialize(options)
19
+ super
20
+ @options = options
21
+ @status_reporter = Skunk::Command::StatusReporter.new(options)
22
+ end
23
+
24
+ # It generates a report and it returns an instance of
25
+ # Skunk::Command::StatusReporter
26
+ #
27
+ # @return [Skunk::Command::StatusReporter]
28
+ def execute
29
+ RubyCritic::Config.formats = [:json]
30
+
31
+ report(critique)
32
+
33
+ status_reporter
34
+ end
35
+
36
+ # It connects the Skunk::Command::StatusReporter with the collection
37
+ # of analysed modules.
38
+ #
39
+ # @param [RubyCritic::AnalysedModulesCollection] A collection of analysed modules
40
+ def report(analysed_modules)
41
+ Reporter.generate_report(analysed_modules)
42
+
43
+ status_reporter.analysed_modules = analysed_modules
44
+ status_reporter.score = analysed_modules.score
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "skunk/commands/base"
4
+ require "rubycritic/commands/help"
5
+
6
+ module Skunk
7
+ module Command
8
+ # Knows how to guide user into using `skunk` properly
9
+ class Help < Skunk::Command::Base
10
+ # Outputs a help message
11
+ def execute
12
+ puts options[:help_text]
13
+ status_reporter
14
+ end
15
+
16
+ def sharing?
17
+ false
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :options, :status_reporter
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Skunk
4
+ module Command
5
+ # This is a module that will be used for sharing reports to a server
6
+ module Shareable
7
+ # It shares the report using SHARE_URL or https://skunk.fastruby.io. It
8
+ # will post all results in JSON format and return a status message.
9
+ #
10
+ # @param [Skunk::Command::StatusReporter] A status reporter with analysed modules
11
+ # :reek:FeatureEnvy
12
+ def share(reporter)
13
+ sharer = Skunk::Command::StatusSharer.new(@options)
14
+ sharer.status_reporter = reporter
15
+ sharer.share
16
+ end
17
+
18
+ # @return [Boolean] If the environment is set to share to an external
19
+ # service
20
+ def sharing?
21
+ ENV["SHARE"] == "true"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -75,7 +75,7 @@ TEMPL
75
75
  width = max.pathname.to_s.length + HEADINGS_WITHOUT_FILE_WIDTH
76
76
  {
77
77
  style: {
78
- width: width # rubocop:disable Style/HashSyntax
78
+ width: width
79
79
  }
80
80
  }
81
81
  end