cobench 0.0.30 → 0.0.33
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/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
|