fief 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/fief ADDED
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (c) 2023 Yegor Bugayenko
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the 'Software'), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+
22
+ STDOUT.sync = true
23
+
24
+ require 'slop'
25
+ require 'loog'
26
+ require 'octokit'
27
+ require 'nokogiri'
28
+ require 'backtrace'
29
+ require 'fileutils'
30
+ require 'obk'
31
+ require_relative '../lib/fief/version'
32
+ require_relative '../lib/fief/repos'
33
+
34
+ loog = Loog::REGULAR
35
+
36
+ def config(path)
37
+ f = File.expand_path(path)
38
+ args = []
39
+ args += File.readlines(f).map(&:strip).reject { |a| a.empty? } if File.exist?(f)
40
+ args
41
+ end
42
+
43
+ args = config('~/.fief') + config('.fief') + ARGV
44
+
45
+ opts = Slop.parse(args, strict: true, help: true) do |o|
46
+ o.banner = "Usage (#{Fief::VERSION}): fief [options]"
47
+ o.bool '-h', '--help', 'Show these instructions'
48
+ o.bool '--version', 'Show current version'
49
+ o.bool '--verbose', 'Print as much log messages as possible'
50
+ o.bool '--dry', 'Make no real round trips to GitHub'
51
+ o.bool '--reuse', 'Don\'t fetch from GitHub, reuse the existing XML file'
52
+ o.integer '--delay', 'Delay between HTTP calls to GitHub API, in milliseconds', default: 1000
53
+ o.string '--to', 'Directory where to save all files to', default: './fief'
54
+ o.string '--token', 'GitHub authentication token'
55
+ o.array '--metrics', 'Names of metrics to use (all by default)'
56
+ o.array '--include', 'Mask of GitHub repo to include, e.g. yegor256/*'
57
+ o.array '--exclude', 'Mask of GitHub repo to exclude'
58
+ end
59
+
60
+ if opts.help? || opts[:include].empty?
61
+ puts opts
62
+ exit
63
+ end
64
+
65
+ if opts.verbose?
66
+ loog = Loog::VERBOSE
67
+ end
68
+
69
+ if opts.version?
70
+ loog.info(Fief::VERSION)
71
+ exit
72
+ end
73
+
74
+ Encoding.default_external = Encoding::UTF_8
75
+ Encoding.default_internal = Encoding::UTF_8
76
+
77
+ def build_xml(opts, loog)
78
+ if opts.token?
79
+ api = Octokit::Client.new(:access_token => opts[:token])
80
+ else
81
+ api = Octokit::Client.new
82
+ loog.warn("Connecting to GitHub without a token, this may lead to errors, use --token")
83
+ end
84
+ api.auto_paginate = true
85
+ api = Obk.new(api, pause: opts[:delay])
86
+ repos = [ 'yegor256/fief' ]
87
+ if !opts[:dry]
88
+ repos = Fief::Repos.new(opts, api, loog).all
89
+ end
90
+ data = []
91
+ repos.each do |repo|
92
+ Dir[File.join(__dir__, '../lib/fief/metrics/*.rb')].each do |f|
93
+ name = File::basename(f).split('.')[0]
94
+ if !opts[:metrics].empty? && !opts[:metrics].include?(name)
95
+ loog.info("Ignoring #{user}/#{name} due to --metrics")
96
+ next
97
+ end
98
+ type = "Fief::#{name.capitalize}"
99
+ loog.info("Reading '#{name}' for #{repo}...")
100
+ require_relative f
101
+ m = type.split('::').reduce(Module, :const_get).new(api, repo, opts)
102
+ if opts.dry?
103
+ measures = [{ title: 'Open Pull Requests', value: 42 }, { title: 'Open Issues', value: 42 }]
104
+ else
105
+ measures = m.take(loog)
106
+ end
107
+ data << {name: repo, metrics: measures}
108
+ end
109
+ end
110
+ builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
111
+ xml.fief(time: Time.now) do
112
+ xml.titles do
113
+ data.map { |r| r[:metrics].map { |ms| ms[:title] } }.flatten.uniq.each do |t|
114
+ xml.title do
115
+ xml.text t
116
+ end
117
+ end
118
+ end
119
+ xml.repositories do
120
+ data.each do |r|
121
+ xml.repository(id: r[:name]) do
122
+ xml.metrics do
123
+ r[:metrics].each do |ms|
124
+ xml.m(id: ms[:title]) do
125
+ xml.text ms[:value]
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ xml = builder.to_xml
135
+ loog.debug(xml)
136
+ xml
137
+ end
138
+ begin
139
+ home = File.absolute_path(opts[:to])
140
+ loog.debug("All files generated will be saved to #{home}")
141
+ if File.exist?(home)
142
+ loog.debug("Directory #{home} exists")
143
+ else
144
+ FileUtils.mkdir_p(home)
145
+ loog.debug("Directory #{home} created")
146
+ end
147
+ index = File.join(home, 'index.xml')
148
+ if opts[:reuse]
149
+ xml = File.read(index)
150
+ else
151
+ xml = build_xml(opts, loog)
152
+ File.write(index, xml)
153
+ loog.debug("XML saved to #{index} (#{File.size(index)} bytes)")
154
+ end
155
+ xslt = Nokogiri::XSLT(File.read(File.join(__dir__, '../assets/index.xsl')))
156
+ html = xslt.transform(Nokogiri::XML(xml), 'version' => "'#{Fief::VERSION}'")
157
+ loog.debug(html)
158
+ front = File.join(home, 'index.html')
159
+ File.write(front, html.to_html(indent: 0).gsub("\n", ''))
160
+ loog.debug("HTML saved to #{front} (#{File.size(front)} bytes)")
161
+ rescue StandardError => e
162
+ loog.error(Backtrace.new(e))
163
+ exit -1
164
+ end
@@ -0,0 +1,33 @@
1
+ Feature: Simple Reporting
2
+ I want to be able to build a report
3
+
4
+ Scenario: Help can be printed
5
+ When I run bin/fief with "-h"
6
+ Then Exit code is zero
7
+ And Stdout contains "--help"
8
+
9
+ Scenario: Version can be printed
10
+ When I run bin/fief with "--version"
11
+ Then Exit code is zero
12
+
13
+ Scenario: Simple report
14
+ When I run bin/fief with "--include yegor256/fief --verbose --dry --to foo"
15
+ Then Stdout contains "XML saved to"
16
+ And Exit code is zero
17
+
18
+ Scenario: Simple report through real GitHub API
19
+ When I run bin/fief with "--include=yegor256/fief --verbose --delay=5000"
20
+ Then Stdout contains "XML saved to"
21
+ And Exit code is zero
22
+
23
+ Scenario: Simple report with defaults
24
+ Given I have a ".fief" file with content:
25
+ """
26
+ --verbose
27
+
28
+ --include=yegor256/fief
29
+ """
30
+ When I run bin/fief with "--dry"
31
+ Then Stdout contains "XML saved to"
32
+ And Exit code is zero
33
+
@@ -0,0 +1,23 @@
1
+ Feature: Gem Package
2
+ As a source code writer I want to be able to
3
+ package the Gem into .gem file
4
+
5
+ Scenario: Gem can be packaged
6
+ Given I have a "execs.rb" file with content:
7
+ """
8
+ #!/usr/bin/env ruby
9
+ require 'rubygems'
10
+ spec = Gem::Specification::load('./spec.rb')
11
+ if spec.executables.empty?
12
+ fail 'no executables: ' + File.read('./spec.rb')
13
+ end
14
+ """
15
+ When I run bash with:
16
+ """
17
+ cd fief
18
+ gem build fief.gemspec
19
+ gem specification --ruby fief-*.gem > ../spec.rb
20
+ cd ..
21
+ ruby execs.rb
22
+ """
23
+ Then Exit code is zero
@@ -0,0 +1,86 @@
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 'nokogiri'
22
+ require 'tmpdir'
23
+ require 'slop'
24
+ require 'English'
25
+
26
+ Before do
27
+ @cwd = Dir.pwd
28
+ @dir = Dir.mktmpdir('test')
29
+ FileUtils.mkdir_p(@dir)
30
+ Dir.chdir(@dir)
31
+ @opts = Slop.parse ['-v'] do |o|
32
+ o.bool '-v', '--verbose'
33
+ end
34
+ end
35
+
36
+ After do
37
+ Dir.chdir(@cwd)
38
+ FileUtils.rm_rf(@dir)
39
+ end
40
+
41
+ Given(/^I have a "([^"]*)" file with content:$/) do |file, text|
42
+ FileUtils.mkdir_p(File.dirname(file)) unless File.exist?(file)
43
+ File.write(file, text.gsub(/\\xFF/, 0xFF.chr))
44
+ end
45
+
46
+ When(%r{^I run bin/fief with "([^"]*)"$}) do |arg|
47
+ home = File.join(File.dirname(__FILE__), '../..')
48
+ @stdout = `ruby -I#{home}/lib #{home}/bin/fief #{arg}`
49
+ @exitstatus = $CHILD_STATUS.exitstatus
50
+ end
51
+
52
+ Then(/^Stdout contains "([^"]*)"$/) do |txt|
53
+ raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt)
54
+ end
55
+
56
+ Then(/^Stdout is empty$/) do
57
+ raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
58
+ end
59
+
60
+ Then(/^Exit code is zero$/) do
61
+ raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero?
62
+ end
63
+
64
+ Then(/^Exit code is not zero$/) do
65
+ raise 'Zero exit code' if @exitstatus.zero?
66
+ end
67
+
68
+ When(/^I run bash with "([^"]*)"$/) do |text|
69
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'fief'))
70
+ @stdout = `#{text}`
71
+ @exitstatus = $CHILD_STATUS.exitstatus
72
+ end
73
+
74
+ When(/^I run bash with:$/) do |text|
75
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'fief'))
76
+ @stdout = `#{text}`
77
+ @exitstatus = $CHILD_STATUS.exitstatus
78
+ end
79
+
80
+ Given(/^It is Unix$/) do
81
+ pending if Gem.win_platform?
82
+ end
83
+
84
+ Given(/^It is Windows$/) do
85
+ pending unless Gem.win_platform?
86
+ end
@@ -0,0 +1,21 @@
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 'simplecov'
data/fief.gemspec ADDED
@@ -0,0 +1,51 @@
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 NONINFRINGEMENT. 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 'English'
22
+
23
+ lib = File.expand_path('lib', __dir__)
24
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
25
+ require_relative './lib/fief/version'
26
+
27
+ Gem::Specification.new do |s|
28
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
29
+ s.required_ruby_version = '>= 2.2'
30
+ s.name = 'fief'
31
+ s.version = Fief::VERSION
32
+ s.license = 'MIT'
33
+ s.metadata = { 'rubygems_mfa_required' => 'true' }
34
+ s.summary = 'GitHub Repositories Monitoring Tool'
35
+ s.description = 'Downloads statistics from GitHub and builds a nice HTML report'
36
+ s.authors = ['Yegor Bugayenko']
37
+ s.email = 'yegor256@gmail.com'
38
+ s.homepage = 'http://github.com/yegor256/fief'
39
+ s.files = `git ls-files`.split($RS)
40
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
41
+ s.rdoc_options = ['--charset=UTF-8']
42
+ s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
43
+ s.add_runtime_dependency 'backtrace', '~>0.3'
44
+ s.add_runtime_dependency 'iri', '~>0.5'
45
+ s.add_runtime_dependency 'loog', '~>0.2'
46
+ s.add_runtime_dependency 'nokogiri', '~>1.10'
47
+ s.add_runtime_dependency 'obk', '0.3.0'
48
+ s.add_runtime_dependency 'octokit', '~>4.0'
49
+ s.add_runtime_dependency 'rainbow', '~>3.0'
50
+ s.add_runtime_dependency 'slop', '~>4.4'
51
+ end
data/lib/fief/mask.rb ADDED
@@ -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_relative 'version'
22
+
23
+ # Mask to apply for a repo name.
24
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
26
+ # License:: MIT
27
+ class Fief::Mask
28
+ def initialize(txt)
29
+ @org, @repo = txt.downcase.split('/')
30
+ end
31
+
32
+ def matches?(repo)
33
+ org, repo = repo.downcase.split('/')
34
+ return false if ['', nil].include?(org)
35
+ return false if ['', nil].include?(repo)
36
+ return false if org != @org && @org != '*'
37
+ return false if repo != @repo && @repo != '*'
38
+ true
39
+ end
40
+ end
data/lib/fief/match.rb ADDED
@@ -0,0 +1,44 @@
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_relative 'mask'
22
+
23
+ # Match of masks.
24
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
26
+ # License:: MIT
27
+ class Fief::Match
28
+ def initialize(opts, loog)
29
+ @opts = opts
30
+ @loog = loog
31
+ end
32
+
33
+ def matches?(repo)
34
+ if @opts[:include] && !@opts[:include].empty? && @opts[:include].none? { |m| Fief::Mask.new(m).matches?(repo) }
35
+ @loog.debug("Excluding #{repo} due to lack of --include")
36
+ return false
37
+ end
38
+ if @opts[:exclude] && @opts[:exclude].any? { |m| Fief::Mask.new(m).matches?(repo) }
39
+ @loog.debug("Excluding #{repo} due to --exclude")
40
+ return false
41
+ end
42
+ true
43
+ end
44
+ end
@@ -0,0 +1,42 @@
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
+ # Issues in GitHub repo.
22
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
24
+ # License:: MIT
25
+ class Fief::Issues
26
+ def initialize(api, repo, opts)
27
+ @api = api
28
+ @repo = repo
29
+ @opts = opts
30
+ end
31
+
32
+ def take(loog)
33
+ json = @api.list_issues(@repo, state: 'open')
34
+ loog.debug("Found #{json.count} open issues in #{@repo}")
35
+ [
36
+ {
37
+ title: 'Open Issues',
38
+ value: json.count
39
+ }
40
+ ]
41
+ end
42
+ end
@@ -0,0 +1,42 @@
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
+ # Pulls in one GitHub repository.
22
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
24
+ # License:: MIT
25
+ class Fief::Pulls
26
+ def initialize(api, repo, opts)
27
+ @api = api
28
+ @repo = repo
29
+ @opts = opts
30
+ end
31
+
32
+ def take(loog)
33
+ json = @api.pull_requests(@repo, state: 'open')
34
+ loog.debug("Found #{json.count} open pull requests in #{@repo}")
35
+ [
36
+ {
37
+ title: 'Open Pull Requests',
38
+ value: json.count
39
+ }
40
+ ]
41
+ end
42
+ end
data/lib/fief/repos.rb ADDED
@@ -0,0 +1,68 @@
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_relative 'mask'
22
+
23
+ # Fetch all repos required by the options.
24
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
26
+ # License:: MIT
27
+ class Fief::Repos
28
+ def initialize(opts, api, loog)
29
+ @opts = opts
30
+ @api = api
31
+ @loog = loog
32
+ end
33
+
34
+ def all
35
+ repos = []
36
+ @opts[:include].each do |mask|
37
+ org, repo = mask.split('/')
38
+ if repo == '*'
39
+ if @api.user(org)[:type] == 'User'
40
+ @loog.debug("GitHub account @#{org} is a user's account")
41
+ @api.repositories(org, { type: 'public' }).each do |json|
42
+ id = json[:full_name]
43
+ repos << id
44
+ @loog.debug("Including #{id} as it is owned by @#{org}")
45
+ end
46
+ else
47
+ @loog.debug("GitHub account @#{org} is an organization account")
48
+ @api.organization_repositories(org, { type: 'public' }).each do |json|
49
+ id = json[:full_name]
50
+ repos << id
51
+ @loog.debug("Including #{id} as a member of @#{org} organization")
52
+ end
53
+ end
54
+ else
55
+ @loog.debug("Including #{org}/#{repo} as requested by --include")
56
+ repos << mask
57
+ end
58
+ end
59
+ repos.reject do |repo|
60
+ if @opts[:exclude] && @opts[:exclude].any? { |m| Fief::Mask.new(m).matches?(repo) }
61
+ @loog.debug("Excluding #{repo} due to --exclude")
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,27 @@
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
+ # Fief main module.
22
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
24
+ # License:: MIT
25
+ module Fief
26
+ VERSION = '0.0.1'.freeze
27
+ end
data/logo.png ADDED
Binary file
data/logo.svg ADDED
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="198px" height="204px" viewBox="0 0 198 204" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <title>Group</title>
4
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5
+ <g id="Group">
6
+ <path d="M0,118.54 C0,165.4 44.17,203.38 98.67,203.41 L98.67,33.68 C44.17,33.7 0,71.68 0,118.54" id="Fill-1099" fill="#C04032"></path>
7
+ <path d="M98.73,33.68 C98.71,33.68 98.689,33.68 98.67,33.68 L98.67,203.41 C98.689,203.41 98.71,203.41 98.73,203.41 C153.249,203.41 197.45,165.42 197.45,118.54 C197.45,71.67 153.249,33.68 98.73,33.68" id="Fill-1100" fill="#AD352B"></path>
8
+ <path d="M97.7,21.2 C85.42,14.2 62.12,6.39 62.12,6.39 C62.12,6.39 70.01,20.52 78.32,29.93 C61.57,31.41 38.16,36.82 38.16,36.82 C38.16,36.82 60.029,43.24 76.49,45.7 C68.27,55.26 60.43,70.52 60.43,70.52 C60.43,70.52 80.97,63.12 93.33,56.16 C94.5,60.86 96.54,66.2 98.67,71.13 L98.67,19.15 C98.34,19.84 97.98,20.54 97.7,21.2" id="Fill-1101" fill="#189893"></path>
9
+ <path d="M174.589,39.54 C174.589,39.54 151.17,34.15 134.43,32.66 C142.74,23.25 150.6,9.11 150.6,9.11 C150.6,9.11 131.3,15.6 118.59,22.04 C116.88,12.59 110.93,0 110.93,0 C110.93,0 102.919,10.35 98.67,19.15 L98.67,71.13 C102.56,80.12 106.79,87.77 106.79,87.77 C106.79,87.77 115.71,71.89 119.57,58.98 C131.92,65.9 152.33,73.24 152.33,73.24 C152.33,73.24 144.46,57.99 136.27,48.44 C152.72,45.95 174.589,39.54 174.589,39.54" id="Fill-1102" fill="#13847C"></path>
10
+ <path d="M33.68,167.92 C20.86,155.54 13.15,139.51 13.15,121.98 C13.15,118.46 13.47,115 14.1,111.64 C15.13,105.95 20.96,101.75 25.99,102.23 C31.04,102.71 32.79,108.31 31.41,114.81 C30.6,118.67 30.16,122.65 30.16,126.73 C30.16,141.38 35.58,154.98 44.85,166.26 C60.11,184.87 54.53,188.05 33.68,167.92 Z M28.48,79.27 C35.06,69.72 45.75,63.68 49.69,63.89 C53.62,64.12 50.43,70.02 44.73,78.42 C39.01,86.84 32.35,94.73 27.58,95.6 C22.8,96.49 21.919,88.83 28.48,79.27 L28.48,79.27 Z" id="Fill-1103" fill="#FFFFFE"></path>
11
+ </g>
12
+ </g>
13
+ </svg>
data/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:base"
5
+ ]
6
+ }