quality_report 1.5.0 → 1.7.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +3 -1
- data/Rakefile +2 -2
- data/exe/ruby-quality-report +101 -14
- data/lib/quality_report/version.rb +1 -1
- data/lib/quality_report.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51abac0022982e8c18d66396b580a4acadcbc14f86fd698f6e551e0d95cd304a
|
4
|
+
data.tar.gz: 8f4c5b26c6dd55268206ebe402642a88a287e5339d93a7dcd2532b11093e5564
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 701288fc0a288adba125cb2299810b79067ef86486ae1c94cdf87f86b0ebdf030226cb4c925c10a43455ee606a2a70f3396b5d538feb5b07200cbeedb22acde2
|
7
|
+
data.tar.gz: cfca2cab37975eed90e80b6c018f35c7a193f4977c7c6d62b21057f6d8513d0a3b3fd1bc33e4f1f9f826bbd5887bfd81bd7a69134b793cec5a22c6beb9c3138d
|
data/.rubocop.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 3.1
|
2
|
+
TargetRubyVersion: 3.1
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
## Installation
|
4
4
|
|
5
5
|
```sh
|
6
|
-
gem install
|
6
|
+
gem install quality_report
|
7
7
|
```
|
8
8
|
|
9
9
|
## Usage
|
@@ -73,6 +73,8 @@ Complex code introduces bugs in a second, more subtle way. This is because code
|
|
73
73
|
|
74
74
|
- [x] Colorize the output to separate high, medium, and low warning percentages.
|
75
75
|
- [x] Fix the numerical alignment.
|
76
|
+
- [ ] --add-column option.
|
77
|
+
- [ ] --skip option.
|
76
78
|
- [ ] Add a progress bar.
|
77
79
|
- [ ] Speed up the scan.
|
78
80
|
- [ ] Refactor from script-style coding to a more standard Ruby project.
|
data/Rakefile
CHANGED
data/exe/ruby-quality-report
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'json'
|
5
|
+
require 'tty-option'
|
4
6
|
require 'tty-table'
|
5
7
|
require 'pastel'
|
6
8
|
|
@@ -19,46 +21,60 @@ def create_combined_stats(part_stats, whole_stats)
|
|
19
21
|
part_data = make_data_set(part_stats)
|
20
22
|
whole_data = make_data_set(whole_stats)
|
21
23
|
|
22
|
-
whole_data.map do |
|
23
|
-
part_count = part_data[
|
24
|
+
whole_data.map do |author, whole_count|
|
25
|
+
part_count = part_data[author] || 0
|
24
26
|
percent = float_to_percent(part_count.to_f / whole_count)
|
25
27
|
|
26
|
-
{
|
28
|
+
{ author:, part_count:, whole_count:, percent: }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
def make_data_set(two_column_data)
|
31
33
|
hash = {}
|
32
34
|
two_column_data.each_line do |line|
|
33
|
-
count,
|
34
|
-
hash[
|
35
|
+
count, author = line.split(' ')
|
36
|
+
hash[author] = count.to_i
|
35
37
|
end
|
36
38
|
hash
|
37
39
|
end
|
38
40
|
|
39
41
|
def generate_csv(combined_stats)
|
40
42
|
generate_data(combined_stats)
|
41
|
-
.map { |stats| [stats[:
|
43
|
+
.map { |stats| [stats[:author], stats[:percent], stats[:part_count], stats[:whole_count]].join(',') }
|
42
44
|
.tap { |x| x.prepend(['Author,Percent Flagged,Flagged Lines,All Lines']) }
|
43
45
|
.join("\n")
|
44
46
|
end
|
45
47
|
|
46
|
-
def generate_table(combined_stats)
|
47
|
-
|
48
|
-
|
48
|
+
def generate_table(combined_stats, colspec: {}, skip: '')
|
49
|
+
author_heading = ['Author']
|
50
|
+
static_heading = [colspec.keys&.first].compact
|
51
|
+
default_headings = ['Percent Flagged', 'Flagged Lines', 'All lines']
|
52
|
+
all_headings = author_heading + static_heading + default_headings
|
53
|
+
|
54
|
+
table = TTY::Table.new(header: all_headings)
|
55
|
+
table_data = generate_data(combined_stats).reject { should_skip?(_1) }
|
56
|
+
static_values = colspec[static_heading.first] || {}
|
49
57
|
|
50
58
|
table_data.each do |stats|
|
51
|
-
|
52
|
-
|
59
|
+
next if skip.include?(stats[:author])
|
60
|
+
|
61
|
+
author_column = [{ value: stats[:author], alignment: :left }]
|
62
|
+
static_column = [static_heading.any? ? { value: static_values[stats[:author]], alignment: :left } : nil]
|
63
|
+
dynamic_columns = [
|
53
64
|
{ value: "#{stats[:percent]}%", alignment: :right },
|
54
65
|
{ value: int_to_accounting(stats[:part_count]), alignment: :right },
|
55
66
|
{ value: int_to_accounting(stats[:whole_count]), alignment: :right }
|
56
67
|
]
|
68
|
+
|
69
|
+
table << (author_column + static_column + dynamic_columns).compact
|
57
70
|
end
|
58
71
|
|
59
72
|
render_table(table, table_data)
|
60
73
|
end
|
61
74
|
|
75
|
+
##
|
76
|
+
# Renders the table with color coding based on the percentage of flagged lines.
|
77
|
+
#
|
62
78
|
def render_table(table, table_data)
|
63
79
|
pastel = Pastel.new
|
64
80
|
|
@@ -96,7 +112,7 @@ def less_than_200_lines_total?(stats)
|
|
96
112
|
end
|
97
113
|
|
98
114
|
def no_commits_in_last_60_days?(stats)
|
99
|
-
author = stats[:
|
115
|
+
author = stats[:author]
|
100
116
|
|
101
117
|
# Get the last commit timestamp in Unix epoch format
|
102
118
|
last_commit = `git log -1 --format="%at" --author="#{author}"`.chomp
|
@@ -126,11 +142,82 @@ def int_to_accounting(an_int)
|
|
126
142
|
an_int.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
127
143
|
end
|
128
144
|
|
145
|
+
#
|
146
|
+
# CLI Argument Parser
|
147
|
+
#
|
148
|
+
class Command
|
149
|
+
include TTY::Option
|
150
|
+
|
151
|
+
usage do
|
152
|
+
program 'ruby-quality-report'
|
153
|
+
no_command
|
154
|
+
header 'Ruby Quality Report'
|
155
|
+
desc <<~DESC
|
156
|
+
Generates a report of the percentage of flagged lines of code written by each author. For improved relevance, it excludes:
|
157
|
+
|
158
|
+
- authors with fewer than 200 lines of code
|
159
|
+
- authors with no commits in the previous 60 days
|
160
|
+
|
161
|
+
It runs a suite of Rubocop metrics on *.rb files recursively starting in the current directory. Then, using git, it calculates the percentage of warnings per line written, per author. Each failing check is another warning.
|
162
|
+
DESC
|
163
|
+
|
164
|
+
example <<~EXAMPLE1
|
165
|
+
Append a column showing office location. The order of the keys in the JSON does not matter:
|
166
|
+
$ ruby-quality-report -c '{"Location": {"Amy": "NYC", "Bob": "Remote"}}'
|
167
|
+
EXAMPLE1
|
168
|
+
|
169
|
+
example <<~EXAMPLE2
|
170
|
+
Skip one author:
|
171
|
+
$ ruby-quality-report --skip Cathy
|
172
|
+
EXAMPLE2
|
173
|
+
end
|
174
|
+
|
175
|
+
option :add_column do
|
176
|
+
long '--add-column JSON'
|
177
|
+
short '-c JSON'
|
178
|
+
desc 'Add a static column to the report. This is a simple way to add known information. See the examples.'
|
179
|
+
end
|
180
|
+
|
181
|
+
flag :skip do
|
182
|
+
long '--skip AUTHOR'
|
183
|
+
short '-s AUTHOR'
|
184
|
+
desc 'Filter out a git author'
|
185
|
+
end
|
186
|
+
|
187
|
+
flag :help do
|
188
|
+
short '-h'
|
189
|
+
long '--help'
|
190
|
+
desc 'Print this help'
|
191
|
+
end
|
192
|
+
|
193
|
+
def run
|
194
|
+
if params[:help]
|
195
|
+
print help
|
196
|
+
exit 1
|
197
|
+
elsif params.errors.any?
|
198
|
+
puts params.errors.summary
|
199
|
+
exit 1
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
129
204
|
#
|
130
205
|
# Execution begins here
|
131
206
|
#
|
207
|
+
|
208
|
+
command = Command.new
|
209
|
+
command.parse
|
210
|
+
command.run
|
211
|
+
|
212
|
+
add_column_param = command.params[:add_column]
|
213
|
+
colspec = add_column_param ? JSON.parse(add_column_param) : {}
|
214
|
+
puts "Adding column: #{colspec.keys.first}" unless colspec.empty?
|
215
|
+
|
216
|
+
skip = command.params[:skip] || ''
|
217
|
+
puts "Skipping author: #{skip}" if skip != ''
|
218
|
+
|
132
219
|
PART_STATS = `ruby-author-warnings | frequency-list`.freeze
|
133
|
-
WHOLE_STATS = `ruby-line-authors
|
220
|
+
WHOLE_STATS = `ruby-line-authors | frequency-list`.freeze
|
134
221
|
COMBINED_STATS = create_combined_stats(PART_STATS, WHOLE_STATS)
|
135
222
|
|
136
|
-
puts generate_table(COMBINED_STATS)
|
223
|
+
puts generate_table(COMBINED_STATS, colspec:, skip:)
|
data/lib/quality_report.rb
CHANGED
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.7.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-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.68'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: tty-option
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: tty-table
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|