rubygems-update 3.4.6 → 3.4.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -1
- data/Manifest.txt +3 -1
- data/POLICIES.md +5 -5
- data/README.md +17 -4
- data/bundler/CHANGELOG.md +74 -0
- data/bundler/README.md +1 -4
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/init.rb +2 -2
- data/bundler/lib/bundler/cli.rb +1 -0
- data/bundler/lib/bundler/current_ruby.rb +2 -0
- data/bundler/lib/bundler/definition.rb +5 -1
- data/bundler/lib/bundler/dependency.rb +1 -1
- data/bundler/lib/bundler/endpoint_specification.rb +0 -4
- data/bundler/lib/bundler/environment_preserver.rb +2 -2
- data/bundler/lib/bundler/fetcher/dependency.rb +1 -5
- data/bundler/lib/bundler/fetcher.rb +2 -2
- data/bundler/lib/bundler/index.rb +2 -2
- data/bundler/lib/bundler/injector.rb +1 -1
- data/bundler/lib/bundler/installer/parallel_installer.rb +3 -2
- data/bundler/lib/bundler/installer/standalone.rb +1 -1
- data/bundler/lib/bundler/lazy_specification.rb +4 -8
- data/bundler/lib/bundler/lockfile_generator.rb +1 -1
- data/bundler/lib/bundler/lockfile_parser.rb +11 -11
- 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 +1 -1
- data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
- data/bundler/lib/bundler/man/bundle-config.1 +1 -1
- 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 +5 -1
- data/bundler/lib/bundler/man/bundle-init.1.ronn +2 -0
- data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
- data/bundler/lib/bundler/man/bundle-install.1 +1 -1
- 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 +1 -1
- 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 +1 -1
- data/bundler/lib/bundler/plugin/installer.rb +5 -2
- data/bundler/lib/bundler/plugin.rb +1 -1
- data/bundler/lib/bundler/remote_specification.rb +2 -6
- data/bundler/lib/bundler/resolver/base.rb +36 -4
- data/bundler/lib/bundler/resolver.rb +6 -9
- data/bundler/lib/bundler/rubygems_integration.rb +1 -1
- data/bundler/lib/bundler/settings.rb +1 -1
- data/bundler/lib/bundler/setup.rb +4 -1
- data/bundler/lib/bundler/shared_helpers.rb +1 -1
- data/bundler/lib/bundler/source/git/git_proxy.rb +27 -8
- data/bundler/lib/bundler/source/git.rb +2 -1
- data/bundler/lib/bundler/source/path.rb +1 -1
- data/bundler/lib/bundler/source/rubygems.rb +1 -2
- data/bundler/lib/bundler/spec_set.rb +13 -3
- data/bundler/lib/bundler/templates/Executable.bundler +1 -1
- data/bundler/lib/bundler/templates/newgem/Gemfile.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/Rakefile.tt +10 -0
- data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/bundler/lib/bundler/uri_normalizer.rb +23 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +6 -7
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +8 -1
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +5 -4
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +4 -2
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +4 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +10 -9
- data/lib/rubygems/bundler_version_finder.rb +1 -1
- data/lib/rubygems/command.rb +10 -6
- data/lib/rubygems/command_manager.rb +1 -0
- data/lib/rubygems/commands/exec_command.rb +248 -0
- data/lib/rubygems/commands/help_command.rb +3 -3
- data/lib/rubygems/commands/pristine_command.rb +9 -0
- data/lib/rubygems/commands/uninstall_command.rb +3 -0
- data/lib/rubygems/core_ext/kernel_require.rb +0 -10
- data/lib/rubygems/defaults.rb +2 -2
- data/lib/rubygems/dependency.rb +1 -1
- data/lib/rubygems/deprecate.rb +2 -2
- data/lib/rubygems/ext/builder.rb +17 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +1 -2
- data/lib/rubygems/ext/rake_builder.rb +1 -1
- data/lib/rubygems/package/tar_header.rb +1 -1
- data/lib/rubygems/package/tar_reader/entry.rb +88 -7
- data/lib/rubygems/package/tar_reader.rb +0 -28
- data/lib/rubygems/platform.rb +2 -2
- data/lib/rubygems/request_set/gem_dependency_api.rb +0 -1
- data/lib/rubygems/requirement.rb +1 -1
- data/lib/rubygems/resolver/stats.rb +1 -1
- data/lib/rubygems/source/git.rb +1 -1
- data/lib/rubygems/specification.rb +9 -1
- data/lib/rubygems/specification_policy.rb +5 -0
- data/lib/rubygems/stub_specification.rb +7 -7
- data/lib/rubygems/text.rb +1 -1
- data/lib/rubygems/util/licenses.rb +2 -2
- data/lib/rubygems/version.rb +2 -2
- data/lib/rubygems.rb +3 -3
- data/rubygems-update.gemspec +1 -1
- data/test/rubygems/helper.rb +2 -3
- data/test/rubygems/package/tar_test_case.rb +50 -15
- data/test/rubygems/simple_gem.rb +1 -1
- data/test/rubygems/test_gem.rb +29 -0
- data/test/rubygems/test_gem_bundler_version_finder.rb +2 -2
- data/test/rubygems/test_gem_command_manager.rb +25 -0
- data/test/rubygems/test_gem_commands_exec_command.rb +851 -0
- data/test/rubygems/test_gem_commands_install_command.rb +1 -1
- data/test/rubygems/test_gem_commands_pristine_command.rb +48 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +1 -1
- data/test/rubygems/test_gem_commands_uninstall_command.rb +31 -14
- data/test/rubygems/test_gem_ext_builder.rb +3 -5
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +20 -6
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +1 -1
- data/test/rubygems/test_gem_ext_cargo_builder.rb +1 -1
- data/test/rubygems/test_gem_gem_runner.rb +6 -1
- data/test/rubygems/test_gem_package.rb +0 -25
- data/test/rubygems/test_gem_package_tar_reader.rb +48 -1
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +151 -6
- data/test/rubygems/test_gem_remote_fetcher.rb +1 -1
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +10 -10
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +2 -2
- data/test/rubygems/test_gem_resolver_git_set.rb +9 -9
- data/test/rubygems/test_gem_resolver_git_specification.rb +1 -1
- data/test/rubygems/test_gem_source.rb +1 -1
- data/test/rubygems/test_gem_source_git.rb +13 -12
- data/test/rubygems/test_gem_source_installed.rb +1 -1
- data/test/rubygems/test_gem_source_lock.rb +3 -3
- data/test/rubygems/test_gem_source_vendor.rb +1 -1
- data/test/rubygems/test_gem_specification.rb +36 -2
- data/test/rubygems/test_gem_version.rb +2 -2
- data/test/rubygems/test_kernel.rb +0 -8
- metadata +6 -4
- data/bundler/lib/bundler/templates/gems.rb +0 -5
@@ -41,6 +41,15 @@ require "standard/rake"
|
|
41
41
|
<% if config[:ext] -%>
|
42
42
|
<% default_task_names.unshift(:compile) -%>
|
43
43
|
<% default_task_names.unshift(:clobber) unless config[:ext] == 'rust' -%>
|
44
|
+
<% if config[:ext] == 'rust' -%>
|
45
|
+
require "rb_sys/extensiontask"
|
46
|
+
|
47
|
+
task build: :compile
|
48
|
+
|
49
|
+
RbSys::ExtensionTask.new(<%= config[:name].inspect %>) do |ext|
|
50
|
+
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
|
51
|
+
end
|
52
|
+
<% else -%>
|
44
53
|
require "rake/extensiontask"
|
45
54
|
|
46
55
|
task build: :compile
|
@@ -48,6 +57,7 @@ task build: :compile
|
|
48
57
|
Rake::ExtensionTask.new("<%= config[:underscored_name] %>") do |ext|
|
49
58
|
ext.lib_dir = "lib/<%= config[:namespaced_path] %>"
|
50
59
|
end
|
60
|
+
<% end -%>
|
51
61
|
|
52
62
|
<% end -%>
|
53
63
|
<% if default_task_names.size == 1 -%>
|
@@ -20,7 +20,7 @@ jobs:
|
|
20
20
|
- uses: actions/checkout@v3
|
21
21
|
<%- if config[:ext] == 'rust' -%>
|
22
22
|
- name: Set up Ruby & Rust
|
23
|
-
uses: oxidize-rb/actions/setup-ruby-and-rust@
|
23
|
+
uses: oxidize-rb/actions/setup-ruby-and-rust@v1
|
24
24
|
with:
|
25
25
|
ruby-version: ${{ matrix.ruby }}
|
26
26
|
bundler-cache: true
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
30
|
spec.files = Dir.chdir(__dir__) do
|
31
31
|
`git ls-files -z`.split("\x0").reject do |f|
|
32
|
-
(f == __FILE__) || f.
|
32
|
+
(File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
|
33
33
|
end
|
34
34
|
end
|
35
35
|
spec.bindir = "exe"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
module URINormalizer
|
5
|
+
module_function
|
6
|
+
|
7
|
+
# Normalizes uri to a consistent version, either with or without trailing
|
8
|
+
# slash.
|
9
|
+
#
|
10
|
+
# TODO: Currently gem sources are locked with a trailing slash, while git
|
11
|
+
# sources are locked without a trailing slash. This should be normalized but
|
12
|
+
# the inconsistency is there for now to avoid changing all lockfiles
|
13
|
+
# including GIT sources. We could normalize this on the next major.
|
14
|
+
#
|
15
|
+
def normalize_suffix(uri, trailing_slash: true)
|
16
|
+
if trailing_slash
|
17
|
+
uri.end_with?("/") ? uri : "#{uri}/"
|
18
|
+
else
|
19
|
+
uri.end_with?("/") ? uri.delete_suffix("/") : uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -8,9 +8,6 @@ module Bundler::PubGrub
|
|
8
8
|
InvalidDependency = Struct.new(:package, :constraint) do
|
9
9
|
end
|
10
10
|
|
11
|
-
CircularDependency = Struct.new(:package, :constraint) do
|
12
|
-
end
|
13
|
-
|
14
11
|
NoVersions = Struct.new(:constraint) do
|
15
12
|
end
|
16
13
|
|
@@ -66,8 +63,6 @@ module Bundler::PubGrub
|
|
66
63
|
"#{terms[0].to_s(allow_every: true)} depends on #{terms[1].invert}"
|
67
64
|
when Bundler::PubGrub::Incompatibility::InvalidDependency
|
68
65
|
"#{terms[0].to_s(allow_every: true)} depends on unknown package #{cause.package}"
|
69
|
-
when Bundler::PubGrub::Incompatibility::CircularDependency
|
70
|
-
"#{terms[0].to_s(allow_every: true)} depends on itself"
|
71
66
|
when Bundler::PubGrub::Incompatibility::NoVersions
|
72
67
|
"no versions satisfy #{cause.constraint}"
|
73
68
|
when Bundler::PubGrub::Incompatibility::ConflictCause
|
@@ -76,9 +71,13 @@ module Bundler::PubGrub
|
|
76
71
|
elsif terms.length == 1
|
77
72
|
term = terms[0]
|
78
73
|
if term.positive?
|
79
|
-
|
74
|
+
if term.constraint.any?
|
75
|
+
"#{term.package} cannot be used"
|
76
|
+
else
|
77
|
+
"#{term.to_s(allow_every: true)} cannot be used"
|
78
|
+
end
|
80
79
|
else
|
81
|
-
"#{
|
80
|
+
"#{term.invert} is required"
|
82
81
|
end
|
83
82
|
else
|
84
83
|
if terms.all?(&:positive?)
|
@@ -19,7 +19,14 @@ module Bundler::PubGrub
|
|
19
19
|
version = Gem::Version.new(version)
|
20
20
|
@packages[name] ||= {}
|
21
21
|
raise ArgumentError, "#{name} #{version} declared twice" if @packages[name].key?(version)
|
22
|
-
@packages[name][version] = deps
|
22
|
+
@packages[name][version] = clean_deps(name, version, deps)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Exclude redundant self-referencing dependencies
|
28
|
+
def clean_deps(name, version, deps)
|
29
|
+
deps.reject {|dep_name, req| name == dep_name && Bundler::PubGrub::RubyGems.parse_range(req).include?(version) }
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
@@ -15,15 +15,16 @@ module Bundler::PubGrub
|
|
15
15
|
package.hash ^ range.hash
|
16
16
|
end
|
17
17
|
|
18
|
+
def ==(other)
|
19
|
+
package == other.package &&
|
20
|
+
range == other.range
|
21
|
+
end
|
22
|
+
|
18
23
|
def eql?(other)
|
19
24
|
package.eql?(other.package) &&
|
20
25
|
range.eql?(other.range)
|
21
26
|
end
|
22
27
|
|
23
|
-
def ==(other)
|
24
|
-
package == other.package && range == other.range
|
25
|
-
end
|
26
|
-
|
27
28
|
class << self
|
28
29
|
def exact(package, version)
|
29
30
|
range = VersionRange.new(min: version, max: version, include_min: true, include_max: true)
|
@@ -19,7 +19,7 @@ module Bundler::PubGrub
|
|
19
19
|
true
|
20
20
|
end
|
21
21
|
|
22
|
-
def eql?
|
22
|
+
def eql?(other)
|
23
23
|
other.empty?
|
24
24
|
end
|
25
25
|
|
@@ -65,6 +65,7 @@ module Bundler::PubGrub
|
|
65
65
|
end
|
66
66
|
|
67
67
|
EMPTY = Empty.new
|
68
|
+
Empty.singleton_class.undef_method(:new)
|
68
69
|
|
69
70
|
def self.empty
|
70
71
|
EMPTY
|
@@ -88,7 +89,8 @@ module Bundler::PubGrub
|
|
88
89
|
|
89
90
|
def eql?(other)
|
90
91
|
if other.is_a?(VersionRange)
|
91
|
-
|
92
|
+
!other.empty? &&
|
93
|
+
min.eql?(other.min) &&
|
92
94
|
max.eql?(other.max) &&
|
93
95
|
include_min.eql?(other.include_min) &&
|
94
96
|
include_max.eql?(other.include_max)
|
@@ -125,6 +125,7 @@ module Bundler::PubGrub
|
|
125
125
|
package = next_package_to_try
|
126
126
|
unsatisfied_term = solution.unsatisfied.find { |t| t.package == package }
|
127
127
|
version = source.versions_for(package, unsatisfied_term.constraint.range).first
|
128
|
+
logger.debug { "attempting #{package} #{version}" }
|
128
129
|
|
129
130
|
if version.nil?
|
130
131
|
add_incompatibility source.no_versions_incompatibility_for(package, unsatisfied_term)
|
@@ -148,9 +149,11 @@ module Bundler::PubGrub
|
|
148
149
|
end
|
149
150
|
|
150
151
|
unless conflict
|
151
|
-
logger.info { "
|
152
|
+
logger.info { "selected #{package} #{version}" }
|
152
153
|
|
153
154
|
solution.decide(package, version)
|
155
|
+
else
|
156
|
+
logger.info { "conflict: #{conflict.inspect}" }
|
154
157
|
end
|
155
158
|
|
156
159
|
package
|
data/bundler/lib/bundler.rb
CHANGED
@@ -39,8 +39,8 @@ module Bundler
|
|
39
39
|
environment_preserver.replace_with_backup
|
40
40
|
SUDO_MUTEX = Thread::Mutex.new
|
41
41
|
|
42
|
-
SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash].freeze
|
43
|
-
SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed."
|
42
|
+
SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash, Gem::Version, Gem::Specification].freeze
|
43
|
+
SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed."
|
44
44
|
SAFE_MARSHAL_PROC = proc do |object|
|
45
45
|
object.tap do
|
46
46
|
unless SAFE_MARSHAL_CLASSES.include?(object.class)
|
@@ -85,6 +85,7 @@ module Bundler
|
|
85
85
|
autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
|
86
86
|
autoload :UI, File.expand_path("bundler/ui", __dir__)
|
87
87
|
autoload :URICredentialsFilter, File.expand_path("bundler/uri_credentials_filter", __dir__)
|
88
|
+
autoload :URINormalizer, File.expand_path("bundler/uri_normalizer", __dir__)
|
88
89
|
|
89
90
|
class << self
|
90
91
|
def configure
|
@@ -506,7 +507,7 @@ EOF
|
|
506
507
|
if File.file?(executable) && File.executable?(executable)
|
507
508
|
executable
|
508
509
|
elsif paths = ENV["PATH"]
|
509
|
-
quote = '"'
|
510
|
+
quote = '"'
|
510
511
|
paths.split(File::PATH_SEPARATOR).find do |path|
|
511
512
|
path = path[1..-2] if path.start_with?(quote) && path.end_with?(quote)
|
512
513
|
executable_path = File.expand_path(executable, path)
|
@@ -525,12 +526,6 @@ EOF
|
|
525
526
|
load_marshal(data, :marshal_proc => SAFE_MARSHAL_PROC)
|
526
527
|
end
|
527
528
|
|
528
|
-
def load_marshal(data, marshal_proc: nil)
|
529
|
-
Marshal.load(data, marshal_proc)
|
530
|
-
rescue TypeError => e
|
531
|
-
raise MarshalError, "#{e.class}: #{e.message}"
|
532
|
-
end
|
533
|
-
|
534
529
|
def load_gemspec(file, validate = false)
|
535
530
|
@gemspec_cache ||= {}
|
536
531
|
key = File.expand_path(file)
|
@@ -619,6 +614,12 @@ EOF
|
|
619
614
|
|
620
615
|
private
|
621
616
|
|
617
|
+
def load_marshal(data, marshal_proc: nil)
|
618
|
+
Marshal.load(data, marshal_proc)
|
619
|
+
rescue TypeError => e
|
620
|
+
raise MarshalError, "#{e.class}: #{e.message}"
|
621
|
+
end
|
622
|
+
|
622
623
|
def eval_yaml_gemspec(path, contents)
|
623
624
|
Kernel.require "psych"
|
624
625
|
|
@@ -21,7 +21,7 @@ module Gem::BundlerVersionFinder
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.bundle_update_bundler_version
|
24
|
-
return unless File.basename($0) == "bundle"
|
24
|
+
return unless File.basename($0) == "bundle"
|
25
25
|
return unless "update".start_with?(ARGV.first || " ")
|
26
26
|
bundler_version = nil
|
27
27
|
update_index = nil
|
data/lib/rubygems/command.rb
CHANGED
@@ -201,11 +201,15 @@ class Gem::Command
|
|
201
201
|
# respectively.
|
202
202
|
def get_all_gem_names_and_versions
|
203
203
|
get_all_gem_names.map do |name|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
204
|
+
extract_gem_name_and_version(name)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def extract_gem_name_and_version(name) # :nodoc:
|
209
|
+
if /\A(.*):(#{Gem::Requirement::PATTERN_RAW})\z/ =~ name
|
210
|
+
[$1, $2]
|
211
|
+
else
|
212
|
+
[name]
|
209
213
|
end
|
210
214
|
end
|
211
215
|
|
@@ -624,7 +628,7 @@ class Gem::Command
|
|
624
628
|
|
625
629
|
# :stopdoc:
|
626
630
|
|
627
|
-
HELP = <<-HELP
|
631
|
+
HELP = <<-HELP
|
628
632
|
RubyGems is a package manager for Ruby.
|
629
633
|
|
630
634
|
Usage:
|
@@ -0,0 +1,248 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative "../command"
|
3
|
+
require_relative "../dependency_installer"
|
4
|
+
require_relative "../gem_runner"
|
5
|
+
require_relative "../package"
|
6
|
+
require_relative "../version_option"
|
7
|
+
|
8
|
+
class Gem::Commands::ExecCommand < Gem::Command
|
9
|
+
include Gem::VersionOption
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super "exec", "Run a command from a gem", {
|
13
|
+
version: Gem::Requirement.default,
|
14
|
+
}
|
15
|
+
|
16
|
+
add_version_option
|
17
|
+
add_prerelease_option "to be installed"
|
18
|
+
|
19
|
+
add_option "-g", "--gem GEM", "run the executable from the given gem" do |value, options|
|
20
|
+
options[:gem_name] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
add_option(:"Install/Update", "--conservative",
|
24
|
+
"Prefer the most recent installed version, ",
|
25
|
+
"rather than the latest version overall") do |value, options|
|
26
|
+
options[:conservative] = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def arguments # :nodoc:
|
31
|
+
"COMMAND the executable command to run"
|
32
|
+
end
|
33
|
+
|
34
|
+
def defaults_str # :nodoc:
|
35
|
+
"--version '#{Gem::Requirement.default}'"
|
36
|
+
end
|
37
|
+
|
38
|
+
def description # :nodoc:
|
39
|
+
<<-EOF
|
40
|
+
The exec command handles installing (if necessary) and running an executable
|
41
|
+
from a gem, regardless of whether that gem is currently installed.
|
42
|
+
|
43
|
+
The exec command can be thought of as a shortcut to running `gem install` and
|
44
|
+
then the executable from the installed gem.
|
45
|
+
|
46
|
+
For example, `gem exec rails new .` will run `rails new .` in the current
|
47
|
+
directory, without having to manually run `gem install rails`.
|
48
|
+
Additionally, the exec command ensures the most recent version of the gem
|
49
|
+
is used (unless run with `--conservative`), and that the gem is not installed
|
50
|
+
to the same gem path as user-installed gems.
|
51
|
+
EOF
|
52
|
+
end
|
53
|
+
|
54
|
+
def usage # :nodoc:
|
55
|
+
"#{program_name} [options --] COMMAND [args]"
|
56
|
+
end
|
57
|
+
|
58
|
+
def execute
|
59
|
+
gem_paths = { "GEM_HOME" => Gem.paths.home, "GEM_PATH" => Gem.paths.path.join(File::PATH_SEPARATOR), "GEM_SPEC_CACHE" => Gem.paths.spec_cache_dir }.compact
|
60
|
+
|
61
|
+
check_executable
|
62
|
+
|
63
|
+
print_command
|
64
|
+
if options[:gem_name] == "gem" && options[:executable] == "gem"
|
65
|
+
set_gem_exec_install_paths
|
66
|
+
Gem::GemRunner.new.run options[:args]
|
67
|
+
return
|
68
|
+
elsif options[:conservative]
|
69
|
+
install_if_needed
|
70
|
+
else
|
71
|
+
install
|
72
|
+
activate!
|
73
|
+
end
|
74
|
+
|
75
|
+
load!
|
76
|
+
ensure
|
77
|
+
ENV.update(gem_paths) if gem_paths
|
78
|
+
Gem.clear_paths
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def handle_options(args)
|
84
|
+
args = add_extra_args(args)
|
85
|
+
check_deprecated_options(args)
|
86
|
+
@options = Marshal.load Marshal.dump @defaults # deep copy
|
87
|
+
parser.order!(args) do |v|
|
88
|
+
# put the non-option back at the front of the list of arguments
|
89
|
+
args.unshift(v)
|
90
|
+
|
91
|
+
# stop parsing once we hit the first non-option,
|
92
|
+
# so you can call `gem exec rails --version` and it prints the rails
|
93
|
+
# version rather than rubygem's
|
94
|
+
break
|
95
|
+
end
|
96
|
+
@options[:args] = args
|
97
|
+
|
98
|
+
options[:executable], gem_version = extract_gem_name_and_version(options[:args].shift)
|
99
|
+
options[:gem_name] ||= options[:executable]
|
100
|
+
|
101
|
+
if gem_version
|
102
|
+
if options[:version].none?
|
103
|
+
options[:version] = Gem::Requirement.new(gem_version)
|
104
|
+
else
|
105
|
+
options[:version].concat [gem_version]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
if options[:prerelease] && !options[:version].prerelease?
|
110
|
+
if options[:version].none?
|
111
|
+
options[:version] = Gem::Requirement.default_prerelease
|
112
|
+
else
|
113
|
+
options[:version].concat [Gem::Requirement.default_prerelease]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def check_executable
|
119
|
+
if options[:executable].nil?
|
120
|
+
raise Gem::CommandLineError,
|
121
|
+
"Please specify an executable to run (e.g. #{program_name} COMMAND)"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def print_command
|
126
|
+
verbose "running #{program_name} with:\n"
|
127
|
+
opts = options.reject {|_, v| v.nil? || Array(v).empty? }
|
128
|
+
max_length = opts.map {|k, _| k.size }.max
|
129
|
+
opts.each do |k, v|
|
130
|
+
next if v.nil?
|
131
|
+
verbose "\t#{k.to_s.rjust(max_length)}: #{v}"
|
132
|
+
end
|
133
|
+
verbose ""
|
134
|
+
end
|
135
|
+
|
136
|
+
def install_if_needed
|
137
|
+
activate!
|
138
|
+
rescue Gem::MissingSpecError
|
139
|
+
verbose "#{Gem::Dependency.new(options[:gem_name], options[:version])} not available locally, installing from remote"
|
140
|
+
install
|
141
|
+
activate!
|
142
|
+
end
|
143
|
+
|
144
|
+
def set_gem_exec_install_paths
|
145
|
+
home = File.join(Gem.dir, "gem_exec")
|
146
|
+
|
147
|
+
ENV["GEM_PATH"] = ([home] + Gem.path).join(File::PATH_SEPARATOR)
|
148
|
+
ENV["GEM_HOME"] = home
|
149
|
+
Gem.clear_paths
|
150
|
+
end
|
151
|
+
|
152
|
+
def install
|
153
|
+
set_gem_exec_install_paths
|
154
|
+
|
155
|
+
gem_name = options[:gem_name]
|
156
|
+
gem_version = options[:version]
|
157
|
+
|
158
|
+
install_options = options.merge(
|
159
|
+
minimal_deps: false,
|
160
|
+
wrappers: true
|
161
|
+
)
|
162
|
+
|
163
|
+
suppress_always_install do
|
164
|
+
dep_installer = Gem::DependencyInstaller.new install_options
|
165
|
+
|
166
|
+
request_set = dep_installer.resolve_dependencies gem_name, gem_version
|
167
|
+
|
168
|
+
verbose "Gems to install:"
|
169
|
+
request_set.sorted_requests.each do |activation_request|
|
170
|
+
verbose "\t#{activation_request.full_name}"
|
171
|
+
end
|
172
|
+
|
173
|
+
request_set.install install_options
|
174
|
+
end
|
175
|
+
|
176
|
+
Gem::Specification.reset
|
177
|
+
rescue Gem::InstallError => e
|
178
|
+
alert_error "Error installing #{gem_name}:\n\t#{e.message}"
|
179
|
+
terminate_interaction 1
|
180
|
+
rescue Gem::GemNotFoundException => e
|
181
|
+
show_lookup_failure e.name, e.version, e.errors, false
|
182
|
+
|
183
|
+
terminate_interaction 2
|
184
|
+
rescue Gem::UnsatisfiableDependencyError => e
|
185
|
+
show_lookup_failure e.name, e.version, e.errors, false,
|
186
|
+
"'#{gem_name}' (#{gem_version})"
|
187
|
+
|
188
|
+
terminate_interaction 2
|
189
|
+
end
|
190
|
+
|
191
|
+
def activate!
|
192
|
+
gem(options[:gem_name], options[:version])
|
193
|
+
Gem.finish_resolve
|
194
|
+
|
195
|
+
verbose "activated #{options[:gem_name]} (#{Gem.loaded_specs[options[:gem_name]].version})"
|
196
|
+
end
|
197
|
+
|
198
|
+
def load!
|
199
|
+
argv = ARGV.clone
|
200
|
+
ARGV.replace options[:args]
|
201
|
+
|
202
|
+
exe = executable = options[:executable]
|
203
|
+
|
204
|
+
contains_executable = Gem.loaded_specs.values.select do |spec|
|
205
|
+
spec.executables.include?(executable)
|
206
|
+
end
|
207
|
+
|
208
|
+
if contains_executable.any? {|s| s.name == executable }
|
209
|
+
contains_executable.select! {|s| s.name == executable }
|
210
|
+
end
|
211
|
+
|
212
|
+
if contains_executable.empty?
|
213
|
+
if (spec = Gem.loaded_specs[executable]) && (exe = spec.executable)
|
214
|
+
contains_executable << spec
|
215
|
+
else
|
216
|
+
alert_error "Failed to load executable `#{executable}`," \
|
217
|
+
" are you sure the gem `#{options[:gem_name]}` contains it?"
|
218
|
+
terminate_interaction 1
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
if contains_executable.size > 1
|
223
|
+
alert_error "Ambiguous which gem `#{executable}` should come from: " \
|
224
|
+
"the options are #{contains_executable.map(&:name)}, " \
|
225
|
+
"specify one via `-g`"
|
226
|
+
terminate_interaction 1
|
227
|
+
end
|
228
|
+
|
229
|
+
load Gem.activate_bin_path(contains_executable.first.name, exe, ">= 0.a")
|
230
|
+
ensure
|
231
|
+
ARGV.replace argv
|
232
|
+
end
|
233
|
+
|
234
|
+
def suppress_always_install
|
235
|
+
name = :always_install
|
236
|
+
cls = ::Gem::Resolver::InstallerSet
|
237
|
+
method = cls.instance_method(name)
|
238
|
+
cls.remove_method(name)
|
239
|
+
cls.define_method(name) { [] }
|
240
|
+
|
241
|
+
begin
|
242
|
+
yield
|
243
|
+
ensure
|
244
|
+
cls.remove_method(name)
|
245
|
+
cls.define_method(name, method)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
@@ -3,7 +3,7 @@ require_relative "../command"
|
|
3
3
|
|
4
4
|
class Gem::Commands::HelpCommand < Gem::Command
|
5
5
|
# :stopdoc:
|
6
|
-
EXAMPLES = <<-EOF
|
6
|
+
EXAMPLES = <<-EOF
|
7
7
|
Some examples of 'gem' usage.
|
8
8
|
|
9
9
|
* Install 'rake', either from local directory or remote server:
|
@@ -52,7 +52,7 @@ Some examples of 'gem' usage.
|
|
52
52
|
gem update --system
|
53
53
|
EOF
|
54
54
|
|
55
|
-
GEM_DEPENDENCIES = <<-EOF
|
55
|
+
GEM_DEPENDENCIES = <<-EOF
|
56
56
|
A gem dependencies file allows installation of a consistent set of gems across
|
57
57
|
multiple environments. The RubyGems implementation is designed to be
|
58
58
|
compatible with Bundler's Gemfile format. You can see additional
|
@@ -229,7 +229,7 @@ default. This may be overridden with the :development_group option:
|
|
229
229
|
|
230
230
|
EOF
|
231
231
|
|
232
|
-
PLATFORMS = <<-'EOF'
|
232
|
+
PLATFORMS = <<-'EOF'
|
233
233
|
RubyGems platforms are composed of three parts, a CPU, an OS, and a
|
234
234
|
version. These values are taken from values in rbconfig.rb. You can view
|
235
235
|
your current platform by running `gem environment`.
|
@@ -34,6 +34,11 @@ class Gem::Commands::PristineCommand < Gem::Command
|
|
34
34
|
options[:extensions] = value
|
35
35
|
end
|
36
36
|
|
37
|
+
add_option("--only-missing-extensions",
|
38
|
+
"Only restore gems with missing extensions") do |value, options|
|
39
|
+
options[:only_missing_extensions] = value
|
40
|
+
end
|
41
|
+
|
37
42
|
add_option("--only-executables",
|
38
43
|
"Only restore executables") do |value, options|
|
39
44
|
options[:only_executables] = value
|
@@ -107,6 +112,10 @@ extensions will be restored.
|
|
107
112
|
Gem::Specification.select do |spec|
|
108
113
|
spec.extensions && !spec.extensions.empty?
|
109
114
|
end
|
115
|
+
elsif options[:only_missing_extensions]
|
116
|
+
Gem::Specification.select do |spec|
|
117
|
+
spec.missing_extensions?
|
118
|
+
end
|
110
119
|
else
|
111
120
|
get_all_gem_names.sort.map do |gem_name|
|
112
121
|
Gem::Specification.find_all_by_name(gem_name, options[:version]).reverse
|
@@ -125,6 +125,9 @@ that is a dependency of an existing gem. You can use the
|
|
125
125
|
def execute
|
126
126
|
check_version
|
127
127
|
|
128
|
+
# Consider only gem specifications installed at `--install-dir`
|
129
|
+
Gem::Specification.dirs = options[:install_dir] if options[:install_dir]
|
130
|
+
|
128
131
|
if options[:all] && !options[:args].empty?
|
129
132
|
uninstall_specific
|
130
133
|
elsif options[:all]
|
@@ -37,9 +37,6 @@ module Kernel
|
|
37
37
|
return gem_original_require(path) unless Gem.discover_gems_on_require
|
38
38
|
|
39
39
|
begin
|
40
|
-
if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
|
41
|
-
monitor_owned = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?
|
42
|
-
end
|
43
40
|
RUBYGEMS_ACTIVATION_MONITOR.enter
|
44
41
|
|
45
42
|
path = path.to_path if path.respond_to? :to_path
|
@@ -163,13 +160,6 @@ module Kernel
|
|
163
160
|
end
|
164
161
|
|
165
162
|
raise load_error
|
166
|
-
ensure
|
167
|
-
if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
|
168
|
-
if monitor_owned != (ow = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?)
|
169
|
-
STDERR.puts [$$, Thread.current, $!, $!.backtrace].inspect if $!
|
170
|
-
raise "CRITICAL: RUBYGEMS_ACTIVATION_MONITOR.owned?: before #{monitor_owned} -> after #{ow}"
|
171
|
-
end
|
172
|
-
end
|
173
163
|
end
|
174
164
|
end
|
175
165
|
|
data/lib/rubygems/defaults.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Gem
|
3
|
-
DEFAULT_HOST = "https://rubygems.org"
|
3
|
+
DEFAULT_HOST = "https://rubygems.org"
|
4
4
|
|
5
5
|
@post_install_hooks ||= []
|
6
6
|
@done_installing_hooks ||= []
|
@@ -158,7 +158,7 @@ module Gem
|
|
158
158
|
# The path to standard location of the user's state directory.
|
159
159
|
|
160
160
|
def self.state_home
|
161
|
-
@
|
161
|
+
@state_home ||= (ENV["XDG_STATE_HOME"] || File.join(Gem.user_home, ".local", "state"))
|
162
162
|
end
|
163
163
|
|
164
164
|
##
|
data/lib/rubygems/dependency.rb
CHANGED
data/lib/rubygems/deprecate.rb
CHANGED
@@ -143,7 +143,7 @@ module Gem::Deprecate
|
|
143
143
|
end
|
144
144
|
|
145
145
|
# Deprecation method to deprecate Rubygems commands
|
146
|
-
def rubygems_deprecate_command
|
146
|
+
def rubygems_deprecate_command(version = Gem::Deprecate.next_rubygems_major_version)
|
147
147
|
class_eval do
|
148
148
|
define_method "deprecated?" do
|
149
149
|
true
|
@@ -151,7 +151,7 @@ module Gem::Deprecate
|
|
151
151
|
|
152
152
|
define_method "deprecation_warning" do
|
153
153
|
msg = [ "#{self.command} command is deprecated",
|
154
|
-
". It will be removed in Rubygems #{
|
154
|
+
". It will be removed in Rubygems #{version}.\n",
|
155
155
|
]
|
156
156
|
|
157
157
|
alert_warning "#{msg.join}" unless Gem::Deprecate.skip
|