cobench 0.0.17 → 0.0.20

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: 4b84694d76fb95dc4c62d1c4ba42d4d4bee5c8c193c33c241b02964d44816e91
4
- data.tar.gz: a56793bef0c5d3bdda384ddd553a47cf135c51cead18e73ed984a7a5f4922077
3
+ metadata.gz: 944037515588754a9074051087759954ea921346dbf852b234a9507836e4ad4d
4
+ data.tar.gz: e718f120d970ae6f60cd83c748d4f33b6570fc4befa9ec7801316700951b56bb
5
5
  SHA512:
6
- metadata.gz: 4fee03b92b8a370f39bc207012bf777b54f459c903b08e25e75e469d98f458d599c85f2bccb51892c165b837192a3450da23d545f84c33263c07bf7469ed6261
7
- data.tar.gz: 71bb57a42b734c46f865beda63815ad1984964bf96a690a4c94c9e67ca6eb32199a59c7efb12e0c5fa99423cd54f7087aa72c2443864ea96ad091fb2e7124bc3
6
+ metadata.gz: 9bed4c1f78e45b2d7185e0c2bb67b928bb4b642cc70ac49851ed81de577817ce54da6fdd2f85f836fb26c30d27814b68c4d6e6164907e69157be0cd209227751
7
+ data.tar.gz: 9768224ff1925aef1a9cfa7656c930ae3782e6f5488aa7aa502f5a8032974925da8f64916147609cc0a2f801afd466d1b6b707ba1a6343a9a063fdf49ff9aed8
data/.rultor.yml CHANGED
@@ -1,3 +1,5 @@
1
+ docker:
2
+ image: yegor256/rultor-image:1.9.1
1
3
  assets:
2
4
  rubygems.yml: yegor256/home#assets/rubygems.yml
3
5
  install: |
@@ -16,7 +18,3 @@ release:
16
18
  merge:
17
19
  script: |-
18
20
  bundle exec rake
19
- deploy:
20
- script: |-
21
- echo "There is nothing to deploy"
22
- exit -1
data/README.md CHANGED
@@ -26,6 +26,8 @@ Then, run it locally and read its output:
26
26
  $ cobench --coder yegor256 --verbose
27
27
  ```
28
28
 
29
+ This is how our report [looks like](https://github.com/cqfn/bench).
30
+
29
31
  ## How to contribute
30
32
 
31
33
  Read [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html).
data/assets/index.xsl CHANGED
@@ -82,11 +82,11 @@ SOFTWARE.
82
82
  <xsl:text> on </xsl:text>
83
83
  <xsl:value-of select="cobench/@time"/>
84
84
  <xsl:text>. </xsl:text>
85
- <xsl:text>"Commits" is the total number of </xsl:text>
85
+ <xsl:text>"Commits" is the total number of non-merge </xsl:text>
86
86
  <a href="https://github.com/git-guides/git-commit">
87
87
  <xsl:text>Git commits</xsl:text>
88
88
  </a>
89
- <xsl:text> authored by the user. </xsl:text>
89
+ <xsl:text> to the default branch, authored by the user. </xsl:text>
90
90
  <xsl:text>"HoC" is the total number of user's </xsl:text>
91
91
  <a href="https://www.yegor256.com/2014/11/14/hits-of-code.html">
92
92
  <xsl:text>hits of code</xsl:text>
@@ -104,11 +104,34 @@ SOFTWARE.
104
104
  <xsl:text> created by the user and already merged. </xsl:text>
105
105
  <xsl:text>"Reviews" is the total number of merged pull requests that were reviewed by the user. </xsl:text>
106
106
  <xsl:text>"Score" is an arithmetic summary of all metrics with multipliers: </xsl:text>
107
- <xsl:text>one Pull costs 100 points, </xsl:text>
108
- <xsl:text>one Issue 50 points, </xsl:text>
109
- <xsl:text>one Review — 40 points, </xsl:text>
110
- <xsl:text>one Commit — 5 points, </xsl:text>
111
- <xsl:text>one HoC — just 1 point.</xsl:text>
107
+ <xsl:for-each select="cobench/weights/w">
108
+ <xsl:if test="position() &gt; 1">
109
+ <xsl:text>, </xsl:text>
110
+ </xsl:if>
111
+ <xsl:text>one </xsl:text>
112
+ <xsl:choose>
113
+ <xsl:when test="substring(@id, string-length(@id)) = 's'">
114
+ <xsl:value-of select="substring(@id, 0, string-length(@id))"/>
115
+ </xsl:when>
116
+ <xsl:otherwise>
117
+ <xsl:value-of select="@id"/>
118
+ </xsl:otherwise>
119
+ </xsl:choose>
120
+ <xsl:choose>
121
+ <xsl:when test="position() = 1">
122
+ <xsl:text> costs </xsl:text>
123
+ </xsl:when>
124
+ <xsl:otherwise>
125
+ <xsl:text> — </xsl:text>
126
+ </xsl:otherwise>
127
+ </xsl:choose>
128
+ <xsl:value-of select="text()"/>
129
+ <xsl:text> point</xsl:text>
130
+ <xsl:if test="text() != '1'">
131
+ <xsl:text>s</xsl:text>
132
+ </xsl:if>
133
+ </xsl:for-each>
134
+ <xsl:text>.</xsl:text>
112
135
  </p>
113
136
  <p>
114
137
  <xsl:text>The numbers you see reflect the activity of the last </xsl:text>
@@ -164,7 +187,7 @@ SOFTWARE.
164
187
  </tr>
165
188
  </xsl:template>
166
189
  <xsl:template match="m">
167
- <td class="num">
190
+ <xsl:variable name="body">
168
191
  <xsl:choose>
169
192
  <xsl:when test="@href = ''">
170
193
  <xsl:value-of select="."/>
@@ -175,6 +198,24 @@ SOFTWARE.
175
198
  </a>
176
199
  </xsl:otherwise>
177
200
  </xsl:choose>
201
+ </xsl:variable>
202
+ <td class="num">
203
+ <xsl:if test="@actual">
204
+ <xsl:choose>
205
+ <xsl:when test="@actual">
206
+ <span class="firebrick">
207
+ <xsl:value-of select="$body"/>
208
+ </span>
209
+ </xsl:when>
210
+ <xsl:otherwise>
211
+ <xsl:value-of select="$body"/>
212
+ </xsl:otherwise>
213
+ </xsl:choose>
214
+ <br/>
215
+ <span class="subtitle" title="The actual value of the metric was capped">
216
+ <xsl:value-of select="@actual"/>
217
+ </span>
218
+ </xsl:if>
178
219
  </td>
179
220
  </xsl:template>
180
221
  <xsl:template match="node()|@*">
data/bin/cobench CHANGED
@@ -35,7 +35,7 @@ loog = Loog::REGULAR
35
35
  def config(path)
36
36
  f = File.expand_path(path)
37
37
  args = []
38
- args += File.readlines(f).map(&:strip) if File.exist?(f)
38
+ args += File.readlines(f).map(&:strip).reject { |a| a.empty? } if File.exist?(f)
39
39
  args
40
40
  end
41
41
 
@@ -47,6 +47,7 @@ opts = Slop.parse(args, strict: true, help: true) do |o|
47
47
  o.bool '--version', 'Show current version'
48
48
  o.bool '--verbose', 'Print as much log messages as possible'
49
49
  o.bool '--dry', 'Make no real round trips to GitHub'
50
+ o.bool '--reuse', 'Don\'t fetch from GitHub, reuse the existing XML file'
50
51
  o.integer '--days', 'How many days to measure', default: 7
51
52
  o.string '--to', 'Directory where to save all files to', default: './cobench'
52
53
  o.string '--token', 'GitHub authentication token'
@@ -73,17 +74,7 @@ end
73
74
  Encoding.default_external = Encoding::UTF_8
74
75
  Encoding.default_internal = Encoding::UTF_8
75
76
 
76
- data = {}
77
-
78
- begin
79
- home = File.absolute_path(opts[:to])
80
- loog.debug("All files generated will be saved to #{home}")
81
- if File.exist?(home)
82
- loog.debug("Directory #{home} exists")
83
- else
84
- FileUtils.mkdir_p(home)
85
- loog.debug("Directory #{home} created")
86
- end
77
+ def build_xml(opts, loog)
87
78
  if opts.token?
88
79
  api = Octokit::Client.new(:access_token => opts[:token])
89
80
  else
@@ -94,6 +85,7 @@ begin
94
85
  api = Obk.new(api, pause: 2000)
95
86
  loog.info("Reading GitHub data for the last #{opts[:days]} days")
96
87
  titles = {}
88
+ data = {}
97
89
  opts[:coder].each do |u|
98
90
  user = u.downcase
99
91
  loog.info("Scanning #{user}...")
@@ -111,9 +103,10 @@ begin
111
103
  if opts.dry?
112
104
  measures = [
113
105
  { title: 'Issues', total: Random.new.rand(100), href: 'https://github.com/' },
114
- { title: 'Pulls', total: Random.new.rand(100), href: '' },
115
- { title: 'HoC', total: Random.new.rand(100), href: '' },
116
- { title: 'HoC', total: Random.new.rand(100), href: '' }
106
+ { title: 'Pulls', total: Random.new.rand(100) },
107
+ { title: 'Commits', total: Random.new.rand(100) },
108
+ { title: 'HoC', total: Random.new.rand(100) },
109
+ { title: 'HoC', total: Random.new.rand(100) }
117
110
  ]
118
111
  else
119
112
  measures = m.take(loog)
@@ -127,21 +120,31 @@ begin
127
120
  end
128
121
  end
129
122
  end
123
+ caps = {
124
+ 'HoC' => lambda { |ms| ms['Commits'][:total] * 512 },
125
+ }
130
126
  data.each do |u, ms|
131
- score = ms.map do |t, h|
132
- h[:total] * if t == 'HoC'
133
- 1
134
- elsif t == 'Pulls'
135
- 100
136
- elsif t == 'Issues'
137
- 50
138
- elsif t == 'Commits'
139
- 5
140
- elsif t == 'Reviews'
141
- 40
142
- else
143
- raise "Unknown title '#{t}'"
127
+ ms.map do |t, h|
128
+ next unless caps.key?(t)
129
+ cap = caps[t].call(ms)
130
+ if h[:total] > cap
131
+ data[u][t][:actual] = h[:total]
132
+ data[u][t][:total] = cap
144
133
  end
134
+ end
135
+ data[u] = ms
136
+ end
137
+ weights = {
138
+ 'HoC' => 1,
139
+ 'Pulls' => 200,
140
+ 'Issues' => 50,
141
+ 'Commits' => 5,
142
+ 'Reviews' => 75
143
+ }
144
+ data.each do |u, ms|
145
+ score = ms.map do |t, h|
146
+ raise "Unknown title '#{t}'" unless weights.key?(t)
147
+ h[:total] * weights[t]
145
148
  end.inject(0, :+)
146
149
  data[u]['Score'] = { total: score, href: '' }
147
150
  end
@@ -152,12 +155,22 @@ begin
152
155
  xml.title t
153
156
  end
154
157
  end
158
+ xml.weights do
159
+ weights.each do |t, w|
160
+ xml.w(id: t) do
161
+ xml.text w
162
+ end
163
+ end
164
+ end
155
165
  xml.coders do
156
166
  data.each do |u, ms|
157
- xml.coder(id: u, details: api.user(u).name) do
167
+ xml.coder(id: u) do
168
+ xml.parent.set_attribute('details', api.user(u).name)
158
169
  xml.metrics do
159
170
  ms.each do |k, v|
160
171
  xml.m(id: k, href: v[:href]) do
172
+ xml.parent.set_attribute('actual', v[:actual]) unless v[:actual].nil?
173
+ xml.parent.set_attribute('href', v[:href]) unless v[:href].nil?
161
174
  xml.text v[:total]
162
175
  end
163
176
  end
@@ -167,11 +180,27 @@ begin
167
180
  end
168
181
  end
169
182
  end
170
- index = File.join(home, 'index.xml')
171
183
  xml = builder.to_xml
172
184
  loog.debug(xml)
173
- File.write(index, xml)
174
- loog.debug("XML saved to #{index} (#{File.size(index)} bytes)")
185
+ xml
186
+ end
187
+ begin
188
+ home = File.absolute_path(opts[:to])
189
+ loog.debug("All files generated will be saved to #{home}")
190
+ if File.exist?(home)
191
+ loog.debug("Directory #{home} exists")
192
+ else
193
+ FileUtils.mkdir_p(home)
194
+ loog.debug("Directory #{home} created")
195
+ end
196
+ index = File.join(home, 'index.xml')
197
+ if opts[:reuse]
198
+ xml = File.read(index)
199
+ else
200
+ xml = build_xml(opts, loog)
201
+ File.write(index, xml)
202
+ loog.debug("XML saved to #{index} (#{File.size(index)} bytes)")
203
+ end
175
204
  xslt = Nokogiri::XSLT(File.read(File.join(__dir__, '../assets/index.xsl')))
176
205
  html = xslt.transform(Nokogiri::XML(xml), 'version' => "'#{Cobench::VERSION}'")
177
206
  loog.debug(html)
data/features/cli.feature CHANGED
@@ -11,7 +11,7 @@ Feature: Simple Reporting
11
11
  Then Exit code is zero
12
12
 
13
13
  Scenario: Simple report
14
- When I run bin/cobench with "--coder yegor256 --coder John --verbose --dry --to foo"
14
+ When I run bin/cobench with "--coder yegor256 --coder Jeff --verbose --dry --to foo"
15
15
  Then Stdout contains "XML saved to"
16
16
  And Exit code is zero
17
17
 
@@ -34,7 +34,7 @@ class Cobench::Commits
34
34
 
35
35
  def take(loog)
36
36
  from = (Time.now - (60 * 60 * 24 * @opts[:days])).strftime('%Y-%m-%d')
37
- q = "author:#{@user} author-date:>#{from}"
37
+ q = "author:#{@user} author-date:>#{from} is:public merge:false"
38
38
  json = @api.search_commits(q)
39
39
  loog.debug("Found #{json.total_count} commits")
40
40
  hoc = 0
@@ -44,6 +44,7 @@ class Cobench::Commits
44
44
  next unless Cobench::Match.new(@opts, loog).matches?(repo)
45
45
  loog.debug("Including #{sha} in #{repo}")
46
46
  json = @api.commit(repo, sha)
47
+ next unless json
47
48
  hocs = json.stats.total
48
49
  loog.debug("Found #{hocs} HoC in #{sha}")
49
50
  hoc += hocs
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2022 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Cobench
26
- VERSION = '0.0.17'.freeze
26
+ VERSION = '0.0.20'.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.17
4
+ version: 0.0.20
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-08-16 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace