bundler-alive 0.1.6 → 0.1.7

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: c3e48b8f0f5a030f9b537e4150f6b10e5bdf3ed709cde30162d2030b3292cbc6
4
- data.tar.gz: dff1d8579c996eeb24c599e2a40ba48b778d2939af8e80f3da94ed133a4ac0b5
3
+ metadata.gz: 4fb0738fac56612f49d0fcc2dadf41f00caa5c34b8e49923185326f3cc6ab744
4
+ data.tar.gz: e89352dbbdec31b5e82e4f42135113d1c464441bcc0d4443709e24437fffb87f
5
5
  SHA512:
6
- metadata.gz: 94d793718656beddd079aaa083fe501b2775a8b658d361b19d5c56906abba39551dd6f84628904c98235db7bc381028fb3ce261bb09178d00154ea3f682e2757
7
- data.tar.gz: 4e4977e62794f2f9cd403187c4d60063788f8589ddef358beb2ba49827b65b7b3be6c64d563489b0c90938fe94f02b98af88fdf6bc93f29ea12bdc29ffc399a5
6
+ metadata.gz: 6692e5114833643c5038b41a8bbff0282837b4e70c05449f76cc810e499751a3f7f8585f5360f31b503376662e6a91f6617a335e59686a9841af65a2917b0d2f
7
+ data.tar.gz: 393f54894aabd833bd0249a54cfab165bbcacb6a9d10cae9ab446b6e81a92c9de83f5e0fc25d38327999b7c2e06fa902a730bbec5eb04b37a476af0067b882c4
@@ -53,4 +53,18 @@ gems:
53
53
  thrift:
54
54
  url: https://github.com/szechyjs/thrift-gem
55
55
  vmstat:
56
- url: https://github.com/threez/ruby-vmstat
56
+ url: https://github.com/threez/ruby-vmstat
57
+ mongoid-rspec:
58
+ url: https://github.com/mongoid/mongoid-rspec
59
+ rack-test:
60
+ url: https://github.com/rack/rack-test
61
+ jmespath:
62
+ url: https://github.com/jmespath/jmespath.rb
63
+ slack-notifier:
64
+ url: https://github.com/slack-notifier/slack-notifier
65
+ ipaddress:
66
+ url: https://github.com/ipaddress-gem/ipaddress
67
+ fog-powerdns:
68
+ url: https://github.com/fog/fog-powerdns
69
+ html_tokenizer:
70
+ url: https://github.com/EiNSTeiN-/html_tokenizer
data/.rspec CHANGED
@@ -1,5 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
- --warnings
4
3
  --require spec_helper
5
4
  --backtrace
data/README.md CHANGED
@@ -5,14 +5,14 @@
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/a79d53257bc5e93842f6/maintainability)](https://codeclimate.com/github/kyoshidajp/bundler-alive/maintainability)
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/a79d53257bc5e93842f6/test_coverage)](https://codeclimate.com/github/kyoshidajp/bundler-alive/test_coverage)
7
7
 
8
- `bunder-alive` checks if gems in a RubyGem's `Gemfile.lock` are active.
8
+ `bundler-alive` checks if gems in a RubyGem's `Gemfile.lock` are active.
9
9
 
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.
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
 
14
14
  ```
15
- $ gem install bunlder-alive
15
+ $ gem install bundler-alive
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -41,26 +41,29 @@ 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
44
+ ## Access Token
45
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).
46
+ You MUST set environment variables to access source code repository services.
47
47
 
48
- ## Exceeding rate limit
48
+ | Repository service | ENV variable |
49
+ | ------- |---- |
50
+ | GitHub | [`BUNDLER_ALIVE_GITHUB_TOKEN`](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) |
51
+ | GitLab | [`BUNDLER_ALIVE_GITLAB_TOKEN`](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) |
49
52
 
50
- In some cases, the following error may be output.
53
+ ## Ignore gems
54
+
55
+ You can ignore certain gems.
51
56
 
52
57
  ```
53
- Too many requested! Retry later.
58
+ $ bundle-alive -i journey rubocop-junit-formatter
54
59
  ```
55
60
 
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.
61
+ ## Following redirect on RubyGems.org
57
62
 
58
- ## Ignore gems
59
-
60
- You can ignore certain gems.
63
+ The URL for some gems in RubyGems.org may have changed. You can follow the URL (default: doesn't follow).
61
64
 
62
65
  ```
63
- $ bundle-alive -i journey rubocop-junit-formatter
66
+ $ bundle-alive --follow_redirect
64
67
  ```
65
68
 
66
69
  ## Specifying repository URL
data/gemspec.yml CHANGED
@@ -8,7 +8,7 @@ homepage: https://github.com/kyoshidajp/bundler-alive
8
8
  metadata:
9
9
  homepage_uri: https://github.com/kyoshidajp/bundler-alive
10
10
  source_code_uri: https://github.com/kyoshidajp/bundler-alive
11
- changelog_uri: https://github.com/kyoshidajp/bundler-alive
11
+ changelog_uri: https://github.com/kyoshidajp/bundler-alive/commits/main
12
12
 
13
13
  required_ruby_version: ">= 2.6.0"
14
14
  bindir: bin
@@ -16,7 +16,7 @@ require_paths: lib
16
16
 
17
17
  dependencies:
18
18
  faraday:
19
- octokit:
19
+ graphql-client:
20
20
  rake:
21
21
  thor:
22
22
  gitlab:
@@ -17,6 +17,7 @@ module Bundler
17
17
 
18
18
  desc "check [DIR]", "Checks the Gemfile.lock"
19
19
  method_option :ignore, type: :array, aliases: "-i", default: []
20
+ method_option :follow_redirect, type: :boolean, aliases: "-r"
20
21
  method_option :gemfile_lock, type: :string, aliases: "-G",
21
22
  default: "Gemfile.lock"
22
23
  method_option :config, type: :string, aliases: "-c", default: ".bundler-alive.yml"
@@ -49,7 +50,10 @@ module Bundler
49
50
  end
50
51
 
51
52
  def initialize_doctor
52
- Doctor.new(options[:gemfile_lock], options[:config], options[:ignore])
53
+ Doctor.new(lock_file: options[:gemfile_lock],
54
+ config_file: options[:config],
55
+ ignore_gems: options[:ignore],
56
+ follow_redirect: options[:follow_redirect])
53
57
  rescue Bundler::GemfileLockNotFound
54
58
  exit 1
55
59
  end
@@ -21,13 +21,16 @@ module Bundler
21
21
  #
22
22
  # A new instance of `GemApiClient`
23
23
  #
24
- # @param [String] config_path
24
+ # @param [String] :config_path
25
+ # @param [Boolean] :follow_redirect
26
+ # Follow redirect URL in gems
25
27
  #
26
28
  # @return [GemApiClient]
27
29
  #
28
- def initialize(config_path = nil)
30
+ def initialize(config_path: nil, follow_redirect: false)
29
31
  @error_messages = []
30
32
  @config_gems = get_config_gems(config_path)
33
+ @follow_redirect = follow_redirect
31
34
 
32
35
  freeze
33
36
  end
@@ -53,7 +56,7 @@ module Bundler
53
56
 
54
57
  private
55
58
 
56
- attr_accessor :error_messages, :config_gems
59
+ attr_accessor :error_messages, :config_gems, :follow_redirect
57
60
 
58
61
  def api_url(gem_name)
59
62
  "https://rubygems.org/api/v1/gems/#{gem_name}.json"
@@ -122,6 +125,8 @@ module Bundler
122
125
  end
123
126
 
124
127
  def url_via_redirect(url)
128
+ return url unless follow_redirect
129
+
125
130
  response = connection.head(url)
126
131
  return response.headers["location"] if response.status == 301
127
132
 
@@ -1,15 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "octokit"
4
3
  require "json"
5
4
 
6
5
  module Bundler
7
6
  module Alive
8
7
  module Client
9
8
  #
10
- # API Client for GitHub API
9
+ # API Client for GitHub GraphQL API
11
10
  #
12
- # @see https://docs.github.com/en/rest/search#search-repositories
11
+ # @see https://docs.github.com/en/graphql
13
12
  #
14
13
  module GithubApi
15
14
  # Environment variable name of GitHub Access Token
@@ -17,27 +16,10 @@ module Bundler
17
16
 
18
17
  # Separator of query condition
19
18
  QUERY_CONDITION_SEPARATOR = " "
19
+ private_constant :QUERY_CONDITION_SEPARATOR
20
20
 
21
- # Number of attempts to request after too many requests
22
- RETRIES_ON_TOO_MANY_REQUESTS = 3
23
-
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
33
- RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS = 120
34
-
35
- #
36
21
  # Max number of conditional operator at once
37
- #
38
- # @see https://docs.github.com/en/rest/search#limitations-on-query-length
39
- QUERY_MAX_OPERATORS_AT_ONCE = 6
40
-
22
+ QUERY_MAX_OPERATORS_AT_ONCE = 50
41
23
  private_constant :QUERY_MAX_OPERATORS_AT_ONCE
42
24
 
43
25
  def self.extended(base)
@@ -49,12 +31,15 @@ module Bundler
49
31
  end
50
32
 
51
33
  #
52
- # Creates a GitHub client
34
+ # Creates a GraphQL client
53
35
  #
54
- # @return [Octokit::Client]
36
+ # @return [GraphQL::Client]
55
37
  #
56
38
  def create_client
57
- Octokit::Client.new(access_token: ENV.fetch(ACCESS_TOKEN_ENV_NAME, nil))
39
+ require_relative "github_graphql"
40
+ extend GithubGraphql
41
+
42
+ GithubGraphql::CLIENT
58
43
  end
59
44
 
60
45
  #
@@ -111,7 +96,7 @@ module Bundler
111
96
  alive_status = if repository.nil?
112
97
  Status::ALIVE_UNKNOWN
113
98
  else
114
- repository["archived"]
99
+ repository["isArchived"]
115
100
  end
116
101
  name_with_status[url.gem_name] = alive_status
117
102
  end
@@ -126,21 +111,24 @@ module Bundler
126
111
  # @return [Sawyer::Resource|nil]
127
112
  def find_repository_from_repositories(url:, repositories:)
128
113
  repositories.find do |repository|
129
- slug(url.url) == repository["full_name"]
114
+ # e.g.) tod's URL is https://github.com/JackC/tod
115
+ # but, the `nameWithOwner` is `jacks/tod`
116
+ slug(url.url).downcase == repository["nameWithOwner"].downcase
130
117
  end
131
118
  end
132
119
 
133
120
  #
134
- # Search query of repositories
121
+ # Search query of repositories (includes forked)
135
122
  #
136
123
  # @param [Array<RepositoryUrl>] urls
137
124
  #
138
125
  # @return [String]
139
126
  #
140
127
  def search_query(urls)
141
- urls.map do |url|
128
+ repository_query = urls.map do |url|
142
129
  "repo:#{slug(url.url)}"
143
130
  end.join(QUERY_CONDITION_SEPARATOR)
131
+ "#{repository_query} fork:true"
144
132
  end
145
133
 
146
134
  #
@@ -148,18 +136,12 @@ module Bundler
148
136
  #
149
137
  # @param [String] query
150
138
  #
151
- # @raise [Octokit::TooManyRequests]
152
- # when too many requested to GitHub.com
153
- # @raise [SourceCodeClient::SearchRepositoryError]
154
- # when Error without `Octokit::TooManyRequests`
155
- #
156
139
  # @return [Array<Sawyer::Resource>|nil]
157
140
  #
158
141
  def search_repositories(query)
159
- result = @client.search_repositories(query)
160
- result[:items]
161
- rescue Octokit::TooManyRequests => e
162
- raise e
142
+ result = @client.query(GithubGraphql::Query,
143
+ variables: { var_query: query, var_first: QUERY_MAX_OPERATORS_AT_ONCE })
144
+ result.data.search.nodes.map(&:to_h)
163
145
  rescue StandardError => e
164
146
  @error_messages << e.message
165
147
  []
@@ -167,21 +149,6 @@ module Bundler
167
149
 
168
150
  def search_repositories_with_retry(query)
169
151
  search_repositories(query)
170
- rescue Octokit::TooManyRequests
171
- if @retries_on_too_many_requests < RETRIES_ON_TOO_MANY_REQUESTS
172
- @retries_on_too_many_requests += 1
173
- sleep_with_message
174
- retry
175
- end
176
-
177
- @rate_limit_exceeded = true
178
- []
179
- end
180
-
181
- def sleep_with_message
182
- puts "Too many requested to GitHub. Sleep #{RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS} sec."
183
- sleep RETRY_INTERVAL_SEC_ON_TOO_MANY_REQUESTS
184
- puts "Retry request (#{@retries_on_too_many_requests}/#{RETRIES_ON_TOO_MANY_REQUESTS})"
185
152
  end
186
153
 
187
154
  #
@@ -192,7 +159,13 @@ module Bundler
192
159
  # @return [String]
193
160
  #
194
161
  def slug(repository_url)
195
- Octokit::Repository.from_url(repository_url).slug.gsub(/\.git/, "")
162
+ # from https://github.com/octokit/octokit.rb/blob/v4.22.0/lib/octokit/repository.rb#L12-L17
163
+ github_slug = URI.parse(repository_url).path[1..]
164
+ .gsub(%r{^repos/}, "")
165
+ .split("/", 3)[0..1]
166
+ .join("/")
167
+
168
+ github_slug.gsub(/\.git/, "")
196
169
  end
197
170
  end
198
171
  end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/client"
4
+ require "graphql/client/http"
5
+
6
+ module Bundler
7
+ module Alive
8
+ module Client
9
+ # GitHub GraphQL Module
10
+ module GithubGraphql
11
+ #
12
+ # Access token isn't set error
13
+ #
14
+ # @see https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
15
+ #
16
+ class AccessTokenNotFoundError < StandardError
17
+ def initialize(_message = nil)
18
+ message = "Environment variable #{ACCESS_TOKEN_ENV_NAME} is not set."\
19
+ " Need to set GitHub Personal Access Token to be authenticated at GitHub GraphQL API."\
20
+ " See: https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#the-graphql-endpoint"
21
+ super(message)
22
+ end
23
+ end
24
+
25
+ # Environment variable name of GitHub Access Token
26
+ ACCESS_TOKEN_ENV_NAME = "BUNDLER_ALIVE_GITHUB_TOKEN"
27
+
28
+ # GraphQL API endpoint
29
+ # @see https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#the-graphql-endpoint
30
+ ENDPOINT = "https://api.github.com/graphql"
31
+ private_constant :ENDPOINT
32
+
33
+ QUERY = <<~QUERY
34
+ query($var_query: String!, $var_first: Int!) {
35
+ search(
36
+ query: $var_query
37
+ type: REPOSITORY
38
+ first: $var_first
39
+ ) {
40
+ repositoryCount
41
+ nodes {
42
+ ... on Repository {
43
+ isArchived
44
+ nameWithOwner
45
+ isMirror
46
+ }
47
+ }
48
+ }
49
+ }
50
+ QUERY
51
+ private_constant :QUERY
52
+
53
+ HTTP = GraphQL::Client::HTTP.new(ENDPOINT) do
54
+ def headers(_context)
55
+ token = ENV.fetch(ACCESS_TOKEN_ENV_NAME, nil)
56
+ raise AccessTokenNotFoundError if token.nil?
57
+
58
+ {
59
+ "Authorization" => "Bearer #{token}"
60
+ }
61
+ end
62
+ end
63
+ private_constant :HTTP
64
+
65
+ if File.exist?(SCHEMA_PATH)
66
+ SCHEMA = GraphQL::Client.load_schema(SCHEMA_PATH)
67
+ else
68
+ SCHEMA = GraphQL::Client.load_schema(HTTP)
69
+ Dir.mkdir(USER_PATH) unless Dir.exist?(USER_PATH)
70
+ GraphQL::Client.dump_schema(SCHEMA, SCHEMA_PATH)
71
+ end
72
+ private_constant :SCHEMA
73
+
74
+ # GraphQL client
75
+ CLIENT = GraphQL::Client.new(schema: SCHEMA, execute: HTTP)
76
+
77
+ # query
78
+ Query = CLIENT.parse(QUERY)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -45,7 +45,7 @@ module Bundler
45
45
  #
46
46
  # Creates a GitLab client
47
47
  #
48
- # @return [Octokit::Client]
48
+ # @return [Gitlab::Client]
49
49
  #
50
50
  def create_client
51
51
  access_token = ENV.fetch(ACCESS_TOKEN_ENV_NAME, nil)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler"
4
- require "octokit"
5
4
 
6
5
  module Bundler
7
6
  module Alive
@@ -12,13 +11,14 @@ module Bundler
12
11
  #
13
12
  # A new instance of Doctor
14
13
  #
15
- # @param [String] lock_file lock file of gem
16
- # @param [String] config_file config file
17
- # @param [Array<String>] ignore_gems ignore gems
14
+ # @param [String] :lock_file # lock file of gem
15
+ # @param [String] :config_file # config file
16
+ # @param [Array<String>] :ignore_gems ignore gems
17
+ # @param [Boolean] :follow_redirect Follow redirect URL in gems
18
18
  #
19
- def initialize(lock_file, config_file, ignore_gems)
19
+ def initialize(lock_file:, config_file:, ignore_gems:, follow_redirect: false)
20
20
  @lock_file = lock_file
21
- @gem_client = Client::GemsApiClient.new(config_file)
21
+ @gem_client = Client::GemsApiClient.new(config_path: config_file, follow_redirect: follow_redirect)
22
22
  @ignore_gems = ignore_gems
23
23
  @result = nil
24
24
  @rate_limit_exceeded = false
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bundler
4
4
  module Alive
5
- VERSION = "0.1.6"
5
+ VERSION = "0.1.7"
6
6
  end
7
7
  end
data/lib/bundler/alive.rb CHANGED
@@ -1,5 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ module Bundler
4
+ module Alive
5
+ USER_PATH = File.expand_path(File.join(Gem.user_home, ".local", "share", "bundler-alive"))
6
+ SCHEMA_PATH = File.join(USER_PATH, "schema.json")
7
+ end
8
+ end
9
+
3
10
  require_relative "alive/version"
4
11
  require_relative "alive/doctor"
5
12
  require_relative "alive/source_code_repository"
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.6
4
+ version: 0.1.7
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-22 00:00:00.000000000 Z
11
+ date: 2022-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: octokit
28
+ name: graphql-client
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -209,6 +209,7 @@ files:
209
209
  - lib/bundler/alive/client/gems_api_client.rb
210
210
  - lib/bundler/alive/client/gems_api_response.rb
211
211
  - lib/bundler/alive/client/github_api.rb
212
+ - lib/bundler/alive/client/github_graphql.rb
212
213
  - lib/bundler/alive/client/gitlab_api.rb
213
214
  - lib/bundler/alive/client/source_code_client.rb
214
215
  - lib/bundler/alive/doctor.rb
@@ -225,7 +226,7 @@ licenses: []
225
226
  metadata:
226
227
  homepage_uri: https://github.com/kyoshidajp/bundler-alive
227
228
  source_code_uri: https://github.com/kyoshidajp/bundler-alive
228
- changelog_uri: https://github.com/kyoshidajp/bundler-alive
229
+ changelog_uri: https://github.com/kyoshidajp/bundler-alive/commits/main
229
230
  rubygems_mfa_required: 'true'
230
231
  post_install_message:
231
232
  rdoc_options: []