quality_report 1.2.2 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +71 -1
- data/exe/ruby-quality-report +40 -14
- data/lib/quality_report/version.rb +1 -1
- data/screenshot-1@2x.webp +0 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c36b81a22b99492d9995e4446769315fe3a01df58e39ed71a3a1050bc05f1791
|
4
|
+
data.tar.gz: ebc3e1150b528d795fd72e926a462a93aca6311f4a232a3d94c04416bc0a7a7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e9379b163149edcab1180868a320b7b5529f6c73b5a8c90cc2ffe3292fa818ccc1a48a1cfef9fb6a319fd9dbdf348fc9e6f66749d9b82e4886f2f4a42a50d4d
|
7
|
+
data.tar.gz: f9911d996413da6cf9264b34749e318d01a1c64e85925c76dae7da609966495341e7fc9d5956866b32c477cc7adbf9f0fbbe50bd0422773242b69e16a122003f
|
data/README.md
CHANGED
@@ -1,12 +1,82 @@
|
|
1
1
|
# Ruby Quality Report
|
2
2
|
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
```sh
|
6
|
+
gem install quality-report
|
7
|
+
```
|
8
|
+
|
3
9
|
## Usage
|
4
10
|
|
5
11
|
```sh
|
6
12
|
ruby-quality-report
|
7
13
|
```
|
8
14
|
|
9
|
-
|
15
|
+
After a bit of a wait, it outputs a report in table form:
|
16
|
+
|
17
|
+
![Screenshot](screenshot-1@2x.webp)
|
18
|
+
|
19
|
+
This is showing, for each author, the percentage of problematic lines of code. Lower is better.
|
20
|
+
|
21
|
+
|
22
|
+
### For improved relevance, it has two filters.
|
23
|
+
|
24
|
+
It excludes:
|
25
|
+
|
26
|
+
- authors with fewer than 200 lines of code
|
27
|
+
- authors with no commits in the previous 60 days
|
28
|
+
|
29
|
+
|
30
|
+
### In Rails Projects
|
31
|
+
|
32
|
+
This works great in Rails projects. It examines code recursively starting in the current directory. In my testing,
|
33
|
+
I like the results best when run from `/app`. This is how I generated the report, above.
|
34
|
+
|
35
|
+
|
36
|
+
## How it works
|
37
|
+
|
38
|
+
It runs a subset of [Rubocop Metrics cops](https://docs.rubocop.org/rubocop/cops_metrics.html) on `*.rb` files that flag single lines or methods:
|
39
|
+
|
40
|
+
- [ABC Size](https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize)
|
41
|
+
- [Block Length](https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength)
|
42
|
+
- [Block Nesting](https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocknesting)
|
43
|
+
- [Cyclomatic Complexity](https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity)
|
44
|
+
- [Method Length](https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength)
|
45
|
+
- [Perceived Complexity](https://docs.rubocop.org/rubocop/cops_metrics.html#metricsperceivedcomplexity)
|
46
|
+
|
47
|
+
It then calculates the percentage of warnings per line written, per author. Each failing check is another warning.
|
48
|
+
|
49
|
+
|
50
|
+
## Intent
|
51
|
+
|
52
|
+
This is a team management tool to:
|
53
|
+
|
54
|
+
- understand the quality of the code your team is producing
|
55
|
+
- identify programmers who'd benefit from mentorship and education
|
56
|
+
|
57
|
+
## Foundational Research
|
58
|
+
|
59
|
+
Diving a little deeper, I've seen the phenomenon of micro-economies of bug-creation and bug-fixing develop within teams. Some developers appear to be extremely productive. They write a lot of code. But they also introduce a lot of bugs. The productivity is illusory.
|
60
|
+
|
61
|
+
This code quality report doesn't track **bugs** per se. But it does report **quality and complexity**. Researchers have found a strong correlation between complexity and bug rate [1]. This link is reflected, _e.g.,_ in international safety standards that mandate low software complexity to reduce failures [2].
|
62
|
+
|
63
|
+
Complex code introduces bugs in a second, more subtle way. This is because code complexity is the killer of understandability. Studies have found that developers devote 64% of their time to understanding code, while only 5% is spent on actually modifying it [3].
|
64
|
+
|
65
|
+
1. De Silva, Dilshan, et al. The Relationship between Code Complexity and Software Quality: An Empirical Study. 2023, https://www.researchgate.net/publication/370761578_The_Relationship_between_Code_Complexity_and_Software_Quality_An_Empirical_Study.
|
66
|
+
2. See e.g., ISO 26262-1:2018(En), Road Vehicles — Functional Safety — Part 1: Vocabulary. https://www.iso.org/obp/ui/en/#iso:std:iso:26262:-1:ed-2:v1:en. Accessed 29 Sept. 2024.
|
67
|
+
3. Feitelson, Dror G. “From Code Complexity Metrics to Program Comprehension.” Communications of the ACM, vol. 66, no. 5, May 2023, pp. 52–61. DOI.org (Crossref), https://doi.org/10.1145/3546576.
|
68
|
+
|
69
|
+
|
70
|
+
## Roadmap
|
71
|
+
|
72
|
+
- [ ] Colorize the output to separate high, medium, and low warning percentages.
|
73
|
+
- [ ] Fix the numerical alignment.
|
74
|
+
- [ ] Add a `--csv` option.
|
75
|
+
- [ ] Make the filters configurable.
|
76
|
+
- [ ] Speed up the scan.
|
77
|
+
- [ ] Add a progress bar.
|
78
|
+
- [ ] Refactor from script-style coding to a more standard Ruby project.
|
79
|
+
|
10
80
|
|
11
81
|
## Contributing
|
12
82
|
|
data/exe/ruby-quality-report
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'tty-table'
|
5
|
+
require 'pastel'
|
5
6
|
|
6
7
|
#
|
7
8
|
# ruby-quality-report
|
@@ -10,6 +11,9 @@ require 'tty-table'
|
|
10
11
|
# of lines of code written by each author that have been flagged as
|
11
12
|
# having too high of a complexity.
|
12
13
|
#
|
14
|
+
#
|
15
|
+
|
16
|
+
SIXTY_DAYS_IN_SECONDS = 60 * 24 * 60 * 60
|
13
17
|
|
14
18
|
def create_combined_stats(part_stats, whole_stats)
|
15
19
|
part_data = make_data_set(part_stats)
|
@@ -17,13 +21,9 @@ def create_combined_stats(part_stats, whole_stats)
|
|
17
21
|
|
18
22
|
whole_data.map do |label, whole_count|
|
19
23
|
part_count = part_data[label] || 0
|
24
|
+
percent = float_to_percent(part_count.to_f / whole_count)
|
20
25
|
|
21
|
-
{
|
22
|
-
label:,
|
23
|
-
part_count:,
|
24
|
-
whole_count:,
|
25
|
-
percent: float_to_percent(part_count.to_f / whole_count)
|
26
|
-
}
|
26
|
+
{ label:, part_count:, whole_count:, percent: }
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -44,21 +44,47 @@ def generate_csv(combined_stats)
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def generate_table(combined_stats)
|
47
|
-
table
|
47
|
+
table = TTY::Table.new(header: %W[Author Percent\nFlagged Flagged\nLines All\nLines])
|
48
|
+
table_data = generate_data(combined_stats).reject { should_skip?(_1) }
|
49
|
+
|
50
|
+
table_data.each do |stats|
|
51
|
+
table << [
|
52
|
+
{ value: stats[:label], alignment: :left },
|
53
|
+
{ value: "#{stats[:percent]}%", alignment: :right },
|
54
|
+
{ value: stats[:part_count], alignment: :right },
|
55
|
+
{ value: stats[:whole_count], alignment: :right }
|
56
|
+
]
|
57
|
+
end
|
48
58
|
|
49
|
-
|
50
|
-
|
59
|
+
render_table(table, table_data)
|
60
|
+
end
|
51
61
|
|
52
|
-
|
62
|
+
def render_table(table, table_data)
|
63
|
+
pastel = Pastel.new
|
64
|
+
|
65
|
+
table.render(:unicode, alignment: :center, padding: [0, 1], multiline: true) do |renderer|
|
66
|
+
renderer.border.style = :dim
|
67
|
+
renderer.filter = lambda { |val, row_index, _col_index|
|
68
|
+
if row_index <= 0
|
69
|
+
# Header row
|
70
|
+
val
|
71
|
+
else
|
72
|
+
case table_data[row_index - 1][:percent]
|
73
|
+
when 0...40
|
74
|
+
val
|
75
|
+
when 40...50
|
76
|
+
pastel.bold.yellow(val)
|
77
|
+
else
|
78
|
+
pastel.bold.red(val)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
}
|
53
82
|
end
|
54
|
-
|
55
|
-
table.render(:unicode)
|
56
83
|
end
|
57
84
|
|
58
85
|
def generate_data(combined_stats)
|
59
86
|
combined_stats
|
60
87
|
.sort_by { |s| s[:percent] }
|
61
|
-
.reverse
|
62
88
|
end
|
63
89
|
|
64
90
|
def should_skip?(stats)
|
@@ -78,7 +104,7 @@ def no_commits_in_last_60_days?(stats)
|
|
78
104
|
|
79
105
|
# Convert Unix timestamp to Time object
|
80
106
|
last_commit_time = Time.at(last_commit.to_i)
|
81
|
-
sixty_days_ago = Time.now -
|
107
|
+
sixty_days_ago = Time.now - SIXTY_DAYS_IN_SECONDS
|
82
108
|
|
83
109
|
last_commit_time < sixty_days_ago
|
84
110
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quality_report
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robb Shecter
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- exe/ruby-quality-report
|
76
76
|
- lib/quality_report.rb
|
77
77
|
- lib/quality_report/version.rb
|
78
|
+
- screenshot-1@2x.webp
|
78
79
|
- sig/quality_report.rbs
|
79
80
|
homepage: https://github.com/dogweather/ruby-quality-report
|
80
81
|
licenses:
|