cobench 0.0.30 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +8 -1
- data/assets/index.xsl +78 -7
- data/bin/cobench +22 -7
- data/cobench.gemspec +1 -0
- data/features/cli.feature +5 -0
- data/lib/cobench/metrics/pulls.rb +7 -0
- data/lib/cobench/version.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: e826b27c5e0587f100676d206c255ab1a49dd031218a983949641434d742642b
|
4
|
+
data.tar.gz: 3f940d517efae58c02800681ce181fce837ea4d33bf6a6698833f808856bfa0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f89fe625b2e9ad37e2f94ec370af8e45552dfcce768a1dea6b583714994ecd119493d7f65113c5cc8262f7e81ed86951ce49f06970929b0b611a7225ce98186
|
7
|
+
data.tar.gz: cb4a616c54c4fba0109a6bd36592f2377896793de5ff05b7ba1ea228d77b89eeccf39962d5ba09af5d94168fc25e103d4809344c1b747a9a96d673305779fc41
|
data/Rakefile
CHANGED
@@ -31,7 +31,7 @@ def version
|
|
31
31
|
Gem::Specification.load(Dir['*.gemspec'].first).version
|
32
32
|
end
|
33
33
|
|
34
|
-
task default: %i[clean test features rubocop copyright]
|
34
|
+
task default: %i[clean test features rubocop xcop copyright]
|
35
35
|
|
36
36
|
require 'rake/testtask'
|
37
37
|
desc 'Run all unit tests'
|
@@ -59,6 +59,13 @@ RuboCop::RakeTask.new(:rubocop) do |task|
|
|
59
59
|
task.options = ['--display-cop-names']
|
60
60
|
end
|
61
61
|
|
62
|
+
require 'xcop/rake_task'
|
63
|
+
Xcop::RakeTask.new(:xcop) do |task|
|
64
|
+
task.license = 'LICENSE.txt'
|
65
|
+
task.includes = ['**/*.xml', '**/*.xsl', '**/*.xsd', '**/*.html']
|
66
|
+
task.excludes = ['cobench/**', 'coverage/**']
|
67
|
+
end
|
68
|
+
|
62
69
|
require 'cucumber/rake/task'
|
63
70
|
Cucumber::Rake::Task.new(:features) do
|
64
71
|
Rake::Cleaner.cleanup_files(['coverage'])
|
data/assets/index.xsl
CHANGED
@@ -23,7 +23,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
SOFTWARE.
|
24
24
|
-->
|
25
25
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
|
26
|
-
<xsl:output encoding="UTF-8"
|
26
|
+
<xsl:output method="xml" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes"/>
|
27
|
+
<xsl:strip-spaces select="*"/>
|
27
28
|
<xsl:param name="version"/>
|
28
29
|
<xsl:template match="/">
|
29
30
|
<html>
|
@@ -45,9 +46,20 @@ SOFTWARE.
|
|
45
46
|
$(function() {
|
46
47
|
$("#metrics").tablesorter();
|
47
48
|
});
|
49
|
+
$(function() {
|
50
|
+
let params = (new URL(document.location)).searchParams;
|
51
|
+
let org = params.get('org');
|
52
|
+
if (org) {
|
53
|
+
$('#metrics tbody tr:not(:has(>td.org-' + org + '))').hide();
|
54
|
+
$('#org').text('@' + org);
|
55
|
+
$('#org-head').css('visibility', 'visible');
|
56
|
+
console.log('Showing @' + org + ' org');
|
57
|
+
}
|
58
|
+
});
|
48
59
|
</script>
|
49
60
|
<style>
|
50
|
-
td, th { font-family: monospace; font-size: 18px; }
|
61
|
+
td, th { font-family: monospace; font-size: 18px; line-height: 1em; }
|
62
|
+
td.top { vertical-align: middle; }
|
51
63
|
.num { text-align: right; }
|
52
64
|
.left { border-bottom: 0; }
|
53
65
|
section { width: auto; }
|
@@ -55,7 +67,8 @@ SOFTWARE.
|
|
55
67
|
footer { text-align: center; font-size: 0.8em; line-height: 1.2em; color: gray; }
|
56
68
|
article { border: 0; }
|
57
69
|
td.avatar { vertical-align: middle; text-align: center; }
|
58
|
-
td.avatar img
|
70
|
+
td.avatar img,
|
71
|
+
td.orgs img { width: 1.5em; height: 1.5em; vertical-align: middle; }
|
59
72
|
.subtitle { font-size: 0.8em; line-height: 1em; color: gray; }
|
60
73
|
.sorter { cursor: pointer; }
|
61
74
|
</style>
|
@@ -70,14 +83,30 @@ SOFTWARE.
|
|
70
83
|
</p>
|
71
84
|
</header>
|
72
85
|
<article>
|
86
|
+
<p id="org-head" style="visibility: hidden;">
|
87
|
+
<xsl:text>You only see people who contributed to </xsl:text>
|
88
|
+
<strong>
|
89
|
+
<span id="org">
|
90
|
+
<xsl:text>@???</xsl:text>
|
91
|
+
</span>
|
92
|
+
</strong>
|
93
|
+
<xsl:text>. </xsl:text>
|
94
|
+
<xsl:text>Click </xsl:text>
|
95
|
+
<a href="index.html">
|
96
|
+
<xsl:text>here</xsl:text>
|
97
|
+
</a>
|
98
|
+
<xsl:text> to see all.</xsl:text>
|
99
|
+
</p>
|
73
100
|
<table id="metrics">
|
74
101
|
<colgroup>
|
75
102
|
<col/>
|
103
|
+
<col style="width: 2.5em;"/>
|
76
104
|
<col/>
|
77
105
|
<xsl:for-each select="cobench/titles/title">
|
78
106
|
<xsl:sort select="."/>
|
79
107
|
<col/>
|
80
108
|
</xsl:for-each>
|
109
|
+
<col/>
|
81
110
|
</colgroup>
|
82
111
|
<thead>
|
83
112
|
<xsl:apply-templates select="cobench/titles"/>
|
@@ -85,7 +114,7 @@ SOFTWARE.
|
|
85
114
|
<xsl:apply-templates select="cobench/coders"/>
|
86
115
|
<tfoot>
|
87
116
|
<xsl:apply-templates select="cobench/totals"/>
|
88
|
-
|
117
|
+
<xsl:apply-templates select="cobench/averages"/>
|
89
118
|
</tfoot>
|
90
119
|
</table>
|
91
120
|
</article>
|
@@ -185,19 +214,27 @@ SOFTWARE.
|
|
185
214
|
</xsl:template>
|
186
215
|
<xsl:template match="cobench/titles">
|
187
216
|
<tr>
|
188
|
-
<th
|
217
|
+
<th class="sorter num">
|
218
|
+
<xsl:text>Top</xsl:text>
|
219
|
+
</th>
|
220
|
+
<th colspan="2">
|
221
|
+
<xsl:text>Programmer</xsl:text>
|
222
|
+
</th>
|
189
223
|
<xsl:for-each select="title">
|
190
224
|
<xsl:sort select="."/>
|
191
225
|
<th class="sorter num">
|
192
226
|
<xsl:value-of select="."/>
|
193
227
|
</th>
|
194
228
|
</xsl:for-each>
|
229
|
+
<th>
|
230
|
+
<xsl:text>Orgs</xsl:text>
|
231
|
+
</th>
|
195
232
|
</tr>
|
196
233
|
</xsl:template>
|
197
234
|
<xsl:template match="cobench/totals">
|
198
235
|
<xsl:variable name="totals" select="."/>
|
199
236
|
<tr>
|
200
|
-
<td colspan="
|
237
|
+
<td colspan="3" style="text-align:right">Total:</td>
|
201
238
|
<xsl:for-each select="/cobench/titles/title">
|
202
239
|
<xsl:sort select="."/>
|
203
240
|
<xsl:variable name="t" select="."/>
|
@@ -205,12 +242,13 @@ SOFTWARE.
|
|
205
242
|
<xsl:value-of select="$totals/w[@id=$t]"/>
|
206
243
|
</td>
|
207
244
|
</xsl:for-each>
|
245
|
+
<td/>
|
208
246
|
</tr>
|
209
247
|
</xsl:template>
|
210
248
|
<xsl:template match="cobench/averages">
|
211
249
|
<xsl:variable name="averages" select="."/>
|
212
250
|
<tr>
|
213
|
-
<td colspan="
|
251
|
+
<td colspan="3" style="text-align:right">Average:</td>
|
214
252
|
<xsl:for-each select="/cobench/titles/title">
|
215
253
|
<xsl:sort select="."/>
|
216
254
|
<xsl:variable name="t" select="."/>
|
@@ -218,6 +256,7 @@ SOFTWARE.
|
|
218
256
|
<xsl:value-of select="$averages/w[@id=$t]"/>
|
219
257
|
</td>
|
220
258
|
</xsl:for-each>
|
259
|
+
<td/>
|
221
260
|
</tr>
|
222
261
|
</xsl:template>
|
223
262
|
<xsl:template match="cobench/coders">
|
@@ -227,6 +266,17 @@ SOFTWARE.
|
|
227
266
|
</xsl:template>
|
228
267
|
<xsl:template match="coder">
|
229
268
|
<tr>
|
269
|
+
<td class="num top">
|
270
|
+
<xsl:variable name="score" select="metrics/m[@id='Score']"/>
|
271
|
+
<xsl:variable name="pos" select="count(/cobench/coders/coder[metrics/m[@id='Score'] > $score]) + 1"/>
|
272
|
+
<xsl:attribute name="title">
|
273
|
+
<xsl:value-of select="$pos"/>
|
274
|
+
</xsl:attribute>
|
275
|
+
<xsl:if test="$pos <= 8">
|
276
|
+
<xsl:text>#</xsl:text>
|
277
|
+
<xsl:value-of select="$pos"/>
|
278
|
+
</xsl:if>
|
279
|
+
</td>
|
230
280
|
<td class="avatar">
|
231
281
|
<img src="https://socatar.com/github/{@id}/64-64"/>
|
232
282
|
</td>
|
@@ -246,6 +296,27 @@ SOFTWARE.
|
|
246
296
|
<xsl:sort select="@id"/>
|
247
297
|
<xsl:apply-templates select="."/>
|
248
298
|
</xsl:for-each>
|
299
|
+
<td class="orgs">
|
300
|
+
<xsl:attribute name="class">
|
301
|
+
<xsl:text>orgs</xsl:text>
|
302
|
+
<xsl:for-each select="orgs/org">
|
303
|
+
<xsl:text> org-</xsl:text>
|
304
|
+
<xsl:value-of select="."/>
|
305
|
+
</xsl:for-each>
|
306
|
+
</xsl:attribute>
|
307
|
+
<xsl:for-each select="orgs/org">
|
308
|
+
<xsl:sort select="."/>
|
309
|
+
<xsl:if test="position() > 1">
|
310
|
+
<xsl:text> </xsl:text>
|
311
|
+
</xsl:if>
|
312
|
+
<a href="?org={.}" title="{.}">
|
313
|
+
<xsl:value-of select="substring(., 1, 2)"/>
|
314
|
+
<xsl:if test="string-length(.) > 2">
|
315
|
+
<xsl:text>…</xsl:text>
|
316
|
+
</xsl:if>
|
317
|
+
</a>
|
318
|
+
</xsl:for-each>
|
319
|
+
</td>
|
249
320
|
</tr>
|
250
321
|
</xsl:template>
|
251
322
|
<xsl:template match="m">
|
data/bin/cobench
CHANGED
@@ -96,6 +96,7 @@ def build_xml(opts, loog)
|
|
96
96
|
loog.info("Reading GitHub data for the last #{opts[:days]} days")
|
97
97
|
titles = {}
|
98
98
|
data = {}
|
99
|
+
orgs = {}
|
99
100
|
opts[:coder].each do |u|
|
100
101
|
user = u.downcase
|
101
102
|
loog.info("Scanning #{user}...")
|
@@ -116,17 +117,24 @@ def build_xml(opts, loog)
|
|
116
117
|
{ title: 'Pulls', total: Random.new.rand(100) },
|
117
118
|
{ title: 'Commits', total: Random.new.rand(100) },
|
118
119
|
{ title: 'HoC', total: Random.new.rand(100) },
|
119
|
-
{ title: 'HoC', total: Random.new.rand(100) }
|
120
|
+
{ title: 'HoC', total: Random.new.rand(100) },
|
121
|
+
{ meta: true, title: 'Orgs', list: ['objectionary', 'artipie'] },
|
120
122
|
]
|
121
123
|
else
|
122
124
|
measures = m.take(loog)
|
123
125
|
end
|
124
|
-
measures.each do |
|
126
|
+
measures.reject {|ms| ms.key?(:meta)}.each do |ms|
|
125
127
|
before = 0
|
126
|
-
before += data[user][
|
127
|
-
data[user][
|
128
|
-
titles[
|
129
|
-
loog.info("The value of #{user}/#{
|
128
|
+
before += data[user][ms[:title]][:total] if data[user][ms[:title]] != nil
|
129
|
+
data[user][ms[:title]] = { total: ms[:total] + before, href: ms[:href] }
|
130
|
+
titles[ms[:title]] = ms[:title]
|
131
|
+
loog.info("The value of #{user}/#{ms[:title]} is #{ms[:total]}")
|
132
|
+
end
|
133
|
+
measures.select {|ms| ms.key?(:meta)}.each do |ms|
|
134
|
+
if ms[:title] == 'Orgs'
|
135
|
+
orgs[user] = [] unless orgs.key?(user)
|
136
|
+
end
|
137
|
+
orgs[user] += ms[:list]
|
130
138
|
end
|
131
139
|
end
|
132
140
|
end
|
@@ -212,6 +220,13 @@ def build_xml(opts, loog)
|
|
212
220
|
data.each do |u, ms|
|
213
221
|
xml.coder(id: u) do
|
214
222
|
xml.parent.set_attribute('details', api.user(u).name) unless opts[:dry]
|
223
|
+
if orgs.key?(u)
|
224
|
+
xml.orgs do
|
225
|
+
orgs[u].uniq.each do |o|
|
226
|
+
xml.org o
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
215
230
|
xml.metrics do
|
216
231
|
ms.each do |k, v|
|
217
232
|
xml.m(id: k) do
|
@@ -251,7 +266,7 @@ begin
|
|
251
266
|
html = xslt.transform(Nokogiri::XML(xml), 'version' => "'#{Cobench::VERSION}'")
|
252
267
|
loog.debug(html)
|
253
268
|
front = File.join(home, 'index.html')
|
254
|
-
File.write(front, html)
|
269
|
+
File.write(front, html.to_html(indent: 0).gsub("\n", ''))
|
255
270
|
loog.debug("HTML saved to #{front} (#{File.size(front)} bytes)")
|
256
271
|
rescue StandardError => e
|
257
272
|
loog.error(Backtrace.new(e))
|
data/cobench.gemspec
CHANGED
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
|
|
48
48
|
s.add_runtime_dependency 'octokit', '~>4.0'
|
49
49
|
s.add_runtime_dependency 'rainbow', '~>3.0'
|
50
50
|
s.add_runtime_dependency 'slop', '~>4.4'
|
51
|
+
s.add_runtime_dependency 'xcop', '~>0.6'
|
51
52
|
s.add_development_dependency 'codecov', '0.6.0'
|
52
53
|
s.add_development_dependency 'cucumber', '8.0.0'
|
53
54
|
s.add_development_dependency 'minitest', '5.15.0'
|
data/features/cli.feature
CHANGED
@@ -15,6 +15,11 @@ Feature: Simple Reporting
|
|
15
15
|
Then Stdout contains "XML saved to"
|
16
16
|
And Exit code is zero
|
17
17
|
|
18
|
+
Scenario: Simple report through real GitHub API
|
19
|
+
When I run bin/cobench with "--coder=yegor256 --include=*/* --days=1 --verbose"
|
20
|
+
Then Stdout contains "XML saved to"
|
21
|
+
And Exit code is zero
|
22
|
+
|
18
23
|
Scenario: Simple report with defaults
|
19
24
|
Given I have a ".cobench" file with content:
|
20
25
|
"""
|
@@ -38,16 +38,23 @@ class Cobench::Pulls
|
|
38
38
|
json = @api.search_issues(q)
|
39
39
|
loog.debug("Found #{json.total_count} pull requests")
|
40
40
|
hoc = 0
|
41
|
+
orgs = []
|
41
42
|
total = json.items.count do |p|
|
42
43
|
pr = p.pull_request.url.split('/')[-1]
|
43
44
|
repo = p.repository_url.split('/')[-2..-1].join('/')
|
44
45
|
next unless Cobench::Match.new(@opts, loog).matches?(repo)
|
46
|
+
orgs << p.repository_url.split('/')[-2]
|
45
47
|
pr_json = @api.pull_request(repo, pr)
|
46
48
|
hocs = pr_json.additions + pr_json.deletions
|
47
49
|
hoc += hocs
|
48
50
|
loog.debug("Including #{repo}##{pr} with #{hocs}")
|
49
51
|
end
|
50
52
|
[
|
53
|
+
{
|
54
|
+
meta: true,
|
55
|
+
title: 'Orgs',
|
56
|
+
list: orgs
|
57
|
+
},
|
51
58
|
{
|
52
59
|
title: 'Pulls',
|
53
60
|
total: total,
|
data/lib/cobench/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cobench
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.33
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '4.4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: xcop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.6'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.6'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: codecov
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|