fief 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.0pdd.yml +9 -0
- data/.gitattributes +7 -0
- data/.github/workflows/cron.yml +33 -0
- data/.github/workflows/pdd.yml +11 -0
- data/.github/workflows/rake.yml +23 -0
- data/.github/workflows/xcop.yml +11 -0
- data/.gitignore +8 -0
- data/.pdd +7 -0
- data/.rubocop.yml +23 -0
- data/.rultor.yml +20 -0
- data/.simplecov +38 -0
- data/Gemfile +31 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +83 -0
- data/assets/index.xsl +200 -0
- data/bin/fief +164 -0
- data/features/cli.feature +33 -0
- data/features/gem_package.feature +23 -0
- data/features/step_definitions/steps.rb +86 -0
- data/features/support/env.rb +21 -0
- data/fief.gemspec +51 -0
- data/lib/fief/mask.rb +40 -0
- data/lib/fief/match.rb +44 -0
- data/lib/fief/metrics/issues.rb +42 -0
- data/lib/fief/metrics/pulls.rb +42 -0
- data/lib/fief/repos.rb +68 -0
- data/lib/fief/version.rb +27 -0
- data/logo.png +0 -0
- data/logo.svg +13 -0
- data/renovate.json +6 -0
- data/test/metrics/test_pulls.rb +41 -0
- data/test/test__helper.rb +26 -0
- data/test/test_mask.rb +40 -0
- data/test/test_match.rb +41 -0
- data/test/test_repos.rb +41 -0
- metadata +195 -0
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
|
data/lib/fief/version.rb
ADDED
@@ -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>
|