Merge the master branch of Bundler

This commit is contained in:
Hiroshi SHIBATA 2021-04-15 12:47:04 +09:00
Родитель 0d9496f924
Коммит ed149dbf46
95 изменённых файлов: 1772 добавлений и 579 удалений

Просмотреть файл

@ -197,7 +197,7 @@ module Bundler
def frozen_bundle?
frozen = settings[:deployment]
frozen ||= settings[:frozen] unless feature_flag.deployment_means_frozen?
frozen ||= settings[:frozen]
frozen
end

Просмотреть файл

@ -475,6 +475,12 @@ module Bundler
"do in future versions. Instead please use `bundle config set cache_all true`, " \
"and stop using this flag" if ARGV.include?("--all")
SharedHelpers.major_deprecation 2,
"The `--path` flag is deprecated because its semantics are unclear. " \
"Use `bundle config cache_path` to configure the path of your cache of gems, " \
"and `bundle config path` to configure the path where your gems are installed, " \
"and stop using this flag" if ARGV.include?("--path")
require_relative "cli/cache"
Cache.new(options).run
end
@ -591,6 +597,9 @@ module Bundler
:desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
:desc => "Generate CI configuration, either GitHub Actions, Travis CI, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|travis|gitlab|circle)`"
method_option :linter, :type => :string, :lazy_default => Bundler.settings["gem.linter"] || "",
:desc => "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
method_option :github_username, :type => :string, :default => Bundler.settings["gem.github_username"], :banner => "Set your username on GitHub", :desc => "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
def gem(name)
end

Просмотреть файл

@ -36,10 +36,15 @@ module Bundler
def self.without_groups_message(command)
command_in_past_tense = command == :install ? "installed" : "updated"
groups = Bundler.settings[:without]
"Gems in the #{verbalize_groups(groups)} were not #{command_in_past_tense}."
end
def self.verbalize_groups(groups)
groups.map!{|g| "'#{g}'" }
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
reject {|s| s.to_s.empty? }.join(" and ")
group_str = groups.size == 1 ? "group" : "groups"
"Gems in the #{group_str} #{group_list} were not #{command_in_past_tense}."
"#{group_str} #{group_list}"
end
def self.select_spec(name, regex_match = nil)
@ -53,7 +58,13 @@ module Bundler
case specs.count
when 0
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
dep_in_other_group = Bundler.definition.current_dependencies.find {|dep|dep.name == name }
if dep_in_other_group
raise GemNotFound, "Could not find gem '#{name}', because it's in the #{verbalize_groups(dep_in_other_group.groups)}, configured to be ignored."
else
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
end
when 1
specs.first
else

Просмотреть файл

@ -42,9 +42,17 @@ module Bundler
use_git = Bundler.git_present? && options[:git]
git_author_name = use_git ? `git config user.name`.chomp : ""
github_username = use_git ? `git config github.user`.chomp : ""
git_username = use_git ? `git config github.user`.chomp : ""
git_user_email = use_git ? `git config user.email`.chomp : ""
github_username = if options[:github_username].nil?
git_username
elsif options[:github_username] == false
""
else
options[:github_username]
end
config = {
:name => name,
:underscored_name => underscored_name,
@ -155,15 +163,16 @@ module Bundler
templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
end
if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
"RuboCop is a static code analyzer that has out-of-the-box rules for many " \
"of the guidelines in the community style guide. " \
"For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
"and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
config[:rubocop] = true
config[:rubocop_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
config[:linter] = ask_and_set_linter
case config[:linter]
when "rubocop"
config[:linter_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
Bundler.ui.info "RuboCop enabled in config"
templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
when "standard"
config[:linter_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.2.5" : "1.0"
Bundler.ui.info "Standard enabled in config"
templates.merge!("standard.yml.tt" => ".standard.yml")
end
templates.merge!("exe/newgem.tt" => "exe/#{name}") if config[:exe]
@ -308,6 +317,58 @@ module Bundler
ci_template
end
def ask_and_set_linter
linter_template = options[:linter] || Bundler.settings["gem.linter"]
linter_template = deprecated_rubocop_option if linter_template.nil?
if linter_template.to_s.empty?
Bundler.ui.confirm "Do you want to add a code linter and formatter to your gem? " \
"Supported Linters:\n" \
"* RuboCop: https://rubocop.org\n" \
"* Standard: https://github.com/testdouble/standard\n" \
"\n"
Bundler.ui.info hint_text("linter")
result = Bundler.ui.ask "Enter a linter. rubocop/standard/(none):"
if result =~ /rubocop|standard/
linter_template = result
else
linter_template = false
end
end
if Bundler.settings["gem.linter"].nil?
Bundler.settings.set_global("gem.linter", linter_template)
end
# Once gem.linter safely set, unset the deprecated gem.rubocop
unless Bundler.settings["gem.rubocop"].nil?
Bundler.settings.set_global("gem.rubocop", nil)
end
if options[:linter] == Bundler.settings["gem.linter"]
Bundler.ui.info "#{options[:linter]} is already configured, ignoring --linter flag."
end
linter_template
end
def deprecated_rubocop_option
if !options[:rubocop].nil?
if options[:rubocop]
Bundler::SharedHelpers.major_deprecation 2, "--rubocop is deprecated, use --linter=rubocop"
"rubocop"
else
Bundler::SharedHelpers.major_deprecation 2, "--no-rubocop is deprecated, use --linter"
false
end
elsif !Bundler.settings["gem.rubocop"].nil?
Bundler::SharedHelpers.major_deprecation 2,
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
Bundler.settings["gem.rubocop"] ? "rubocop" : false
end
end
def bundler_dependency_version
v = Gem::Version.new(Bundler::VERSION)
req = v.segments[0..1]

Просмотреть файл

@ -33,12 +33,8 @@ module Bundler
options[:local] = true if Bundler.app_cache.exist?
if Bundler.feature_flag.deployment_means_frozen?
Bundler.settings.set_command_option :deployment, true
else
Bundler.settings.set_command_option :deployment, true if options[:deployment]
Bundler.settings.set_command_option :frozen, true if options[:frozen]
end
Bundler.settings.set_command_option :deployment, true if options[:deployment]
Bundler.settings.set_command_option :frozen, true if options[:frozen]
end
# When install is called with --no-deployment, disable deployment mode

Просмотреть файл

@ -72,7 +72,7 @@ module Bundler
gemfile_specs + dependency_specs
end
specs.sort_by(&:name).each do |current_spec|
specs.sort_by(&:name).uniq(&:name).each do |current_spec|
next unless gems.empty? || gems.include?(current_spec.name)
active_spec = retrieve_active_spec(definition, current_spec)

Просмотреть файл

@ -92,11 +92,11 @@ module Bundler
def checksum_for_file(path)
return nil unless path.file?
# This must use IO.read instead of Digest.file().hexdigest
# This must use File.read instead of Digest.file().hexdigest
# because we need to preserve \n line endings on windows when calculating
# the checksum
SharedHelpers.filesystem_access(path, :read) do
SharedHelpers.digest(:MD5).hexdigest(IO.read(path))
SharedHelpers.digest(:MD5).hexdigest(File.read(path))
end
end
end

Просмотреть файл

@ -111,6 +111,17 @@ module Bundler
@locked_platforms = []
end
@locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
unless @disable_multisource
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch."
Bundler::SharedHelpers.major_deprecation 2, msg
@sources.merged_gem_lockfile_sections!
end
@unlock[:gems] ||= []
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@ -150,6 +161,10 @@ module Bundler
end
end
def disable_multisource?
@disable_multisource
end
def resolve_with_cache!
raise "Specs already loaded" if @specs
sources.cached!
@ -177,10 +192,10 @@ module Bundler
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
"be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
"that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
"to a version other than #{locked_gem} that hasn't been removed in order to install."
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
@ -537,6 +552,9 @@ module Bundler
attr_reader :sources
private :sources
attr_reader :locked_gem_sources
private :locked_gem_sources
def nothing_changed?
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
end
@ -661,10 +679,8 @@ module Bundler
end
def converge_rubygems_sources
return false if Bundler.feature_flag.disable_multisource?
return false if disable_multisource?
# Get the RubyGems sources from the Gemfile.lock
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
return false if locked_gem_sources.empty?
# Get the RubyGems remotes from the Gemfile
@ -950,7 +966,7 @@ module Bundler
end
def additional_base_requirements_for_resolve
return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions?
return [] unless @locked_gems
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
name = locked_spec.name

Просмотреть файл

@ -460,19 +460,16 @@ repo_name ||= user_name
@sources.add_rubygems_remote(source)
end
if Bundler.feature_flag.disable_multisource?
if Bundler.feature_flag.bundler_3_mode?
msg = "This Gemfile contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
"should come from that source. To downgrade this error to a warning, run " \
"`bundle config unset disable_multisource`"
"should come from that source"
raise GemfileEvalError, msg
else
Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
"To upgrade this warning to an error, run `bundle config set --local " \
"disable_multisource true`."
"a block to indicate which gems should come from the secondary source."
end
end

Просмотреть файл

@ -31,11 +31,9 @@ module Bundler
settings_flag(:auto_clean_without_path) { bundler_3_mode? }
settings_flag(:cache_all) { bundler_3_mode? }
settings_flag(:default_install_uses_path) { bundler_3_mode? }
settings_flag(:deployment_means_frozen) { bundler_3_mode? }
settings_flag(:disable_multisource) { bundler_3_mode? }
settings_flag(:forget_cli_options) { bundler_3_mode? }
settings_flag(:global_gem_cache) { bundler_3_mode? }
settings_flag(:only_update_to_newer_versions) { bundler_3_mode? }
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
settings_flag(:print_only_version_number) { bundler_3_mode? }

Просмотреть файл

@ -47,6 +47,11 @@ module Bundler
built_gem_path = build_gem
end
desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
task "build:checksum" => "build" do
build_checksum(built_gem_path)
end
desc "Build and install #{name}-#{version}.gem into system gems."
task "install" => "build" do
install_gem(built_gem_path)
@ -100,6 +105,17 @@ module Bundler
Bundler.ui.confirm "#{name} (#{version}) installed."
end
def build_checksum(built_gem_path = nil)
built_gem_path ||= build_gem
SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) }
file_name = "#{File.basename(built_gem_path)}.sha512"
require "digest/sha2"
checksum = Digest::SHA512.new.hexdigest(built_gem_path.to_s)
target = File.join(base, "checksums", file_name)
File.write(target, checksum)
Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}."
end
protected
def rubygem_push(path)

Просмотреть файл

@ -128,7 +128,7 @@ module Bundler
# evaluates a gemfile to remove the specified gem
# from it.
def remove_deps(gemfile_path)
initial_gemfile = IO.readlines(gemfile_path)
initial_gemfile = File.readlines(gemfile_path)
Bundler.ui.info "Removing gems from #{gemfile_path}"
@ -181,7 +181,7 @@ module Bundler
patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
new_gemfile = []
multiline_removal = false
IO.readlines(gemfile_path).each do |line|
File.readlines(gemfile_path).each do |line|
match_data = line.match(patterns)
if match_data && is_not_within_comment?(line, match_data)
multiline_removal = line.rstrip.end_with?(",")

Просмотреть файл

@ -52,7 +52,7 @@ def gemfile(install = false, options = {}, &gemfile)
builder.instance_eval(&gemfile)
builder.check_primary_source_safety
Bundler.settings.temporary(:frozen => false) do
Bundler.settings.temporary(:deployment => false, :frozen => false) do
definition = builder.to_definition(nil, true)
def definition.lock(*); end
definition.validate_runtime!

Просмотреть файл

@ -6,10 +6,11 @@ require_relative "gem_installer"
module Bundler
class ParallelInstaller
class SpecInstallation
attr_accessor :spec, :name, :post_install_message, :state, :error
attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
def initialize(spec)
@spec = spec
@name = spec.name
@full_name = spec.full_name
@state = :none
@post_install_message = ""
@error = nil
@ -27,13 +28,8 @@ module Bundler
state == :failed
end
def installation_attempted?
installed? || failed?
end
# Only true when spec in neither installed nor already enqueued
def ready_to_enqueue?
!enqueued? && !installation_attempted?
state == :none
end
def has_post_install_message?
@ -54,14 +50,11 @@ module Bundler
# Represents only the non-development dependencies, the ones that are
# itself and are in the total list.
def dependencies
@dependencies ||= begin
all_dependencies.reject {|dep| ignorable_dependency? dep }
end
@dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
end
def missing_lockfile_dependencies(all_spec_names)
deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
deps.reject {|dep| all_spec_names.include? dep.name }
dependencies.reject {|dep| all_spec_names.include? dep.name }
end
# Represents all dependencies
@ -70,7 +63,7 @@ module Bundler
end
def to_s
"#<#{self.class} #{@spec.full_name} (#{state})>"
"#<#{self.class} #{full_name} (#{state})>"
end
end
@ -93,18 +86,48 @@ module Bundler
def call
check_for_corrupt_lockfile
if @rake
do_install(@rake, 0)
Gem::Specification.reset
end
if @size > 1
install_with_worker
else
install_serially
end
check_for_unmet_dependencies
handle_error if failed_specs.any?
@specs
ensure
worker_pool && worker_pool.stop
end
def check_for_unmet_dependencies
unmet_dependencies = @specs.map do |s|
[
s,
s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
]
end.reject {|a| a.last.empty? }
return if unmet_dependencies.empty?
warning = []
warning << "Your lockfile doesn't include a valid resolution."
warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies."
warning << "The unmet dependencies are:"
unmet_dependencies.each do |spec, unmet_spec_dependencies|
unmet_spec_dependencies.each do |unmet_spec_dependency|
warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}"
end
end
Bundler.ui.warn(warning.join("\n"))
end
def check_for_corrupt_lockfile
missing_dependencies = @specs.map do |s|
[
@ -217,8 +240,6 @@ module Bundler
# are installed.
def enqueue_specs
@specs.select(&:ready_to_enqueue?).each do |spec|
next if @rake && !@rake.installed? && spec.name != @rake.name
if spec.dependencies_installed? @specs
spec.state = :enqueued
worker_pool.enq spec

Просмотреть файл

@ -73,7 +73,12 @@ module Bundler
same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object)
end
search = same_platform_candidates.last || candidates.last
installable_candidates = same_platform_candidates.select do |spec|
!spec.is_a?(EndpointSpecification) ||
(spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
end
search = installable_candidates.last || same_platform_candidates.last
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
search
end

Просмотреть файл

@ -131,18 +131,8 @@ module Bundler
@sources << @current_source
end
when GEM
source_remotes = Array(@opts["remote"])
if source_remotes.size == 1
@opts["remotes"] = @opts.delete("remote")
@current_source = TYPES[@type].from_lock(@opts)
else
source_remotes.each do |url|
rubygems_aggregate.add_remote(url)
end
@current_source = rubygems_aggregate
end
@opts["remotes"] = Array(@opts.delete("remote")).reverse
@current_source = TYPES[@type].from_lock(@opts)
@sources << @current_source
when PLUGIN
@current_source = Plugin.source_from_lock(@opts)
@ -245,9 +235,5 @@ module Bundler
def parse_ruby(line)
@ruby_version = line.strip
end
def rubygems_aggregate
@rubygems_aggregate ||= Source::Rubygems.new
end
end
end

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-ADD" "1" "January 2021" "" ""
.TH "BUNDLE\-ADD" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-BINSTUBS" "1" "January 2021" "" ""
.TH "BUNDLE\-BINSTUBS" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CACHE" "1" "January 2021" "" ""
.TH "BUNDLE\-CACHE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CHECK" "1" "January 2021" "" ""
.TH "BUNDLE\-CHECK" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CLEAN" "1" "January 2021" "" ""
.TH "BUNDLE\-CLEAN" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-CONFIG" "1" "January 2021" "" ""
.TH "BUNDLE\-CONFIG" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
@ -199,6 +199,9 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow changes to the \fBGemfile\fR\. When the \fBGemfile\fR is changed and the lockfile has not been updated, running Bundler commands will be blocked\. Defaults to \fBtrue\fR when \fB\-\-deployment\fR is used\.
.
.IP "\(bu" 4
\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in \fBREADME\fR file when you create a new gem via \fBbundle gem\fR command\. It can be overriden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\.
.
.IP "\(bu" 4
\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\.
.
.IP "\(bu" 4
@ -223,9 +226,6 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
.
.IP "\(bu" 4
\fBonly_update_to_newer_versions\fR (\fBBUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS\fR): During \fBbundle update\fR, only resolve to newer versions of the gems in the lockfile\.
.
.IP "\(bu" 4
\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. Defaults to \fBGem\.dir\fR\. When \-\-deployment is used, defaults to vendor/bundle\.
.
.IP "\(bu" 4

Просмотреть файл

@ -194,6 +194,10 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the
lockfile has not been updated, running Bundler commands will be blocked.
Defaults to `true` when `--deployment` is used.
* `gem.github_username` (`BUNDLE_GEM__GITHUB_USERNAME`):
Sets a GitHub username or organization to be used in `README` file when you
create a new gem via `bundle gem` command. It can be overriden by passing an
explicit `--github-username` flag to `bundle gem`.
* `gem.push_key` (`BUNDLE_GEM__PUSH_KEY`):
Sets the `--key` parameter for `gem push` when using the `rake release`
command with a private gemstash server.
@ -218,9 +222,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
Whether `bundle package` should skip installing gems.
* `no_prune` (`BUNDLE_NO_PRUNE`):
Whether Bundler should leave outdated gems unpruned when caching.
* `only_update_to_newer_versions` (`BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS`):
During `bundle update`, only resolve to newer versions of the gems in the
lockfile.
* `path` (`BUNDLE_PATH`):
The location on disk where all gems in your bundle will be located regardless
of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-DOCTOR" "1" "January 2021" "" ""
.TH "BUNDLE\-DOCTOR" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-EXEC" "1" "January 2021" "" ""
.TH "BUNDLE\-EXEC" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-GEM" "1" "January 2021" "" ""
.TH "BUNDLE\-GEM" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
@ -90,6 +90,19 @@ When Bundler is configured to not generate CI files, an interactive prompt will
When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
.
.TP
\fB\-\-linter\fR, \fB\-\-linter=rubocop\fR, \fB\-\-linter=standard\fR
Specify the linter and code formatter that Bundler should add to the project\'s development dependencies\. Acceptable values are \fBrubocop\fR and \fBstandard\fR\. A configuration file will be generated in the project directory\. Given no option is specified:
.
.IP
When Bundler is configured to add a linter, this defaults to Bundler\'s global config setting \fBgem\.linter\fR\.
.
.IP
When Bundler is configured not to add a linter, an interactive prompt will be displayed and the answer will be used for the current rubygem project\.
.
.IP
When Bundler is unconfigured, an interactive prompt will be displayed and the answer will be saved in Bundler\'s global config for future \fBbundle gem\fR use\.
.
.TP
\fB\-e\fR, \fB\-\-edit[=EDITOR]\fR
Open the resulting GEM_NAME\.gemspec in EDITOR, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\.
.

Просмотреть файл

@ -92,6 +92,22 @@ configuration file using the following names:
the answer will be saved in Bundler's global config for future `bundle gem`
use.
* `--linter`, `--linter=rubocop`, `--linter=standard`:
Specify the linter and code formatter that Bundler should add to the
project's development dependencies. Acceptable values are `rubocop` and
`standard`. A configuration file will be generated in the project directory.
Given no option is specified:
When Bundler is configured to add a linter, this defaults to Bundler's
global config setting `gem.linter`.
When Bundler is configured not to add a linter, an interactive prompt
will be displayed and the answer will be used for the current rubygem project.
When Bundler is unconfigured, an interactive prompt will be displayed and
the answer will be saved in Bundler's global config for future `bundle gem`
use.
* `-e`, `--edit[=EDITOR]`:
Open the resulting GEM_NAME.gemspec in EDITOR, or the default editor if not
specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`.

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INFO" "1" "January 2021" "" ""
.TH "BUNDLE\-INFO" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INIT" "1" "January 2021" "" ""
.TH "BUNDLE\-INIT" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INJECT" "1" "January 2021" "" ""
.TH "BUNDLE\-INJECT" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-INSTALL" "1" "January 2021" "" ""
.TH "BUNDLE\-INSTALL" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-LIST" "1" "January 2021" "" ""
.TH "BUNDLE\-LIST" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-LOCK" "1" "January 2021" "" ""
.TH "BUNDLE\-LOCK" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-OPEN" "1" "January 2021" "" ""
.TH "BUNDLE\-OPEN" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-OUTDATED" "1" "January 2021" "" ""
.TH "BUNDLE\-OUTDATED" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-PLATFORM" "1" "January 2021" "" ""
.TH "BUNDLE\-PLATFORM" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-PRISTINE" "1" "January 2021" "" ""
.TH "BUNDLE\-PRISTINE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-REMOVE" "1" "January 2021" "" ""
.TH "BUNDLE\-REMOVE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-SHOW" "1" "January 2021" "" ""
.TH "BUNDLE\-SHOW" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-UPDATE" "1" "January 2021" "" ""
.TH "BUNDLE\-UPDATE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE\-VIZ" "1" "January 2021" "" ""
.TH "BUNDLE\-VIZ" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BUNDLE" "1" "January 2021" "" ""
.TH "BUNDLE" "1" "April 2021" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management

Просмотреть файл

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GEMFILE" "5" "January 2021" "" ""
.TH "GEMFILE" "5" "April 2021" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs

Просмотреть файл

@ -140,6 +140,13 @@ module Bundler
end
end
# Set internal representation to fetch the gems/specs locally.
#
# When this is called, the source should try to fetch the specs and
# install from the local system.
def local!
end
# Set internal representation to fetch the gems/specs from remote.
#
# When this is called, the source should try to fetch the specs and

Просмотреть файл

@ -15,7 +15,6 @@ module Bundler
cache_all_platforms
default_install_uses_path
deployment
deployment_means_frozen
disable_checksum_validation
disable_exec_load
disable_local_branch_check
@ -33,7 +32,6 @@ module Bundler
init_gems_rb
no_install
no_prune
only_update_to_newer_versions
path_relative_to_cwd
path.system
plugins

Просмотреть файл

@ -33,6 +33,12 @@ module Bundler
spec.source == self
end
def local!; end
def cached!; end
def remote!; end
# it's possible that gems from one source depend on gems from some
# other source, so now we download gemspecs and iterate over those
# dependencies, looking for gems we don't have info on yet.

Просмотреть файл

@ -33,10 +33,6 @@ module Bundler
end
end
def cached!; end
def remote!; end
def options
{}
end

Просмотреть файл

@ -82,7 +82,9 @@ module Bundler
end
def install(spec, options = {})
print_using_message "Using #{version_message(spec)} from #{self}"
using_message = "Using #{version_message(spec)} from #{self}"
using_message += " and installing its executables" unless spec.executables.empty?
print_using_message using_message
generate_bin(spec, :disable_extensions => true)
nil # no post-install message
end

Просмотреть файл

@ -35,7 +35,7 @@ module Bundler
run_hooks(:post_build)
end
generate_bin unless spec.executables.nil? || spec.executables.empty?
generate_bin unless spec.executables.empty?
run_hooks(:post_install)
ensure

Просмотреть файл

@ -20,17 +20,29 @@ module Bundler
@dependency_names = []
@allow_remote = false
@allow_cached = false
@allow_local = options["allow_local"] || false
@caches = [cache_path, *Bundler.rubygems.gem_cache]
Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
Array(options["remotes"]).reverse_each {|r| add_remote(r) }
end
def local!
return if @allow_local
@specs = nil
@allow_local = true
end
def remote!
return if @allow_remote
@specs = nil
@allow_remote = true
end
def cached!
return if @allow_cached
@specs = nil
@allow_cached = true
end
@ -49,8 +61,12 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
def disable_multisource?
@remotes.size <= 1
end
def can_lock?(spec)
return super if Bundler.feature_flag.disable_multisource?
return super if disable_multisource?
spec.source.is_a?(Rubygems)
end
@ -87,7 +103,7 @@ module Bundler
# small_idx.use large_idx.
idx = @allow_remote ? remote_specs.dup : Index.new
idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
idx.use(installed_specs, :override_dupes)
idx.use(installed_specs, :override_dupes) if @allow_local
idx
end
end
@ -365,7 +381,7 @@ module Bundler
def cached_specs
@cached_specs ||= begin
idx = installed_specs.dup
idx = @allow_local ? installed_specs.dup : Index.new
Dir["#{cache_path}/*.gem"].each do |gemfile|
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/

Просмотреть файл

@ -9,7 +9,7 @@ module Bundler
:metadata_source
def global_rubygems_source
@global_rubygems_source ||= rubygems_aggregate_class.new
@global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
end
def initialize
@ -20,6 +20,16 @@ module Bundler
@global_path_source = nil
@rubygems_sources = []
@metadata_source = Source::Metadata.new
@disable_multisource = true
end
def disable_multisource?
@disable_multisource
end
def merged_gem_lockfile_sections!
@disable_multisource = false
end
def add_path_source(options = {})
@ -47,7 +57,7 @@ module Bundler
end
def global_rubygems_source=(uri)
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
end
def add_rubygems_remote(uri)
@ -77,8 +87,8 @@ module Bundler
def lock_sources
lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
if Bundler.feature_flag.disable_multisource?
lock_sources + rubygems_sources.sort_by(&:to_s)
if disable_multisource?
lock_sources + rubygems_sources.sort_by(&:to_s).uniq
else
lock_sources << combine_rubygems_sources
end
@ -94,7 +104,7 @@ module Bundler
end
end
replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
replacement_rubygems = !disable_multisource? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@global_rubygems_source = replacement_rubygems if replacement_rubygems

Просмотреть файл

@ -82,6 +82,7 @@ module Bundler
materialized.map! do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
s.source.local!
spec = s.__materialize__
unless spec
unless missing_specs
@ -102,6 +103,7 @@ module Bundler
@specs.map do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
s.source.local!
s.source.remote!
spec = s.__materialize__
raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec

Просмотреть файл

@ -2,6 +2,6 @@
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# gem "rails"

Просмотреть файл

@ -3,6 +3,6 @@
# A sample gems.rb
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
# gem "rails"

Просмотреть файл

@ -14,7 +14,10 @@ gem "rake-compiler"
gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
<%- end -%>
<%- if config[:rubocop] -%>
<%- if config[:linter] == "rubocop" -%>
gem "rubocop", "~> <%= config[:rubocop_version] %>"
gem "rubocop", "~> <%= config[:linter_version] %>"
<%- elsif config[:linter] == "standard" -%>
gem "standard", "~> <%= config[:linter_version] %>"
<%- end -%>

Просмотреть файл

@ -27,12 +27,16 @@ require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)
<% end -%>
<% if config[:rubocop] -%>
<% if config[:linter] == "rubocop" -%>
<% default_task_names << :rubocop -%>
require "rubocop/rake_task"
RuboCop::RakeTask.new
<% elsif config[:linter] == "standard" -%>
<% default_task_names << :standard -%>
require "standard/rake"
<% end -%>
<% if config[:ext] -%>
<% default_task_names.unshift(:clobber, :compile) -%>

Просмотреть файл

@ -11,8 +11,6 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: <%= RUBY_VERSION %>
bundler-cache: true
- name: Run the default task
run: |
gem install bundler -v <%= Bundler::VERSION %>
bundle install
bundle exec rake
run: bundle exec rake

Просмотреть файл

@ -3,16 +3,16 @@
require_relative "lib/<%=config[:namespaced_path]%>/version"
Gem::Specification.new do |spec|
spec.name = <%= config[:name].inspect %>
spec.version = <%= config[:constant_name] %>::VERSION
spec.authors = [<%= config[:author].inspect %>]
spec.email = [<%= config[:email].inspect %>]
spec.name = <%= config[:name].inspect %>
spec.version = <%= config[:constant_name] %>::VERSION
spec.authors = [<%= config[:author].inspect %>]
spec.email = [<%= config[:email].inspect %>]
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
spec.description = "TODO: Write a longer description or delete this line."
spec.homepage = "TODO: Put your gem's website or public repo URL here."
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
spec.description = "TODO: Write a longer description or delete this line."
spec.homepage = "TODO: Put your gem's website or public repo URL here."
<%- if config[:mit] -%>
spec.license = "MIT"
spec.license = "MIT"
<%- end -%>
spec.required_ruby_version = Gem::Requirement.new(">= <%= config[:required_ruby_version] %>")
@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
end
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
<%- if config[:ext] -%>
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
<%- end -%>
# Uncomment to register a new dependency of your gem

Просмотреть файл

@ -0,0 +1,4 @@
# For available configuration options, see:
# https://github.com/testdouble/standard
default_ignores: false

2
lib/bundler/vendor/tmpdir/lib/tmpdir.rb поставляемый
Просмотреть файл

@ -115,7 +115,7 @@ class Bundler::Dir < Dir
Bundler::Dir.tmpdir
end
UNUSABLE_CHARS = [File::SEPARATOR, File::ALT_SEPARATOR, File::PATH_SEPARATOR, ":"].uniq.join("").freeze
UNUSABLE_CHARS = "^,-.0-9A-Z_a-z~"
class << (RANDOM = Random.new)
MAX = 36**6 # < 0x100000000

Просмотреть файл

@ -22,7 +22,7 @@ RSpec.describe Bundler::DepProxy do
end
describe "frozen" do
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.5.0")
if Gem.ruby_version >= Gem::Version.new("2.5.0")
error = Object.const_get("FrozenError")
else
error = RuntimeError

Просмотреть файл

@ -9,7 +9,7 @@ RSpec.describe Bundler::GemHelper do
let(:app_gemspec_path) { app_path.join("#{app_name}.gemspec") }
before(:each) do
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
"BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
bundle "gem #{app_name}"
prepare_gemspec(app_gemspec_path)
@ -61,10 +61,16 @@ RSpec.describe Bundler::GemHelper do
mock_confirm_message message
end
def mock_checksum_message(name, version)
message = "#{name} #{version} checksum written to checksums/#{name}-#{version}.gem.sha512."
mock_confirm_message message
end
subject! { Bundler::GemHelper.new(app_path) }
let(:app_version) { "0.1.0" }
let(:app_gem_dir) { app_path.join("pkg") }
let(:app_gem_path) { app_gem_dir.join("#{app_name}-#{app_version}.gem") }
let(:app_sha_path) { app_path.join("checksums", "#{app_name}-#{app_version}.gem.sha512") }
let(:app_gemspec_content) { File.read(app_gemspec_path) }
before(:each) do
@ -162,6 +168,37 @@ RSpec.describe Bundler::GemHelper do
end
end
describe "#build_checksum" do
context "when build was successful" do
it "creates .sha512 file" do
mock_build_message app_name, app_version
mock_checksum_message app_name, app_version
subject.build_checksum
expect(app_sha_path).to exist
end
end
context "when building in the current working directory" do
it "creates a .sha512 file" do
mock_build_message app_name, app_version
mock_checksum_message app_name, app_version
Dir.chdir app_path do
Bundler::GemHelper.new.build_checksum
end
expect(app_sha_path).to exist
end
end
context "when building in a location relative to the current working directory" do
it "creates a .sha512 file" do
mock_build_message app_name, app_version
mock_checksum_message app_name, app_version
Dir.chdir File.dirname(app_path) do
Bundler::GemHelper.new(File.basename(app_path)).build_checksum
end
expect(app_sha_path).to exist
end
end
end
describe "#install_gem" do
context "when installation was successful" do
it "gem is installed" do

Просмотреть файл

@ -44,4 +44,37 @@ The missing gems are:
end
end
end
context "when the spec set is not a valid resolution" do
let(:all_specs) do
[
build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
build_spec("diff-lcs", "1.4.4"),
].flatten
end
it "prints a warning" do
expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
Your lockfile doesn't include a valid resolution.
You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies.
The unmet dependencies are:
* diff-lcs (< 1.4), depended upon cucumber-4.1.0, unsatisfied by diff-lcs-1.4.4
W
subject.check_for_unmet_dependencies
end
end
context "when the spec set is a valid resolution" do
let(:all_specs) do
[
build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
build_spec("diff-lcs", "1.3"),
].flatten
end
it "doesn't print a warning" do
expect(Bundler.ui).not_to receive(:warn)
subject.check_for_unmet_dependencies
end
end
end

Просмотреть файл

@ -8,6 +8,10 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
def a_spec.name
"I like tests"
end
def a_spec.full_name
"I really like tests"
end
a_spec
end

Просмотреть файл

@ -372,26 +372,7 @@ RSpec.describe Bundler::SourceList do
source_list.add_git_source("uri" => "git://first-git.org/path.git")
end
it "combines the rubygems sources into a single instance, removing duplicate remotes from the end", :bundler => "< 3" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://third-git.org/path.git"),
ASourcePlugin.new("uri" => "https://second-plugin.org/random"),
ASourcePlugin.new("uri" => "https://third-bar.org/foo"),
Bundler::Source::Path.new("path" => "/first/path/to/gem"),
Bundler::Source::Path.new("path" => "/second/path/to/gem"),
Bundler::Source::Path.new("path" => "/third/path/to/gem"),
Bundler::Source::Rubygems.new("remotes" => [
"https://duplicate-rubygems.org",
"https://first-rubygems.org",
"https://second-rubygems.org",
"https://third-rubygems.org",
]),
]
end
it "returns all sources, without combining rubygems sources", :bundler => "3" do
it "returns all sources, without combining rubygems sources" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),

Просмотреть файл

@ -182,4 +182,18 @@ RSpec.describe "bundle info" do
expect(err).to include("Could not find gem '#{invalid_regexp}'.")
end
end
context "with without configured" do
it "does not find the gem, but gives a helpful error" do
bundle "config without test"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rails", group: :test
G
bundle "info rails", :raise_on_error => false
expect(err).to include("Could not find gem 'rails', because it's in the group 'test', configured to be ignored.")
end
end
end

Просмотреть файл

@ -86,7 +86,7 @@ RSpec.describe "bundle lock" do
it "does not fetch remote specs when using the --local option" do
bundle "lock --update --local", :raise_on_error => false
expect(err).to match(/sources listed in your Gemfile|installed locally/)
expect(err).to match(/installed locally/)
end
it "works with --gemfile flag" do

Просмотреть файл

@ -12,15 +12,16 @@ RSpec.describe "bundle gem" do
def bundle_exec_rubocop
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
rubocop_version = RUBY_VERSION > "2.4" ? "1.7.0" : "0.81.0"
gems = ["minitest", "rake", "rake-compiler", "rspec", "rubocop -v #{rubocop_version}", "test-unit"]
gems.unshift "parallel -v 1.19.2" if RUBY_VERSION < "2.5"
gems += ["rubocop-ast -v 1.4.0"] if rubocop_version == "1.7.0"
path = Bundler.feature_flag.default_install_uses_path? ? local_gem_path(:base => bundled_app(gem_name)) : system_gem_path
realworld_system_gems gems, :path => path
bundle "config set path #{rubocop_gems}", :dir => bundled_app(gem_name)
bundle "exec rubocop --debug --config .rubocop.yml", :dir => bundled_app(gem_name)
end
def bundle_exec_standardrb
prepare_gemspec(bundled_app(gem_name, "#{gem_name}.gemspec"))
bundle "config set path #{standard_gems}", :dir => bundled_app(gem_name)
bundle "exec standardrb --debug", :dir => bundled_app(gem_name)
end
let(:generated_gemspec) { Bundler.load_gemspec_uncached(bundled_app(gem_name).join("#{gem_name}.gemspec")) }
let(:gem_name) { "mygem" }
@ -102,7 +103,7 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
it "generates the README with a section for the Code of Conduct, respecting the configured git default branch" do
it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", :git => ">= 2.28.0" do
sys_exec("git config --global init.defaultBranch main")
bundle "gem #{gem_name} --coc"
@ -147,8 +148,68 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--rubocop flag" do
context "is deprecated", :bundler => "< 3" do
before do
bundle "gem #{gem_name} --rubocop"
end
it "generates a gem skeleton with rubocop" do
gem_skeleton_assertions
expect(bundled_app("test-gem/Rakefile")).to read_as(
include("# frozen_string_literal: true").
and(include('require "rubocop/rake_task"').
and(include("RuboCop::RakeTask.new").
and(match(/default:.+:rubocop/))))
)
end
it "includes rubocop in generated Gemfile" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
builder = Bundler::Dsl.new
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
builder.dependencies
rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
expect(rubocop_dep).not_to be_nil
end
it "generates a default .rubocop.yml" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
end
end
shared_examples_for "--no-rubocop flag" do
context "is deprecated", :bundler => "< 3" do
define_negated_matcher :exclude, :include
before do
bundle "gem #{gem_name} --no-rubocop"
end
it "generates a gem skeleton without rubocop" do
gem_skeleton_assertions
expect(bundled_app("test-gem/Rakefile")).to read_as(exclude("rubocop"))
expect(bundled_app("test-gem/#{gem_name}.gemspec")).to read_as(exclude("rubocop"))
end
it "does not include rubocop in generated Gemfile" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
builder = Bundler::Dsl.new
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
builder.dependencies
rubocop_dep = builder.dependencies.find {|d| d.name == "rubocop" }
expect(rubocop_dep).to be_nil
end
it "doesn't generate a default .rubocop.yml" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
end
end
end
shared_examples_for "--linter=rubocop flag" do
before do
bundle "gem #{gem_name} --rubocop"
bundle "gem #{gem_name} --linter=rubocop"
end
it "generates a gem skeleton with rubocop" do
@ -175,11 +236,38 @@ RSpec.describe "bundle gem" do
end
end
shared_examples_for "--no-rubocop flag" do
shared_examples_for "--linter=standard flag" do
before do
bundle "gem #{gem_name} --linter=standard"
end
it "generates a gem skeleton with standard" do
gem_skeleton_assertions
expect(bundled_app("test-gem/Rakefile")).to read_as(
include('require "standard/rake"').
and(match(/default:.+:standard/))
)
end
it "includes standard in generated Gemfile" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
builder = Bundler::Dsl.new
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
builder.dependencies
standard_dep = builder.dependencies.find {|d| d.name == "standard" }
expect(standard_dep).not_to be_nil
end
it "generates a default .standard.yml" do
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
end
end
shared_examples_for "--linter=none flag" do
define_negated_matcher :exclude, :include
before do
bundle "gem #{gem_name} --no-rubocop"
bundle "gem #{gem_name} --linter=none"
end
it "generates a gem skeleton without rubocop" do
@ -197,46 +285,66 @@ RSpec.describe "bundle gem" do
expect(rubocop_dep).to be_nil
end
it "does not include standard in generated Gemfile" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
builder = Bundler::Dsl.new
builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile"))
builder.dependencies
standard_dep = builder.dependencies.find {|d| d.name == "standard" }
expect(standard_dep).to be_nil
end
it "doesn't generate a default .rubocop.yml" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
end
it "doesn't generate a default .standard.yml" do
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
end
it "has no rubocop offenses when using --rubocop flag", :readline do
it "has no rubocop offenses when using --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --rubocop"
bundle "gem #{gem_name} --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
it "has no rubocop offenses when using --ext and --rubocop flag", :readline do
it "has no rubocop offenses when using --ext and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext --rubocop"
bundle "gem #{gem_name} --ext --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
it "has no rubocop offenses when using --ext, --test=minitest, and --rubocop flag", :readline do
it "has no rubocop offenses when using --ext, --test=minitest, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext --test=minitest --rubocop"
bundle "gem #{gem_name} --ext --test=minitest --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
it "has no rubocop offenses when using --ext, --test=rspec, and --rubocop flag", :readline do
it "has no rubocop offenses when using --ext, --test=rspec, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext --test=rspec --rubocop"
bundle "gem #{gem_name} --ext --test=rspec --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
it "has no rubocop offenses when using --ext, --ext=test-unit, and --rubocop flag", :readline do
it "has no rubocop offenses when using --ext, --ext=test-unit, and --linter=rubocop flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext --test=test-unit --rubocop"
bundle "gem #{gem_name} --ext --test=test-unit --linter=rubocop"
bundle_exec_rubocop
expect(err).to be_empty
end
it "has no standard offenses when using --linter=standard flag", :readline do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --linter=standard"
bundle_exec_standardrb
expect(err).to be_empty
end
shared_examples_for "CI config is absent" do
it "does not create any CI files" do
expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist
@ -351,6 +459,55 @@ RSpec.describe "bundle gem" do
end
end
shared_examples_for "--github-username option" do |github_username|
before do
bundle "gem #{gem_name} --github-username=#{github_username}"
end
it "generates a gem skeleton" do
gem_skeleton_assertions
end
it "contribute URL set to given github username" do
expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/#{github_username}")
end
end
shared_examples_for "github_username configuration" do
context "with github_username setting set to some value" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
bundle "gem #{gem_name}"
end
it "generates a gem skeleton" do
gem_skeleton_assertions
end
it "contribute URL set to bundle config setting" do
expect(bundled_app("#{gem_name}/README.md").read).not_to include("[USERNAME]")
expect(bundled_app("#{gem_name}/README.md").read).to include("github.com/different_username")
end
end
context "with github_username setting set to false" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
bundle "gem #{gem_name}"
end
it "generates a gem skeleton" do
gem_skeleton_assertions
end
it "contribute URL set to [USERNAME]" do
expect(bundled_app("#{gem_name}/README.md").read).to include("[USERNAME]")
expect(bundled_app("#{gem_name}/README.md").read).not_to include("github.com/bundleuser")
end
end
end
shared_examples_for "generating a gem" do
it "generates a gem skeleton" do
bundle "gem #{gem_name}"
@ -841,6 +998,127 @@ RSpec.describe "bundle gem" do
end
end
context "--linter with no argument" do
it "does not generate any linter config" do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
end
context "--linter set to rubocop" do
it "generates a RuboCop config" do
bundle "gem #{gem_name} --linter=rubocop"
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
end
context "--linter set to standard" do
it "generates a Standard config" do
bundle "gem #{gem_name} --linter=standard"
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
end
end
context "gem.linter setting set to none" do
it "doesn't generate any linter config" do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist
expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist
end
end
context "gem.linter setting set to rubocop" do
it "generates a RuboCop config file" do
bundle "config set gem.linter rubocop"
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
end
context "gem.linter setting set to standard" do
it "generates a Standard config file" do
bundle "config set gem.linter standard"
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.standard.yml")).to exist
end
end
context "gem.rubocop setting set to true", :bundler => "< 3" do
before do
bundle "config set gem.rubocop true"
bundle "gem #{gem_name}"
end
it "generates rubocop config" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
it "unsets gem.rubocop" do
bundle "config gem.rubocop"
expect(out).to include("You have not configured a value for `gem.rubocop`")
end
it "sets gem.linter=rubocop instead" do
bundle "config gem.linter"
expect(out).to match(/Set for the current user .*: "rubocop"/)
end
end
context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
before do
bundle "config set gem.linter rubocop"
bundle "gem #{gem_name} --linter"
end
it "generates a RuboCop config file" do
expect(bundled_app("#{gem_name}/.rubocop.yml")).to exist
end
it "hints that --linter is already configured" do
expect(out).to match("rubocop is already configured, ignoring --linter flag.")
end
end
context "gem.linter setting set to false and --linter with no arguments", :hint_text do
before do
bundle "config set gem.linter false"
bundle "gem #{gem_name} --linter"
end
it "asks to setup a linter" do
expect(out).to match("Do you want to add a code linter and formatter to your gem?")
end
it "hints that the choice will only be applied to the current gem" do
expect(out).to match("Your choice will only be applied to this gem.")
end
end
context "gem.linter setting not set and --linter with no arguments", :hint_text do
before do
bundle "gem #{gem_name} --linter"
end
it "asks to setup a linter" do
expect(out).to match("Do you want to add a code linter and formatter to your gem?")
end
it "hints that the choice will be applied to future bundle gem calls" do
hint = "Future `bundle gem` calls will use your choice. " \
"This setting can be changed anytime with `bundle config gem.linter`."
expect(out).to match(hint)
end
end
context "--edit option" do
it "opens the generated gemspec in the user's text editor" do
output = bundle "gem #{gem_name} --edit=echo"
@ -891,6 +1169,9 @@ RSpec.describe "bundle gem" do
before do
global_config "BUNDLE_GEM__RUBOCOP" => "true"
end
it_behaves_like "--linter=rubocop flag"
it_behaves_like "--linter=standard flag"
it_behaves_like "--linter=none flag"
it_behaves_like "--rubocop flag"
it_behaves_like "--no-rubocop flag"
end
@ -899,10 +1180,40 @@ RSpec.describe "bundle gem" do
before do
global_config "BUNDLE_GEM__RUBOCOP" => "false"
end
it_behaves_like "--linter=rubocop flag"
it_behaves_like "--linter=standard flag"
it_behaves_like "--linter=none flag"
it_behaves_like "--rubocop flag"
it_behaves_like "--no-rubocop flag"
end
context "with linter option in bundle config settings set to rubocop" do
before do
global_config "BUNDLE_GEM__LINTER" => "rubocop"
end
it_behaves_like "--linter=rubocop flag"
it_behaves_like "--linter=standard flag"
it_behaves_like "--linter=none flag"
end
context "with linter option in bundle config settings set to standard" do
before do
global_config "BUNDLE_GEM__LINTER" => "standard"
end
it_behaves_like "--linter=rubocop flag"
it_behaves_like "--linter=standard flag"
it_behaves_like "--linter=none flag"
end
context "with linter option in bundle config settings set to false" do
before do
global_config "BUNDLE_GEM__LINTER" => "false"
end
it_behaves_like "--linter=rubocop flag"
it_behaves_like "--linter=standard flag"
it_behaves_like "--linter=none flag"
end
context "with changelog option in bundle config settings set to true" do
before do
global_config "BUNDLE_GEM__CHANGELOG" => "true"
@ -920,6 +1231,57 @@ RSpec.describe "bundle gem" do
end
end
context "testing --github-username option against git and bundle config settings", :readline do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
end
context "with github-username option in bundle config settings set to some value" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
end
it_behaves_like "--github-username option", "gh_user"
end
context "with github-username option in bundle config settings set to false" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
end
it_behaves_like "--github-username option", "gh_user"
end
end
context "with git config set" do
context "with github-username option in bundle config settings set to some value" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "different_username"
end
it_behaves_like "--github-username option", "gh_user"
end
context "with github-username option in bundle config settings set to false" do
before do
global_config "BUNDLE_GEM__GITHUB_USERNAME" => "false"
end
it_behaves_like "--github-username option", "gh_user"
end
end
end
context "testing github_username bundle config against git config settings", :readline do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
end
it_behaves_like "github_username configuration"
end
context "with git config set" do
it_behaves_like "github_username configuration"
end
end
context "gem naming with underscore", :readline do
let(:gem_name) { "test_gem" }
@ -1073,7 +1435,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CI service" do
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "github"
@ -1083,7 +1445,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about MIT license" do
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "config list"
@ -1095,7 +1457,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CoC" do
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false"
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@ -1105,7 +1467,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CHANGELOG" do
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__RUBOCOP" => "false",
global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
"BUNDLE_GEM__COC" => "false"
bundle "gem foobar" do |input, _, _|

Просмотреть файл

@ -929,4 +929,54 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with(expected_output)
end
end
describe "with a multiplatform lockfile" do
before do
build_repo4 do
build_gem "nokogiri", "1.11.1"
build_gem "nokogiri", "1.11.1" do |s|
s.platform = Bundler.local_platform
end
build_gem "nokogiri", "1.11.2"
build_gem "nokogiri", "1.11.2" do |s|
s.platform = Bundler.local_platform
end
end
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.11.1)
nokogiri (1.11.1-#{Bundler.local_platform})
PLATFORMS
ruby
#{Bundler.local_platform}
DEPENDENCIES
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "nokogiri"
G
end
it "reports a single entry per gem" do
bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
nokogiri 1.11.1 1.11.2 >= 0 default
TABLE
expect(out).to end_with(expected_output)
end
end
end

Просмотреть файл

@ -32,21 +32,21 @@ RSpec.describe "post bundle message" do
bundle "config set --local without emo"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the group emo were not installed")
expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include(installed_gems_stats)
bundle "config set --local without emo test"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the groups emo and test were not installed")
expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include("4 Gemfile dependencies, 3 gems now installed.")
bundle "config set --local without emo obama test"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the groups emo, obama and test were not installed")
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include("4 Gemfile dependencies, 2 gems now installed.")
end
@ -65,21 +65,21 @@ RSpec.describe "post bundle message" do
bundle "config set --local without emo"
bundle :install
expect(out).to include(bundle_show_path_message)
expect(out).to include("Gems in the group emo were not installed")
expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
bundle "config set --local path vendor"
bundle "config set --local without emo test"
bundle :install
expect(out).to include(bundle_show_path_message)
expect(out).to include("Gems in the groups emo and test were not installed")
expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
bundle "config set --local path vendor"
bundle "config set --local without emo obama test"
bundle :install
expect(out).to include(bundle_show_path_message)
expect(out).to include("Gems in the groups emo, obama and test were not installed")
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
end
@ -156,7 +156,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the group emo were not installed")
expect(out).to include("Gems in the group 'emo' were not installed")
expect(out).to include(bundle_complete_message)
expect(out).to include(installed_gems_stats)
end
@ -165,7 +165,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo test"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the groups emo and test were not installed")
expect(out).to include("Gems in the groups 'emo' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
@ -173,7 +173,7 @@ The source does not contain any versions of 'not-a-gem'
bundle "install --without emo obama test"
bundle :install
expect(out).to include(bundle_show_message)
expect(out).to include("Gems in the groups emo, obama and test were not installed")
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not installed")
expect(out).to include(bundle_complete_message)
end
end
@ -187,19 +187,19 @@ The source does not contain any versions of 'not-a-gem'
bundle "config set --local without emo"
bundle :install
bundle :update, :all => true
expect(out).to include("Gems in the group emo were not updated")
expect(out).to include("Gems in the group 'emo' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo test"
bundle :install
bundle :update, :all => true
expect(out).to include("Gems in the groups emo and test were not updated")
expect(out).to include("Gems in the groups 'emo' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
bundle "config set --local without emo obama test"
bundle :install
bundle :update, :all => true
expect(out).to include("Gems in the groups emo, obama and test were not updated")
expect(out).to include("Gems in the groups 'emo', 'obama' and 'test' were not updated")
expect(out).to include(bundle_updated_message)
end
end

Просмотреть файл

@ -148,72 +148,66 @@ RSpec.describe "bundle update" do
end
describe "when a possible resolve requires an older version of a locked gem" do
context "and only_update_to_newer_versions is set" do
before do
bundle "config set only_update_to_newer_versions true"
it "does not go to an older version" do
build_repo4 do
build_gem "tilt", "2.0.8"
build_gem "slim", "3.0.9" do |s|
s.add_dependency "tilt", [">= 1.3.3", "< 2.1"]
end
build_gem "slim_lint", "0.16.1" do |s|
s.add_dependency "slim", [">= 3.0", "< 5.0"]
end
build_gem "slim-rails", "0.2.1" do |s|
s.add_dependency "slim", ">= 0.9.2"
end
build_gem "slim-rails", "3.1.3" do |s|
s.add_dependency "slim", "~> 3.0"
end
end
it "does not go to an older version" do
build_repo4 do
build_gem "tilt", "2.0.8"
build_gem "slim", "3.0.9" do |s|
s.add_dependency "tilt", [">= 1.3.3", "< 2.1"]
end
build_gem "slim_lint", "0.16.1" do |s|
s.add_dependency "slim", [">= 3.0", "< 5.0"]
end
build_gem "slim-rails", "0.2.1" do |s|
s.add_dependency "slim", ">= 0.9.2"
end
build_gem "slim-rails", "3.1.3" do |s|
s.add_dependency "slim", "~> 3.0"
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "slim-rails"
gem "slim_lint"
G
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
update_repo4 do
build_gem "slim", "4.0.0" do |s|
s.add_dependency "tilt", [">= 2.0.6", "< 2.1"]
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "slim-rails"
gem "slim_lint"
G
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
update_repo4 do
build_gem "slim", "4.0.0" do |s|
s.add_dependency "tilt", [">= 2.0.6", "< 2.1"]
end
end
bundle "update", :all => true
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
end
it "should still downgrade if forced by the Gemfile" do
build_repo4 do
build_gem "a"
build_gem "b", "1.0"
build_gem "b", "2.0"
end
bundle "update", :all => true
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "a"
gem "b"
G
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
end
expect(the_bundle).to include_gems("a 1.0", "b 2.0")
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "a"
gem "b", "1.0"
G
bundle "update b"
expect(the_bundle).to include_gems("a 1.0", "b 1.0")
it "should still downgrade if forced by the Gemfile" do
build_repo4 do
build_gem "a"
build_gem "b", "1.0"
build_gem "b", "2.0"
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "a"
gem "b"
G
expect(the_bundle).to include_gems("a 1.0", "b 2.0")
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "a"
gem "b", "1.0"
G
bundle "update b"
expect(the_bundle).to include_gems("a 1.0", "b 1.0")
end
end

Просмотреть файл

@ -126,21 +126,21 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config set --local path vendor/bundle"
bundle "install"
gemfile <<-G
source "http://user_name:password@localgemserver.test/"
gem "rack"
source "http://user_name:password@localgemserver.test/"
gem "rack"
G
lockfile <<-G
GEM
remote: http://localgemserver.test/
specs:
rack (1.0.0)
GEM
remote: http://localgemserver.test/
specs:
rack (1.0.0)
PLATFORMS
#{local}
PLATFORMS
#{local}
DEPENDENCIES
rack
DEPENDENCIES
rack
G
bundle "config set --local deployment true"

Просмотреть файл

@ -259,7 +259,7 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(out).to eq("WIN")
end
it "works with only_update_to_newer_versions" do
it "handles downgrades" do
build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
@ -268,7 +268,7 @@ RSpec.describe "bundle install from an existing gemspec" do
build_lib "omg", "1.0", :path => lib_path("omg")
bundle :install, :env => { "BUNDLE_BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS" => "true" }
bundle :install
expect(the_bundle).to include_gems "omg 1.0"
end

Просмотреть файл

@ -173,7 +173,7 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "foo 1.0"
end
it "works with only_update_to_newer_versions" do
it "handles downgrades" do
build_lib "omg", "2.0", :path => lib_path("omg")
install_gemfile <<-G
@ -182,7 +182,7 @@ RSpec.describe "bundle install with explicit source paths" do
build_lib "omg", "1.0", :path => lib_path("omg")
bundle :install, :env => { "BUNDLE_BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS" => "true" }
bundle :install
expect(the_bundle).to include_gems "omg 1.0"
end
@ -328,11 +328,12 @@ RSpec.describe "bundle install with explicit source paths" do
s.executables = "foobar"
end
install_gemfile <<-G
install_gemfile <<-G, :verbose => true
path "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
expect(out).to include("Using foo 1.0 from source at `#{lib_path("foo-1.0")}` and installing its executables")
expect(the_bundle).to include_gems "foo 1.0"
bundle "exec foobar"

Просмотреть файл

@ -141,23 +141,84 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a pinned gem has an indirect dependency" do
context "when a pinned gem has an indirect dependency in the pinned source" do
before do
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
# we need a working rack gem in repo3
update_repo gem_repo3 do
build_gem "rack", "1.0.0"
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
context "when the indirect dependency is in the pinned source" do
context "and not in any other sources" do
before do
# we need a working rack gem in repo3
update_repo gem_repo3 do
build_gem "rack", "1.0.0"
end
build_repo(gem_repo2) {}
end
gemfile <<-G
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
context "and in another source" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
end
context "when a pinned gem has an indirect dependency in a different source" do
before do
# In these tests, we need a working rack gem in repo2 and not repo3
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
build_repo gem_repo2 do
build_gem "rack", "1.0.0"
end
end
context "and not in any other sources" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
@ -165,132 +226,74 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
context "and not in any other sources" do
before do
build_repo(gem_repo2) {}
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
context "and in another source" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
it "installs from the other source without any warning" do
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
end
context "when the indirect dependency is in a different source" do
context "and in yet another source" do
before do
# In these tests, we need a working rack gem in repo2 and not repo3
build_repo gem_repo2 do
build_gem "rack", "1.0.0"
end
end
context "and not in any other sources" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
it "installs from the other source without any warning" do
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
end
context "and in yet another source" do
before do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
bundle :install
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
context "and only the dependency is pinned" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
gemfile <<-G
source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
source "#{file_uri_for(gem_repo2)}" # contains broken rack
it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
bundle :install
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
gem "depends_on_rack" # installed from gem_repo3
gem "rack", :source => "#{file_uri_for(gem_repo1)}"
G
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
context "and only the dependency is pinned" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
bundle :install
gemfile <<-G
source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
source "#{file_uri_for(gem_repo2)}" # contains broken rack
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
gem "depends_on_rack" # installed from gem_repo3
gem "rack", :source => "#{file_uri_for(gem_repo1)}"
G
end
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
end
@ -511,9 +514,149 @@ RSpec.describe "bundle install with gems on multiple sources" do
L
end
it "upgrades gems when running bundle update, without printing any warnings or errors" do
it "does not install newer versions or generate lockfile changes when running bundle install, and warns", :bundler => "< 3" do
initial_lockfile = lockfile
bundle :install
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
expect(the_bundle).to include_gems("tzinfo 1.2.9")
expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
expect(lockfile).to eq(initial_lockfile)
end
it "fails when running bundle install", :bundler => "3" do
initial_lockfile = lockfile
bundle :install, :raise_on_error => false
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(lockfile).to eq(initial_lockfile)
end
it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
bundle "update --all"
expect(err).to be_empty
expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
expect(the_bundle).to include_gems("activesupport 6.1.2.1")
expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
expect(the_bundle).to include_gems("tzinfo 2.0.4")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
activesupport (6.1.2.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.1.9)
connection_pool (2.2.3)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
minitest (5.14.3)
rack (2.2.3)
redis (4.2.5)
sidekiq (6.1.3)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
zeitwerk (2.4.2)
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
sidekiq-pro (5.2.1)
connection_pool (>= 2.2.3)
sidekiq (>= 6.1.0)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "it keeps the currrent lockfile format and upgrades the requested gem when running bundle update with an argument, and warns", :bundler => "< 3" do
bundle "update concurrent-ruby"
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
expect(the_bundle).to include_gems("tzinfo 1.2.9")
expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
concurrent-ruby (1.1.9)
connection_pool (2.2.3)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
minitest (5.14.3)
rack (2.2.3)
redis (4.2.5)
sidekiq (6.1.3)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
sidekiq-pro (5.2.1)
connection_pool (>= 2.2.3)
sidekiq (>= 6.1.0)
thread_safe (0.3.6)
tzinfo (1.2.9)
thread_safe (~> 0.1)
zeitwerk (2.4.2)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "fails when running bundle update with an argument", :bundler => "3" do
initial_lockfile = lockfile
bundle "update concurrent-ruby", :raise_on_error => false
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(lockfile).to eq(initial_lockfile)
end
end
end
@ -551,7 +694,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source ", :bundler => "< 3" do
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do
before do
build_repo gem_repo3 do
build_gem "handsoap", "0.2.5.5" do |s|
@ -578,12 +721,38 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
it "installs from the proper sources without any warnings or errors" do
it "installs from the default source without any warnings or errors and generates a proper lockfile" do
expected_lockfile = <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
nokogiri (1.11.1)
racca (~> 1.4)
racca (1.5.2)
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
handsoap (0.2.5.5)
nokogiri (>= 1.2.3)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
handsoap!
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install --verbose"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
@ -592,6 +761,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
end
end
@ -619,6 +789,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo1)}
specs:
GEM
remote: #{file_uri_for(gem_repo3)}
specs:
rack (0.9.1)
@ -644,6 +817,84 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "with a lockfile with aggregated rubygems sources" do
let(:aggregate_gem_section_lockfile) do
<<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
let(:split_gem_section_lockfile) do
<<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
before do
build_repo gem_repo3 do
build_gem "rack", "0.9.1"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo3)}" do
gem 'rack'
end
G
lockfile aggregate_gem_section_lockfile
end
it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
bundle "config set --local deployment true"
bundle "install"
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("rack 0.9.1", :source => "remote3")
end
it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
bundle "config set --local deployment true"
bundle "install", :raise_on_error =>false
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(out).to be_empty
end
end
context "with a path gem in the same Gemfile" do
before do
build_lib "foo"
@ -825,15 +1076,36 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
it "keeps the old version", :bundler => "< 3" do
expect(the_bundle).to include_gems("rack 1.0.0")
end
it "installs the higher version in the new repo", :bundler => "3" do
it "installs the higher version in the new repo" do
expect(the_bundle).to include_gems("rack 1.2")
end
end
it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do
build_repo2 do
build_gem "example", "0.1.0"
end
build_repo4 do
build_gem "example", "1.0.2"
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "example", :source => "#{file_uri_for(gem_repo2)}"
G
bundle "info example"
expect(out).to include("example (0.1.0)")
system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
bundle "update example --verbose"
expect(out).not_to include("Using example 1.0.2")
expect(out).to include("Using example 0.1.0")
end
context "when a gem is available from multiple ambiguous sources", :bundler => "3" do
it "raises, suggesting a source block" do
build_repo4 do

Просмотреть файл

@ -104,6 +104,50 @@ RSpec.describe "bundle install with specific platforms" do
L
end
it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do
build_repo2 do
build_gem("libv8", "8.4.255.0")
build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" }
build_gem("mini_racer", "1.0.0") do |s|
s.add_runtime_dependency "libv8"
end
end
system_gems "bundler-2.1.4"
# Consistent location to install and look for gems
bundle "config set --local path vendor/bundle", :env => { "BUNDLER_VERSION" => "2.1.4" }
gemfile <<-G
source "https://localgemserver.test"
gem "libv8"
G
# simulate lockfile created with old bundler, which only locks for ruby platform
lockfile <<-L
GEM
remote: https://localgemserver.test/
specs:
libv8 (8.4.255.0)
PLATFORMS
ruby
DEPENDENCIES
libv8
BUNDLED WITH
2.1.4
L
bundle "install --verbose", :artifice => :compact_index, :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)")
bundle "add mini_racer --verbose", :artifice => :compact_index, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
end
it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do
setup_multiplatform_gem
gemfile(google_protobuf)

Просмотреть файл

@ -245,37 +245,7 @@ RSpec.describe "bundle flex_install" do
end
describe "when adding a new source" do
it "updates the lockfile", :bundler => "< 3" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
lockfile_should_be <<-L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "updates the lockfile", :bundler => "3" do
it "updates the lockfile" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"

Просмотреть файл

@ -3,6 +3,32 @@
RSpec.describe "bundle install with install-time dependencies" do
before do
build_repo2 do
build_gem "with_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
f.puts "IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
# Test complicated gem dependencies for install
build_gem "net_a" do |s|
s.add_dependency "net_b"
@ -55,6 +81,25 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to eq("YES\nYES")
end
it "installs gems with implicit rake dependencies without rake previously installed" do
with_path_as("") do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "with_implicit_rake_dep"
gem "another_implicit_rake_dep"
gem "rake"
G
end
run <<-R
require 'implicit_rake_dep'
require 'another_implicit_rake_dep'
puts IMPLICIT_RAKE_DEP
puts ANOTHER_IMPLICIT_RAKE_DEP
R
expect(out).to eq("YES\nYES")
end
it "installs gems with a dependency with no type" do
skip "incorrect data check error" if Gem.win_platform?

Просмотреть файл

@ -49,8 +49,23 @@ RSpec.describe "when using sudo", :sudo => true do
end
it "installs rake and a gem dependent on rake in the same session" do
build_repo2 do
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
gem "rake"
gem "another_implicit_rake_dep"
G

Просмотреть файл

@ -13,7 +13,7 @@ RSpec.describe "bundle install" do
expect(the_bundle).to include_gems "foo 1.0", :source => "git@#{lib_path("foo")}"
end
it "displays the correct default branch" do
it "displays the correct default branch", :git => ">= 2.28.0" do
build_git "foo", "1.0", :path => lib_path("foo"), :default_branch => "main"
install_gemfile <<-G, :verbose => true

Просмотреть файл

@ -318,40 +318,7 @@ RSpec.describe "the lockfile format" do
G
end
it "generates a lockfile without credentials for a configured source", :bundler => "< 3" do
bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
source "http://localgemserver.test/" do
end
source "http://user:pass@othergemserver.test/" do
gem "rack-obama", ">= 1.0"
end
G
lockfile_should_be <<-G
GEM
remote: http://localgemserver.test/
remote: http://user:pass@othergemserver.test/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rack-obama (>= 1.0)!
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "generates a lockfile without credentials for a configured source", :bundler => "3" do
it "generates a lockfile without credentials for a configured source" do
bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
@ -674,6 +641,30 @@ RSpec.describe "the lockfile format" do
G
end
it "removes redundant sources" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
G
lockfile_should_be <<-G
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "lists gems alphabetically" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"

Просмотреть файл

@ -165,6 +165,28 @@ RSpec.describe "major deprecations" do
pending "fails with a helpful error", :bundler => "3"
end
context "bundle cache --path" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "cache --path foo", :raise_on_error => false
end
it "should print a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include(
"The `--path` flag is deprecated because its semantics are unclear. " \
"Use `bundle config cache_path` to configure the path of your cache of gems, " \
"and `bundle config path` to configure the path where your gems are installed, " \
"and stop using this flag"
)
end
pending "fails with a helpful error", :bundler => "3"
end
describe "bundle config" do
describe "old list interface" do
before do
@ -383,15 +405,53 @@ RSpec.describe "major deprecations" do
"Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
"To upgrade this warning to an error, run `bundle config set --local " \
"disable_multisource true`."
"a block to indicate which gems should come from the secondary source."
)
end
pending "fails with a helpful error", :bundler => "3"
end
context "bundle install with a lockfile with a single rubygems section with multiple remotes" do
before do
build_repo gem_repo3 do
build_gem "rack", "0.9.1"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo3)}" do
gem 'rack'
end
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
ruby
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "shows a deprecation", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch.")
end
pending "fails with a helpful error", :bundler => "3"
end
context "when Bundler.setup is run in a ruby script" do
before do
create_file "gems.rb"
@ -609,4 +669,50 @@ The :gist git source is deprecated, and will be removed in the future. Add this
pending "fails with a helpful message", :bundler => "3"
end
describe "deprecating rubocop", :readline do
context "bundle gem --rubocop" do
before do
bundle "gem my_new_gem --rubocop", :raise_on_error => false
end
it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"--rubocop is deprecated, use --linter=rubocop"
end
end
context "bundle gem --no-rubocop" do
before do
bundle "gem my_new_gem --no-rubocop", :raise_on_error => false
end
it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"--no-rubocop is deprecated, use --linter"
end
end
context "bundle gem with gem.rubocop set to true" do
before do
bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "true" }, :raise_on_error => false
end
it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
end
end
context "bundle gem with gem.rubocop set to false" do
before do
bundle "gem my_new_gem", :env => { "BUNDLE_GEM__RUBOCOP" => "false" }, :raise_on_error => false
end
it "prints a deprecation warning", :bundler => "< 3" do
expect(deprecations).to include \
"config gem.rubocop is deprecated; we've updated your config to use gem.linter instead"
end
end
end
end

Просмотреть файл

@ -169,7 +169,6 @@ RSpec.describe "The library itself" do
it "documents all used settings" do
exemptions = %w[
deployment_means_frozen
forget_cli_options
gem.coc
gem.mit

Просмотреть файл

@ -6,7 +6,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
jruby-jars (9.2.14.0)
jruby-jars (9.2.16.0)
jruby-rack (1.1.21)
rake (13.0.1)
rubyzip (1.3.0)
@ -19,6 +19,7 @@ GEM
PLATFORMS
java
ruby
universal-java-11
DEPENDENCIES
demo!
@ -26,4 +27,4 @@ DEPENDENCIES
warbler (~> 2.0)
BUNDLED WITH
2.2.0.rc.2
2.3.0.dev

Просмотреть файл

@ -246,6 +246,19 @@ RSpec.describe "bundler/inline#gemfile" do
expect(last_command.stderr).to be_empty
end
it "installs inline gems when deployment is set" do
script <<-RUBY, :env => { "BUNDLE_DEPLOYMENT" => "true" }
gemfile do
source "#{file_uri_for(gem_repo1)}"
gem "rack"
end
puts RACK
RUBY
expect(last_command.stderr).to be_empty
end
it "installs inline gems when BUNDLE_GEMFILE is set to an empty string" do
ENV["BUNDLE_GEMFILE"] = ""

Просмотреть файл

@ -108,6 +108,44 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(lockfile).to eq(good_lockfile)
end
it "will not try to install platform specific gems when they don't match the current ruby if locked only to ruby" do
build_repo4 do
build_gem "nokogiri", "1.11.1"
build_gem "nokogiri", "1.11.1" do |s|
s.platform = Bundler.local_platform
s.required_ruby_version = "< #{Gem.ruby_version}"
end
end
gemfile <<-G
source "https://gems.repo4"
gem "nokogiri"
G
lockfile <<~L
GEM
remote: https://gems.repo4/
specs:
nokogiri (1.11.1)
PLATFORMS
ruby
DEPENDENCIES
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(out).to include("Fetching nokogiri 1.11.1")
expect(the_bundle).to include_gems "nokogiri 1.11.1"
expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}"
end
it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"

Просмотреть файл

@ -1244,16 +1244,16 @@ end
describe "default gem activation" do
let(:exemptions) do
exempts = if Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7")
exempts = if Gem.rubygems_version >= Gem::Version.new("2.7")
%w[did_you_mean]
else
%w[io-console openssl]
end << "bundler"
exempts << "fiddle" if Gem.win_platform? && Gem::Version.new(Gem::VERSION) >= Gem::Version.new("2.7")
exempts << "uri" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7")
exempts << "pathname" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0")
exempts << "set" unless Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.2.6")
exempts << "tsort" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0")
exempts << "fiddle" if Gem.win_platform? && Gem.rubygems_version >= Gem::Version.new("2.7")
exempts << "uri" if Gem.ruby_version >= Gem::Version.new("2.7")
exempts << "pathname" if Gem.ruby_version >= Gem::Version.new("3.0")
exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6")
exempts << "tsort" if Gem.ruby_version >= Gem::Version.new("3.0")
exempts
end

Просмотреть файл

@ -66,16 +66,9 @@ RSpec.configure do |config|
mocks.allow_message_expectations_on_nil = false
end
config.around :each do |example|
if ENV["RUBY"]
orig_ruby = Gem.ruby
Gem.ruby = ENV["RUBY"]
end
example.run
Gem.ruby = orig_ruby if ENV["RUBY"]
end
config.before :suite do
Gem.ruby = ENV["RUBY"] if ENV["RUBY"]
require_relative "support/rubygems_ext"
Spec::Rubygems.test_setup
ENV["BUNDLE_SPEC_RUN"] = "true"
@ -90,6 +83,8 @@ RSpec.configure do |config|
end
config.before :all do
check_test_gems!
build_repo1
reset_paths!

Просмотреть файл

@ -30,7 +30,11 @@ module Spec
end
def build_repo1
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
build_repo gem_repo1 do
FileUtils.cp rake_path, "#{gem_repo1}/gems/"
build_gem "rack", %w[0.9.1 1.0.0] do |s|
s.executables = "rackup"
s.post_install_message = "Rack's post install message"
@ -150,32 +154,6 @@ module Spec
build_gem "duradura", "7.0"
build_gem "with_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
f.puts "IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "very_simple_binary", &:add_c_extension
build_gem "simple_binary", &:add_c_extension
@ -255,6 +233,13 @@ module Spec
def build_repo(path, &blk)
return if File.directory?(path)
FileUtils.mkdir_p("#{path}/gems")
update_repo(path, &blk)
end
def check_test_gems!
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
if rake_path.nil?
@ -263,14 +248,9 @@ module Spec
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
end
if rake_path
FileUtils.mkdir_p("#{path}/gems")
FileUtils.cp rake_path, "#{path}/gems/"
else
if rake_path.nil?
abort "Your test gems are missing! Run `rm -rf #{tmp}` and try again."
end
update_repo(path, &blk)
end
def update_repo(path)

Просмотреть файл

@ -0,0 +1,8 @@
# frozen_string_literal: true
require "rubygems"
require_relative "path"
bundler_gemspec = Spec::Path.loaded_gemspec
bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root)
bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate)
load File.expand_path("bundle", Spec::Path.bindir)

Просмотреть файл

@ -29,7 +29,7 @@ module Gem
end
# We only need this hack for rubygems versions without the BundlerVersionFinder
if Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
if Gem.rubygems_version < Gem::Version.new("2.7.0")
@path_to_default_spec_map.delete_if do |_path, spec|
spec.name == "bundler"
end

Просмотреть файл

@ -10,7 +10,7 @@ module Spec
def reset!
Dir.glob("#{tmp}/{gems/*,*}", File::FNM_DOTMATCH).each do |dir|
next if %w[base base_system remote1 gems rubygems . ..].include?(File.basename(dir))
next if %w[base base_system remote1 rubocop standard gems rubygems . ..].include?(File.basename(dir))
FileUtils.rm_rf(dir)
end
FileUtils.mkdir_p(home)
@ -130,7 +130,7 @@ module Spec
def ruby(ruby, options = {})
ruby_cmd = build_ruby_cmd
escaped_ruby = RUBY_PLATFORM == "java" ? ruby.shellescape.dump : ruby.shellescape
escaped_ruby = ruby.shellescape
sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options)
end

Просмотреть файл

@ -114,30 +114,49 @@ module Spec
match do
opts = names.last.is_a?(Hash) ? names.pop : {}
source = opts.delete(:source)
groups = Array(opts[:groups])
groups = Array(opts.delete(:groups)).map(&:inspect).join(", ")
opts[:raise_on_error] = false
groups << opts
@errors = names.map do |name|
name, version, platform = name.split(/\s+/)
@errors = names.map do |full_name|
name, version, platform = full_name.split(/\s+/)
require_path = name == "bundler" ? "#{lib_dir}/bundler" : name.tr("-", "/")
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
code = []
code << "require '#{require_path}.rb'"
code << "puts #{version_const}"
run code.join("; "), *groups
actual_version, actual_platform = out.strip.split(/\s+/, 2)
unless Gem::Version.new(actual_version) == Gem::Version.new(version)
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
ruby <<~R, opts
require '#{lib_dir}/bundler'
Bundler.setup(#{groups})
require '#{require_path}.rb'
actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
puts actual_version
exit 64
end
unless actual_platform.to_s == '#{platform}'
puts actual_platform
exit 65
end
require '#{require_path}/source'
exit 0 if #{source.nil?}
actual_source = #{source_const}
unless actual_source == '#{source}'
puts actual_source
exit 66
end
R
next if exitstatus == 0
if exitstatus == 64
actual_version = out.split("\n").last
next "#{name} was expected to be at version #{version} but was #{actual_version}"
end
unless actual_platform == platform
if exitstatus == 65
actual_platform = out.split("\n").last
next "#{name} was expected to be of platform #{platform} but was #{actual_platform}"
end
next unless source
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
run "require '#{require_path}/source'; puts #{source_const}", *groups
unless out.strip == source
next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{out}`"
if exitstatus == 66
actual_source = out.split("\n").last
next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{actual_source}`"
end
next "Command to check forgem inclusion of gem #{full_name} failed"
end.compact
@errors.empty?

Просмотреть файл

@ -6,7 +6,7 @@ require "rbconfig"
module Spec
module Path
def source_root
@source_root ||= Pathname.new(ruby_core? ? "../../../.." : "../../..").expand_path(__FILE__)
@source_root ||= Pathname.new(ruby_core? ? "../../.." : "../..").expand_path(__dir__)
end
def root
@ -30,7 +30,15 @@ module Spec
end
def test_gemfile
@test_gemfile ||= source_root.join(ruby_core? ? "tool/bundler/test_gems.rb" : "test_gems.rb")
@test_gemfile ||= source_root.join("tool/bundler/test_gems.rb")
end
def rubocop_gemfile
@rubocop_gemfile ||= source_root.join(rubocop_gemfile_basename)
end
def standard_gemfile
@standard_gemfile ||= source_root.join(standard_gemfile_basename)
end
def dev_gemfile
@ -119,7 +127,7 @@ module Spec
end
def vendored_gems(path = nil)
bundled_app(*["vendor/bundle", Gem.ruby_engine, RbConfig::CONFIG["ruby_version"], path].compact)
scoped_gem_path(bundled_app("vendor/bundle")).join(*[path].compact)
end
def cached_gem(path)
@ -138,6 +146,14 @@ module Spec
tmp.join("gems/base")
end
def rubocop_gems
tmp.join("gems/rubocop")
end
def standard_gems
tmp.join("gems/standard")
end
def file_uri_for(path)
protocol = "file://"
root = Gem.win_platform? ? "/" : ""
@ -178,7 +194,11 @@ module Spec
end
def local_gem_path(*path, base: bundled_app)
base.join(*[".bundle", Gem.ruby_engine, RbConfig::CONFIG["ruby_version"], *path].compact)
scoped_gem_path(base.join(".bundle")).join(*path)
end
def scoped_gem_path(base)
base.join(Gem.ruby_engine, RbConfig::CONFIG["ruby_version"])
end
def lib_path(*args)
@ -193,10 +213,6 @@ module Spec
root.join("lib")
end
def xdg_config_home
home(".config")
end
def global_plugin_gem(*args)
home ".bundle", "plugin", "gems", *args
end
@ -255,6 +271,14 @@ module Spec
!git_root.join(".git").directory?
end
def rubocop_gemfile_basename
source_root.join("tool/bundler/#{RUBY_VERSION.start_with?("2.3") ? "rubocop23_gems.rb" : "rubocop_gems.rb"}")
end
def standard_gemfile_basename
source_root.join("tool/bundler/#{RUBY_VERSION.start_with?("2.3") ? "standard23_gems.rb" : "standard_gems.rb"}")
end
extend self
end
end

Просмотреть файл

@ -9,7 +9,7 @@ module Spec
extend self
def dev_setup
install_gems(dev_gemfile, dev_lockfile)
install_gems(dev_gemfile)
end
def gem_load(gem_name, bin_container)
@ -33,25 +33,25 @@ module Spec
ENV["HOME"] = Path.home.to_s
ENV["TMPDIR"] = Path.tmpdir.to_s
ENV["XDG_CONFIG_HOME"] = Path.xdg_config_home.to_s
require "rubygems/user_interaction"
Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
end
def install_parallel_test_deps
Gem.clear_paths
require "parallel"
require "fileutils"
prev_env_test_number = ENV["TEST_ENV_NUMBER"]
install_test_deps
begin
Parallel.processor_count.times do |n|
ENV["TEST_ENV_NUMBER"] = (n + 1).to_s
(2..Parallel.processor_count).each do |n|
source = Path.source_root.join("tmp", "1")
destination = Path.source_root.join("tmp", n.to_s)
install_test_deps
end
ensure
ENV["TEST_ENV_NUMBER"] = prev_env_test_number
FileUtils.rm_rf destination
FileUtils.cp_r source, destination
end
end
@ -67,9 +67,9 @@ module Spec
def install_test_deps
setup_test_paths
workaround_loaded_specs_issue
install_gems(test_gemfile, test_lockfile)
install_gems(test_gemfile)
install_gems(rubocop_gemfile, Path.rubocop_gems.to_s)
install_gems(standard_gemfile, Path.standard_gems.to_s)
end
def check_source_control_changes(success_message:, error_message:)
@ -94,18 +94,6 @@ module Spec
private
# Some rubygems versions include loaded specs when loading gemspec stubs
# from the file system. In this situation, that makes bundler incorrectly
# assume that `rake` is already installed at `tmp/` because it's installed
# globally, and makes it skip installing it to the proper location for our
# tests. To workaround, we remove `rake` from the loaded specs when running
# under those versions, so that `bundler` does the right thing.
def workaround_loaded_specs_issue
current_rubygems_version = Gem::Version.new(Gem::VERSION)
Gem.loaded_specs.delete("rake") if current_rubygems_version >= Gem::Version.new("3.0.0.beta2") && current_rubygems_version < Gem::Version.new("3.2.0")
end
def gem_load_and_activate(gem_name, bin_container)
gem_activate(gem_name)
load Gem.bin_path(gem_name, bin_container)
@ -119,14 +107,27 @@ module Spec
gem gem_name, gem_requirement
end
def install_gems(gemfile, lockfile)
def install_gems(gemfile, path = nil)
old_gemfile = ENV["BUNDLE_GEMFILE"]
ENV["BUNDLE_GEMFILE"] = gemfile.to_s
require "bundler"
definition = Bundler::Definition.build(gemfile, lockfile, nil)
definition.validate_runtime!
Bundler::Installer.install(Path.source_root, definition, :path => ENV["GEM_HOME"])
if path
old_path = ENV["BUNDLE_PATH"]
ENV["BUNDLE_PATH"] = path
else
old_path__system = ENV["BUNDLE_PATH__SYSTEM"]
ENV["BUNDLE_PATH__SYSTEM"] = "true"
end
output = `#{Gem.ruby} #{File.expand_path("support/bundle.rb", Path.spec_dir)} install`
raise "Error when installing gems in #{gemfile}: #{output}" unless $?.success?
ensure
if path
ENV["BUNDLE_PATH"] = old_path
else
ENV["BUNDLE_PATH__SYSTEM"] = old_path__system
end
ENV["BUNDLE_GEMFILE"] = old_gemfile
end
@ -134,8 +135,12 @@ module Spec
Path.test_gemfile
end
def test_lockfile
lockfile_for(test_gemfile)
def rubocop_gemfile
Path.rubocop_gemfile
end
def standard_gemfile
Path.standard_gemfile
end
def dev_gemfile