fief 0.0.2 → 0.0.4

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: ba06e870d6a95356820b15bd3f692a4662057e7a466cf7a877065228bd74e536
4
- data.tar.gz: 1deec8fafbe79d23d4d2f7a580daec7089b056ad3c03a2d29c36150251721496
3
+ metadata.gz: 8283e5cbb1075fb17ae4ee598290b94836df887ef58f00f25a369128afd3f469
4
+ data.tar.gz: ed4fe0314ef1b4cc6bd591ad7eec31da037642dac59d5834c11fadd43900098e
5
5
  SHA512:
6
- metadata.gz: 0b80671ae6d23c725dcaf3f94920682a45b2ec0d304736e6266d888fd976ceab3eb810c06d48dd828fe4d0d1c8c24c45943a33b17668e3baf790a9a39d149076
7
- data.tar.gz: 24d27ab6bb0cf97bf7b4ef9176381918f295641448f31dbaca719ddb3cb45eed6ab5dd977b100572a77734e8612a2c5ce4038d1feb7dd5388b7e6967174cb686
6
+ metadata.gz: 690bb54a315e20c3519411fabeb34aa0a49948a710e840c4b28c84d857b1148d52e022cf7433e6ab4262ed969c634f3701ede8c03a15761282b0b9ed2cfc54f9
7
+ data.tar.gz: bb116efa704b8e4f8eec845d84649eff42fec4582e93992c07756f6e79460634c3f935e17ccabccaf8772fa47d2cbede16aa461ddbf8f5a868f2565a0abd4a28
@@ -2,10 +2,7 @@
2
2
  name: cron
3
3
  on:
4
4
  schedule:
5
- - cron: "23 23 * * *"
6
- push:
7
- branches:
8
- - master
5
+ - cron: "13 4 * * 1,3,5"
9
6
  concurrency:
10
7
  group: cron
11
8
  cancel-in-progress: true
@@ -19,12 +16,20 @@ jobs:
19
16
  ruby-version: 2.7
20
17
  - run: bundle install
21
18
  - run: |
22
- bin/fief --verbose --token ${{ secrets.TOKEN }} --to gh-pages \
19
+ bin/fief --token ${{ secrets.TOKEN }} --delay 1500 \
23
20
  --include jcabi/* \
21
+ --include yegor256/* \
22
+ --include sttc/* \
23
+ --include objectionary/* \
24
+ --include polystat/* \
25
+ --include zerocracy/* \
26
+ --include zold-io/* \
24
27
  --exclude jcabi/.github \
25
- --include yegor256/cactoos \
26
- --include yegor256/takes \
27
- --include yegor256/xembly
28
+ --exclude yegor256/quiz \
29
+ --exclude yegor256/hangman \
30
+ --exclude objectionary/.github \
31
+ --exclude polystat/.github \
32
+ --to gh-pages
28
33
  - run: mkdir -p gh-pages/$(date +'%Y/%m/%d')
29
34
  - run: cp gh-pages/index.xml gh-pages/$(date +'%Y/%m/%d')/index.xml
30
35
  - uses: JamesIves/github-pages-deploy-action@v4.4.2
data/.rubocop.yml CHANGED
@@ -8,7 +8,7 @@ AllCops:
8
8
  SuggestExtensions: false
9
9
 
10
10
  Metrics/CyclomaticComplexity:
11
- Max: 10
11
+ Max: 14
12
12
  Metrics/MethodLength:
13
13
  Enabled: false
14
14
  Layout/MultilineMethodCallIndentation:
@@ -21,3 +21,5 @@ Layout/EmptyLineAfterGuardClause:
21
21
  Enabled: false
22
22
  Style/ClassAndModuleChildren:
23
23
  Enabled: false
24
+ Metrics/BlockLength:
25
+ Max: 30
data/Gemfile CHANGED
@@ -25,7 +25,7 @@ gem 'cucumber', '8.0.0', require: false
25
25
  gem 'minitest', '5.15.0', require: false
26
26
  gem 'rake', '13.0.6', require: false
27
27
  gem 'rdoc', '6.5.0', require: false
28
- gem 'rubocop', '1.52.0', require: false
28
+ gem 'rubocop', '1.52.1', require: false
29
29
  gem 'rubocop-rspec', '2.22.0', require: false
30
30
  gem 'simplecov', '0.22.0', require: false
31
31
  gem 'xcop', '0.7.1', require: false
data/assets/index.xsl CHANGED
@@ -110,7 +110,15 @@ SOFTWARE.
110
110
  </thead>
111
111
  <xsl:apply-templates select="fief/repositories"/>
112
112
  <tfoot>
113
- <!-- nothing yet -->
113
+ <tr>
114
+ <td>Total:</td>
115
+ <xsl:for-each select="fief/titles/title">
116
+ <xsl:variable name="title" select="."/>
117
+ <td class="num">
118
+ <xsl:value-of select="sum(//m[@id=$title])"/>
119
+ </td>
120
+ </xsl:for-each>
121
+ </tr>
114
122
  </tfoot>
115
123
  </table>
116
124
  </article>
@@ -131,6 +139,18 @@ SOFTWARE.
131
139
  </xsl:for-each>
132
140
  <xsl:text>.</xsl:text>
133
141
  </p>
142
+ <p>
143
+ <xsl:for-each select="fief/legend/column">
144
+ <xsl:if test="position() &gt; 1">
145
+ <xsl:text>, </xsl:text>
146
+ </xsl:if>
147
+ <xsl:text>"</xsl:text>
148
+ <xsl:value-of select="@title"/>
149
+ <xsl:text>" is </xsl:text>
150
+ <xsl:value-of select="."/>
151
+ </xsl:for-each>
152
+ <xsl:text>.</xsl:text>
153
+ </p>
134
154
  <p>
135
155
  <xsl:text>The page was generated by </xsl:text>
136
156
  <a href="https://github.com/yegor256/fief">
@@ -142,6 +162,24 @@ SOFTWARE.
142
162
  <xsl:value-of select="fief/@time"/>
143
163
  <xsl:text>. </xsl:text>
144
164
  <br/>
165
+ <xsl:text>It took </xsl:text>
166
+ <xsl:variable name="sec" select="round(fief/@sec)"/>
167
+ <xsl:choose>
168
+ <xsl:when test="$sec &lt; 60">
169
+ <xsl:value-of select="$sec"/>
170
+ <xsl:text>s</xsl:text>
171
+ </xsl:when>
172
+ <xsl:when test="$sec &lt; 3600">
173
+ <xsl:value-of select="format-number($sec div 60, '#.##')"/>
174
+ <xsl:text>min</xsl:text>
175
+ </xsl:when>
176
+ <xsl:otherwise>
177
+ <xsl:value-of select="format-number($sec div 3600, '#.#')"/>
178
+ <xsl:text>h</xsl:text>
179
+ </xsl:otherwise>
180
+ </xsl:choose>
181
+ <xsl:text> to build the report.</xsl:text>
182
+ <br/>
145
183
  <xsl:text>The XML with the data </xsl:text>
146
184
  <a href="index.xml">
147
185
  <xsl:text>is here</xsl:text>
@@ -185,15 +223,16 @@ SOFTWARE.
185
223
  </tr>
186
224
  </xsl:template>
187
225
  <xsl:template match="m">
188
- <td class="num">
226
+ <td>
227
+ <xsl:attribute name="class">
228
+ <xsl:text>num</xsl:text>
229
+ <xsl:if test="@alert">
230
+ <xsl:text> firebrick</xsl:text>
231
+ </xsl:if>
232
+ </xsl:attribute>
189
233
  <xsl:attribute name="data-sort-value">
190
234
  <xsl:copy-of select="."/>
191
235
  </xsl:attribute>
192
- <xsl:if test="@alert">
193
- <xsl:attribute name="class">
194
- <xsl:text>firebrick</xsl:text>
195
- </xsl:attribute>
196
- </xsl:if>
197
236
  <xsl:copy-of select="."/>
198
237
  </td>
199
238
  </xsl:template>
data/bin/fief CHANGED
@@ -57,7 +57,7 @@ opts = Slop.parse(args, strict: true, help: true) do |o|
57
57
  o.array '--exclude', 'Mask of GitHub repo to exclude'
58
58
  end
59
59
 
60
- if opts.help? || opts[:include].empty?
60
+ if opts.help?
61
61
  puts opts
62
62
  exit
63
63
  end
@@ -75,6 +75,7 @@ Encoding.default_external = Encoding::UTF_8
75
75
  Encoding.default_internal = Encoding::UTF_8
76
76
 
77
77
  def build_xml(opts, loog)
78
+ start = Time.now
78
79
  if opts.token?
79
80
  api = Octokit::Client.new(:access_token => opts[:token])
80
81
  else
@@ -88,6 +89,7 @@ def build_xml(opts, loog)
88
89
  repos = Fief::Repos.new(opts, api, loog).all
89
90
  end
90
91
  data = []
92
+ legend = {}
91
93
  repos.each do |repo|
92
94
  Dir[File.join(__dir__, '../lib/fief/metrics/*.rb')].each do |f|
93
95
  name = File::basename(f).split('.')[0]
@@ -100,18 +102,23 @@ def build_xml(opts, loog)
100
102
  require_relative f
101
103
  m = type.split('::').reduce(Module, :const_get).new(api, repo, opts)
102
104
  if opts.dry?
103
- measures = [{ title: 'Open Pull Requests', value: 42 }, { title: 'Open Issues', value: 42 }]
105
+ measures = [{ title: 'Pulls+', value: 42, legend: 'Open pulls' }, { title: 'Issues', value: 42 }]
104
106
  else
105
107
  measures = m.take(loog)
106
108
  end
109
+ measures.each do |m|
110
+ legend[m[:title]] = m[:legend]
111
+ end
107
112
  if data.find { |d| d[:name] == repo }.nil?
108
113
  data << {name: repo, metrics: []}
109
114
  end
110
115
  data.find { |d| d[:name] == repo }[:metrics] += measures
116
+ loog.info("Read from '#{name}': #{measures.map { |m| "#{m[:title]}=#{m[:value]}" }.join(', ')}")
111
117
  end
112
118
  end
119
+ p data
113
120
  builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
114
- xml.fief(time: Time.now) do
121
+ xml.fief(time: Time.now, sec: Time.now - start) do
115
122
  xml.titles do
116
123
  data.map { |r| r[:metrics].map { |ms| ms[:title] } }.flatten.uniq.each do |t|
117
124
  xml.title do
@@ -119,6 +126,13 @@ def build_xml(opts, loog)
119
126
  end
120
127
  end
121
128
  end
129
+ xml.legend do
130
+ legend.each do |t, text|
131
+ xml.column(title: t) do
132
+ xml.text text
133
+ end
134
+ end
135
+ end
122
136
  xml.repositories do
123
137
  data.each do |r|
124
138
  xml.repository(id: r[:name]) do
@@ -140,6 +154,7 @@ def build_xml(opts, loog)
140
154
  xml
141
155
  end
142
156
  begin
157
+ raise 'At least one --include is required' if opts[:include].empty?
143
158
  home = File.absolute_path(opts[:to])
144
159
  loog.debug("All files generated will be saved to #{home}")
145
160
  if File.exist?(home)
@@ -31,6 +31,7 @@ class Fief::Issues
31
31
 
32
32
  def take(loog)
33
33
  json = @api.list_issues(@repo, state: 'open')
34
+ json.select! { |i| i[:pull_request].nil? }
34
35
  total = json.count
35
36
  loog.debug("Found #{total} open issues in #{@repo}")
36
37
  old = 0
@@ -38,31 +39,44 @@ class Fief::Issues
38
39
  json.each do |issue|
39
40
  num = issue[:number]
40
41
  data = @api.issue(@repo, num)
41
- if data[:created_at] < Time.now - (60 * 60 * 24 * 14)
42
+ if data[:created_at] < Time.now - (60 * 60 * 24 * old_days)
42
43
  loog.debug("Issue #{@repo}/##{num} is old")
43
44
  old += 1
44
45
  end
45
- if data[:created_at] < Time.now - (60 * 60 * 24 * 56)
46
+ if data[:created_at] < Time.now - (60 * 60 * 24 * older_days)
46
47
  loog.debug("Issue #{@repo}/##{num} is very old")
47
48
  older += 1
48
49
  end
49
50
  end
50
51
  [
51
52
  {
52
- title: 'Open Issues',
53
+ title: 'Issues',
53
54
  value: total,
54
- alert: false
55
+ alert: false,
56
+ legend: 'сurrently unresolved issues'
55
57
  },
56
58
  {
57
- title: 'Old Issues',
59
+ title: 'Issues+',
58
60
  value: old,
59
- alert: older > total * 0.4
61
+ alert: older > total * 0.4,
62
+ legend: "issues unresolved for more than #{old_days} days"
60
63
  },
61
64
  {
62
- title: 'Older Issues',
65
+ title: 'Issues++',
63
66
  value: older,
64
- alert: older > total * 0.4
67
+ alert: older > total * 0.4,
68
+ legend: "issues unresolved for more than #{older_days} days"
65
69
  }
66
70
  ]
67
71
  end
72
+
73
+ private
74
+
75
+ def old_days
76
+ 28
77
+ end
78
+
79
+ def older_days
80
+ 112
81
+ end
68
82
  end
@@ -38,31 +38,44 @@ class Fief::Pulls
38
38
  json.each do |pr|
39
39
  num = pr[:number]
40
40
  data = @api.pull_request(@repo, num)
41
- if data[:created_at] < Time.now - (60 * 60 * 24 * 14)
41
+ if data[:created_at] < Time.now - (60 * 60 * 24 * old_days)
42
42
  loog.debug("PR #{@repo}/##{num} is old")
43
43
  old += 1
44
44
  end
45
- if data[:created_at] < Time.now - (60 * 60 * 24 * 56)
45
+ if data[:created_at] < Time.now - (60 * 60 * 24 * older_days)
46
46
  loog.debug("PR #{@repo}/##{num} is very old")
47
47
  older += 1
48
48
  end
49
49
  end
50
50
  [
51
51
  {
52
- title: 'Open PRs',
52
+ title: 'Pulls',
53
53
  value: total,
54
- alert: false
54
+ alert: false,
55
+ legend: 'currently open pull requests'
55
56
  },
56
57
  {
57
- title: 'Old PRs',
58
+ title: 'Pulls+',
58
59
  value: old,
59
- alert: older > total * 0.4
60
+ alert: older > total * 0.4,
61
+ legend: "pull requests open for more than #{old_days} days"
60
62
  },
61
63
  {
62
- title: 'Older PRs',
64
+ title: 'Pulls++',
63
65
  value: older,
64
- alert: older > total * 0.2
66
+ alert: older > total * 0.2,
67
+ legend: "pull requests open for more than #{older_days} days"
65
68
  }
66
69
  ]
67
70
  end
71
+
72
+ private
73
+
74
+ def old_days
75
+ 28
76
+ end
77
+
78
+ def older_days
79
+ 112
80
+ end
68
81
  end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2023 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ # GitHub Action Runs in one GitHub repository.
22
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
24
+ # License:: MIT
25
+ class Fief::Runs
26
+ def initialize(api, repo, opts)
27
+ @api = api
28
+ @repo = repo
29
+ @opts = opts
30
+ end
31
+
32
+ def take(loog)
33
+ master = @api.repository(@repo)[:default_branch]
34
+ json = @api.repository_workflow_runs(@repo, branch: master)
35
+ workflows = []
36
+ failures = 0
37
+ json[:workflow_runs].take(32).each do |run|
38
+ workflow = run[:workflow_id]
39
+ next if workflows.include?(workflow)
40
+ workflows << workflow
41
+ next if run[:status] != 'completed'
42
+ conclusion = run[:conclusion]
43
+ loog.debug("Workflow run '#{run[:name]}' in #{@repo} is '#{conclusion}'")
44
+ if conclusion == 'failure'
45
+ loog.debug("Workflow run '#{run[:name]}' is failed")
46
+ failures += 1
47
+ end
48
+ end
49
+ [
50
+ {
51
+ title: 'CI failures',
52
+ value: failures,
53
+ alert: failures > 0
54
+ }
55
+ ]
56
+ end
57
+ end
data/lib/fief/repos.rb CHANGED
@@ -40,6 +40,10 @@ class Fief::Repos
40
40
  @loog.debug("GitHub account @#{org} is a user's account")
41
41
  @api.repositories(org, { type: 'public' }).each do |json|
42
42
  id = json[:full_name]
43
+ if json[:archived]
44
+ @loog.debug("The #{id} repo is archived, ignoring it")
45
+ next
46
+ end
43
47
  repos << id
44
48
  @loog.debug("Including #{id} as it is owned by @#{org}")
45
49
  end
@@ -47,6 +51,10 @@ class Fief::Repos
47
51
  @loog.debug("GitHub account @#{org} is an organization account")
48
52
  @api.organization_repositories(org, { type: 'public' }).each do |json|
49
53
  id = json[:full_name]
54
+ if json[:archived]
55
+ @loog.debug("The #{id} repo is archived, ignoring it")
56
+ next
57
+ end
50
58
  repos << id
51
59
  @loog.debug("Including #{id} as a member of @#{org} organization")
52
60
  end
data/lib/fief/version.rb CHANGED
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2023 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Fief
26
- VERSION = '0.0.2'.freeze
26
+ VERSION = '0.0.4'.freeze
27
27
  end
@@ -33,7 +33,6 @@ class TestIssues < Minitest::Test
33
33
  m = Fief::Issues.new(api, 'yegor256/fief', {})
34
34
  ms = m.take(Loog::VERBOSE)
35
35
  assert !ms.empty?
36
- p ms
37
36
  rescue Octokit::TooManyRequests => e
38
37
  puts e.message
39
38
  skip
@@ -33,7 +33,6 @@ class TestPulls < Minitest::Test
33
33
  m = Fief::Pulls.new(api, 'yegor256/fief', {})
34
34
  ms = m.take(Loog::VERBOSE)
35
35
  assert !ms.empty?
36
- p ms
37
36
  rescue Octokit::TooManyRequests => e
38
37
  puts e.message
39
38
  skip
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2023 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'octokit'
23
+ require 'loog'
24
+ require_relative '../../lib/fief/metrics/runs'
25
+
26
+ # Test for Workflow Runs.
27
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
29
+ # License:: MIT
30
+ class TestRuns < Minitest::Test
31
+ def test_real
32
+ api = Octokit::Client.new
33
+ m = Fief::Runs.new(api, 'yegor256/debate', {})
34
+ ms = m.take(Loog::VERBOSE)
35
+ assert !ms.empty?
36
+ rescue Octokit::TooManyRequests => e
37
+ puts e.message
38
+ skip
39
+ end
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fief
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-03 00:00:00.000000000 Z
11
+ date: 2023-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -157,6 +157,7 @@ files:
157
157
  - lib/fief/match.rb
158
158
  - lib/fief/metrics/issues.rb
159
159
  - lib/fief/metrics/pulls.rb
160
+ - lib/fief/metrics/runs.rb
160
161
  - lib/fief/repos.rb
161
162
  - lib/fief/version.rb
162
163
  - logo.png
@@ -164,6 +165,7 @@ files:
164
165
  - renovate.json
165
166
  - test/metrics/test_issues.rb
166
167
  - test/metrics/test_pulls.rb
168
+ - test/metrics/test_runs.rb
167
169
  - test/test__helper.rb
168
170
  - test/test_mask.rb
169
171
  - test/test_match.rb