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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf64468693c247f87a2ffbce58960dd82d1313614d1433d0d032210f080e8fd4
4
- data.tar.gz: a3d9f48ce1e8a932ae954897448acf7ab5cc82123992bd82b72ab33b7a8902b0
3
+ metadata.gz: c3e48b8f0f5a030f9b537e4150f6b10e5bdf3ed709cde30162d2030b3292cbc6
4
+ data.tar.gz: dff1d8579c996eeb24c599e2a40ba48b778d2939af8e80f3da94ed133a4ac0b5
5
5
  SHA512:
6
- metadata.gz: 0c4d5747e3b1a133bcc8e1d757fb0ca790b280c667b7f2aa865c95363db66a878f2b0383d436a3b83cb43c19b28d06815c226d7fde09411d626ecdbc0508836f
7
- data.tar.gz: e4ad9d70fb50258517e8cfbde02aea45435575e0e41435a26e9c5e35141b6df5e71bbebd85f11837afc6fdaa2b76c89508191234417214471f64c18b43d5f8d9
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
@@ -4,14 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
- gem "faraday"
8
- gem "octokit"
9
- gem "rake", "~> 13.0"
10
- gem "rspec", "~> 3.0"
11
- gem "rubocop", "~> 1.21"
12
- gem "thor"
13
- gem "toml-rb"
14
-
15
7
  group :development do
16
8
  gem "yard"
17
9
  end
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 only github.com is supported as a source code repository. If the source code repository is archived, then reports as not alive.
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
- Gem: bundle-alive is not found in RubyGems.org.
27
+ Errors:
28
+ [bundle-alive] Not found in RubyGems.org.
31
29
 
32
- Total: 6 (Dead: 1, Alive: 4, Unknown: 1)
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
- In some cases, the following error is output.
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
- If you run again, it will resume.
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
 
@@ -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
- Gem::Specification.new do |spec|
6
- spec.name = "bundler-alive"
7
- spec.version = Bundler::Alive::VERSION
8
- spec.authors = ["Katsuhiko YOSHIDA"]
9
- spec.email = ["claddvd@gmail.com"]
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
- spec.summary = "Are your gems alive?"
12
- spec.description = "bundler-alive reports gems are archived or not."
13
- spec.homepage = "https://github.com/kyoshidajp/bundler-alive"
14
- spec.required_ruby_version = ">= 2.6.0"
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
- spec.metadata["homepage_uri"] = "https://github.com/kyoshidajp/bundler-alive"
17
- spec.metadata["source_code_uri"] = "https://github.com/kyoshidajp/bundler-alive"
18
- spec.metadata["changelog_uri"] = "https://github.com/kyoshidajp/bundler-alive"
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
- spec.files = Dir.chdir(__dir__) do
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
- spec.bindir = "bin"
26
- spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
28
- spec.metadata["rubygems_mfa_required"] = "true"
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:
@@ -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 :result, type: :string, aliases: "-r",
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 = begin
43
- Doctor.new(options[:gemfile_lock], options[:result])
44
- rescue Bundler::GemfileLockNotFound
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
- doctor.diagnose
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
- def initialize
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, &block)
33
- urls = service_with_urls(gem_names, &block)
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 service_with_urls(gem_names, &block)
59
- urls = get_repository_urls(gem_names, &block)
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, "Gem: #{gem_name} is not found in RubyGems.org." unless response.success?
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
- raise NotFound, "[#{gem_name}] source code repository is not found in RubyGems.org."
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
- yield if block_given?
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 GitHubApi
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 = !name_with_archived[gem_name]
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
- repositories.each do |repository|
97
- name = repository["name"]
98
- name_with_status[name] = repository["archived"]
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 => GitHubApi
19
+ SourceCodeRepository::Service::GITHUB => GithubApi,
20
+ SourceCodeRepository::Service::GITLAB => GitlabApi
20
21
  }.freeze
21
22
 
22
23
  private_constant :SERVICE_WITH_STRATEGIES
@@ -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` with a TOML file
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] result_file file of result
16
+ # @param [String] config_file config file
17
+ # @param [Array<String>] ignore_gems ignore gems
18
18
  #
19
- def initialize(lock_file, result_file)
19
+ def initialize(lock_file, config_file, ignore_gems)
20
20
  @lock_file = lock_file
21
- @result_file = result_file
22
- @gem_client = Client::GemsApiClient.new
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 file of gem
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
- $stdout.puts "#{collection_from_gemfile.total_size} gems are in Gemfile.lock"
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, :result_file, :gem_client, :announcer,
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) do
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) do
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
- def fetch_target_collection(base_collection, gem_names)
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 = fetch_target_collection(collection_from_gemfile, no_need_to_get_gems)
87
+ collection = collection_from_gemfile
109
88
  result = result_by_search(collection)
110
- collection_from_toml_file = StatusCollection.new_from_toml_file(result_file)
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)
@@ -20,16 +20,6 @@ module Bundler
20
20
 
21
21
  freeze
22
22
  end
23
-
24
- #
25
- # Save result to file
26
- #
27
- # @param [String] file_path
28
- #
29
- def save_as_file(file_path)
30
- body = TomlRB.dump(result.to_h)
31
- File.write(file_path, body)
32
- end
33
23
  end
34
24
  end
35
25
  end
@@ -21,11 +21,11 @@ module Bundler
21
21
  error_messages = report.error_messages
22
22
  print_error(error_messages)
23
23
 
24
- gems = result.need_to_report_gems
25
- $stdout.puts if gems.size.positive?
26
- gems.each do |_name, gem|
27
- $stdout.puts gem.report
28
- end
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.nil?
49
+ return if error_messages.empty?
38
50
 
39
51
  $stdout.puts <<~ERROR
40
52
 
41
- #{error_messages.join("\n")}
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
- Total: #{result.total_size} (Dead: #{result.dead_size}, Alive: #{result.alive_size}, Unknown: #{result.unknown_size})
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.dead_size.positive?
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
 
@@ -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, :dead_size, :unknown_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
- @dead_size = _dead_size
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 need_to_report_gems
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 _dead_size
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: nil, error_messages: nil, rate_limit_exceeded: nil)
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
- self.class.new(collection: result.collection,
35
- error_messages: result.error_messages,
36
- rate_limit_exceeded: result.rate_limit_exceeded)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bundler
4
4
  module Alive
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.6"
6
6
  end
7
7
  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/git_hub_api"
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.3
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-15 00:00:00.000000000 Z
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/git_hub_api.rb
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