bundler-alive 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.bundler-alive.default.yml +56 -0
- data/.yardopts +1 -0
- data/Gemfile +0 -8
- data/README.md +43 -8
- data/bundler-alive.gemspec +42 -17
- data/gemspec.yml +36 -0
- data/lib/bundler/alive/cli.rb +13 -7
- data/lib/bundler/alive/client/gems_api_client.rb +48 -11
- data/lib/bundler/alive/client/{git_hub_api.rb → github_api.rb} +42 -14
- data/lib/bundler/alive/client/gitlab_api.rb +121 -0
- data/lib/bundler/alive/client/source_code_client.rb +2 -1
- data/lib/bundler/alive/doctor.rb +22 -45
- data/lib/bundler/alive/report.rb +0 -10
- data/lib/bundler/alive/reportable.rb +24 -9
- data/lib/bundler/alive/source_code_repository.rb +3 -0
- data/lib/bundler/alive/source_code_repository_url.rb +4 -1
- data/lib/bundler/alive/status.rb +1 -2
- data/lib/bundler/alive/status_collection.rb +9 -27
- data/lib/bundler/alive/status_result.rb +9 -4
- data/lib/bundler/alive/version.rb +1 -1
- data/lib/bundler/alive.rb +2 -2
- metadata +183 -7
- data/lib/bundler/alive/announcer.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3e48b8f0f5a030f9b537e4150f6b10e5bdf3ed709cde30162d2030b3292cbc6
|
4
|
+
data.tar.gz: dff1d8579c996eeb24c599e2a40ba48b778d2939af8e80f3da94ed133a4ac0b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94d793718656beddd079aaa083fe501b2775a8b658d361b19d5c56906abba39551dd6f84628904c98235db7bc381028fb3ce261bb09178d00154ea3f682e2757
|
7
|
+
data.tar.gz: 4e4977e62794f2f9cd403187c4d60063788f8589ddef358beb2ba49827b65b7b3be6c64d563489b0c90938fe94f02b98af88fdf6bc93f29ea12bdc29ffc399a5
|
@@ -0,0 +1,56 @@
|
|
1
|
+
---
|
2
|
+
gems:
|
3
|
+
coffee-script-source:
|
4
|
+
url: https://github.com/jashkenas/coffeescript/
|
5
|
+
erubis:
|
6
|
+
url: https://github.com/kwatch/erubis
|
7
|
+
ffi-compiler:
|
8
|
+
url: https://github.com/ffi/ffi
|
9
|
+
foundation-rails:
|
10
|
+
url: https://github.com/foundation/foundation-rails
|
11
|
+
guard-compat:
|
12
|
+
url: https://github.com/guard/guard-compat
|
13
|
+
spoon:
|
14
|
+
url: https://github.com/headius/spoon
|
15
|
+
shellany:
|
16
|
+
url: https://github.com/guard/shellany
|
17
|
+
vegas:
|
18
|
+
url: https://github.com/quirkey/vegas
|
19
|
+
zipruby:
|
20
|
+
url: https://github.com/fjg/zipruby
|
21
|
+
gli:
|
22
|
+
url: https://github.com/davetron5000/gli
|
23
|
+
zen_to_i:
|
24
|
+
url: https://github.com/yoshitsugu/zen_to_i
|
25
|
+
trailblazer-option:
|
26
|
+
url: https://github.com/trailblazer/trailblazer-option
|
27
|
+
fog-sakuracloud:
|
28
|
+
url: https://github.com/fog/fog-sakuracloud
|
29
|
+
ovirt-engine-sdk:
|
30
|
+
url: https://github.com/oVirt/ovirt-engine-sdk-ruby
|
31
|
+
declarative_policy:
|
32
|
+
url: https://gitlab.com/gitlab-org/ruby/gems/declarative-policy
|
33
|
+
spamcheck:
|
34
|
+
url: https://gitlab.com/gitlab-com/gl-security/engineering-and-research/automation-team/spam/spamcheck
|
35
|
+
tanuki_emoji:
|
36
|
+
url: https://gitlab.com/gitlab-org/ruby/gems/tanuki_emoji
|
37
|
+
cbor:
|
38
|
+
url: https://github.com/cabo/cbor-ruby
|
39
|
+
expression_parser:
|
40
|
+
url: https://github.com/nricciar/expression_parser
|
41
|
+
extended-markdown-filter:
|
42
|
+
url: https://github.com/gjtorikian/extended-markdown-filter
|
43
|
+
gettext:
|
44
|
+
url: https://github.com/ruby-gettext/gettext
|
45
|
+
png_quantizator:
|
46
|
+
url: https://github.com/rogercampos/png_quantizator
|
47
|
+
redis-actionpack:
|
48
|
+
url: https://github.com/redis-store/redis-actionpack
|
49
|
+
redis-rack:
|
50
|
+
url: https://github.com/redis-store/redis-rack
|
51
|
+
sixarm_ruby_unaccent:
|
52
|
+
url: https://github.com/SixArm/sixarm_ruby_unaccent
|
53
|
+
thrift:
|
54
|
+
url: https://github.com/szechyjs/thrift-gem
|
55
|
+
vmstat:
|
56
|
+
url: https://github.com/threez/ruby-vmstat
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "bundler-alive Documentation" --protected
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
`bunder-alive` checks if gems in a RubyGem's `Gemfile.lock` are active.
|
9
9
|
|
10
|
-
Currently
|
10
|
+
Currently GitHub.com and GitLab.com are supported as a source code repository. If the source code repository is archived, then reports as not alive.
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -23,13 +23,15 @@ $ bundle-alive
|
|
23
23
|
..W....
|
24
24
|
Get all source code repository URLs of gems are done!
|
25
25
|
.....
|
26
|
-
Name: journey
|
27
|
-
URL: http://github.com/rails/journey
|
28
|
-
Status: false
|
29
26
|
|
30
|
-
|
27
|
+
Errors:
|
28
|
+
[bundle-alive] Not found in RubyGems.org.
|
31
29
|
|
32
|
-
|
30
|
+
Archived gems:
|
31
|
+
Name: journey
|
32
|
+
URL: http://github.com/rails/journey
|
33
|
+
|
34
|
+
Total: 6 (Archived: 1, Alive: 4, Unknown: 1)
|
33
35
|
Not alive gems are found!
|
34
36
|
```
|
35
37
|
|
@@ -39,7 +41,13 @@ Default `Gemfile.lock` location is in your current directory. You can specify it
|
|
39
41
|
$ bundle-alive -G /path/to/Gemfile.lock
|
40
42
|
```
|
41
43
|
|
42
|
-
|
44
|
+
## GitLab Access Token
|
45
|
+
|
46
|
+
When gems are in GitLab.com repository, you MUST set environment variable `BUNDLER_ALIVE_GITLAB_TOKEN`. See the document [Personal access tokens](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html).
|
47
|
+
|
48
|
+
## Exceeding rate limit
|
49
|
+
|
50
|
+
In some cases, the following error may be output.
|
43
51
|
|
44
52
|
```
|
45
53
|
Too many requested! Retry later.
|
@@ -47,7 +55,34 @@ Too many requested! Retry later.
|
|
47
55
|
|
48
56
|
In this case, setting [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) as `BUNDLER_ALIVE_GITHUB_TOKEN` environment variable may alleviate the error.
|
49
57
|
|
50
|
-
|
58
|
+
## Ignore gems
|
59
|
+
|
60
|
+
You can ignore certain gems.
|
61
|
+
|
62
|
+
```
|
63
|
+
$ bundle-alive -i journey rubocop-junit-formatter
|
64
|
+
```
|
65
|
+
|
66
|
+
## Specifying repository URL
|
67
|
+
|
68
|
+
In some cases, some gems cannot find the URL of their source code repositories. For this case, you can specify a mapping between the gem and its URL.
|
69
|
+
|
70
|
+
Put `.bundler-alive.yml` in your current directory. The following code is the sample.
|
71
|
+
|
72
|
+
```yaml
|
73
|
+
---
|
74
|
+
gems:
|
75
|
+
coffee-script-source:
|
76
|
+
url: https://github.com/jashkenas/coffeescript/
|
77
|
+
```
|
78
|
+
|
79
|
+
You can also specify the file path.
|
80
|
+
|
81
|
+
```
|
82
|
+
$ bundle-alive -c /path/to/.bundler-alive.yml
|
83
|
+
```
|
84
|
+
|
85
|
+
[.bundler-alive.default.yml](https://github.com/kyoshidajp/bundler-alive/blob/main/.bundler-alive.default.yml) may also be helpful. Considering that having these mappings obtained automatically in the future.
|
51
86
|
|
52
87
|
## Contributing
|
53
88
|
|
data/bundler-alive.gemspec
CHANGED
@@ -1,29 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "lib/bundler/alive/version"
|
4
|
+
require "yaml"
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
# rubocop:disable Metrics/BlockLength
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gemspec = YAML.load_file("gemspec.yml")
|
9
|
+
gem.name = gemspec.fetch("name")
|
10
|
+
gem.version = Bundler::Alive::VERSION
|
11
|
+
gem.authors = gemspec.fetch("authors")
|
12
|
+
gem.email = gemspec.fetch("email")
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
gem.summary = gemspec.fetch("summary")
|
15
|
+
gem.description = gemspec.fetch("description")
|
16
|
+
gem.homepage = gemspec.fetch("homepage")
|
17
|
+
gem.required_ruby_version = gemspec.fetch("required_ruby_version")
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
metadata = gemspec.fetch("metadata")
|
20
|
+
gem.metadata["homepage_uri"] = metadata["homepage_uri"]
|
21
|
+
gem.metadata["source_code_uri"] = metadata["source_code_uri"]
|
22
|
+
gem.metadata["changelog_uri"] = metadata["changelog_uri"]
|
23
|
+
gem.metadata["rubygems_mfa_required"] = "true"
|
19
24
|
|
20
|
-
|
25
|
+
gem.files = Dir.chdir(__dir__) do
|
21
26
|
`git ls-files -z`.split("\x0").reject do |f|
|
22
27
|
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
23
28
|
end
|
24
29
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
gem.bindir = gemspec.fetch("bindir")
|
31
|
+
gem.executables = gem.files.grep(%r{\Abin/}) { |f| File.basename(f) }
|
32
|
+
gem.require_paths = gemspec.fetch("require_paths")
|
33
|
+
|
34
|
+
split = lambda do |string|
|
35
|
+
string.nil? ? "" : string.split(/,\s*/)
|
36
|
+
end
|
37
|
+
|
38
|
+
gemspec["dependencies"].each do |name, versions|
|
39
|
+
if versions.nil?
|
40
|
+
gem.add_dependency(name)
|
41
|
+
else
|
42
|
+
gem.add_dependency(name, split[versions])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
gemspec["development_dependencies"].each do |name, versions|
|
47
|
+
if versions.nil?
|
48
|
+
gem.add_development_dependency(name)
|
49
|
+
else
|
50
|
+
gem.add_development_dependency(name, split[versions])
|
51
|
+
end
|
52
|
+
end
|
29
53
|
end
|
54
|
+
# rubocop:enable Metrics/BlockLength
|
data/gemspec.yml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
name: bundler-alive
|
2
|
+
summary: Are your gems alive?
|
3
|
+
description: bundler-alive reports gems are archived or not.
|
4
|
+
authors: Katsuhiko YOSHIDA
|
5
|
+
email: claddvd@gmail.com
|
6
|
+
homepage: https://github.com/kyoshidajp/bundler-alive
|
7
|
+
|
8
|
+
metadata:
|
9
|
+
homepage_uri: https://github.com/kyoshidajp/bundler-alive
|
10
|
+
source_code_uri: https://github.com/kyoshidajp/bundler-alive
|
11
|
+
changelog_uri: https://github.com/kyoshidajp/bundler-alive
|
12
|
+
|
13
|
+
required_ruby_version: ">= 2.6.0"
|
14
|
+
bindir: bin
|
15
|
+
require_paths: lib
|
16
|
+
|
17
|
+
dependencies:
|
18
|
+
faraday:
|
19
|
+
octokit:
|
20
|
+
rake:
|
21
|
+
thor:
|
22
|
+
gitlab:
|
23
|
+
|
24
|
+
development_dependencies:
|
25
|
+
rspec:
|
26
|
+
rubocop:
|
27
|
+
yard:
|
28
|
+
|
29
|
+
# Workaround for cc-test-reporter with SimpleCov 0.18.
|
30
|
+
# Stop upgrading SimpleCov until the following issue will be resolved.
|
31
|
+
# https://github.com/codeclimate/test-reporter/issues/418
|
32
|
+
simplecov: "~> 0.10, < 0.18"
|
33
|
+
|
34
|
+
factory_bot:
|
35
|
+
vcr:
|
36
|
+
webmock:
|
data/lib/bundler/alive/cli.rb
CHANGED
@@ -16,15 +16,14 @@ module Bundler
|
|
16
16
|
map "--version" => :version
|
17
17
|
|
18
18
|
desc "check [DIR]", "Checks the Gemfile.lock"
|
19
|
+
method_option :ignore, type: :array, aliases: "-i", default: []
|
19
20
|
method_option :gemfile_lock, type: :string, aliases: "-G",
|
20
21
|
default: "Gemfile.lock"
|
21
|
-
method_option :
|
22
|
-
default: "result.toml"
|
22
|
+
method_option :config, type: :string, aliases: "-c", default: ".bundler-alive.yml"
|
23
23
|
|
24
24
|
def check(_dir = Dir.pwd)
|
25
25
|
extend Reportable
|
26
26
|
report = check_by_doctor
|
27
|
-
report.save_as_file(options[:result])
|
28
27
|
print_report(report)
|
29
28
|
|
30
29
|
exit_status = report.result.all_alive? ? 0 : 1
|
@@ -39,13 +38,20 @@ module Bundler
|
|
39
38
|
private
|
40
39
|
|
41
40
|
def check_by_doctor
|
42
|
-
doctor =
|
43
|
-
|
44
|
-
|
41
|
+
doctor = initialize_doctor
|
42
|
+
|
43
|
+
begin
|
44
|
+
doctor.diagnose
|
45
|
+
rescue Bundler::Alive::Client::GitlabApi::AccessTokenNotFoundError => e
|
46
|
+
say "\n#{e.message}", :yellow
|
45
47
|
exit 1
|
46
48
|
end
|
49
|
+
end
|
47
50
|
|
48
|
-
|
51
|
+
def initialize_doctor
|
52
|
+
Doctor.new(options[:gemfile_lock], options[:config], options[:ignore])
|
53
|
+
rescue Bundler::GemfileLockNotFound
|
54
|
+
exit 1
|
49
55
|
end
|
50
56
|
end
|
51
57
|
end
|
@@ -18,8 +18,18 @@ module Bundler
|
|
18
18
|
class NotFound < StandardError
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
#
|
22
|
+
# A new instance of `GemApiClient`
|
23
|
+
#
|
24
|
+
# @param [String] config_path
|
25
|
+
#
|
26
|
+
# @return [GemApiClient]
|
27
|
+
#
|
28
|
+
def initialize(config_path = nil)
|
22
29
|
@error_messages = []
|
30
|
+
@config_gems = get_config_gems(config_path)
|
31
|
+
|
32
|
+
freeze
|
23
33
|
end
|
24
34
|
|
25
35
|
#
|
@@ -29,8 +39,8 @@ module Bundler
|
|
29
39
|
#
|
30
40
|
# @return [Client::GemsApiResponse]
|
31
41
|
#
|
32
|
-
def gems_api_response(gem_names
|
33
|
-
urls = service_with_urls(gem_names
|
42
|
+
def gems_api_response(gem_names)
|
43
|
+
urls = service_with_urls(gem_names)
|
34
44
|
$stdout.puts <<~MESSAGE
|
35
45
|
|
36
46
|
Get all source code repository URLs of gems are done!
|
@@ -43,7 +53,7 @@ module Bundler
|
|
43
53
|
|
44
54
|
private
|
45
55
|
|
46
|
-
attr_accessor :error_messages
|
56
|
+
attr_accessor :error_messages, :config_gems
|
47
57
|
|
48
58
|
def api_url(gem_name)
|
49
59
|
"https://rubygems.org/api/v1/gems/#{gem_name}.json"
|
@@ -55,8 +65,15 @@ module Bundler
|
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
58
|
-
def
|
59
|
-
|
68
|
+
def get_config_gems(path)
|
69
|
+
return {} if path.nil? || !File.exist?(path)
|
70
|
+
|
71
|
+
config = YAML.load_file(path)
|
72
|
+
config["gems"]
|
73
|
+
end
|
74
|
+
|
75
|
+
def service_with_urls(gem_names)
|
76
|
+
urls = get_repository_urls(gem_names)
|
60
77
|
urls.each_with_object({}) do |url, hash|
|
61
78
|
service_name = url.service_name
|
62
79
|
hash[service_name] = Array(hash[service_name]) << url
|
@@ -71,29 +88,49 @@ module Bundler
|
|
71
88
|
# @return [SourceCodeRepositoryUrl]
|
72
89
|
#
|
73
90
|
def get_repository_url(gem_name)
|
91
|
+
url_from_config = get_repository_url_from_config(gem_name)
|
92
|
+
return url_from_config unless url_from_config.nil?
|
93
|
+
|
74
94
|
url = api_url(gem_name)
|
75
95
|
response = connection.get(url)
|
76
96
|
|
77
|
-
raise NotFound, "
|
97
|
+
raise NotFound, "[#{gem_name}] Not found in RubyGems.org." unless response.success?
|
78
98
|
|
79
99
|
body = JSON.parse(response.body)
|
80
100
|
raw_url = source_code_url(body: body, gem_name: gem_name)
|
81
101
|
SourceCodeRepositoryUrl.new(raw_url, gem_name)
|
82
102
|
end
|
83
103
|
|
104
|
+
def get_repository_url_from_config(gem_name)
|
105
|
+
return nil if config_gems.nil?
|
106
|
+
return nil unless config_gems.key?(gem_name)
|
107
|
+
|
108
|
+
gem = config_gems[gem_name]
|
109
|
+
SourceCodeRepositoryUrl.new(gem["url"], gem_name)
|
110
|
+
end
|
111
|
+
|
84
112
|
def source_code_url(body:, gem_name:)
|
85
113
|
url = body["source_code_uri"]
|
86
|
-
return url if SourceCodeRepositoryUrl.support_url?(url)
|
114
|
+
return url_via_redirect(url) if SourceCodeRepositoryUrl.support_url?(url)
|
87
115
|
|
88
116
|
url = body["homepage_uri"]
|
89
|
-
return url if SourceCodeRepositoryUrl.support_url?(url)
|
117
|
+
return url_via_redirect(url) if SourceCodeRepositoryUrl.support_url?(url)
|
118
|
+
|
119
|
+
message = "[#{gem_name}] Source code repository is not found in RubyGems.org,"\
|
120
|
+
" or not supported. URL: https://rubygems.org/gems/#{gem_name}"
|
121
|
+
raise NotFound, message
|
122
|
+
end
|
123
|
+
|
124
|
+
def url_via_redirect(url)
|
125
|
+
response = connection.head(url)
|
126
|
+
return response.headers["location"] if response.status == 301
|
90
127
|
|
91
|
-
|
128
|
+
url
|
92
129
|
end
|
93
130
|
|
94
131
|
def get_repository_urls(gem_names)
|
95
132
|
result = gem_names.map do |gem_name|
|
96
|
-
|
133
|
+
$stdout.write "."
|
97
134
|
get_repository_url(gem_name)
|
98
135
|
rescue StandardError => e
|
99
136
|
$stdout.write "W"
|
@@ -11,7 +11,7 @@ module Bundler
|
|
11
11
|
#
|
12
12
|
# @see https://docs.github.com/en/rest/search#search-repositories
|
13
13
|
#
|
14
|
-
module
|
14
|
+
module GithubApi
|
15
15
|
# Environment variable name of GitHub Access Token
|
16
16
|
ACCESS_TOKEN_ENV_NAME = "BUNDLER_ALIVE_GITHUB_TOKEN"
|
17
17
|
|
@@ -21,7 +21,15 @@ module Bundler
|
|
21
21
|
# Number of attempts to request after too many requests
|
22
22
|
RETRIES_ON_TOO_MANY_REQUESTS = 3
|
23
23
|
|
24
|
+
#
|
24
25
|
# Interval second when retrying request
|
26
|
+
#
|
27
|
+
# @note
|
28
|
+
# This is an empirical value and should
|
29
|
+
# refer to response of Rate Limit API
|
30
|
+
#
|
31
|
+
# @see
|
32
|
+
# https://docs.github.com/en/rest/overview/resources-in-the-rest-api#checking-your-rate-limit-status
|
25
33
|
RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS = 120
|
26
34
|
|
27
35
|
#
|
@@ -36,6 +44,7 @@ module Bundler
|
|
36
44
|
base.instance_eval do
|
37
45
|
@rate_limit_exceeded = false
|
38
46
|
@retries_on_too_many_requests = 0
|
47
|
+
@name_with_archived = {}
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
@@ -55,15 +64,12 @@ module Bundler
|
|
55
64
|
#
|
56
65
|
# @return [StatusResult]
|
57
66
|
#
|
58
|
-
# rubocop:disable Metrics/MethodLength
|
59
67
|
def query(urls:)
|
60
68
|
collection = StatusCollection.new
|
61
|
-
name_with_archived = get_name_with_statuses(urls)
|
69
|
+
@name_with_archived = get_name_with_statuses(urls)
|
62
70
|
urls.each do |url|
|
63
|
-
yield if block_given?
|
64
|
-
|
65
71
|
gem_name = url.gem_name
|
66
|
-
alive =
|
72
|
+
alive = alive?(gem_name)
|
67
73
|
status = Status.new(name: gem_name, repository_url: url, alive: alive, checked_at: Time.now)
|
68
74
|
collection = collection.add(gem_name, status)
|
69
75
|
end
|
@@ -71,10 +77,16 @@ module Bundler
|
|
71
77
|
StatusResult.new(collection: collection, error_messages: @error_messages,
|
72
78
|
rate_limit_exceeded: @rate_limit_exceeded)
|
73
79
|
end
|
74
|
-
# rubocop:enable Metrics/MethodLength
|
75
80
|
|
76
81
|
private
|
77
82
|
|
83
|
+
def alive?(gem_name)
|
84
|
+
return false unless @name_with_archived.key?(gem_name)
|
85
|
+
|
86
|
+
value = @name_with_archived[gem_name]
|
87
|
+
value == Status::ALIVE_UNKNOWN ? Status::ALIVE_UNKNOWN : !value
|
88
|
+
end
|
89
|
+
|
78
90
|
#
|
79
91
|
# Search status of repositories
|
80
92
|
#
|
@@ -85,23 +97,39 @@ module Bundler
|
|
85
97
|
#
|
86
98
|
# rubocop:disable Metrics/MethodLength
|
87
99
|
def get_name_with_statuses(urls)
|
88
|
-
raise ArgumentError unless urls.instance_of?(Array)
|
89
|
-
|
90
100
|
name_with_status = {}
|
91
101
|
urls.each_slice(QUERY_MAX_OPERATORS_AT_ONCE) do |sliced_urls|
|
102
|
+
$stdout.print "." * sliced_urls.size
|
103
|
+
|
92
104
|
q = search_query(sliced_urls)
|
93
105
|
repositories = search_repositories_with_retry(q)
|
94
106
|
next if repositories.nil?
|
95
107
|
|
96
|
-
|
97
|
-
|
98
|
-
|
108
|
+
sliced_urls.each do |url|
|
109
|
+
repository = find_repository_from_repositories(url: url,
|
110
|
+
repositories: repositories)
|
111
|
+
alive_status = if repository.nil?
|
112
|
+
Status::ALIVE_UNKNOWN
|
113
|
+
else
|
114
|
+
repository["archived"]
|
115
|
+
end
|
116
|
+
name_with_status[url.gem_name] = alive_status
|
99
117
|
end
|
100
118
|
end
|
101
119
|
name_with_status
|
102
120
|
end
|
103
121
|
# rubocop:enable Metrics/MethodLength
|
104
122
|
|
123
|
+
# @param [SourceCodeRepositoryUrl] :url
|
124
|
+
# @param [Array<Sawyer::Resource>] :repositories
|
125
|
+
#
|
126
|
+
# @return [Sawyer::Resource|nil]
|
127
|
+
def find_repository_from_repositories(url:, repositories:)
|
128
|
+
repositories.find do |repository|
|
129
|
+
slug(url.url) == repository["full_name"]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
105
133
|
#
|
106
134
|
# Search query of repositories
|
107
135
|
#
|
@@ -151,7 +179,7 @@ module Bundler
|
|
151
179
|
end
|
152
180
|
|
153
181
|
def sleep_with_message
|
154
|
-
puts "Too many requested. Sleep #{RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS} sec."
|
182
|
+
puts "Too many requested to GitHub. Sleep #{RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS} sec."
|
155
183
|
sleep RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS
|
156
184
|
puts "Retry request (#{@retries_on_too_many_requests}/#{RETRIES_ON_TOO_MANY_REQUESTS})"
|
157
185
|
end
|
@@ -164,7 +192,7 @@ module Bundler
|
|
164
192
|
# @return [String]
|
165
193
|
#
|
166
194
|
def slug(repository_url)
|
167
|
-
Octokit::Repository.from_url(repository_url).slug
|
195
|
+
Octokit::Repository.from_url(repository_url).slug.gsub(/\.git/, "")
|
168
196
|
end
|
169
197
|
end
|
170
198
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "gitlab"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Bundler
|
7
|
+
module Alive
|
8
|
+
module Client
|
9
|
+
#
|
10
|
+
# API Client for GitLab API
|
11
|
+
#
|
12
|
+
# @see https://docs.gitlab.com/ee/api/projects.html#get-single-project
|
13
|
+
#
|
14
|
+
module GitlabApi
|
15
|
+
#
|
16
|
+
# Access token isn't set error
|
17
|
+
#
|
18
|
+
# @see https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html
|
19
|
+
#
|
20
|
+
class AccessTokenNotFoundError < StandardError
|
21
|
+
def initialize(_message = nil)
|
22
|
+
message = "Environment variable #{ACCESS_TOKEN_ENV_NAME} is not set."\
|
23
|
+
" Need to set GitLab Personal Access Token to be authenticated at gitlab.com API."\
|
24
|
+
" See: https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"
|
25
|
+
super(message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Environment variable name of GitLab Access Token
|
30
|
+
#
|
31
|
+
# @see https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html
|
32
|
+
#
|
33
|
+
ACCESS_TOKEN_ENV_NAME = "BUNDLER_ALIVE_GITLAB_TOKEN"
|
34
|
+
|
35
|
+
# Endpoint of GitLab API
|
36
|
+
ENDPOINT = "https://gitlab.com/api/v4"
|
37
|
+
|
38
|
+
def self.extended(base)
|
39
|
+
base.instance_eval do
|
40
|
+
@rate_limit_exceeded = false
|
41
|
+
@retries_on_too_many_requests = 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Creates a GitLab client
|
47
|
+
#
|
48
|
+
# @return [Octokit::Client]
|
49
|
+
#
|
50
|
+
def create_client
|
51
|
+
access_token = ENV.fetch(ACCESS_TOKEN_ENV_NAME, nil)
|
52
|
+
raise AccessTokenNotFoundError if access_token.nil?
|
53
|
+
|
54
|
+
Gitlab.client(
|
55
|
+
endpoint: ENDPOINT,
|
56
|
+
private_token: access_token
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Query repository statuses
|
62
|
+
#
|
63
|
+
# @param [Array<RepositoryUrl>] :urls
|
64
|
+
#
|
65
|
+
# @return [StatusResult]
|
66
|
+
#
|
67
|
+
def query(urls:)
|
68
|
+
collection = StatusCollection.new
|
69
|
+
name_with_archived = get_name_with_statuses(urls)
|
70
|
+
urls.each do |url|
|
71
|
+
gem_name = url.gem_name
|
72
|
+
alive = name_with_archived.key?(gem_name) && !name_with_archived[gem_name]
|
73
|
+
status = Status.new(name: gem_name, repository_url: url, alive: alive, checked_at: Time.now)
|
74
|
+
collection = collection.add(gem_name, status)
|
75
|
+
end
|
76
|
+
|
77
|
+
StatusResult.new(collection: collection, error_messages: @error_messages,
|
78
|
+
rate_limit_exceeded: @rate_limit_exceeded)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
#
|
84
|
+
# Search status of repositories
|
85
|
+
#
|
86
|
+
# @param [Array<RepositoryUrl>] urls
|
87
|
+
#
|
88
|
+
# @return [Hash<String, Boolean>]
|
89
|
+
# gem name with archived or not
|
90
|
+
#
|
91
|
+
def get_name_with_statuses(urls)
|
92
|
+
name_with_status = {}
|
93
|
+
urls.each do |url|
|
94
|
+
$stdout.write "."
|
95
|
+
project = search_repositories_with_retry(url)
|
96
|
+
next if project.nil? || project.empty?
|
97
|
+
|
98
|
+
name = url.gem_name
|
99
|
+
name_with_status[name] = project["archived"]
|
100
|
+
end
|
101
|
+
name_with_status
|
102
|
+
end
|
103
|
+
|
104
|
+
def project_path_from_url(url)
|
105
|
+
uri = URI.parse(url.url)
|
106
|
+
uri.path.split("/")[1..].join("/")
|
107
|
+
end
|
108
|
+
|
109
|
+
def search_repositories_with_retry(url)
|
110
|
+
project_path = project_path_from_url(url)
|
111
|
+
|
112
|
+
# Must be converted to hash due to warnings
|
113
|
+
@client.project(project_path).to_h
|
114
|
+
rescue StandardError => e
|
115
|
+
@error_messages << e.message
|
116
|
+
[]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -16,7 +16,8 @@ module Bundler
|
|
16
16
|
end
|
17
17
|
|
18
18
|
SERVICE_WITH_STRATEGIES = {
|
19
|
-
SourceCodeRepository::Service::GITHUB =>
|
19
|
+
SourceCodeRepository::Service::GITHUB => GithubApi,
|
20
|
+
SourceCodeRepository::Service::GITLAB => GitlabApi
|
20
21
|
}.freeze
|
21
22
|
|
22
23
|
private_constant :SERVICE_WITH_STRATEGIES
|
data/lib/bundler/alive/doctor.rb
CHANGED
@@ -2,32 +2,31 @@
|
|
2
2
|
|
3
3
|
require "bundler"
|
4
4
|
require "octokit"
|
5
|
-
require "toml-rb"
|
6
5
|
|
7
6
|
module Bundler
|
8
7
|
module Alive
|
9
8
|
#
|
10
|
-
# Diagnoses a `Gemfile.lock`
|
9
|
+
# Diagnoses a `Gemfile.lock`
|
11
10
|
#
|
12
11
|
class Doctor
|
13
12
|
#
|
14
13
|
# A new instance of Doctor
|
15
14
|
#
|
16
15
|
# @param [String] lock_file lock file of gem
|
17
|
-
# @param [String]
|
16
|
+
# @param [String] config_file config file
|
17
|
+
# @param [Array<String>] ignore_gems ignore gems
|
18
18
|
#
|
19
|
-
def initialize(lock_file,
|
19
|
+
def initialize(lock_file, config_file, ignore_gems)
|
20
20
|
@lock_file = lock_file
|
21
|
-
@
|
22
|
-
@
|
21
|
+
@gem_client = Client::GemsApiClient.new(config_file)
|
22
|
+
@ignore_gems = ignore_gems
|
23
23
|
@result = nil
|
24
24
|
@rate_limit_exceeded = false
|
25
|
-
@announcer = Announcer.new
|
26
25
|
@error_messages = []
|
27
26
|
end
|
28
27
|
|
29
28
|
#
|
30
|
-
# Diagnoses gems in lock
|
29
|
+
# Diagnoses gems in Gemfile.lock
|
31
30
|
#
|
32
31
|
# @raise [Client::SourceCodeClient::RateLimitExceededError]
|
33
32
|
# When exceeded access rate limit
|
@@ -38,41 +37,27 @@ module Bundler
|
|
38
37
|
# @return [Report]
|
39
38
|
#
|
40
39
|
def diagnose
|
41
|
-
|
40
|
+
message = "#{collection_from_gemfile.total_size + ignore_gems.size} gems are in Gemfile.lock"
|
41
|
+
message = "#{message} (#{ignore_gems.size} gems are ignored)" if ignore_gems.size.positive?
|
42
|
+
$stdout.puts message
|
43
|
+
|
42
44
|
result = _diagnose
|
43
45
|
Report.new(result)
|
44
46
|
end
|
45
47
|
|
46
48
|
private
|
47
49
|
|
48
|
-
attr_reader :lock_file, :
|
50
|
+
attr_reader :lock_file, :gem_client, :ignore_gems,
|
49
51
|
:result, :error_messages, :rate_limit_exceeded
|
50
52
|
|
51
|
-
#
|
52
|
-
# @return [Array<String>]
|
53
|
-
#
|
54
|
-
def no_need_to_get_gems
|
55
|
-
return [] unless File.exist?(result_file)
|
56
|
-
|
57
|
-
toml_hash = TomlRB.load_file(result_file)
|
58
|
-
toml_hash.each_with_object([]) do |(gem_name, v), array|
|
59
|
-
alive = v["alive"]
|
60
|
-
array << gem_name unless alive
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
53
|
def diagnose_by_service(service, urls)
|
65
54
|
client = Client::SourceCodeClient.new(service_name: service)
|
66
|
-
client.query(urls: urls)
|
67
|
-
announcer.announce
|
68
|
-
end
|
55
|
+
client.query(urls: urls)
|
69
56
|
end
|
70
57
|
|
58
|
+
# @return [StatusResult]
|
71
59
|
def result_by_search(collection)
|
72
|
-
gems_api_response = gem_client.gems_api_response(collection.names)
|
73
|
-
announcer.announce
|
74
|
-
end
|
75
|
-
|
60
|
+
gems_api_response = gem_client.gems_api_response(collection.names)
|
76
61
|
service_with_urls = gems_api_response.service_with_urls
|
77
62
|
error_messages.concat(gems_api_response.error_messages)
|
78
63
|
|
@@ -83,19 +68,12 @@ module Bundler
|
|
83
68
|
result
|
84
69
|
end
|
85
70
|
|
86
|
-
|
87
|
-
collection = StatusCollection.new
|
88
|
-
base_collection.each do |name, status|
|
89
|
-
next if gem_names.include?(name)
|
90
|
-
|
91
|
-
collection = collection.add(name, status)
|
92
|
-
end
|
93
|
-
collection
|
94
|
-
end
|
95
|
-
|
71
|
+
# @return [StatusCollection]
|
96
72
|
def collection_from_gemfile
|
97
73
|
gems_from_lockfile.each_with_object(StatusCollection.new) do |gem, collection|
|
98
74
|
gem_name = gem.name
|
75
|
+
next if ignore_gems.include?(gem_name)
|
76
|
+
|
99
77
|
status = Status.new(name: gem_name,
|
100
78
|
repository_url: nil,
|
101
79
|
alive: nil,
|
@@ -104,14 +82,13 @@ module Bundler
|
|
104
82
|
end
|
105
83
|
end
|
106
84
|
|
85
|
+
# @return [StatusResult]
|
107
86
|
def _diagnose
|
108
|
-
collection =
|
87
|
+
collection = collection_from_gemfile
|
109
88
|
result = result_by_search(collection)
|
110
|
-
|
111
|
-
new_collection = collection_from_gemfile.merge(collection_from_toml_file)
|
112
|
-
.merge(result.collection)
|
113
|
-
|
89
|
+
new_collection = collection.merge(result.collection)
|
114
90
|
messages = error_messages.concat(result.error_messages)
|
91
|
+
|
115
92
|
StatusResult.new(collection: new_collection,
|
116
93
|
error_messages: messages,
|
117
94
|
rate_limit_exceeded: result.rate_limit_exceeded)
|
data/lib/bundler/alive/report.rb
CHANGED
@@ -21,11 +21,11 @@ module Bundler
|
|
21
21
|
error_messages = report.error_messages
|
22
22
|
print_error(error_messages)
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
unknown_gems = result.unknown_gems
|
25
|
+
print_archived_gems(unknown_gems, header: "Unknown gems:") if unknown_gems.size.positive?
|
26
|
+
|
27
|
+
archived_gems = result.archived_gems
|
28
|
+
print_archived_gems(archived_gems, header: "Archived gems:") if archived_gems.size.positive?
|
29
29
|
|
30
30
|
print_summary(result)
|
31
31
|
print_message(result, report.rate_limit_exceeded)
|
@@ -33,18 +33,33 @@ module Bundler
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
# soo messy
|
37
|
+
def print_archived_gems(gems, header:)
|
38
|
+
$stdout.puts
|
39
|
+
$stdout.puts header
|
40
|
+
gems_to_report = gems.map do |_name, gem|
|
41
|
+
gem.report.split("\n").each_with_object([]) do |line, gem_str|
|
42
|
+
gem_str << " #{line}"
|
43
|
+
end.join("\n")
|
44
|
+
end
|
45
|
+
$stdout.puts gems_to_report.join("\n\n")
|
46
|
+
end
|
47
|
+
|
36
48
|
def print_error(error_messages)
|
37
|
-
return if error_messages.
|
49
|
+
return if error_messages.empty?
|
38
50
|
|
39
51
|
$stdout.puts <<~ERROR
|
40
52
|
|
41
|
-
|
53
|
+
|
54
|
+
Errors:
|
55
|
+
#{error_messages.join("\n ")}
|
42
56
|
ERROR
|
43
57
|
end
|
44
58
|
|
45
59
|
def print_summary(result)
|
46
60
|
$stdout.puts <<~RESULT
|
47
|
-
|
61
|
+
|
62
|
+
Total: #{result.total_size} (Archived: #{result.archived_size}, Unknown: #{result.unknown_size}, Alive: #{result.alive_size})
|
48
63
|
RESULT
|
49
64
|
end
|
50
65
|
|
@@ -55,7 +70,7 @@ module Bundler
|
|
55
70
|
end
|
56
71
|
|
57
72
|
say "Too many requested! Retry later.", :yellow if rate_limit_exceeded
|
58
|
-
if result.
|
73
|
+
if result.archived_size.positive?
|
59
74
|
say "Not alive gems are found!", :red
|
60
75
|
return
|
61
76
|
end
|
@@ -6,6 +6,7 @@ module Bundler
|
|
6
6
|
class SourceCodeRepository
|
7
7
|
module Service
|
8
8
|
GITHUB = :github
|
9
|
+
GITLAB = :gitlab
|
9
10
|
end
|
10
11
|
|
11
12
|
#
|
@@ -17,6 +18,8 @@ module Bundler
|
|
17
18
|
raise ArgumentError, "Unknown url: #{url}" unless url.instance_of?(SourceCodeRepositoryUrl)
|
18
19
|
|
19
20
|
@url = url
|
21
|
+
|
22
|
+
freeze
|
20
23
|
end
|
21
24
|
|
22
25
|
private
|
@@ -7,7 +7,8 @@ module Bundler
|
|
7
7
|
# service domain with service
|
8
8
|
DOMAIN_WITH_SERVICES = {
|
9
9
|
"github.com" => SourceCodeRepository::Service::GITHUB,
|
10
|
-
"www.github.com" => SourceCodeRepository::Service::GITHUB
|
10
|
+
"www.github.com" => SourceCodeRepository::Service::GITHUB,
|
11
|
+
"gitlab.com" => SourceCodeRepository::Service::GITLAB
|
11
12
|
}.freeze
|
12
13
|
|
13
14
|
private_constant :DOMAIN_WITH_SERVICES
|
@@ -44,6 +45,8 @@ module Bundler
|
|
44
45
|
end
|
45
46
|
message = "[#{name}] is not support URL: #{decorated_url}"
|
46
47
|
super(message)
|
48
|
+
|
49
|
+
freeze
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
data/lib/bundler/alive/status.rb
CHANGED
@@ -20,7 +20,7 @@ module Bundler
|
|
20
20
|
# @param [String] :name
|
21
21
|
# @param [SourceCodeRepositoryUrl] :repository_url
|
22
22
|
# @param [Boolean] :alive
|
23
|
-
# @param [] :checked_at
|
23
|
+
# @param [Time] :checked_at
|
24
24
|
#
|
25
25
|
# @return [Status]
|
26
26
|
#
|
@@ -67,7 +67,6 @@ module Bundler
|
|
67
67
|
<<~REPORT
|
68
68
|
Name: #{name}
|
69
69
|
URL: #{decorated_repository_url}
|
70
|
-
Status: #{decorated_alive}
|
71
70
|
|
72
71
|
REPORT
|
73
72
|
end
|
@@ -10,30 +10,7 @@ module Bundler
|
|
10
10
|
delegate each: :collection
|
11
11
|
delegate values: :collection
|
12
12
|
|
13
|
-
attr_reader :alive_size, :
|
14
|
-
|
15
|
-
#
|
16
|
-
# Creates `StatusCollection` from TOML file
|
17
|
-
#
|
18
|
-
# @param [String] path
|
19
|
-
#
|
20
|
-
# @return [StatusCollection]
|
21
|
-
#
|
22
|
-
def self.new_from_toml_file(path)
|
23
|
-
return new unless File.exist?(path)
|
24
|
-
|
25
|
-
collection = new
|
26
|
-
TomlRB.load_file(path).each do |name, v|
|
27
|
-
next if v["alive"] == Status::ALIVE_UNKNOWN
|
28
|
-
|
29
|
-
url = SourceCodeRepositoryUrl.new(v["repository_url"], name)
|
30
|
-
status = Status.new(name: name, repository_url: url,
|
31
|
-
alive: v["alive"], checked_at: v["checked_at"])
|
32
|
-
collection = collection.add(name, status)
|
33
|
-
end
|
34
|
-
|
35
|
-
collection
|
36
|
-
end
|
13
|
+
attr_reader :alive_size, :archived_size, :unknown_size
|
37
14
|
|
38
15
|
#
|
39
16
|
# Generates instance of `StatusCollection`
|
@@ -48,7 +25,8 @@ module Bundler
|
|
48
25
|
|
49
26
|
@alive_size = _alive_size
|
50
27
|
@unknown_size = _unknown_size
|
51
|
-
@
|
28
|
+
@archived_size = _archived_size
|
29
|
+
|
52
30
|
freeze
|
53
31
|
end
|
54
32
|
|
@@ -107,10 +85,14 @@ module Bundler
|
|
107
85
|
collection.transform_values(&:to_h)
|
108
86
|
end
|
109
87
|
|
110
|
-
def
|
88
|
+
def archived_gems
|
111
89
|
collection.find_all { |_name, gem| !!!gem.alive }
|
112
90
|
end
|
113
91
|
|
92
|
+
def unknown_gems
|
93
|
+
collection.find_all { |_name, gem| gem.unknown? }
|
94
|
+
end
|
95
|
+
|
114
96
|
#
|
115
97
|
# All of statuses are alive nor not
|
116
98
|
#
|
@@ -137,7 +119,7 @@ module Bundler
|
|
137
119
|
statuses_values.count { |gem| !!gem.alive && !gem.unknown? }
|
138
120
|
end
|
139
121
|
|
140
|
-
def
|
122
|
+
def _archived_size
|
141
123
|
statuses_values.count { |gem| !gem.alive && !gem.unknown? }
|
142
124
|
end
|
143
125
|
|
@@ -17,10 +17,12 @@ module Bundler
|
|
17
17
|
#
|
18
18
|
# @return [StatusResult]
|
19
19
|
#
|
20
|
-
def initialize(collection:
|
20
|
+
def initialize(collection: StatusCollection.new, error_messages: [], rate_limit_exceeded: false)
|
21
21
|
@collection = collection
|
22
22
|
@error_messages = error_messages
|
23
23
|
@rate_limit_exceeded = rate_limit_exceeded
|
24
|
+
|
25
|
+
freeze
|
24
26
|
end
|
25
27
|
|
26
28
|
#
|
@@ -31,9 +33,12 @@ module Bundler
|
|
31
33
|
# @return [StatusResult]
|
32
34
|
#
|
33
35
|
def merge(result)
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
merged_collection = collection.merge(result.collection)
|
37
|
+
merged_error_messages = error_messages + result.error_messages
|
38
|
+
merged_rate_limit_exceeded = rate_limit_exceeded || result.rate_limit_exceeded
|
39
|
+
self.class.new(collection: merged_collection,
|
40
|
+
error_messages: merged_error_messages,
|
41
|
+
rate_limit_exceeded: merged_rate_limit_exceeded)
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
data/lib/bundler/alive.rb
CHANGED
@@ -7,10 +7,10 @@ require_relative "alive/source_code_repository_url"
|
|
7
7
|
require_relative "alive/status"
|
8
8
|
require_relative "alive/status_result"
|
9
9
|
require_relative "alive/status_collection"
|
10
|
-
require_relative "alive/announcer"
|
11
10
|
require_relative "alive/report"
|
12
11
|
require_relative "alive/client/gems_api_client"
|
13
12
|
require_relative "alive/client/gems_api_response"
|
14
|
-
require_relative "alive/client/
|
13
|
+
require_relative "alive/client/github_api"
|
14
|
+
require_relative "alive/client/gitlab_api"
|
15
15
|
require_relative "alive/client/source_code_client"
|
16
16
|
require_relative "alive/reportable"
|
metadata
CHANGED
@@ -1,26 +1,201 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler-alive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katsuhiko YOSHIDA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-05-
|
12
|
-
dependencies:
|
11
|
+
date: 2022-05-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: octokit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gitlab
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.10'
|
132
|
+
- - "<"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0.18'
|
135
|
+
type: :development
|
136
|
+
prerelease: false
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "~>"
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0.10'
|
142
|
+
- - "<"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0.18'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: factory_bot
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: vcr
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: webmock
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
13
187
|
description: bundler-alive reports gems are archived or not.
|
14
|
-
email:
|
15
|
-
- claddvd@gmail.com
|
188
|
+
email: claddvd@gmail.com
|
16
189
|
executables:
|
17
190
|
- bundle-alive
|
18
191
|
- bundler-alive
|
19
192
|
extensions: []
|
20
193
|
extra_rdoc_files: []
|
21
194
|
files:
|
195
|
+
- ".bundler-alive.default.yml"
|
22
196
|
- ".rspec"
|
23
197
|
- ".rubocop.yml"
|
198
|
+
- ".yardopts"
|
24
199
|
- Gemfile
|
25
200
|
- LICENSE
|
26
201
|
- README.md
|
@@ -28,12 +203,13 @@ files:
|
|
28
203
|
- bin/bundle-alive
|
29
204
|
- bin/bundler-alive
|
30
205
|
- bundler-alive.gemspec
|
206
|
+
- gemspec.yml
|
31
207
|
- lib/bundler/alive.rb
|
32
|
-
- lib/bundler/alive/announcer.rb
|
33
208
|
- lib/bundler/alive/cli.rb
|
34
209
|
- lib/bundler/alive/client/gems_api_client.rb
|
35
210
|
- lib/bundler/alive/client/gems_api_response.rb
|
36
|
-
- lib/bundler/alive/client/
|
211
|
+
- lib/bundler/alive/client/github_api.rb
|
212
|
+
- lib/bundler/alive/client/gitlab_api.rb
|
37
213
|
- lib/bundler/alive/client/source_code_client.rb
|
38
214
|
- lib/bundler/alive/doctor.rb
|
39
215
|
- lib/bundler/alive/report.rb
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bundler"
|
4
|
-
|
5
|
-
module Bundler
|
6
|
-
module Alive
|
7
|
-
#
|
8
|
-
# Announces check progress
|
9
|
-
#
|
10
|
-
class Announcer
|
11
|
-
DOT = "."
|
12
|
-
|
13
|
-
private_constant :DOT
|
14
|
-
|
15
|
-
#
|
16
|
-
# A new instance of Reporter
|
17
|
-
#
|
18
|
-
def initialize
|
19
|
-
@output = $stdout
|
20
|
-
end
|
21
|
-
|
22
|
-
def announce
|
23
|
-
output.write DOT
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
attr_reader :output
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|