skunk 0.5.1 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +21 -54
- data/.github/workflows/skunk.yml +4 -3
- data/.reek.yml +4 -2
- data/.rubocop_todo.yml +17 -24
- data/CHANGELOG.md +59 -37
- data/CONTRIBUTING.md +84 -0
- data/Gemfile +4 -0
- data/Gemfile-Ruby-2-4 +3 -0
- data/Gemfile-Ruby-2-5 +13 -0
- data/README.md +106 -148
- data/fastruby-logo.png +0 -0
- data/lib/skunk/cli/application.rb +7 -5
- data/lib/skunk/command_factory.rb +25 -0
- data/lib/skunk/commands/base.rb +20 -0
- data/lib/skunk/commands/compare.rb +64 -0
- data/lib/skunk/commands/compare_score.rb +39 -0
- data/lib/skunk/commands/default.rb +47 -0
- data/lib/skunk/commands/help.rb +25 -0
- data/lib/skunk/commands/shareable.rb +25 -0
- data/lib/skunk/{cli/commands → commands}/status_sharer.rb +1 -1
- data/lib/skunk/{cli/commands → commands}/version.rb +4 -0
- data/lib/skunk/rubycritic/analysed_module.rb +15 -7
- data/lib/skunk/version.rb +1 -1
- data/pull_request_template.md +11 -0
- data/skunk.gemspec +6 -7
- metadata +36 -51
- data/CODEOWNERS +0 -5
- data/lib/skunk/cli/command_factory.rb +0 -27
- data/lib/skunk/cli/commands/base.rb +0 -22
- data/lib/skunk/cli/commands/compare.rb +0 -66
- data/lib/skunk/cli/commands/compare_score.rb +0 -41
- data/lib/skunk/cli/commands/default.rb +0 -49
- data/lib/skunk/cli/commands/help.rb +0 -23
- data/lib/skunk/cli/commands/shareable.rb +0 -21
- /data/lib/skunk/{cli/commands → commands}/output.rb +0 -0
- /data/lib/skunk/{cli/commands → commands}/status_reporter.rb +0 -0
data/README.md
CHANGED
@@ -1,55 +1,66 @@
|
|
1
1
|
# Skunk
|
2
2
|
|
3
|
-
![skunk](
|
3
|
+
![skunk](logo.png)
|
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
|
-
|
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
8
|
|
9
|
-
##
|
10
|
-
|
11
|
-
|
12
|
-
|
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)
|
13
20
|
|
14
|
-
|
15
|
-
- Code Smells
|
16
|
-
- Code Coverage
|
21
|
+
## What is the SkunkScore?
|
17
22
|
|
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
|
24
|
-
- What are good candidates for
|
27
|
+
- What are good candidates for my next test-writing efforts?
|
28
|
+
- What are good candidates for my next refactoring efforts?
|
25
29
|
|
26
|
-
|
27
|
-
|
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
|
-
##
|
35
|
+
## Getting started
|
30
36
|
|
31
|
-
|
37
|
+
Start by including `skunk` in your Gemfile:
|
32
38
|
|
33
39
|
```ruby
|
34
40
|
gem 'skunk'
|
35
41
|
```
|
36
42
|
|
37
|
-
|
43
|
+
Then run `bundle`.
|
44
|
+
|
45
|
+
Or, install it yourself by running: `$ gem install skunk`
|
38
46
|
|
39
|
-
|
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.
|
40
49
|
|
41
|
-
|
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.
|
42
51
|
|
43
|
-
|
52
|
+
SimpleCov was successfully installed when it generated a JSON file under `coverage/.resultset.json` in your application directory.
|
44
53
|
|
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.
|
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
|
59
|
+
### Help commands
|
48
60
|
|
49
|
-
|
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,178 +68,125 @@ Usage: skunk [options] [paths]
|
|
57
68
|
-h, --help Show this message
|
58
69
|
```
|
59
70
|
|
60
|
-
###
|
61
|
-
|
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.
|
71
|
+
### Generating the SkunkCore for your project
|
65
72
|
|
66
|
-
|
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
|
-
|
79
|
+
The result is a list of smelly files and the SkunkScore of the project/files:
|
73
80
|
|
74
81
|
```
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
|
93
|
-
|
94
|
-
| lib/skunk/
|
95
|
-
| lib/skunk
|
96
|
-
| lib/skunk/
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
116
|
-
|
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
|
117
121
|
|
118
|
-
|
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:
|
119
123
|
|
120
|
-
|
124
|
+
`skunk app lib`
|
121
125
|
|
122
|
-
|
126
|
+
### Comparing feature branches
|
127
|
+
|
128
|
+
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.
|
129
|
+
|
130
|
+
To generate the SkunkScore of your feature branch, run:
|
123
131
|
|
124
132
|
```
|
125
|
-
skunk -b <
|
133
|
+
skunk -b <your-feature-branch-name>
|
126
134
|
```
|
127
135
|
|
128
|
-
Then get a SkunkScore average comparison:
|
136
|
+
Then, get a SkunkScore average comparison with `main` by running:
|
137
|
+
|
138
|
+
`$ skunk -b main`
|
129
139
|
|
130
140
|
```
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
141
|
+
Switched to branch 'main'
|
142
|
+
....
|
143
|
+
|
144
|
+
Base branch (main) average skunk score: 290.53999999999996
|
163
145
|
Feature branch (feature/compare) average skunk score: 340.3005882352941
|
164
146
|
Score: 340.3
|
165
147
|
```
|
166
148
|
|
167
|
-
This should give you an idea if you're moving in the
|
149
|
+
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.
|
168
150
|
|
169
|
-
|
151
|
+
## Sharing your SkunkScore
|
170
152
|
|
171
|
-
If you want to
|
172
|
-
|
153
|
+
If you want to share the results of your Skunk report with the Ruby community, run:
|
154
|
+
|
155
|
+
`SHARE=true skunk app/`
|
173
156
|
|
174
157
|
```
|
175
|
-
SHARE=true skunk app/
|
176
|
-
...
|
177
158
|
SkunkScore Total: 126.99
|
178
159
|
Modules Analysed: 17
|
179
160
|
SkunkScore Average: 7.47
|
180
|
-
Worst SkunkScore: 41.92 (lib/skunk/
|
161
|
+
Worst SkunkScore: 41.92 (lib/skunk/commands/status_sharer.rb)
|
181
162
|
|
182
163
|
Generated with Skunk v0.5.0
|
183
|
-
Shared at: https://skunk.fastruby.io/
|
164
|
+
Shared at: https://skunk.fastruby.io/
|
184
165
|
```
|
185
166
|
|
186
|
-
Results will be posted by default to https://skunk.fastruby.io which is a free
|
187
|
-
|
188
|
-
|
167
|
+
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)).
|
168
|
+
|
169
|
+
If you prefer to post results to your server, set your own `SHARE_URL`:
|
189
170
|
|
190
|
-
|
171
|
+
`$ SHARE_URL=https://path.to.your.skunk-fyi-server.example.com skunk app/`
|
191
172
|
|
192
173
|
```
|
193
|
-
SHARE_URL=https://path.to.your.skunk-fyi-server.example.com skunk app/
|
194
|
-
...
|
195
174
|
SkunkScore Total: 126.99
|
196
175
|
Modules Analysed: 17
|
197
176
|
SkunkScore Average: 7.47
|
198
|
-
Worst SkunkScore: 41.92 (lib/skunk/
|
177
|
+
Worst SkunkScore: 41.92 (lib/skunk/commands/status_sharer.rb)
|
199
178
|
|
200
179
|
Generated with Skunk v0.5.0
|
201
|
-
Shared at: https://path.to.your.skunk-fyi-server.example.com
|
180
|
+
Shared at: https://path.to.your.skunk-fyi-server.example.com
|
202
181
|
```
|
203
182
|
|
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
183
|
## Contributing
|
184
|
+
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
185
|
|
228
|
-
|
186
|
+
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.
|
229
187
|
|
230
188
|
## Sponsorship
|
231
189
|
|
232
|
-
![FastRuby.io | Rails Upgrade Services](
|
190
|
+
![FastRuby.io | Rails Upgrade Services](fastruby-logo.png)
|
233
191
|
|
234
192
|
`skunk` is maintained and funded by [FastRuby.io](https://fastruby.io). The names and logos for FastRuby.io are trademarks of The Lean Software Boutique LLC.
|
data/fastruby-logo.png
CHANGED
Binary file
|
@@ -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/
|
10
|
-
require "skunk/
|
9
|
+
require "skunk/command_factory"
|
10
|
+
require "skunk/commands/status_sharer"
|
11
11
|
|
12
12
|
module Skunk
|
13
13
|
module Cli
|
@@ -26,12 +26,14 @@ module Skunk
|
|
26
26
|
|
27
27
|
# :reek:NilCheck
|
28
28
|
@parsed_options = @options.parse.to_h
|
29
|
-
command = Skunk::
|
29
|
+
command = Skunk::CommandFactory.create(@parsed_options)
|
30
30
|
reporter = command.execute
|
31
31
|
|
32
32
|
print(reporter.status_message)
|
33
|
-
|
34
|
-
|
33
|
+
if command.sharing?
|
34
|
+
share_status_message = command.share(reporter)
|
35
|
+
print(share_status_message)
|
36
|
+
end
|
35
37
|
|
36
38
|
reporter.status
|
37
39
|
rescue OptionParser::InvalidOption => e
|
@@ -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,20 @@
|
|
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
|
+
@options = options
|
14
|
+
@status_reporter = Skunk::Command::StatusReporter.new(@options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def share(_); end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
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,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubycritic/commands/default"
|
4
|
+
require "rubycritic/analysers_runner"
|
5
|
+
require "rubycritic/revision_comparator"
|
6
|
+
require "rubycritic/reporter"
|
7
|
+
|
8
|
+
require "skunk/commands/base"
|
9
|
+
require "skunk/commands/shareable"
|
10
|
+
require "skunk/commands/status_reporter"
|
11
|
+
|
12
|
+
module Skunk
|
13
|
+
module Command
|
14
|
+
# Default command runs a critique using RubyCritic and uses
|
15
|
+
# Skunk::Command::StatusReporter to report status
|
16
|
+
class Default < RubyCritic::Command::Default
|
17
|
+
include Skunk::Command::Shareable
|
18
|
+
|
19
|
+
def initialize(options)
|
20
|
+
super
|
21
|
+
@options = options
|
22
|
+
@status_reporter = Skunk::Command::StatusReporter.new(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
# It generates a report and it returns an instance of
|
26
|
+
# Skunk::Command::StatusReporter
|
27
|
+
#
|
28
|
+
# @return [Skunk::Command::StatusReporter]
|
29
|
+
def execute
|
30
|
+
RubyCritic::Config.formats = []
|
31
|
+
|
32
|
+
report(critique)
|
33
|
+
|
34
|
+
status_reporter
|
35
|
+
end
|
36
|
+
|
37
|
+
# It connects the Skunk::Command::StatusReporter with the collection
|
38
|
+
# of analysed modules.
|
39
|
+
#
|
40
|
+
# @param [RubyCritic::AnalysedModulesCollection] A collection of analysed modules
|
41
|
+
def report(analysed_modules)
|
42
|
+
status_reporter.analysed_modules = analysed_modules
|
43
|
+
status_reporter.score = analysed_modules.score
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
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
|