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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c726b87f27512eee21ac9d00359322b70b689b5aa6d751d9055e5468f8f7b4b
4
- data.tar.gz: '097f0d797bfed3aeb5ce0b1142c03e0677585543833e36463688a165ebc68155'
3
+ metadata.gz: e826b27c5e0587f100676d206c255ab1a49dd031218a983949641434d742642b
4
+ data.tar.gz: 3f940d517efae58c02800681ce181fce837ea4d33bf6a6698833f808856bfa0a
5
5
  SHA512:
6
- metadata.gz: 3ec99505d0010744a2fd76b98d594ada1d4c0974d347b39a2f05a4541b43ce7c098f49a1f4c1fff11461ae2b0648a04dd0ecc1fe8f1e34fd8d44d1d2f73064a2
7
- data.tar.gz: 47cc50faa72a451e6d294d0540703f03359a4ff05a869be61b51ce548070444ee8c9b8dab25ab69617ef259994d668e6d270e68adf059a838d2b6889156fee40
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" method="xml"/>
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(&gt;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 { width: 1.5em; height: 1.5em; vertical-align: middle; }
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
- <xsl:apply-templates select="cobench/averages"/>
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 colspan="2"/>
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="2" style="text-align:right">Total:</td>
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="2" style="text-align:right">Average:</td>
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'] &gt; $score]) + 1"/>
272
+ <xsl:attribute name="title">
273
+ <xsl:value-of select="$pos"/>
274
+ </xsl:attribute>
275
+ <xsl:if test="$pos &lt;= 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() &gt; 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(.) &gt; 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 |d|
126
+ measures.reject {|ms| ms.key?(:meta)}.each do |ms|
125
127
  before = 0
126
- before += data[user][d[:title]][:total] if data[user][d[:title]] != nil
127
- data[user][d[:title]] = { total: d[:total] + before, href: d[:href] }
128
- titles[d[:title]] = d[:title]
129
- loog.info("The value of #{user}/#{d[:title]} is #{d[:total]}")
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,
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2022 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Cobench
26
- VERSION = '0.0.30'.freeze
26
+ VERSION = '0.0.33'.freeze
27
27
  end
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.30
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-03 00:00:00.000000000 Z
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