bundler-alive 0.1.5 → 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 +27 -1
- data/README.md +5 -1
- data/gemspec.yml +1 -0
- data/lib/bundler/alive/cli.rb +11 -4
- data/lib/bundler/alive/client/gems_api_client.rb +9 -2
- data/lib/bundler/alive/client/{git_hub_api.rb → github_api.rb} +33 -13
- 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/reportable.rb +10 -7
- data/lib/bundler/alive/source_code_repository.rb +1 -0
- data/lib/bundler/alive/source_code_repository_url.rb +2 -1
- data/lib/bundler/alive/status_collection.rb +4 -0
- data/lib/bundler/alive/status_result.rb +7 -4
- data/lib/bundler/alive/version.rb +1 -1
- data/lib/bundler/alive.rb +2 -1
- metadata +18 -3
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
|
data/.bundler-alive.default.yml
CHANGED
@@ -27,4 +27,30 @@ gems:
|
|
27
27
|
fog-sakuracloud:
|
28
28
|
url: https://github.com/fog/fog-sakuracloud
|
29
29
|
ovirt-engine-sdk:
|
30
|
-
url: https://github.com/oVirt/ovirt-engine-sdk-ruby
|
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/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
|
|
@@ -41,6 +41,10 @@ Default `Gemfile.lock` location is in your current directory. You can specify it
|
|
41
41
|
$ bundle-alive -G /path/to/Gemfile.lock
|
42
42
|
```
|
43
43
|
|
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
|
+
|
44
48
|
## Exceeding rate limit
|
45
49
|
|
46
50
|
In some cases, the following error may be output.
|
data/gemspec.yml
CHANGED
data/lib/bundler/alive/cli.rb
CHANGED
@@ -38,13 +38,20 @@ module Bundler
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def check_by_doctor
|
41
|
-
doctor =
|
42
|
-
|
43
|
-
|
41
|
+
doctor = initialize_doctor
|
42
|
+
|
43
|
+
begin
|
44
|
+
doctor.diagnose
|
45
|
+
rescue Bundler::Alive::Client::GitlabApi::AccessTokenNotFoundError => e
|
46
|
+
say "\n#{e.message}", :yellow
|
44
47
|
exit 1
|
45
48
|
end
|
49
|
+
end
|
46
50
|
|
47
|
-
|
51
|
+
def initialize_doctor
|
52
|
+
Doctor.new(options[:gemfile_lock], options[:config], options[:ignore])
|
53
|
+
rescue Bundler::GemfileLockNotFound
|
54
|
+
exit 1
|
48
55
|
end
|
49
56
|
end
|
50
57
|
end
|
@@ -111,16 +111,23 @@ module Bundler
|
|
111
111
|
|
112
112
|
def source_code_url(body:, gem_name:)
|
113
113
|
url = body["source_code_uri"]
|
114
|
-
return url if SourceCodeRepositoryUrl.support_url?(url)
|
114
|
+
return url_via_redirect(url) if SourceCodeRepositoryUrl.support_url?(url)
|
115
115
|
|
116
116
|
url = body["homepage_uri"]
|
117
|
-
return url if SourceCodeRepositoryUrl.support_url?(url)
|
117
|
+
return url_via_redirect(url) if SourceCodeRepositoryUrl.support_url?(url)
|
118
118
|
|
119
119
|
message = "[#{gem_name}] Source code repository is not found in RubyGems.org,"\
|
120
120
|
" or not supported. URL: https://rubygems.org/gems/#{gem_name}"
|
121
121
|
raise NotFound, message
|
122
122
|
end
|
123
123
|
|
124
|
+
def url_via_redirect(url)
|
125
|
+
response = connection.head(url)
|
126
|
+
return response.headers["location"] if response.status == 301
|
127
|
+
|
128
|
+
url
|
129
|
+
end
|
130
|
+
|
124
131
|
def get_repository_urls(gem_names)
|
125
132
|
result = gem_names.map do |gem_name|
|
126
133
|
$stdout.write "."
|
@@ -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
|
|
@@ -44,6 +44,7 @@ module Bundler
|
|
44
44
|
base.instance_eval do
|
45
45
|
@rate_limit_exceeded = false
|
46
46
|
@retries_on_too_many_requests = 0
|
47
|
+
@name_with_archived = {}
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
@@ -63,15 +64,12 @@ module Bundler
|
|
63
64
|
#
|
64
65
|
# @return [StatusResult]
|
65
66
|
#
|
66
|
-
# rubocop:disable Metrics/MethodLength
|
67
67
|
def query(urls:)
|
68
68
|
collection = StatusCollection.new
|
69
|
-
name_with_archived = get_name_with_statuses(urls)
|
69
|
+
@name_with_archived = get_name_with_statuses(urls)
|
70
70
|
urls.each do |url|
|
71
|
-
$stdout.write "."
|
72
|
-
|
73
71
|
gem_name = url.gem_name
|
74
|
-
alive =
|
72
|
+
alive = alive?(gem_name)
|
75
73
|
status = Status.new(name: gem_name, repository_url: url, alive: alive, checked_at: Time.now)
|
76
74
|
collection = collection.add(gem_name, status)
|
77
75
|
end
|
@@ -79,10 +77,16 @@ module Bundler
|
|
79
77
|
StatusResult.new(collection: collection, error_messages: @error_messages,
|
80
78
|
rate_limit_exceeded: @rate_limit_exceeded)
|
81
79
|
end
|
82
|
-
# rubocop:enable Metrics/MethodLength
|
83
80
|
|
84
81
|
private
|
85
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
|
+
|
86
90
|
#
|
87
91
|
# Search status of repositories
|
88
92
|
#
|
@@ -93,23 +97,39 @@ module Bundler
|
|
93
97
|
#
|
94
98
|
# rubocop:disable Metrics/MethodLength
|
95
99
|
def get_name_with_statuses(urls)
|
96
|
-
raise ArgumentError unless urls.instance_of?(Array)
|
97
|
-
|
98
100
|
name_with_status = {}
|
99
101
|
urls.each_slice(QUERY_MAX_OPERATORS_AT_ONCE) do |sliced_urls|
|
102
|
+
$stdout.print "." * sliced_urls.size
|
103
|
+
|
100
104
|
q = search_query(sliced_urls)
|
101
105
|
repositories = search_repositories_with_retry(q)
|
102
106
|
next if repositories.nil?
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
107
117
|
end
|
108
118
|
end
|
109
119
|
name_with_status
|
110
120
|
end
|
111
121
|
# rubocop:enable Metrics/MethodLength
|
112
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
|
+
|
113
133
|
#
|
114
134
|
# Search query of repositories
|
115
135
|
#
|
@@ -172,7 +192,7 @@ module Bundler
|
|
172
192
|
# @return [String]
|
173
193
|
#
|
174
194
|
def slug(repository_url)
|
175
|
-
Octokit::Repository.from_url(repository_url).slug
|
195
|
+
Octokit::Repository.from_url(repository_url).slug.gsub(/\.git/, "")
|
176
196
|
end
|
177
197
|
end
|
178
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
|
@@ -21,8 +21,11 @@ module Bundler
|
|
21
21
|
error_messages = report.error_messages
|
22
22
|
print_error(error_messages)
|
23
23
|
|
24
|
-
|
25
|
-
print_archived_gems(gems) if
|
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?
|
26
29
|
|
27
30
|
print_summary(result)
|
28
31
|
print_message(result, report.rate_limit_exceeded)
|
@@ -31,15 +34,15 @@ module Bundler
|
|
31
34
|
private
|
32
35
|
|
33
36
|
# soo messy
|
34
|
-
def print_archived_gems(gems)
|
37
|
+
def print_archived_gems(gems, header:)
|
35
38
|
$stdout.puts
|
36
|
-
$stdout.puts
|
37
|
-
|
39
|
+
$stdout.puts header
|
40
|
+
gems_to_report = gems.map do |_name, gem|
|
38
41
|
gem.report.split("\n").each_with_object([]) do |line, gem_str|
|
39
42
|
gem_str << " #{line}"
|
40
43
|
end.join("\n")
|
41
44
|
end
|
42
|
-
$stdout.puts
|
45
|
+
$stdout.puts gems_to_report.join("\n\n")
|
43
46
|
end
|
44
47
|
|
45
48
|
def print_error(error_messages)
|
@@ -56,7 +59,7 @@ module Bundler
|
|
56
59
|
def print_summary(result)
|
57
60
|
$stdout.puts <<~RESULT
|
58
61
|
|
59
|
-
Total: #{result.total_size} (Archived: #{result.archived_size},
|
62
|
+
Total: #{result.total_size} (Archived: #{result.archived_size}, Unknown: #{result.unknown_size}, Alive: #{result.alive_size})
|
60
63
|
RESULT
|
61
64
|
end
|
62
65
|
|
@@ -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
|
@@ -17,7 +17,7 @@ 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
|
@@ -33,9 +33,12 @@ module Bundler
|
|
33
33
|
# @return [StatusResult]
|
34
34
|
#
|
35
35
|
def merge(result)
|
36
|
-
|
37
|
-
|
38
|
-
|
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)
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|
data/lib/bundler/alive.rb
CHANGED
@@ -10,6 +10,7 @@ require_relative "alive/status_collection"
|
|
10
10
|
require_relative "alive/report"
|
11
11
|
require_relative "alive/client/gems_api_client"
|
12
12
|
require_relative "alive/client/gems_api_response"
|
13
|
-
require_relative "alive/client/
|
13
|
+
require_relative "alive/client/github_api"
|
14
|
+
require_relative "alive/client/gitlab_api"
|
14
15
|
require_relative "alive/client/source_code_client"
|
15
16
|
require_relative "alive/reportable"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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-
|
11
|
+
date: 2022-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
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'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,7 +208,8 @@ files:
|
|
194
208
|
- lib/bundler/alive/cli.rb
|
195
209
|
- lib/bundler/alive/client/gems_api_client.rb
|
196
210
|
- lib/bundler/alive/client/gems_api_response.rb
|
197
|
-
- lib/bundler/alive/client/
|
211
|
+
- lib/bundler/alive/client/github_api.rb
|
212
|
+
- lib/bundler/alive/client/gitlab_api.rb
|
198
213
|
- lib/bundler/alive/client/source_code_client.rb
|
199
214
|
- lib/bundler/alive/doctor.rb
|
200
215
|
- lib/bundler/alive/report.rb
|