diff options
64 files changed, 529 insertions, 361 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index 84ef033fe3..132254bb25 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -40,7 +40,7 @@ module Bundler SUDO_MUTEX = Thread::Mutex.new SAFE_MARSHAL_CLASSES = [Symbol, TrueClass, String, Array, Hash].freeze - SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed.".freeze + SAFE_MARSHAL_ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed." SAFE_MARSHAL_PROC = proc do |object| object.tap do unless SAFE_MARSHAL_CLASSES.include?(object.class) @@ -506,7 +506,7 @@ EOF if File.file?(executable) && File.executable?(executable) executable elsif paths = ENV["PATH"] - quote = '"'.freeze + quote = '"' paths.split(File::PATH_SEPARATOR).find do |path| path = path[1..-2] if path.start_with?(quote) && path.end_with?(quote) executable_path = File.expand_path(executable, path) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 2f652cb5a7..09a756abc7 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -79,6 +79,7 @@ module Bundler @locked_bundler_version = nil @locked_ruby_version = nil @new_platform = nil + @removed_platform = nil if lockfile && File.exist?(lockfile) @lockfile_contents = Bundler.read_file(lockfile) @@ -129,7 +130,7 @@ module Bundler end @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version) - add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle? + add_current_platform unless Bundler.frozen_bundle? converge_path_sources_to_gemspec_sources @path_changes = converge_paths @@ -267,7 +268,7 @@ module Bundler SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps)) else Bundler.ui.debug "Found no changes, using resolution from the lockfile" - if @locked_gems.may_include_redundant_platform_specific_gems? + if @removed_platform || @locked_gems.may_include_redundant_platform_specific_gems? SpecSet.new(filter_specs(@locked_specs, @dependencies)) else @locked_specs @@ -446,7 +447,9 @@ module Bundler end def remove_platform(platform) - return if @platforms.delete(Gem::Platform.new(platform)) + removed_platform = @platforms.delete(Gem::Platform.new(platform)) + @removed_platform ||= removed_platform + return if removed_platform raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" end @@ -584,6 +587,8 @@ module Bundler end def add_current_platform + return if current_ruby_platform_locked? + add_platform(local_platform) end diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 0492f52cfc..03c80a408c 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -277,8 +277,8 @@ module Bundler if repo_name =~ GITHUB_PULL_REQUEST_URL { "git" => "https://github.com/#{$1}.git", - "branch" => "refs/pull/#{$2}/head", - "ref" => nil, + "branch" => nil, + "ref" => "refs/pull/#{$2}/head", "tag" => nil, } else diff --git a/lib/bundler/environment_preserver.rb b/lib/bundler/environment_preserver.rb index 70967522af..57013f5d50 100644 --- a/lib/bundler/environment_preserver.rb +++ b/lib/bundler/environment_preserver.rb @@ -2,7 +2,7 @@ module Bundler class EnvironmentPreserver - INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL".freeze + INTENTIONALLY_NIL = "BUNDLER_ENVIRONMENT_PRESERVER_INTENTIONALLY_NIL" BUNDLER_KEYS = %w[ BUNDLE_BIN_PATH BUNDLE_GEMFILE @@ -16,7 +16,7 @@ module Bundler RUBYLIB RUBYOPT ].map(&:freeze).freeze - BUNDLER_PREFIX = "BUNDLER_ORIG_".freeze + BUNDLER_PREFIX = "BUNDLER_ORIG_" def self.from_env new(env_to_hash(ENV), BUNDLER_KEYS) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 0301986ca9..b8c599f63a 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -13,8 +13,8 @@ module Bundler attr_reader :specs, :all_specs, :sources protected :specs, :all_specs - RUBY = "ruby".freeze - NULL = "\0".freeze + RUBY = "ruby" + NULL = "\0" def initialize @sources = [] diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb index c2edc9b43a..cb644a7f69 100644 --- a/lib/bundler/injector.rb +++ b/lib/bundler/injector.rb @@ -2,7 +2,7 @@ module Bundler class Injector - INJECTED_GEMS = "injected gems".freeze + INJECTED_GEMS = "injected gems" def self.inject(new_deps, options = {}) injector = new(new_deps, options) diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index ca51691b5c..dccfe48bba 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -16,7 +16,6 @@ module Bundler @dependencies = [] @platform = platform || Gem::Platform::RUBY @source = source - @specification = nil @force_ruby_platform = default_force_ruby_platform end @@ -80,37 +79,41 @@ module Bundler def materialize_for_installation source.local! - candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? - target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : local_platform + matching_specs = source.specs.search(use_exact_resolved_specifications? ? self : [name, version]) + return self if matching_specs.empty? - GemHelpers.select_best_platform_match(source.specs.search([name, version]), target_platform) + candidates = if use_exact_resolved_specifications? + matching_specs else - source.specs.search(self) - end + target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : local_platform - return self if candidates.empty? + installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform) - __materialize__(candidates) - end + specification = __materialize__(installable_candidates) + return specification unless specification.nil? - def __materialize__(candidates) - @specification = begin - search = candidates.reverse.find do |spec| - spec.is_a?(StubSpecification) || - (spec.matches_current_ruby? && - spec.matches_current_rubygems?) - end - if search.nil? && Bundler.frozen_bundle? - search = candidates.last - else - search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + if target_platform != platform + installable_candidates = GemHelpers.select_best_platform_match(matching_specs, platform) end - search + + installable_candidates end + + __materialize__(candidates) end - def respond_to?(*args) - super || @specification ? @specification.respond_to?(*args) : nil + def __materialize__(candidates) + search = candidates.reverse.find do |spec| + spec.is_a?(StubSpecification) || + (spec.matches_current_ruby? && + spec.matches_current_rubygems?) + end + if search.nil? && Bundler.frozen_bundle? + search = candidates.last + else + search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) + end + search end def to_s @@ -132,16 +135,8 @@ module Bundler private - def to_ary - nil - end - - def method_missing(method, *args, &blk) - raise "LazySpecification has not been materialized yet (calling :#{method} #{args.inspect})" unless @specification - - return super unless respond_to?(method) - - @specification.send(method, *args, &blk) + def use_exact_resolved_specifications? + @use_exact_resolved_specifications ||= !source.is_a?(Source::Path) && ruby_platform_materializes_to_ruby_platform? end # diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb index 23413dbdd6..a7ee026f67 100644 --- a/lib/bundler/lockfile_generator.rb +++ b/lib/bundler/lockfile_generator.rb @@ -45,7 +45,7 @@ module Bundler # gems with the same name, but different platform # are ordered consistently specs.sort_by(&:full_name).each do |spec| - next if spec.name == "bundler".freeze + next if spec.name == "bundler" out << spec.to_lock end end diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 0ec5b7de8a..237749c525 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -4,15 +4,15 @@ module Bundler class LockfileParser attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version - BUNDLED = "BUNDLED WITH".freeze - DEPENDENCIES = "DEPENDENCIES".freeze - PLATFORMS = "PLATFORMS".freeze - RUBY = "RUBY VERSION".freeze - GIT = "GIT".freeze - GEM = "GEM".freeze - PATH = "PATH".freeze - PLUGIN = "PLUGIN SOURCE".freeze - SPECS = " specs:".freeze + BUNDLED = "BUNDLED WITH" + DEPENDENCIES = "DEPENDENCIES" + PLATFORMS = "PLATFORMS" + RUBY = "RUBY VERSION" + GIT = "GIT" + GEM = "GEM" + PATH = "PATH" + PLUGIN = "PLUGIN SOURCE" + SPECS = " specs:" OPTIONS = /^ ([a-z]+): (.*)$/i.freeze SOURCE = [GIT, GEM, PATH, PLUGIN].freeze diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index 26458bd596..f3caff8963 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -15,7 +15,7 @@ module Bundler class UnknownSourceError < PluginError; end class PluginInstallError < PluginError; end - PLUGIN_FILE_NAME = "plugins.rb".freeze + PLUGIN_FILE_NAME = "plugins.rb" module_function diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 403ce825d3..df9ce2ff3f 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -337,7 +337,8 @@ module Bundler def requirement_to_range(requirement) ranges = requirement.requirements.map do |(op, version)| - ver = Resolver::Candidate.new(version) + ver = Resolver::Candidate.new(version).generic! + platform_ver = Resolver::Candidate.new(version).platform_specific! case op when "~>" @@ -345,17 +346,17 @@ module Bundler bump = Resolver::Candidate.new(version.bump.to_s + ".A") PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true) when ">" - PubGrub::VersionRange.new(:min => ver) + PubGrub::VersionRange.new(:min => platform_ver) when ">=" PubGrub::VersionRange.new(:min => ver, :include_min => true) when "<" PubGrub::VersionRange.new(:max => ver) when "<=" - PubGrub::VersionRange.new(:max => ver, :include_max => true) + PubGrub::VersionRange.new(:max => platform_ver, :include_max => true) when "=" - PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true) + PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true) when "!=" - PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true).invert + PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true).invert else raise "bad version specifier: #{op}" end diff --git a/lib/bundler/resolver/candidate.rb b/lib/bundler/resolver/candidate.rb index cf5691ccc7..681f9aca73 100644 --- a/lib/bundler/resolver/candidate.rb +++ b/lib/bundler/resolver/candidate.rb @@ -41,6 +41,18 @@ module Bundler @spec_group.to_specs(package.force_ruby_platform?) end + def generic! + @ruby_only = true + + self + end + + def platform_specific! + @ruby_only = false + + self + end + def prerelease? @version.prerelease? end @@ -53,27 +65,20 @@ module Bundler [@version, @ruby_only ? -1 : 1] end - def canonical? - !@spec_group.empty? - end - def <=>(other) return unless other.is_a?(self.class) - return @version <=> other.version unless canonical? && other.canonical? sort_obj <=> other.sort_obj end def ==(other) return unless other.is_a?(self.class) - return @version == other.version unless canonical? && other.canonical? sort_obj == other.sort_obj end def eql?(other) return unless other.is_a?(self.class) - return @version.eql?(other.version) unless canonical? || other.canonical? sort_obj.eql?(other.sort_obj) end diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 20975e20ca..bdfcf8274a 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -11,7 +11,7 @@ module Bundler protected :original_path - DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze + DEFAULT_GLOB = "{,*,*/*}.gemspec" def initialize(options) @options = options.dup diff --git a/lib/bundler/templates/newgem/Cargo.toml.tt b/lib/bundler/templates/newgem/Cargo.toml.tt index 7be7550cce..f5a460c9bb 100644 --- a/lib/bundler/templates/newgem/Cargo.toml.tt +++ b/lib/bundler/templates/newgem/Cargo.toml.tt @@ -1,5 +1,5 @@ # This Cargo.toml is here to let externals tools (IDEs, etc.) know that this is -# a Rust project. Your extensions depedencies should be added to the Cargo.toml +# a Rust project. Your extensions dependencies should be added to the Cargo.toml # in the ext/ directory. [workspace] diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb index c222542435..9133332d01 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb @@ -20,6 +20,10 @@ module Bundler::PubGrub range.eql?(other.range) end + def ==(other) + package == other.package && range == other.range + end + class << self def exact(package, version) range = VersionRange.new(min: version, max: version, include_min: true, include_max: true) diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb index e384178973..506b447b36 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb @@ -397,7 +397,7 @@ module Bundler::PubGrub def constraints return ["any"] if any? - return ["= #{min}"] if min == max + return ["= #{min}"] if min.to_s == max.to_s c = [] c << "#{include_min ? ">=" : ">"} #{min}" if min diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb index c898a6522d..bbc10c3804 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb @@ -148,7 +148,7 @@ module Bundler::PubGrub while !ranges.empty? ne = [] range = ranges.shift - while !ranges.empty? && ranges[0].min == range.max + while !ranges.empty? && ranges[0].min.to_s == range.max.to_s ne << range.max range = range.span(ranges.shift) end diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 18547a5a34..102597b0f5 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require "rbconfig" module Gem - VERSION = "3.5.0.dev".freeze + VERSION = "3.5.0.dev" end # Must be first since it unloads the prelude from 1.9.2 @@ -822,7 +822,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} def self.env_requirement(gem_name) @env_requirements_by_name ||= {} @env_requirements_by_name[gem_name] ||= begin - req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || ">= 0".freeze + req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || ">= 0" Gem::Requirement.create(req) end end @@ -1290,7 +1290,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} ## # Location of Marshal quick gemspecs on remote repositories - MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/".freeze + MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/" autoload :ConfigFile, File.expand_path("rubygems/config_file", __dir__) autoload :Dependency, File.expand_path("rubygems/dependency", __dir__) diff --git a/lib/rubygems/bundler_version_finder.rb b/lib/rubygems/bundler_version_finder.rb index d47573ead6..5b34227d3a 100644 --- a/lib/rubygems/bundler_version_finder.rb +++ b/lib/rubygems/bundler_version_finder.rb @@ -21,7 +21,7 @@ module Gem::BundlerVersionFinder end def self.bundle_update_bundler_version - return unless File.basename($0) == "bundle".freeze + return unless File.basename($0) == "bundle" return unless "update".start_with?(ARGV.first || " ") bundler_version = nil update_index = nil diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb index f4688d793b..59bfc5a118 100644 --- a/lib/rubygems/command.rb +++ b/lib/rubygems/command.rb @@ -624,7 +624,7 @@ class Gem::Command # :stopdoc: - HELP = <<-HELP.freeze + HELP = <<-HELP RubyGems is a package manager for Ruby. Usage: diff --git a/lib/rubygems/commands/help_command.rb b/lib/rubygems/commands/help_command.rb index 8bfb4458ff..bf4ffefbb7 100644 --- a/lib/rubygems/commands/help_command.rb +++ b/lib/rubygems/commands/help_command.rb @@ -3,7 +3,7 @@ require_relative "../command" class Gem::Commands::HelpCommand < Gem::Command # :stopdoc: - EXAMPLES = <<-EOF.freeze + EXAMPLES = <<-EOF Some examples of 'gem' usage. * Install 'rake', either from local directory or remote server: @@ -52,7 +52,7 @@ Some examples of 'gem' usage. gem update --system EOF - GEM_DEPENDENCIES = <<-EOF.freeze + GEM_DEPENDENCIES = <<-EOF A gem dependencies file allows installation of a consistent set of gems across multiple environments. The RubyGems implementation is designed to be compatible with Bundler's Gemfile format. You can see additional @@ -229,7 +229,7 @@ default. This may be overridden with the :development_group option: EOF - PLATFORMS = <<-'EOF'.freeze + PLATFORMS = <<-'EOF' RubyGems platforms are composed of three parts, a CPU, an OS, and a version. These values are taken from values in rbconfig.rb. You can view your current platform by running `gem environment`. diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb index 4a0f7aa3e4..959a6186dc 100644 --- a/lib/rubygems/commands/owner_command.rb +++ b/lib/rubygems/commands/owner_command.rb @@ -15,7 +15,7 @@ The owner command lets you add and remove owners of a gem on a push server (the default is https://rubygems.org). Multiple owners can be added or removed at the same time, if the flag is given multiple times. -The supported user identifiers are dependant on the push server. +The supported user identifiers are dependent on the push server. For rubygems.org, both e-mail and handle are supported, even though the user identifier field is called "email". diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 8daff0bc30..4806ea6469 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true module Gem - DEFAULT_HOST = "https://rubygems.org".freeze + DEFAULT_HOST = "https://rubygems.org" @post_install_hooks ||= [] @done_installing_hooks ||= [] diff --git a/lib/rubygems/dependency.rb b/lib/rubygems/dependency.rb index 7fa0f91bd4..cd03e7e299 100644 --- a/lib/rubygems/dependency.rb +++ b/lib/rubygems/dependency.rb @@ -299,7 +299,7 @@ class Gem::Dependency end def prioritizes_bundler? - name == "bundler".freeze && !specific? + name == "bundler" && !specific? end def to_specs diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb index 3851e8d523..60ab5544fe 100644 --- a/lib/rubygems/ext/cargo_builder.rb +++ b/lib/rubygems/ext/cargo_builder.rb @@ -203,7 +203,7 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder !!Gem::WIN_PATTERNS.find {|r| target_platform =~ r } end - # Interpolate substition vars in the arg (i.e. $(DEFFILE)) + # Interpolate substitution vars in the arg (i.e. $(DEFFILE)) def maybe_resolve_ldflag_variable(input_arg, dest_dir) var_matches = input_arg.match(/\$\((\w+)\)/) diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index 1e7a5c503a..f4983c1153 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -158,7 +158,7 @@ class Gem::Platform # Of note, this method is not commutative. Indeed the OS 'linux' has a # special case: the version is the libc name, yet while "no version" stands # as a wildcard for a binary gem platform (as for other OSes), for the - # runtime platform "no version" stands for 'gnu'. To be able to disinguish + # runtime platform "no version" stands for 'gnu'. To be able to distinguish # these, the method receiver is the gem platform, while the argument is # the runtime platform. # @@ -235,11 +235,11 @@ class Gem::Platform # A pure-Ruby gem that may use Gem::Specification#extensions to build # binary files. - RUBY = "ruby".freeze + RUBY = "ruby" ## # A platform-specific gem that is built for the packaging Ruby's platform. # This will be replaced with Gem::Platform::local. - CURRENT = "current".freeze + CURRENT = "current" end diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb index 64f9ac3465..bc2fd9af55 100644 --- a/lib/rubygems/requirement.rb +++ b/lib/rubygems/requirement.rb @@ -22,7 +22,7 @@ class Gem::Requirement SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc: quoted = OPS.keys.map {|k| Regexp.quote k }.join "|" - PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*".freeze # :nodoc: + PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gem::Version::VERSION_PATTERN})\\s*" # :nodoc: ## # A regular expression that matches a requirement diff --git a/lib/rubygems/resolver/stats.rb b/lib/rubygems/resolver/stats.rb index 64b458f504..3b95efebf7 100644 --- a/lib/rubygems/resolver/stats.rb +++ b/lib/rubygems/resolver/stats.rb @@ -32,7 +32,7 @@ class Gem::Resolver::Stats @iterations += 1 end - PATTERN = "%20s: %d\n".freeze + PATTERN = "%20s: %d\n" def display $stdout.puts "=== Resolver Statistics ===" diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb index 512ca9143d..d87abdd993 100644 --- a/lib/rubygems/stub_specification.rb +++ b/lib/rubygems/stub_specification.rb @@ -6,10 +6,10 @@ class Gem::StubSpecification < Gem::BasicSpecification # :nodoc: - PREFIX = "# stub: ".freeze + PREFIX = "# stub: " # :nodoc: - OPEN_MODE = "r:UTF-8:-".freeze + OPEN_MODE = "r:UTF-8:-" class StubLine # :nodoc: all attr_reader :name, :version, :platform, :require_paths, :extensions, @@ -19,9 +19,9 @@ class Gem::StubSpecification < Gem::BasicSpecification # These are common require paths. REQUIRE_PATHS = { # :nodoc: - "lib" => "lib".freeze, - "test" => "test".freeze, - "ext" => "ext".freeze, + "lib" => "lib", + "test" => "test", + "ext" => "ext", }.freeze # These are common require path lists. This hash is used to optimize @@ -33,7 +33,7 @@ class Gem::StubSpecification < Gem::BasicSpecification }.freeze def initialize(data, extensions) - parts = data[PREFIX.length..-1].split(" ".freeze, 4) + parts = data[PREFIX.length..-1].split(" ", 4) @name = parts[0].freeze @version = if Gem::Version.correct?(parts[1]) Gem::Version.new(parts[1]) @@ -50,7 +50,7 @@ class Gem::StubSpecification < Gem::BasicSpecification end path_list = parts.last - @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! do |x| + @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0").map! do |x| REQUIRE_PATHS[x] || x end end diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb index d6b891380e..be811525f2 100644 --- a/lib/rubygems/text.rb +++ b/lib/rubygems/text.rb @@ -9,7 +9,7 @@ module Gem::Text # Remove any non-printable characters and make the text suitable for # printing. def clean_text(text) - text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze) + text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".") end def truncate_text(text, description, max_length = 100_000) diff --git a/lib/rubygems/util/licenses.rb b/lib/rubygems/util/licenses.rb index 96f47781c0..a823521d10 100644 --- a/lib/rubygems/util/licenses.rb +++ b/lib/rubygems/util/licenses.rb @@ -4,8 +4,8 @@ require_relative "../text" class Gem::Licenses extend Gem::Text - NONSTANDARD = "Nonstandard".freeze - LICENSE_REF = "LicenseRef-.+".freeze + NONSTANDARD = "Nonstandard" + LICENSE_REF = "LicenseRef-.+" # Software Package Data Exchange (SPDX) standard open-source software # license identifiers diff --git a/lib/rubygems/version.rb b/lib/rubygems/version.rb index f67889ef1a..903b7de99d 100644 --- a/lib/rubygems/version.rb +++ b/lib/rubygems/version.rb @@ -155,7 +155,7 @@ require_relative "deprecate" class Gem::Version include Comparable - VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?'.freeze # :nodoc: + VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc: ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})?\s*\z/.freeze # :nodoc: ## diff --git a/spec/bundler/bundler/dsl_spec.rb b/spec/bundler/bundler/dsl_spec.rb index 19c8f2e889..8cb51b8a52 100644 --- a/spec/bundler/bundler/dsl_spec.rb +++ b/spec/bundler/bundler/dsl_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Bundler::Dsl do subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5") github_uri = "https://github.com/indirect/sparks.git" expect(subject.dependencies.first.source.uri).to eq(github_uri) - expect(subject.dependencies.first.source.branch).to eq("refs/pull/5/head") + expect(subject.dependencies.first.source.ref).to eq("refs/pull/5/head") end it "rejects :github PR URI with a branch, ref or tag" do diff --git a/spec/bundler/bundler/plugin/index_spec.rb b/spec/bundler/bundler/plugin/index_spec.rb index d34b0de342..5a7047459f 100644 --- a/spec/bundler/bundler/plugin/index_spec.rb +++ b/spec/bundler/bundler/plugin/index_spec.rb @@ -140,7 +140,7 @@ RSpec.describe Bundler::Plugin::Index do describe "after conflict" do let(:commands) { ["foo"] } let(:sources) { ["bar"] } - let(:hooks) { ["hoook"] } + let(:hooks) { ["thehook"] } shared_examples "it cleans up" do it "the path" do @@ -156,7 +156,7 @@ RSpec.describe Bundler::Plugin::Index do end it "the hook" do - expect(index.hook_plugins("xhoook")).to be_empty + expect(index.hook_plugins("xthehook")).to be_empty end end @@ -164,7 +164,7 @@ RSpec.describe Bundler::Plugin::Index do before do expect do path = lib_path("cplugin") - index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["xbar"], ["xhoook"]) + index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["xbar"], ["xthehook"]) end.to raise_error(Index::CommandConflict) end @@ -175,7 +175,7 @@ RSpec.describe Bundler::Plugin::Index do before do expect do path = lib_path("cplugin") - index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["xfoo"], ["bar"], ["xhoook"]) + index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["xfoo"], ["bar"], ["xthehook"]) end.to raise_error(Index::SourceConflict) end @@ -186,7 +186,7 @@ RSpec.describe Bundler::Plugin::Index do before do expect do path = lib_path("cplugin") - index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["bar"], ["xhoook"]) + index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["bar"], ["xthehook"]) end.to raise_error(Index::CommandConflict) end diff --git a/spec/bundler/bundler/resolver/candidate_spec.rb b/spec/bundler/bundler/resolver/candidate_spec.rb index 0840f77245..cd52c867c4 100644 --- a/spec/bundler/bundler/resolver/candidate_spec.rb +++ b/spec/bundler/bundler/resolver/candidate_spec.rb @@ -3,8 +3,19 @@ RSpec.describe Bundler::Resolver::Candidate do it "compares fine" do version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }]) - version2 = described_class.new("1.12.5") + version2 = described_class.new("1.12.5") # passing no specs creates a platform specific candidate, so sorts higher - expect(version1 >= version2).to be true + expect(version2 >= version1).to be true + + expect(version1.generic! == version2.generic!).to be true + expect(version1.platform_specific! == version2.platform_specific!).to be true + + expect(version1.platform_specific! >= version2.generic!).to be true + expect(version2.platform_specific! >= version1.generic!).to be true + + version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }]) + version2 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::X64_LINUX }]) + + expect(version2 >= version1).to be true end end diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb index 24e3de7ba8..4636993d9f 100644 --- a/spec/bundler/bundler/settings_spec.rb +++ b/spec/bundler/bundler/settings_spec.rb @@ -27,7 +27,7 @@ RSpec.describe Bundler::Settings do "gem.mit" => "false", "gem.test" => "minitest", "thingy" => <<-EOS.tr("\n", " "), ---asdf --fdsa --ty=oh man i hope this doesnt break bundler because +--asdf --fdsa --ty=oh man i hope this doesn't break bundler because that would suck --ehhh=oh geez it looks like i might have broken bundler somehow --very-important-option=DontDeleteRoo --very-important-option=DontDeleteRoo diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb index 43ae9cdceb..3d8014b665 100644 --- a/spec/bundler/bundler/shared_helpers_spec.rb +++ b/spec/bundler/bundler/shared_helpers_spec.rb @@ -288,7 +288,7 @@ RSpec.describe Bundler::SharedHelpers do if Gem.respond_to?(:path_separator) allow(Gem).to receive(:path_separator).and_return(":") else - stub_const("File::PATH_SEPARATOR", ":".freeze) + stub_const("File::PATH_SEPARATOR", ":") end allow(Bundler).to receive(:bundle_path) { Pathname.new("so:me/dir/bin") } expect { subject.send(:validate_bundle_path) }.to raise_error( diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb index 36d7616949..5a5b534e8d 100644 --- a/spec/bundler/commands/add_spec.rb +++ b/spec/bundler/commands/add_spec.rb @@ -144,7 +144,7 @@ RSpec.describe "bundle add" do end describe "with --github" do - it "adds dependency with specified github source" do + it "adds dependency with specified github source", :realworld do bundle "add rake --github=ruby/rake" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake"}) @@ -152,7 +152,7 @@ RSpec.describe "bundle add" do end describe "with --github and --branch" do - it "adds dependency with specified github source and branch" do + it "adds dependency with specified github source and branch", :realworld do bundle "add rake --github=ruby/rake --branch=master" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :branch => "master"}) @@ -160,7 +160,7 @@ RSpec.describe "bundle add" do end describe "with --github and --ref" do - it "adds dependency with specified github source and ref" do + it "adds dependency with specified github source and ref", :realworld do bundle "add rake --github=ruby/rake --ref=5c60da8" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :ref => "5c60da8"}) diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb index 2634f43417..61a911621f 100644 --- a/spec/bundler/commands/binstubs_spec.rb +++ b/spec/bundler/commands/binstubs_spec.rb @@ -188,7 +188,7 @@ RSpec.describe "bundle binstubs <gem>" do lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0") end - it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev" do + it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev", :realworld => true do sys_exec "bin/bundle install --verbose", :artifice => "vcr" expect(exitstatus).not_to eq(42) expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.") @@ -224,7 +224,7 @@ RSpec.describe "bundle binstubs <gem>" do context "when update --bundler is called" do before { lockfile.gsub(system_bundler_version, "1.1.1") } - it "calls through to the latest bundler version" do + it "calls through to the latest bundler version", :realworld do sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" } using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out) expect(using_bundler_line).to_not be_nil diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb index 2b83a71dae..471cd6c354 100644 --- a/spec/bundler/commands/clean_spec.rb +++ b/spec/bundler/commands/clean_spec.rb @@ -625,7 +625,7 @@ RSpec.describe "bundle clean" do expect(out).to eq("1.0") end - it "when using --force, it doesn't remove default gem binaries" do + it "when using --force, it doesn't remove default gem binaries", :realworld do skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0" skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2 diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb index 1eeb276105..1afac00923 100644 --- a/spec/bundler/commands/doctor_spec.rb +++ b/spec/bundler/commands/doctor_spec.rb @@ -134,7 +134,7 @@ RSpec.describe "bundle doctor" do end end - context "when home contains filesname with special characters" do + context "when home contains filenames with special characters" do it "escape filename before command execute" do doctor = Bundler::CLI::Doctor.new({}) expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string") diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index c80b9dc646..38bef77eaf 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -319,6 +319,61 @@ RSpec.describe "bundle lock" do expect(lockfile.platforms).to match_array([x86_mingw32, specific_local_platform].uniq) end + it "also cleans up redundant platform gems when removing platforms" do + build_repo4 do + build_gem "nokogiri", "1.12.0" + build_gem "nokogiri", "1.12.0" do |s| + s.platform = "x86_64-darwin" + end + end + + simulate_platform "x86_64-darwin-22" do + install_gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + G + end + + lockfile <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.12.0) + nokogiri (1.12.0-x86_64-darwin) + + PLATFORMS + ruby + x86_64-darwin + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "x86_64-darwin-22" do + bundle "lock --remove-platform ruby" + end + + expect(lockfile).to eq <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.12.0-x86_64-darwin) + + PLATFORMS + x86_64-darwin + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + end + it "errors when removing all platforms" do bundle "lock --remove-platform #{specific_local_platform}", :raise_on_error => false expect(err).to include("Removing all platforms from the bundle is not allowed") diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb index 811fc255ef..cf612397ab 100644 --- a/spec/bundler/commands/viz_spec.rb +++ b/spec/bundler/commands/viz_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do +RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot"), :realworld => true do before do realworld_system_gems "ruby-graphviz --version 1.2.5" end diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index 3f386f65f4..b6ea32819b 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1481,8 +1481,6 @@ In Gemfile: describe "without git installed" do it "prints a better error message when installing" do - build_git "foo" - gemfile <<-G source "#{file_uri_for(gem_repo1)}" diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index 174bac511e..2199d8bedc 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -36,7 +36,7 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "fails", :bundler => "3" do - bundle :instal, :artifice => "compact_index", :raise_on_error => false + bundle :install, :artifice => "compact_index", :raise_on_error => false expect(err).to include("Each source after the first must include a block") expect(exitstatus).to eq(4) end @@ -1320,7 +1320,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(out).to include("Using example 0.1.0") end - it "fails inmmediately with a helpful error when a rubygems source does not exist and bundler/setup is required" do + it "fails immediately with a helpful error when a rubygems source does not exist and bundler/setup is required" do gemfile <<-G source "https://gem.repo1" @@ -1339,7 +1339,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to include("Could not find gem 'example' in locally installed gems.") end - it "fails inmmediately with a helpful error when a non retriable network error happens while resolving sources" do + it "fails immediately with a helpful error when a non retriable network error happens while resolving sources" do gemfile <<-G source "https://gem.repo1" diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 628ae89431..5d302a79ba 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -104,6 +104,47 @@ RSpec.describe "bundle install with specific platforms" do L end + it "still installs the generic RUBY variant if necessary even when running on a legacy lockfile locked only to RUBY" do + build_repo4 do + build_gem "nokogiri", "1.3.10" + build_gem "nokogiri", "1.3.10" do |s| + s.platform = "arm64-darwin" + s.required_ruby_version = "< #{Gem.ruby_version}" + end + + build_gem "bundler", "2.1.4" + end + + gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + G + + lockfile <<-L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.3.10) + + PLATFORMS + ruby + + DEPENDENCIES + nokogiri + + RUBY VERSION + 2.5.3p105 + + BUNDLED WITH + 2.1.4 + L + + simulate_platform "arm64-darwin-22" do + bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + end + 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") @@ -148,7 +189,7 @@ RSpec.describe "bundle install with specific platforms" do expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)") end - it "chooses platform specific gems even when resolving upon materialization and the API returns more specific plaforms first" do + it "chooses platform specific gems even when resolving upon materialization and the API returns more specific platforms first" do build_repo4 do build_gem("grpc", "1.50.0") build_gem("grpc", "1.50.0") {|s| s.platform = "universal-darwin" } @@ -268,7 +309,7 @@ RSpec.describe "bundle install with specific platforms" do ]) end - it "falls back on plain ruby when that version doesnt have a platform-specific gem" do + it "falls back on plain ruby when that version doesn't have a platform-specific gem" do setup_multiplatform_gem install_gemfile(google_protobuf) bundle "lock --add-platform=#{java}" @@ -483,6 +524,75 @@ RSpec.describe "bundle install with specific platforms" do L end + it "automatically fixes the lockfile if both RUBY platform and a more specific platform are locked, and some gem has no RUBY variant available" do + build_repo4 do + build_gem "nokogiri", "1.12.0" + build_gem "nokogiri", "1.12.0" do |s| + s.platform = "x86_64-darwin" + end + + build_gem "nokogiri", "1.13.0" + build_gem "nokogiri", "1.13.0" do |s| + s.platform = "x86_64-darwin" + end + + build_gem("sorbet-static", "0.5.10601") do |s| + s.platform = "x86_64-darwin" + end + end + + simulate_platform "x86_64-darwin-22" do + install_gemfile <<~G + source "#{file_uri_for(gem_repo4)}" + + gem "nokogiri" + gem "sorbet-static" + G + end + + lockfile <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.12.0) + nokogiri (1.12.0-x86_64-darwin) + sorbet-static (0.5.10601-x86_64-darwin) + + PLATFORMS + ruby + x86_64-darwin + + DEPENDENCIES + nokogiri + sorbet + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "x86_64-darwin-22" do + bundle "update --conservative nokogiri" + end + + expect(lockfile).to eq <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + nokogiri (1.13.0-x86_64-darwin) + sorbet-static (0.5.10601-x86_64-darwin) + + PLATFORMS + x86_64-darwin + + DEPENDENCIES + nokogiri + sorbet-static + + BUNDLED WITH + #{Bundler::VERSION} + L + end + it "automatically fixes the lockfile if only RUBY platform is locked and some gem has no RUBY variant available" do build_repo4 do build_gem("sorbet-static-and-runtime", "0.5.10160") do |s| @@ -607,7 +717,7 @@ RSpec.describe "bundle install with specific platforms" do G # simulate lockfile which includes both a precompiled gem with: - # - Gem the current platform (with imcompatible ruby version) + # - Gem the current platform (with incompatible ruby version) # - A source gem with compatible ruby version lockfile <<-L GEM diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb index ad7d8d9be6..ab10670fdf 100644 --- a/spec/bundler/install/gems/standalone_spec.rb +++ b/spec/bundler/install/gems/standalone_spec.rb @@ -157,7 +157,7 @@ RSpec.shared_examples "bundle install --standalone" do bundle "lock", :dir => cwd, :artifice => "compact_index" end - it "works and points to the vendored copies, not to the default copies" do + it "works and points to the vendored copies, not to the default copies", :realworld do bundle "config set --local path #{bundled_app("bundle")}" bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb index 6465bea0d2..7b7ceb4586 100644 --- a/spec/bundler/other/major_deprecation_spec.rb +++ b/spec/bundler/other/major_deprecation_spec.rb @@ -587,7 +587,7 @@ RSpec.describe "major deprecations" do pending "fails with a helpful message", :bundler => "3" end - context "bundle viz" do + context "bundle viz", :realworld do before do realworld_system_gems "ruby-graphviz --version 1.2.5" create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\"" diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index e1bb92d36e..d04da0c334 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -219,14 +219,14 @@ RSpec.describe "real world edgecases", :realworld => true do end it "doesn't hang on big gemfile" do - skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") + skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7") gemfile <<~G # frozen_string_literal: true source "https://rubygems.org" - ruby "2.7.3" + ruby "~> 2.7.7" gem "rails" gem "pg", ">= 0.18", "< 2.0" @@ -321,17 +321,17 @@ RSpec.describe "real world edgecases", :realworld => true do G if Bundler.feature_flag.bundler_3_mode? - # Conflicts on bundler version, so fails earlier + # Conflicts on bundler version, so we count attempts differently bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false - expect(out).to display_total_steps_of(435) + expect(out.split("\n").grep(/backtracking to/).count).to eq(8) else bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } - expect(out).to display_total_steps_of(1025) + expect(out).to include("Solution found after 7 attempts") end end it "doesn't hang on tricky gemfile" do - skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") + skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7") gemfile <<~G source 'https://rubygems.org' @@ -349,190 +349,168 @@ RSpec.describe "real world edgecases", :realworld => true do bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } - if Bundler.feature_flag.bundler_3_mode? - expect(out).to display_total_steps_of(890) - else - expect(out).to display_total_steps_of(891) - end + expect(out).to include("Solution found after 6 attempts") end it "doesn't hang on nix gemfile" do - skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM.include?("darwin") + skip "Only for ruby 3.0" unless RUBY_VERSION.start_with?("3.0") gemfile <<~G - source "https://rubygems.org" do - gem "addressable" - gem "atk" - gem "awesome_print" - gem "bacon" - gem "byebug" - gem "cairo" - gem "cairo-gobject" - gem "camping" - gem "charlock_holmes" - gem "cld3" - gem "cocoapods" - gem "cocoapods-acknowledgements" - gem "cocoapods-art" - gem "cocoapods-bin" - gem "cocoapods-browser" - gem "cocoapods-bugsnag" - gem "cocoapods-check" - gem "cocoapods-clean" - gem "cocoapods-clean_build_phases_scripts" - gem "cocoapods-core" - gem "cocoapods-coverage" - gem "cocoapods-deintegrate" - gem "cocoapods-dependencies" - gem "cocoapods-deploy" - gem "cocoapods-downloader" - gem "cocoapods-expert-difficulty" - gem "cocoapods-fix-react-native" - gem "cocoapods-generate" - gem "cocoapods-git_url_rewriter" - gem "cocoapods-keys" - gem "cocoapods-no-dev-schemes" - gem "cocoapods-open" - gem "cocoapods-packager" - gem "cocoapods-playgrounds" - gem "cocoapods-plugins" - gem "cocoapods-prune-localizations" - gem "cocoapods-rome" - gem "cocoapods-search" - gem "cocoapods-sorted-search" - gem "cocoapods-static-swift-framework" - gem "cocoapods-stats" - gem "cocoapods-tdfire-binary" - gem "cocoapods-testing" - gem "cocoapods-trunk" - gem "cocoapods-try" - gem "cocoapods-try-release-fix" - gem "cocoapods-update-if-you-dare" - gem "cocoapods-whitelist" - gem "cocoapods-wholemodule" - gem "coderay" - gem "concurrent-ruby" - gem "curb" - gem "curses" - gem "daemons" - gem "dep-selector-libgecode" - gem "digest-sha3" - gem "domain_name" - gem "do_sqlite3" - gem "ethon" - gem "eventmachine" - gem "excon" - gem "faraday" - gem "ffi" - gem "ffi-rzmq-core" - gem "fog-dnsimple" - gem "gdk_pixbuf2" - gem "gio2" - gem "gitlab-markup" - gem "glib2" - gem "gpgme" - gem "gtk2" - gem "hashie" - gem "highline" - gem "hike" - gem "hitimes" - gem "hpricot" - gem "httpclient" - gem "http-cookie" - gem "iconv" - gem "idn-ruby" - gem "jbuilder" - gem "jekyll" - gem "jmespath" - gem "jwt" - gem "libv8" - gem "libxml-ruby" - gem "magic" - gem "markaby" - gem "method_source" - gem "mini_magick" - gem "msgpack" - gem "mysql2" - gem "ncursesw" - gem "netrc" - gem "net-scp" - gem "net-ssh" - gem "nokogiri" - gem "opus-ruby" - gem "ovirt-engine-sdk" - gem "pango" - gem "patron" - gem "pcaprub" - gem "pg" - gem "pry" - gem "pry-byebug" - gem "pry-doc" - gem "public_suffix" - gem "puma" - gem "rails" - gem "rainbow" - gem "rbnacl" - gem "rb-readline" - gem "re2" - gem "redis" - gem "redis-rack" - gem "rest-client" - gem "rmagick" - gem "rpam2" - gem "rspec" - gem "rubocop" - gem "rubocop-performance" - gem "ruby-libvirt" - gem "ruby-lxc" - gem "ruby-progressbar" - gem "ruby-terminfo" - gem "ruby-vips" - gem "rubyzip" - gem "rugged" - gem "sassc" - gem "scrypt" - gem "semian" - gem "sequel" - gem "sequel_pg" - gem "simplecov" - gem "sinatra" - gem "slop" - gem "snappy" - gem "sqlite3" - gem "taglib-ruby" - gem "thrift" - gem "tilt" - gem "tiny_tds" - gem "treetop" - gem "typhoeus" - gem "tzinfo" - gem "unf_ext" - gem "uuid4r" - gem "whois" - gem "zookeeper" - end + source "https://rubygems.org" + + gem "addressable" + gem "atk" + gem "awesome_print" + gem "bacon" + gem "byebug" + gem "cairo" + gem "cairo-gobject" + gem "camping" + gem "charlock_holmes" + gem "cld3" + gem "cocoapods" + gem "cocoapods-acknowledgements" + gem "cocoapods-art" + gem "cocoapods-bin" + gem "cocoapods-browser" + gem "cocoapods-bugsnag" + gem "cocoapods-check" + gem "cocoapods-clean" + gem "cocoapods-clean_build_phases_scripts" + gem "cocoapods-core" + gem "cocoapods-coverage" + gem "cocoapods-deintegrate" + gem "cocoapods-dependencies" + gem "cocoapods-deploy" + gem "cocoapods-downloader" + gem "cocoapods-expert-difficulty" + gem "cocoapods-fix-react-native" + gem "cocoapods-generate" + gem "cocoapods-git_url_rewriter" + gem "cocoapods-keys" + gem "cocoapods-no-dev-schemes" + gem "cocoapods-open" + gem "cocoapods-packager" + gem "cocoapods-playgrounds" + gem "cocoapods-plugins" + gem "cocoapods-prune-localizations" + gem "cocoapods-rome" + gem "cocoapods-search" + gem "cocoapods-sorted-search" + gem "cocoapods-static-swift-framework" + gem "cocoapods-stats" + gem "cocoapods-tdfire-binary" + gem "cocoapods-testing" + gem "cocoapods-trunk" + gem "cocoapods-try" + gem "cocoapods-try-release-fix" + gem "cocoapods-update-if-you-dare" + gem "cocoapods-whitelist" + gem "cocoapods-wholemodule" + gem "coderay" + gem "concurrent-ruby" + gem "curb" + gem "curses" + gem "daemons" + gem "dep-selector-libgecode" + gem "digest-sha3" + gem "domain_name" + gem "do_sqlite3" + gem "ethon" + gem "eventmachine" + gem "excon" + gem "faraday" + gem "ffi" + gem "ffi-rzmq-core" + gem "fog-dnsimple" + gem "gdk_pixbuf2" + gem "gio2" + gem "gitlab-markup" + gem "glib2" + gem "gpgme" + gem "gtk2" + gem "hashie" + gem "highline" + gem "hike" + gem "hitimes" + gem "hpricot" + gem "httpclient" + gem "http-cookie" + gem "iconv" + gem "idn-ruby" + gem "jbuilder" + gem "jekyll" + gem "jmespath" + gem "jwt" + gem "libv8" + gem "libxml-ruby" + gem "magic" + gem "markaby" + gem "method_source" + gem "mini_magick" + gem "msgpack" + gem "mysql2" + gem "ncursesw" + gem "netrc" + gem "net-scp" + gem "net-ssh" + gem "nokogiri" + gem "opus-ruby" + gem "ovirt-engine-sdk" + gem "pango" + gem "patron" + gem "pcaprub" + gem "pg" + gem "pry" + gem "pry-byebug" + gem "pry-doc" + gem "public_suffix" + gem "puma" + gem "rails" + gem "rainbow" + gem "rbnacl" + gem "rb-readline" + gem "re2" + gem "redis" + gem "redis-rack" + gem "rest-client" + gem "rmagick" + gem "rpam2" + gem "rspec" + gem "rubocop" + gem "rubocop-performance" + gem "ruby-libvirt" + gem "ruby-lxc" + gem "ruby-progressbar" + gem "ruby-terminfo" + gem "ruby-vips" + gem "rubyzip" + gem "rugged" + gem "sassc" + gem "scrypt" + gem "semian" + gem "sequel" + gem "sequel_pg" + gem "simplecov" + gem "sinatra" + gem "slop" + gem "snappy" + gem "sqlite3" + gem "taglib-ruby" + gem "thrift" + gem "tilt" + gem "tiny_tds" + gem "treetop" + gem "typhoeus" + gem "tzinfo" + gem "unf_ext" + gem "uuid4r" + gem "whois" + gem "zookeeper" G bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } - if Bundler.feature_flag.bundler_3_mode? - expect(out).to display_total_steps_of(1874) - else - expect(out).to display_total_steps_of(1922) - end - end - - private - - RSpec::Matchers.define :display_total_steps_of do |expected_steps| - match do |out| - out.include?("BUNDLER: Finished resolution (#{expected_steps} steps)") - end - - failure_message do |out| - actual_steps = out.scan(/BUNDLER: Finished resolution \((\d+) steps\)/).first.first - - "Expected resolution to finish in #{expected_steps} steps, but took #{actual_steps}" - end + expect(out).to include("Solution found after 4 attempts") end end diff --git a/spec/bundler/realworld/ffi_spec.rb b/spec/bundler/realworld/ffi_spec.rb index 083ea38901..fdefc14091 100644 --- a/spec/bundler/realworld/ffi_spec.rb +++ b/spec/bundler/realworld/ffi_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe "loading dinamically linked library on a bundle exec context", :realworld => true do +RSpec.describe "loading dynamically linked library on a bundle exec context", :realworld => true do it "passes ENV right after argv in memory" do create_file "foo.rb", <<~RUBY require 'ffi' diff --git a/spec/bundler/realworld/git_spec.rb b/spec/bundler/realworld/git_spec.rb new file mode 100644 index 0000000000..3d352626ea --- /dev/null +++ b/spec/bundler/realworld/git_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.describe "github source", :realworld => true do + it "properly fetches PRs" do + install_gemfile <<-G + source "https://rubygems.org" + + gem "reline", github: "https://github.com/ruby/reline/pull/488" + G + end +end diff --git a/spec/bundler/resolver/platform_spec.rb b/spec/bundler/resolver/platform_spec.rb index 2d143fd84a..a710dfcb28 100644 --- a/spec/bundler/resolver/platform_spec.rb +++ b/spec/bundler/resolver/platform_spec.rb @@ -155,21 +155,32 @@ RSpec.describe "Resolving platform craziness" do end end - it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do - @index = build_index do - gem "foo", "1.0.0" - gem "foo", "1.0.0", "x64-mingw32" - gem "foo", "1.1.0" - gem "foo", "1.1.0", "x64-mingw32" do |s| - s.required_ruby_version = [">= 2.0", "< 2.4"] + context "when the platform specific gem doesn't match the required_ruby_version" do + before do + @index = build_index do + gem "foo", "1.0.0" + gem "foo", "1.0.0", "x64-mingw32" + gem "foo", "1.1.0" + gem "foo", "1.1.0", "x64-mingw32" do |s| + s.required_ruby_version = [">= 2.0", "< 2.4"] + end + gem "Ruby\0", "2.5.1" end - gem "Ruby\0", "2.5.1" + dep "Ruby\0", "2.5.1" + platforms "x64-mingw32" end - dep "foo" - dep "Ruby\0", "2.5.1" - platforms "x64-mingw32" - should_resolve_as %w[foo-1.1.0] + it "takes the latest ruby gem" do + dep "foo" + + should_resolve_as %w[foo-1.1.0] + end + + it "takes the latest ruby gem, even if requirement does not match previous versions with the same ruby requirement" do + dep "foo", "1.1.0" + + should_resolve_as %w[foo-1.1.0] + end end it "takes the latest ruby gem with required_ruby_version if the platform specific gem doesn't match the required_ruby_version" do diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index fd1dd6dc26..abef235e08 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -436,7 +436,7 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end - it "when requiring fileutils after does not show redefinition warnings" do + it "when requiring fileutils after does not show redefinition warnings", :realworld do dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty? diff --git a/spec/bundler/runtime/self_management_spec.rb b/spec/bundler/runtime/self_management_spec.rb index 0032c6aef6..61cfc9b795 100644 --- a/spec/bundler/runtime/self_management_spec.rb +++ b/spec/bundler/runtime/self_management_spec.rb @@ -91,7 +91,7 @@ RSpec.describe "Self management", :rubygems => ">= 3.3.0.dev", :realworld => tru expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION) end - it "shows a discreet message if locked bundler does not exist" do + it "shows a discrete message if locked bundler does not exist" do missing_minor ="#{Bundler::VERSION[0]}.999.999" lockfile_bundled_with(missing_minor) diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index f244289c88..f5b86433dc 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -556,12 +556,12 @@ RSpec.describe "Bundler.setup" do gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistant" + gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistent" G bundle %(config set local.rack #{lib_path("local-rack")}) run "require 'rack'", :raise_on_error => false - expect(err).to match(/is using branch main but Gemfile specifies nonexistant/) + expect(err).to match(/is using branch main but Gemfile specifies nonexistent/) end end diff --git a/spec/bundler/support/artifice/vcr.rb b/spec/bundler/support/artifice/vcr.rb index 8428391688..6a346f1ff9 100644 --- a/spec/bundler/support/artifice/vcr.rb +++ b/spec/bundler/support/artifice/vcr.rb @@ -4,6 +4,7 @@ require "net/http" require_relative "../path" CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes" +USED_CASSETTES_PATH = "#{Spec::Path.spec_dir}/support/artifice/used_cassettes.txt" CASSETTE_NAME = ENV.fetch("BUNDLER_SPEC_VCR_CASSETTE_NAME") { "realworld" } class BundlerVCRHTTP < Net::HTTP @@ -22,6 +23,10 @@ class BundlerVCRHTTP < Net::HTTP @__vcr_request_handler = handler end + File.open(USED_CASSETTES_PATH, "a+") do |f| + f.puts request_pair_paths.map {|path| Pathname.new(path).relative_path_from(Spec::Path.source_root).to_s }.join("\n") + end + if recorded_response? recorded_response else @@ -74,25 +79,8 @@ class BundlerVCRHTTP < Net::HTTP def request_pair_paths %w[request response].map do |kind| - File.join(CASSETTE_PATH, CASSETTE_NAME, file_name_for_key(key + [kind])) - end - end - - def read_stored_request(path) - contents = File.binread(path) - headers = {} - method = nil - path = nil - contents.lines.grep(/^> /).each do |line| - if line =~ /^> (GET|HEAD|POST|PATCH|PUT|DELETE) (.*)/ - method = $1 - path = $2.strip - elsif line =~ /^> (.*?): (.*)/ - headers[$1] = $2 - end + File.join(CASSETTE_PATH, CASSETTE_NAME, file_name_for_key(key), kind) end - body = contents =~ /^([^>].*)/m && $1 - Net::HTTP.const_get(method.capitalize).new(path, headers).tap {|r| r.body = body if body } end def request_to_string(request) diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index b4d4976379..3aa5454b6a 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -298,10 +298,6 @@ module Spec end end - def build_dep(name, requirements = Gem::Requirement.default, type = :runtime) - Bundler::Dependency.new(name, :version => requirements) - end - def build_lib(name, *args, &blk) build_with(LibBuilder, name, args, &blk) end diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index aab875fec9..c4c69be75e 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -1555,7 +1555,7 @@ Also, a list: # :stopdoc: # only available in RubyGems tests - PRIVATE_KEY_PASSPHRASE = "Foo bar".freeze + PRIVATE_KEY_PASSPHRASE = "Foo bar" begin PRIVATE_KEY = load_key "private" diff --git a/test/rubygems/simple_gem.rb b/test/rubygems/simple_gem.rb index 0f2ea48198..1650910aaf 100644 --- a/test/rubygems/simple_gem.rb +++ b/test/rubygems/simple_gem.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -SIMPLE_GEM = <<-GEMDATA.freeze +SIMPLE_GEM = <<-GEMDATA MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405" if $0 == __FILE__ require 'optparse' diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index dd688a4421..02c6a1b957 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -8,7 +8,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase if File.exist?(bundler_gemspec) BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1] else - BUNDLER_VERS = "2.0.1".freeze + BUNDLER_VERS = "2.0.1" end def setup diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 5f54230c77..098df5a538 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -28,7 +28,7 @@ require "rubygems/package" class TestGemRemoteFetcher < Gem::TestCase include Gem::DefaultUserInteraction - SERVER_DATA = <<-EOY.freeze + SERVER_DATA = <<-EOY --- !ruby/object:Gem::Cache gems: rake-0.4.11: !ruby/object:Gem::Specification diff --git a/test/rubygems/test_gem_request_set_lockfile_parser.rb b/test/rubygems/test_gem_request_set_lockfile_parser.rb index 757c764dc1..ecb145e697 100644 --- a/test/rubygems/test_gem_request_set_lockfile_parser.rb +++ b/test/rubygems/test_gem_request_set_lockfile_parser.rb @@ -275,7 +275,7 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - refute lockfile_set, "fount a LockSet" + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set @@ -318,7 +318,7 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - refute lockfile_set, "fount a LockSet" + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set @@ -355,7 +355,7 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - refute lockfile_set, "fount a LockSet" + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set @@ -392,7 +392,7 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - refute lockfile_set, "fount a LockSet" + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index dda47e6bdf..b20e8b321a 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -10,7 +10,7 @@ require "rubygems/installer" require "rubygems/platform" class TestGemSpecification < Gem::TestCase - LEGACY_YAML_SPEC = <<-EOF.freeze + LEGACY_YAML_SPEC = <<-EOF --- !ruby/object:Gem::Specification rubygems_version: "1.0" name: keyedlist @@ -29,7 +29,7 @@ email: flgr@ccan.de has_rdoc: true EOF - LEGACY_RUBY_SPEC = <<-EOF.freeze + LEGACY_RUBY_SPEC = <<-EOF Gem::Specification.new do |s| s.name = %q{keyedlist} s.version = %q{0.4.0} diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index 9237608d4a..f45c72b29c 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -43,7 +43,7 @@ class TestGemVersion < Gem::TestCase assert_equal v("5.1"), Gem::Version.create("5.1") - ver = "1.1".freeze + ver = "1.1" assert_equal v("1.1"), Gem::Version.create(ver) end @@ -88,7 +88,7 @@ class TestGemVersion < Gem::TestCase end def test_initialize - ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0".freeze].each do |good| + ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0"].each do |good| assert_version_equal "1.0", good end |