rubygems-update 3.5.5 → 3.5.10
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/CHANGELOG.md +107 -0
- data/Manifest.txt +84 -64
- data/POLICIES.md +75 -6
- data/bundler/CHANGELOG.md +75 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/binstubs.rb +1 -1
- data/bundler/lib/bundler/cli/gem.rb +1 -1
- data/bundler/lib/bundler/cli/lock.rb +5 -4
- data/bundler/lib/bundler/cli/plugin.rb +3 -2
- data/bundler/lib/bundler/cli.rb +7 -24
- data/bundler/lib/bundler/definition.rb +111 -56
- data/bundler/lib/bundler/dependency.rb +2 -1
- data/bundler/lib/bundler/dsl.rb +16 -1
- data/bundler/lib/bundler/environment_preserver.rb +5 -23
- data/bundler/lib/bundler/fetcher/downloader.rb +1 -1
- data/bundler/lib/bundler/fetcher.rb +2 -2
- data/bundler/lib/bundler/gem_version_promoter.rb +42 -38
- data/bundler/lib/bundler/injector.rb +3 -2
- data/bundler/lib/bundler/installer.rb +2 -2
- data/bundler/lib/bundler/man/bundle-add.1 +1 -1
- data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
- data/bundler/lib/bundler/man/bundle-check.1 +3 -1
- data/bundler/lib/bundler/man/bundle-check.1.ronn +3 -0
- data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
- data/bundler/lib/bundler/man/bundle-config.1 +1 -3
- data/bundler/lib/bundler/man/bundle-config.1.ronn +0 -3
- data/bundler/lib/bundler/man/bundle-console.1 +1 -1
- data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
- data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
- data/bundler/lib/bundler/man/bundle-gem.1 +1 -1
- data/bundler/lib/bundler/man/bundle-help.1 +1 -1
- data/bundler/lib/bundler/man/bundle-info.1 +1 -1
- data/bundler/lib/bundler/man/bundle-init.1 +1 -1
- data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
- data/bundler/lib/bundler/man/bundle-install.1 +3 -3
- data/bundler/lib/bundler/man/bundle-install.1.ronn +2 -2
- data/bundler/lib/bundler/man/bundle-list.1 +1 -1
- data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
- data/bundler/lib/bundler/man/bundle-open.1 +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
- data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
- data/bundler/lib/bundler/man/bundle-plugin.1 +7 -4
- data/bundler/lib/bundler/man/bundle-plugin.1.ronn +7 -3
- data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
- data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
- data/bundler/lib/bundler/man/bundle-show.1 +1 -1
- data/bundler/lib/bundler/man/bundle-update.1 +1 -1
- data/bundler/lib/bundler/man/bundle-version.1 +1 -1
- data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
- data/bundler/lib/bundler/man/bundle.1 +1 -1
- data/bundler/lib/bundler/man/gemfile.5 +3 -3
- data/bundler/lib/bundler/man/gemfile.5.ronn +2 -2
- data/bundler/lib/bundler/mirror.rb +3 -3
- data/bundler/lib/bundler/plugin/api/source.rb +2 -2
- data/bundler/lib/bundler/plugin/installer/path.rb +18 -0
- data/bundler/lib/bundler/plugin/installer.rb +36 -16
- data/bundler/lib/bundler/plugin/source_list.rb +4 -4
- data/bundler/lib/bundler/resolver/candidate.rb +1 -1
- data/bundler/lib/bundler/resolver.rb +54 -24
- data/bundler/lib/bundler/rubygems_ext.rb +12 -0
- data/bundler/lib/bundler/runtime.rb +1 -1
- data/bundler/lib/bundler/self_manager.rb +1 -1
- data/bundler/lib/bundler/settings.rb +14 -12
- data/bundler/lib/bundler/setup.rb +3 -0
- data/bundler/lib/bundler/source/git/git_proxy.rb +1 -1
- data/bundler/lib/bundler/source/git.rb +1 -1
- data/bundler/lib/bundler/source/rubygems/remote.rb +1 -1
- data/bundler/lib/bundler/source/rubygems.rb +7 -20
- data/bundler/lib/bundler/source_list.rb +17 -4
- data/bundler/lib/bundler/spec_set.rb +1 -1
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +4 -3
- data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
- data/bundler/lib/bundler/uri_credentials_filter.rb +2 -2
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +22 -22
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +1 -0
- data/bundler/lib/bundler/vendored_net_http.rb +7 -3
- data/bundler/lib/bundler/vendored_timeout.rb +7 -3
- data/bundler/lib/bundler/vendored_uri.rb +18 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler/yaml_serializer.rb +12 -0
- data/bundler/lib/bundler.rb +23 -2
- data/lib/rubygems/command.rb +1 -1
- data/lib/rubygems/command_manager.rb +2 -1
- data/lib/rubygems/commands/build_command.rb +2 -11
- data/lib/rubygems/commands/help_command.rb +2 -2
- data/lib/rubygems/commands/rdoc_command.rb +1 -8
- data/lib/rubygems/commands/rebuild_command.rb +264 -0
- data/lib/rubygems/commands/sources_command.rb +2 -2
- data/lib/rubygems/commands/update_command.rb +8 -9
- data/lib/rubygems/config_file.rb +20 -8
- data/lib/rubygems/defaults.rb +4 -4
- data/lib/rubygems/dependency.rb +2 -2
- data/lib/rubygems/dependency_list.rb +1 -1
- data/lib/rubygems/deprecate.rb +79 -77
- data/lib/rubygems/ext/cargo_builder.rb +1 -1
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +1 -1
- data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -1
- data/lib/rubygems/gemcutter_utilities.rb +40 -23
- data/lib/rubygems/gemspec_helpers.rb +19 -0
- data/lib/rubygems/local_remote_options.rb +6 -6
- data/lib/rubygems/package.rb +13 -7
- data/lib/rubygems/remote_fetcher.rb +3 -3
- data/lib/rubygems/request.rb +5 -5
- data/lib/rubygems/request_set.rb +1 -1
- data/lib/rubygems/requirement.rb +5 -0
- data/lib/rubygems/resolver/api_set.rb +1 -1
- data/lib/rubygems/resolver/best_set.rb +1 -1
- data/lib/rubygems/resolver/spec_specification.rb +7 -0
- data/lib/rubygems/resolver.rb +5 -5
- data/lib/rubygems/s3_uri_signer.rb +3 -3
- data/lib/rubygems/safe_yaml.rb +10 -1
- data/lib/rubygems/security.rb +1 -1
- data/lib/rubygems/source/git.rb +2 -2
- data/lib/rubygems/source_list.rb +1 -1
- data/lib/rubygems/specification.rb +6 -6
- data/lib/rubygems/specification_policy.rb +15 -7
- data/lib/rubygems/uri.rb +6 -6
- data/lib/rubygems/util/licenses.rb +43 -0
- data/lib/rubygems/util.rb +1 -1
- data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/delegates/specification_provider.rb +11 -11
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/log.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/vertex.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph.rb +2 -2
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/errors.rb +1 -1
- data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/specification_provider.rb +2 -2
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/ui.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolution.rb +3 -3
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolver.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/state.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo.rb +2 -2
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/generic_request.rb +9 -9
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/header.rb +2 -2
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/request.rb +3 -3
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/requests.rb +30 -30
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/response.rb +2 -2
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/responses.rb +6 -6
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/status.rb +1 -1
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http.rb +15 -15
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/https.rb +1 -1
- data/lib/rubygems/vendor/optparse/lib/optparse/uri.rb +7 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse.rb +11 -11
- data/lib/rubygems/{timeout → vendor/timeout}/lib/timeout.rb +1 -1
- data/lib/rubygems/{tsort → vendor/tsort}/lib/tsort.rb +2 -2
- data/lib/rubygems/vendor/uri/.document +1 -0
- data/lib/rubygems/vendor/uri/LICENSE.txt +22 -0
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +853 -0
- data/lib/rubygems/vendor/uri/lib/uri/file.rb +100 -0
- data/lib/rubygems/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +1588 -0
- data/lib/rubygems/vendor/uri/lib/uri/http.rb +125 -0
- data/lib/rubygems/vendor/uri/lib/uri/https.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldap.rb +261 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldaps.rb +22 -0
- data/lib/rubygems/vendor/uri/lib/uri/mailto.rb +293 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb +539 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb +183 -0
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +6 -0
- data/lib/rubygems/vendor/uri/lib/uri/ws.rb +83 -0
- data/lib/rubygems/vendor/uri/lib/uri/wss.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri.rb +104 -0
- data/lib/rubygems/vendored_molinillo.rb +3 -0
- data/lib/rubygems/vendored_net_http.rb +5 -0
- data/lib/rubygems/vendored_optparse.rb +3 -0
- data/lib/rubygems/vendored_timeout.rb +5 -0
- data/lib/rubygems/vendored_tsort.rb +3 -0
- data/lib/rubygems/yaml_serializer.rb +12 -0
- data/lib/rubygems.rb +2 -2
- data/rubygems-update.gemspec +7 -2
- metadata +90 -67
- data/lib/rubygems/net/http.rb +0 -3
- data/lib/rubygems/optparse/lib/optparse/uri.rb +0 -7
- data/lib/rubygems/optparse.rb +0 -3
- data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/lib/rubygems/resolver/molinillo.rb +0 -3
- data/lib/rubygems/timeout.rb +0 -3
- data/lib/rubygems/tsort.rb +0 -3
- /data/lib/rubygems/{net-http → vendor/molinillo}/.document +0 -0
- /data/lib/rubygems/{resolver → vendor}/molinillo/LICENSE +0 -0
- /data/lib/rubygems/{net-protocol → vendor/net-http}/.document +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/LICENSE.txt +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/backward.rb +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/exceptions.rb +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/proxy_delta.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/net-protocol}/.document +0 -0
- /data/lib/rubygems/{net-protocol → vendor/net-protocol}/LICENSE.txt +0 -0
- /data/lib/rubygems/{net-protocol → vendor/net-protocol}/lib/net/protocol.rb +0 -0
- /data/lib/rubygems/{resolv → vendor/optparse}/.document +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/COPYING +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optionparser.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/ac.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/date.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/kwargs.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/shellwords.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/time.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/version.rb +0 -0
- /data/lib/rubygems/{resolver/molinillo → vendor/resolv}/.document +0 -0
- /data/lib/rubygems/{resolv → vendor/resolv}/LICENSE.txt +0 -0
- /data/lib/rubygems/{resolv → vendor/resolv}/lib/resolv.rb +0 -0
- /data/lib/rubygems/{timeout → vendor/timeout}/.document +0 -0
- /data/lib/rubygems/{timeout → vendor/timeout}/LICENSE.txt +0 -0
- /data/lib/rubygems/{tsort → vendor/tsort}/.document +0 -0
- /data/lib/rubygems/{tsort → vendor/tsort}/LICENSE.txt +0 -0
@@ -1,4 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Bundler; end
|
4
|
-
|
4
|
+
|
5
|
+
# Use RubyGems vendored copy when available. Otherwise fallback to Bundler
|
6
|
+
# vendored copy. The vendored copy in Bundler can be removed once support for
|
7
|
+
# RubyGems 3.5 is dropped.
|
8
|
+
|
9
|
+
begin
|
10
|
+
require "rubygems/vendor/uri/lib/uri"
|
11
|
+
rescue LoadError
|
12
|
+
require_relative "vendor/uri/lib/uri"
|
13
|
+
Gem::URI = Bundler::URI
|
14
|
+
|
15
|
+
module Gem
|
16
|
+
def URI(uri) # rubocop:disable Naming/MethodName
|
17
|
+
Bundler::URI(uri)
|
18
|
+
end
|
19
|
+
module_function :URI
|
20
|
+
end
|
21
|
+
end
|
@@ -58,6 +58,8 @@ module Bundler
|
|
58
58
|
str.split(/\r?\n/) do |line|
|
59
59
|
if match = HASH_REGEX.match(line)
|
60
60
|
indent, key, quote, val = match.captures
|
61
|
+
val = strip_comment(val)
|
62
|
+
|
61
63
|
convert_to_backward_compatible_key!(key)
|
62
64
|
depth = indent.size / 2
|
63
65
|
if quote.empty? && val.empty?
|
@@ -72,6 +74,8 @@ module Bundler
|
|
72
74
|
end
|
73
75
|
elsif match = ARRAY_REGEX.match(line)
|
74
76
|
_, val = match.captures
|
77
|
+
val = strip_comment(val)
|
78
|
+
|
75
79
|
last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)
|
76
80
|
|
77
81
|
last_hash[last_empty_key].push(val)
|
@@ -80,6 +84,14 @@ module Bundler
|
|
80
84
|
res
|
81
85
|
end
|
82
86
|
|
87
|
+
def strip_comment(val)
|
88
|
+
if val.include?("#") && !val.start_with?("#")
|
89
|
+
val.split("#", 2).first.strip
|
90
|
+
else
|
91
|
+
val
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
83
95
|
# for settings' keys
|
84
96
|
def convert_to_backward_compatible_key!(key)
|
85
97
|
key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
|
data/bundler/lib/bundler.rb
CHANGED
@@ -40,6 +40,7 @@ module Bundler
|
|
40
40
|
SUDO_MUTEX = Thread::Mutex.new
|
41
41
|
|
42
42
|
autoload :Checksum, File.expand_path("bundler/checksum", __dir__)
|
43
|
+
autoload :CLI, File.expand_path("bundler/cli", __dir__)
|
43
44
|
autoload :CIDetector, File.expand_path("bundler/ci_detector", __dir__)
|
44
45
|
autoload :Definition, File.expand_path("bundler/definition", __dir__)
|
45
46
|
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
|
@@ -165,6 +166,25 @@ module Bundler
|
|
165
166
|
end
|
166
167
|
end
|
167
168
|
|
169
|
+
# Automatically install dependencies if Bundler.settings[:auto_install] exists.
|
170
|
+
# This is set through config cmd `bundle config set --global auto_install 1`.
|
171
|
+
#
|
172
|
+
# Note that this method `nil`s out the global Definition object, so it
|
173
|
+
# should be called first, before you instantiate anything like an
|
174
|
+
# `Installer` that'll keep a reference to the old one instead.
|
175
|
+
def auto_install
|
176
|
+
return unless settings[:auto_install]
|
177
|
+
|
178
|
+
begin
|
179
|
+
definition.specs
|
180
|
+
rescue GemNotFound, GitError
|
181
|
+
ui.info "Automatically installing missing gems."
|
182
|
+
reset!
|
183
|
+
CLI::Install.new({}).run
|
184
|
+
reset!
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
168
188
|
# Setups Bundler environment (see Bundler.setup) if it is not already set,
|
169
189
|
# and loads all gems from groups specified. Unlike ::setup, can be called
|
170
190
|
# multiple times with different groups (if they were allowed by setup).
|
@@ -200,12 +220,13 @@ module Bundler
|
|
200
220
|
#
|
201
221
|
# @param unlock [Hash, Boolean, nil] Gems that have been requested
|
202
222
|
# to be updated or true if all gems should be updated
|
223
|
+
# @param lockfile [Pathname] Path to Gemfile.lock
|
203
224
|
# @return [Bundler::Definition]
|
204
|
-
def definition(unlock = nil)
|
225
|
+
def definition(unlock = nil, lockfile = default_lockfile)
|
205
226
|
@definition = nil if unlock
|
206
227
|
@definition ||= begin
|
207
228
|
configure
|
208
|
-
Definition.build(default_gemfile,
|
229
|
+
Definition.build(default_gemfile, lockfile, unlock)
|
209
230
|
end
|
210
231
|
end
|
211
232
|
|
data/lib/rubygems/command.rb
CHANGED
@@ -60,6 +60,7 @@ class Gem::CommandManager
|
|
60
60
|
:push,
|
61
61
|
:query,
|
62
62
|
:rdoc,
|
63
|
+
:rebuild,
|
63
64
|
:search,
|
64
65
|
:server,
|
65
66
|
:signin,
|
@@ -106,7 +107,7 @@ class Gem::CommandManager
|
|
106
107
|
# Register all the subcommands supported by the gem command.
|
107
108
|
|
108
109
|
def initialize
|
109
|
-
require_relative "
|
110
|
+
require_relative "vendored_timeout"
|
110
111
|
@commands = {}
|
111
112
|
|
112
113
|
BUILTIN_COMMANDS.each do |name|
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "../command"
|
4
|
+
require_relative "../gemspec_helpers"
|
4
5
|
require_relative "../package"
|
5
6
|
require_relative "../version_option"
|
6
7
|
|
7
8
|
class Gem::Commands::BuildCommand < Gem::Command
|
8
9
|
include Gem::VersionOption
|
10
|
+
include Gem::GemspecHelpers
|
9
11
|
|
10
12
|
def initialize
|
11
13
|
super "build", "Build a gem from a gemspec"
|
@@ -75,17 +77,6 @@ Gems can be saved to a specified filename with the output option:
|
|
75
77
|
|
76
78
|
private
|
77
79
|
|
78
|
-
def find_gemspec(glob = "*.gemspec")
|
79
|
-
gemspecs = Dir.glob(glob).sort
|
80
|
-
|
81
|
-
if gemspecs.size > 1
|
82
|
-
alert_error "Multiple gemspecs found: #{gemspecs}, please specify one"
|
83
|
-
terminate_interaction(1)
|
84
|
-
end
|
85
|
-
|
86
|
-
gemspecs.first
|
87
|
-
end
|
88
|
-
|
89
80
|
def build_gem
|
90
81
|
gemspec = resolve_gem_name
|
91
82
|
|
@@ -59,7 +59,7 @@ multiple environments. The RubyGems implementation is designed to be
|
|
59
59
|
compatible with Bundler's Gemfile format. You can see additional
|
60
60
|
documentation on the format at:
|
61
61
|
|
62
|
-
|
62
|
+
https://bundler.io
|
63
63
|
|
64
64
|
RubyGems automatically looks for these gem dependencies files:
|
65
65
|
|
@@ -172,7 +172,7 @@ and #platforms methods:
|
|
172
172
|
See the bundler Gemfile manual page for a list of platforms supported in a gem
|
173
173
|
dependencies file.:
|
174
174
|
|
175
|
-
|
175
|
+
https://bundler.io/v2.5/man/gemfile.5.html
|
176
176
|
|
177
177
|
Ruby Version and Engine Dependency
|
178
178
|
==================================
|
@@ -84,14 +84,7 @@ Use --overwrite to force rebuilding of documentation.
|
|
84
84
|
FileUtils.rm_rf File.join(spec.doc_dir, "rdoc")
|
85
85
|
end
|
86
86
|
|
87
|
-
|
88
|
-
doc.generate
|
89
|
-
rescue Errno::ENOENT => e
|
90
|
-
match = / - /.match(e.message)
|
91
|
-
alert_error "Unable to document #{spec.full_name}, " \
|
92
|
-
" #{match.post_match} is missing, skipping"
|
93
|
-
terminate_interaction 1 if specs.length == 1
|
94
|
-
end
|
87
|
+
doc.generate
|
95
88
|
end
|
96
89
|
end
|
97
90
|
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "digest"
|
5
|
+
require "fileutils"
|
6
|
+
require "tmpdir"
|
7
|
+
require_relative "../gemspec_helpers"
|
8
|
+
require_relative "../package"
|
9
|
+
|
10
|
+
class Gem::Commands::RebuildCommand < Gem::Command
|
11
|
+
include Gem::GemspecHelpers
|
12
|
+
|
13
|
+
DATE_FORMAT = "%Y-%m-%d %H:%M:%S.%N Z"
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
super "rebuild", "Attempt to reproduce a build of a gem."
|
17
|
+
|
18
|
+
add_option "--diff", "If the files don't match, compare them using diffoscope." do |_value, options|
|
19
|
+
options[:diff] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
add_option "--force", "Skip validation of the spec." do |_value, options|
|
23
|
+
options[:force] = true
|
24
|
+
end
|
25
|
+
|
26
|
+
add_option "--strict", "Consider warnings as errors when validating the spec." do |_value, options|
|
27
|
+
options[:strict] = true
|
28
|
+
end
|
29
|
+
|
30
|
+
add_option "--source GEM_SOURCE", "Specify the source to download the gem from." do |value, options|
|
31
|
+
options[:source] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
add_option "--original GEM_FILE", "Specify a local file to compare against (instead of downloading it)." do |value, options|
|
35
|
+
options[:original_gem_file] = value
|
36
|
+
end
|
37
|
+
|
38
|
+
add_option "--gemspec GEMSPEC_FILE", "Specify the name of the gemspec file." do |value, options|
|
39
|
+
options[:gemspec_file] = value
|
40
|
+
end
|
41
|
+
|
42
|
+
add_option "-C PATH", "Run as if gem build was started in <PATH> instead of the current working directory." do |value, options|
|
43
|
+
options[:build_path] = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def arguments # :nodoc:
|
48
|
+
"GEM_NAME gem name on gem server\n" \
|
49
|
+
"GEM_VERSION gem version you are attempting to rebuild"
|
50
|
+
end
|
51
|
+
|
52
|
+
def description # :nodoc:
|
53
|
+
<<-EOF
|
54
|
+
The rebuild command allows you to (attempt to) reproduce a build of a gem
|
55
|
+
from a ruby gemspec.
|
56
|
+
|
57
|
+
This command assumes the gemspec can be built with the `gem build` command.
|
58
|
+
If you use any of `gem build`, `rake build`, or`rake release` in the
|
59
|
+
build/release process for a gem, it is a potential candidate.
|
60
|
+
|
61
|
+
You will need to match the RubyGems version used, since this is included in
|
62
|
+
the Gem metadata.
|
63
|
+
|
64
|
+
If the gem includes lockfiles (e.g. Gemfile.lock) and similar, it will
|
65
|
+
require more effort to reproduce a build. For example, it might require
|
66
|
+
more precisely matched versions of Ruby and/or Bundler to be used.
|
67
|
+
EOF
|
68
|
+
end
|
69
|
+
|
70
|
+
def usage # :nodoc:
|
71
|
+
"#{program_name} GEM_NAME GEM_VERSION"
|
72
|
+
end
|
73
|
+
|
74
|
+
def execute
|
75
|
+
gem_name, gem_version = get_gem_name_and_version
|
76
|
+
|
77
|
+
old_dir, new_dir = prep_dirs
|
78
|
+
|
79
|
+
gem_filename = "#{gem_name}-#{gem_version}.gem"
|
80
|
+
old_file = File.join(old_dir, gem_filename)
|
81
|
+
new_file = File.join(new_dir, gem_filename)
|
82
|
+
|
83
|
+
if options[:original_gem_file]
|
84
|
+
FileUtils.copy_file(options[:original_gem_file], old_file)
|
85
|
+
else
|
86
|
+
download_gem(gem_name, gem_version, old_file)
|
87
|
+
end
|
88
|
+
|
89
|
+
rg_version = rubygems_version(old_file)
|
90
|
+
unless rg_version == Gem::VERSION
|
91
|
+
alert_error <<-EOF
|
92
|
+
You need to use the same RubyGems version #{gem_name} v#{gem_version} was built with.
|
93
|
+
|
94
|
+
#{gem_name} v#{gem_version} was built using RubyGems v#{rg_version}.
|
95
|
+
Gem files include the version of RubyGems used to build them.
|
96
|
+
This means in order to reproduce #{gem_filename}, you must also use RubyGems v#{rg_version}.
|
97
|
+
|
98
|
+
You're using RubyGems v#{Gem::VERSION}.
|
99
|
+
|
100
|
+
Please install RubyGems v#{rg_version} and try again.
|
101
|
+
EOF
|
102
|
+
terminate_interaction 1
|
103
|
+
end
|
104
|
+
|
105
|
+
source_date_epoch = get_timestamp(old_file).to_s
|
106
|
+
|
107
|
+
if build_path = options[:build_path]
|
108
|
+
Dir.chdir(build_path) { build_gem(gem_name, source_date_epoch, new_file) }
|
109
|
+
else
|
110
|
+
build_gem(gem_name, source_date_epoch, new_file)
|
111
|
+
end
|
112
|
+
|
113
|
+
compare(source_date_epoch, old_file, new_file)
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def sha256(file)
|
119
|
+
Digest::SHA256.hexdigest(Gem.read_binary(file))
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_timestamp(file)
|
123
|
+
mtime = nil
|
124
|
+
File.open(file, Gem.binary_mode) do |f|
|
125
|
+
Gem::Package::TarReader.new(f) do |tar|
|
126
|
+
mtime = tar.seek("metadata.gz") {|tf| tf.header.mtime }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
mtime
|
131
|
+
end
|
132
|
+
|
133
|
+
def compare(source_date_epoch, old_file, new_file)
|
134
|
+
date = Time.at(source_date_epoch.to_i).strftime("%F %T %Z")
|
135
|
+
|
136
|
+
old_hash = sha256(old_file)
|
137
|
+
new_hash = sha256(new_file)
|
138
|
+
|
139
|
+
say
|
140
|
+
say "Built at: #{date} (#{source_date_epoch})"
|
141
|
+
say "Original build saved to: #{old_file}"
|
142
|
+
say "Reproduced build saved to: #{new_file}"
|
143
|
+
say "Working directory: #{options[:build_path] || Dir.pwd}"
|
144
|
+
say
|
145
|
+
say "Hash comparison:"
|
146
|
+
say " #{old_hash}\t#{old_file}"
|
147
|
+
say " #{new_hash}\t#{new_file}"
|
148
|
+
say
|
149
|
+
|
150
|
+
if old_hash == new_hash
|
151
|
+
say "SUCCESS - original and rebuild hashes matched"
|
152
|
+
else
|
153
|
+
say "FAILURE - original and rebuild hashes did not match"
|
154
|
+
say
|
155
|
+
|
156
|
+
if options[:diff]
|
157
|
+
if system("diffoscope", old_file, new_file).nil?
|
158
|
+
alert_error "error: could not find `diffoscope` executable"
|
159
|
+
end
|
160
|
+
else
|
161
|
+
say "Pass --diff for more details (requires diffoscope to be installed)."
|
162
|
+
end
|
163
|
+
|
164
|
+
terminate_interaction 1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def prep_dirs
|
169
|
+
rebuild_dir = Dir.mktmpdir("gem_rebuild")
|
170
|
+
old_dir = File.join(rebuild_dir, "old")
|
171
|
+
new_dir = File.join(rebuild_dir, "new")
|
172
|
+
|
173
|
+
FileUtils.mkdir_p(old_dir)
|
174
|
+
FileUtils.mkdir_p(new_dir)
|
175
|
+
|
176
|
+
[old_dir, new_dir]
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_gem_name_and_version
|
180
|
+
args = options[:args] || []
|
181
|
+
if args.length == 2
|
182
|
+
gem_name, gem_version = args
|
183
|
+
elsif args.length > 2
|
184
|
+
raise Gem::CommandLineError, "Too many arguments"
|
185
|
+
else
|
186
|
+
raise Gem::CommandLineError, "Expected GEM_NAME and GEM_VERSION arguments (gem rebuild GEM_NAME GEM_VERSION)"
|
187
|
+
end
|
188
|
+
|
189
|
+
[gem_name, gem_version]
|
190
|
+
end
|
191
|
+
|
192
|
+
def build_gem(gem_name, source_date_epoch, output_file)
|
193
|
+
gemspec = options[:gemspec_file] || find_gemspec("#{gem_name}.gemspec")
|
194
|
+
|
195
|
+
if gemspec
|
196
|
+
build_package(gemspec, source_date_epoch, output_file)
|
197
|
+
else
|
198
|
+
alert_error error_message(gem_name)
|
199
|
+
terminate_interaction(1)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def build_package(gemspec, source_date_epoch, output_file)
|
204
|
+
with_source_date_epoch(source_date_epoch) do
|
205
|
+
spec = Gem::Specification.load(gemspec)
|
206
|
+
if spec
|
207
|
+
Gem::Package.build(
|
208
|
+
spec,
|
209
|
+
options[:force],
|
210
|
+
options[:strict],
|
211
|
+
output_file
|
212
|
+
)
|
213
|
+
else
|
214
|
+
alert_error "Error loading gemspec. Aborting."
|
215
|
+
terminate_interaction 1
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def with_source_date_epoch(source_date_epoch)
|
221
|
+
old_sde = ENV["SOURCE_DATE_EPOCH"]
|
222
|
+
ENV["SOURCE_DATE_EPOCH"] = source_date_epoch.to_s
|
223
|
+
|
224
|
+
yield
|
225
|
+
ensure
|
226
|
+
ENV["SOURCE_DATE_EPOCH"] = old_sde
|
227
|
+
end
|
228
|
+
|
229
|
+
def error_message(gem_name)
|
230
|
+
if gem_name
|
231
|
+
"Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}"
|
232
|
+
else
|
233
|
+
"Couldn't find a gemspec file in #{Dir.pwd}"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def download_gem(gem_name, gem_version, old_file)
|
238
|
+
# This code was based loosely off the `gem fetch` command.
|
239
|
+
version = "= #{gem_version}"
|
240
|
+
dep = Gem::Dependency.new gem_name, version
|
241
|
+
|
242
|
+
specs_and_sources, errors =
|
243
|
+
Gem::SpecFetcher.fetcher.spec_for_dependency dep
|
244
|
+
|
245
|
+
# There should never be more than one item in specs_and_sources,
|
246
|
+
# since we search for an exact version.
|
247
|
+
spec, source = specs_and_sources[0]
|
248
|
+
|
249
|
+
if spec.nil?
|
250
|
+
show_lookup_failure gem_name, version, errors, options[:domain]
|
251
|
+
terminate_interaction 1
|
252
|
+
end
|
253
|
+
|
254
|
+
download_path = source.download spec
|
255
|
+
|
256
|
+
FileUtils.move(download_path, old_file)
|
257
|
+
|
258
|
+
say "Downloaded #{gem_name} version #{gem_version} as #{old_file}."
|
259
|
+
end
|
260
|
+
|
261
|
+
def rubygems_version(gem_file)
|
262
|
+
Gem::Package.new(gem_file).spec.rubygems_version
|
263
|
+
end
|
264
|
+
end
|
@@ -59,7 +59,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
|
|
59
59
|
|
60
60
|
say "#{source_uri} added to sources"
|
61
61
|
end
|
62
|
-
rescue URI::Error, ArgumentError
|
62
|
+
rescue Gem::URI::Error, ArgumentError
|
63
63
|
say "#{source_uri} is not a URI"
|
64
64
|
terminate_interaction 1
|
65
65
|
rescue Gem::RemoteFetcher::FetchError => e
|
@@ -81,7 +81,7 @@ Do you want to add this source?
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def check_rubygems_https(source_uri) # :nodoc:
|
84
|
-
uri = URI source_uri
|
84
|
+
uri = Gem::URI source_uri
|
85
85
|
|
86
86
|
if uri.scheme && uri.scheme.casecmp("http").zero? &&
|
87
87
|
uri.host.casecmp("rubygems.org").zero?
|
@@ -197,18 +197,17 @@ command to remove old versions.
|
|
197
197
|
yield
|
198
198
|
else
|
199
199
|
require "tmpdir"
|
200
|
-
|
201
|
-
|
200
|
+
Dir.mktmpdir("gem_update") do |tmpdir|
|
201
|
+
FileUtils.mv Gem.plugindir, tmpdir
|
202
202
|
|
203
|
-
|
203
|
+
status = yield
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
|
209
|
-
end
|
205
|
+
unless status
|
206
|
+
FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
|
207
|
+
end
|
210
208
|
|
211
|
-
|
209
|
+
status
|
210
|
+
end
|
212
211
|
end
|
213
212
|
end
|
214
213
|
|
data/lib/rubygems/config_file.rb
CHANGED
@@ -202,21 +202,33 @@ class Gem::ConfigFile
|
|
202
202
|
@hash = @hash.merge environment_config
|
203
203
|
end
|
204
204
|
|
205
|
+
@hash.transform_keys! do |k|
|
206
|
+
# gemhome and gempath are not working with symbol keys
|
207
|
+
if %w[backtrace bulk_threshold verbose update_sources cert_expiration_length_days
|
208
|
+
install_extension_in_lib ipv4_fallback_enabled sources disable_default_gem_server
|
209
|
+
ssl_verify_mode ssl_ca_cert ssl_client_cert].include?(k)
|
210
|
+
k.to_sym
|
211
|
+
else
|
212
|
+
k
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
205
216
|
# HACK: these override command-line args, which is bad
|
206
217
|
@backtrace = @hash[:backtrace] if @hash.key? :backtrace
|
207
218
|
@bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
|
208
|
-
@home = @hash[:gemhome] if @hash.key? :gemhome
|
209
|
-
@path = @hash[:gempath] if @hash.key? :gempath
|
210
|
-
@update_sources = @hash[:update_sources] if @hash.key? :update_sources
|
211
219
|
@verbose = @hash[:verbose] if @hash.key? :verbose
|
212
|
-
@
|
213
|
-
|
220
|
+
@update_sources = @hash[:update_sources] if @hash.key? :update_sources
|
221
|
+
# TODO: We should handle concurrent_downloads same as other options
|
214
222
|
@cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
|
215
223
|
@ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
|
216
224
|
|
217
|
-
@
|
218
|
-
@
|
219
|
-
@
|
225
|
+
@home = @hash[:gemhome] if @hash.key? :gemhome
|
226
|
+
@path = @hash[:gempath] if @hash.key? :gempath
|
227
|
+
@sources = @hash[:sources] if @hash.key? :sources
|
228
|
+
@disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
|
229
|
+
@ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
|
230
|
+
@ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
|
231
|
+
@ssl_client_cert = @hash[:ssl_client_cert] if @hash.key? :ssl_client_cert
|
220
232
|
|
221
233
|
@api_keys = nil
|
222
234
|
@rubygems_api_key = nil
|
data/lib/rubygems/defaults.rb
CHANGED
@@ -112,7 +112,7 @@ module Gem
|
|
112
112
|
# The path to standard location of the user's configuration directory.
|
113
113
|
|
114
114
|
def self.config_home
|
115
|
-
@config_home ||=
|
115
|
+
@config_home ||= ENV["XDG_CONFIG_HOME"] || File.join(Gem.user_home, ".config")
|
116
116
|
end
|
117
117
|
|
118
118
|
##
|
@@ -145,21 +145,21 @@ module Gem
|
|
145
145
|
# The path to standard location of the user's cache directory.
|
146
146
|
|
147
147
|
def self.cache_home
|
148
|
-
@cache_home ||=
|
148
|
+
@cache_home ||= ENV["XDG_CACHE_HOME"] || File.join(Gem.user_home, ".cache")
|
149
149
|
end
|
150
150
|
|
151
151
|
##
|
152
152
|
# The path to standard location of the user's data directory.
|
153
153
|
|
154
154
|
def self.data_home
|
155
|
-
@data_home ||=
|
155
|
+
@data_home ||= ENV["XDG_DATA_HOME"] || File.join(Gem.user_home, ".local", "share")
|
156
156
|
end
|
157
157
|
|
158
158
|
##
|
159
159
|
# The path to standard location of the user's state directory.
|
160
160
|
|
161
161
|
def self.state_home
|
162
|
-
@state_home ||=
|
162
|
+
@state_home ||= ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state")
|
163
163
|
end
|
164
164
|
|
165
165
|
##
|
data/lib/rubygems/dependency.rb
CHANGED
@@ -328,9 +328,9 @@ class Gem::Dependency
|
|
328
328
|
return active if active
|
329
329
|
|
330
330
|
unless prerelease?
|
331
|
-
#
|
331
|
+
# Consider prereleases only as a fallback
|
332
332
|
pre, matches = matches.partition {|spec| spec.version.prerelease? }
|
333
|
-
matches
|
333
|
+
matches = pre if matches.empty?
|
334
334
|
end
|
335
335
|
|
336
336
|
matches.first
|