diff options
Diffstat (limited to 'lib')
146 files changed, 1733 insertions, 1057 deletions
diff --git a/lib/bundled_gems.rb b/lib/bundled_gems.rb index fab79f42a9..50fc31937c 100644 --- a/lib/bundled_gems.rb +++ b/lib/bundled_gems.rb @@ -49,12 +49,7 @@ module Gem::BUNDLED_GEMS # :nodoc: kernel_class.send(:alias_method, :no_warning_require, :require) kernel_class.send(:define_method, :require) do |name| if message = ::Gem::BUNDLED_GEMS.warning?(name, specs: spec_names) - uplevel = ::Gem::BUNDLED_GEMS.uplevel - if uplevel > 0 - Kernel.warn message, uplevel: uplevel - else - Kernel.warn message - end + Kernel.warn message, uplevel: ::Gem::BUNDLED_GEMS.uplevel end kernel_class.send(:no_warning_require, name) end @@ -86,11 +81,10 @@ module Gem::BUNDLED_GEMS # :nodoc: uplevel += 1 # Don't show script name when bundle exec and call ruby script directly. if cl.path.end_with?("bundle") - frame_count = 0 - break + return end end - require_found ? 1 : frame_count - 1 + require_found ? 1 : (frame_count - 1).nonzero? end def self.warning?(name, specs: nil) @@ -105,11 +99,14 @@ module Gem::BUNDLED_GEMS # :nodoc: # and `require "syslog"` to `require "#{ARCHDIR}/syslog.so"`. feature.delete_prefix!(ARCHDIR) feature.delete_prefix!(LIBDIR) - segments = feature.split("/") + # 1. A segment for the EXACT mapping and SINCE check + # 2. A segment for the SINCE check for dashed names + # 3. A segment to check if there's a subfeature + segments = feature.split("/", 3) name = segments.shift name = EXACT[name] || name if !SINCE[name] - name = [name, segments.shift].join("-") + name = "#{name}-#{segments.shift}" return unless SINCE[name] end segments.any? @@ -124,24 +121,24 @@ module Gem::BUNDLED_GEMS # :nodoc: return if WARNED[name] WARNED[name] = true - level = RUBY_VERSION < SINCE[name] ? "warning" : "error" + level = RUBY_VERSION < SINCE[name] ? :warning : :error if subfeature "#{feature} is found in #{name}, which" else - "#{feature} #{level == "warning" ? "was loaded" : "used to be loaded"} from the standard library, but" + "#{feature} #{level == :warning ? "was loaded" : "used to be loaded"} from the standard library, but" end + build_message(name, level) end def self.build_message(name, level) - msg = if level == "warning" + msg = if level == :warning " will no longer be part of the default gems starting from Ruby #{SINCE[name]}" else " is not part of the default gems since Ruby #{SINCE[name]}." end if defined?(Bundler) - motivation = level == "warning" ? "silence this warning" : "fix this error" + motivation = level == :warning ? "silence this warning" : "fix this error" msg += "\nYou can add #{name} to your Gemfile or gemspec to #{motivation}." # We detect the gem name from caller_locations. First we walk until we find `require` @@ -236,7 +233,7 @@ class LoadError name = path.tr("/", "-") if !defined?(Bundler) && Gem::BUNDLED_GEMS::SINCE[name] && !Gem::BUNDLED_GEMS::WARNED[name] - warn name + Gem::BUNDLED_GEMS.build_message(name, "error"), uplevel: Gem::BUNDLED_GEMS.uplevel + warn name + Gem::BUNDLED_GEMS.build_message(name, :error), uplevel: Gem::BUNDLED_GEMS.uplevel end super end diff --git a/lib/bundler.rb b/lib/bundler.rb index eea3b0cf17..d3219fe46e 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -53,7 +53,6 @@ module Bundler autoload :FeatureFlag, File.expand_path("bundler/feature_flag", __dir__) autoload :FREEBSD, File.expand_path("bundler/constants", __dir__) autoload :GemHelper, File.expand_path("bundler/gem_helper", __dir__) - autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) autoload :Graph, File.expand_path("bundler/graph", __dir__) autoload :Index, File.expand_path("bundler/index", __dir__) @@ -114,13 +113,13 @@ module Bundler end def configured_bundle_path - @configured_bundle_path ||= settings.path.tap(&:validate!) + @configured_bundle_path ||= Bundler.settings.path.tap(&:validate!) end # Returns absolute location of where binstubs are installed to. def bin_path @bin_path ||= begin - path = settings[:bin] || "bin" + path = Bundler.settings[:bin] || "bin" path = Pathname.new(path).expand_path(root).expand_path mkdir_p(path) path @@ -174,14 +173,14 @@ module Bundler self_manager.restart_with_locked_bundler_if_needed end - # Automatically install dependencies if Bundler.settings[:auto_install] exists. + # Automatically install dependencies if settings[:auto_install] exists. # This is set through config cmd `bundle config set --global auto_install 1`. # # Note that this method `nil`s out the global Definition object, so it # should be called first, before you instantiate anything like an # `Installer` that'll keep a reference to the old one instead. def auto_install - return unless settings[:auto_install] + return unless Bundler.settings[:auto_install] begin definition.specs @@ -239,10 +238,10 @@ module Bundler end def frozen_bundle? - frozen = settings[:frozen] + frozen = Bundler.settings[:frozen] return frozen unless frozen.nil? - settings[:deployment] + Bundler.settings[:deployment] end def locked_gems @@ -343,7 +342,7 @@ module Bundler def app_cache(custom_path = nil) path = custom_path || root - Pathname.new(path).join(settings.app_cache_path) + Pathname.new(path).join(Bundler.settings.app_cache_path) end def tmp(name = Process.pid.to_s) @@ -455,10 +454,14 @@ module Bundler end def local_platform - return Gem::Platform::RUBY if settings[:force_ruby_platform] + return Gem::Platform::RUBY if Bundler.settings[:force_ruby_platform] Gem::Platform.local end + def generic_local_platform + Gem::Platform.generic(local_platform) + end + def default_gemfile SharedHelpers.default_gemfile end @@ -564,7 +567,7 @@ module Bundler end def feature_flag - @feature_flag ||= FeatureFlag.new(VERSION) + @feature_flag ||= FeatureFlag.new(Bundler.settings[:simulate_version] || VERSION) end def reset! @@ -580,7 +583,6 @@ module Bundler def reset_paths! @bin_path = nil - @bundler_major_version = nil @bundle_path = nil @configure = nil @configured_bundle_path = nil diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec index 88411f295d..16ca4a022c 100644 --- a/lib/bundler/bundler.gemspec +++ b/lib/bundler/bundler.gemspec @@ -29,10 +29,10 @@ Gem::Specification.new do |s| "source_code_uri" => "https://github.com/rubygems/rubygems/tree/master/bundler", } - s.required_ruby_version = ">= 3.1.0" + s.required_ruby_version = ">= 3.2.0" # It should match the RubyGems version shipped with `required_ruby_version` above - s.required_rubygems_version = ">= 3.3.3" + s.required_rubygems_version = ">= 3.4.1" s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 51f71af501..25e442c04f 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -77,7 +77,7 @@ module Bundler self.options ||= {} unprinted_warnings = Bundler.ui.unprinted_warnings Bundler.ui = UI::Shell.new(options) - Bundler.ui.level = "debug" if options["verbose"] + Bundler.ui.level = "debug" if options[:verbose] || Bundler.settings[:verbose] unprinted_warnings.each {|w| Bundler.ui.warn(w) } end @@ -130,7 +130,7 @@ module Bundler if man_pages.include?(command) man_page = man_pages[command] - if Bundler.which("man") && !man_path.match?(%r{^file:/.+!/META-INF/jruby.home/.+}) + if Bundler.which("man") && !man_path.match?(%r{^(?:file:/.+!|uri:classloader:)/META-INF/jruby.home/.+}) Kernel.exec("man", man_page) else puts File.read("#{man_path}/#{File.basename(man_page)}.ronn") @@ -489,10 +489,10 @@ module Bundler build_info = " (#{BuildMetadata.built_at} commit #{BuildMetadata.git_commit_sha})" end - if !cli_help && Bundler.feature_flag.print_only_version_number? - Bundler.ui.info "#{Bundler::VERSION}#{build_info}" + if !cli_help && Bundler.feature_flag.bundler_4_mode? + Bundler.ui.info "#{Bundler.verbose_version}#{build_info}" else - Bundler.ui.info "Bundler version #{Bundler::VERSION}#{build_info}" + Bundler.ui.info "Bundler version #{Bundler.verbose_version}#{build_info}" end end @@ -512,7 +512,7 @@ module Bundler end end - unless Bundler.feature_flag.bundler_3_mode? + unless Bundler.feature_flag.bundler_4_mode? desc "viz [OPTIONS]", "Generates a visual dependency graph", hide: true long_desc <<-D Viz generates a PNG file of the current Gemfile as a dependency graph. @@ -544,6 +544,7 @@ module Bundler method_option :ci, type: :string, lazy_default: Bundler.settings["gem.ci"] || "", enum: %w[github gitlab circle], desc: "Generate CI configuration, either GitHub Actions, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|gitlab|circle)`" method_option :linter, type: :string, lazy_default: Bundler.settings["gem.linter"] || "", enum: %w[rubocop standard], 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>`." + method_option :bundle, type: :boolean, default: Bundler.settings["gem.bundle"], desc: "Automatically run `bundle install` after creation. Set a default with `bundle config set --global gem.bundle true`" def gem(name) require_relative "cli/gem" @@ -713,14 +714,9 @@ module Bundler command_name = cmd.name return if PARSEABLE_COMMANDS.include?(command_name) command = ["bundle", command_name] + args - options_to_print = options.dup - options_to_print.delete_if do |k, v| - next unless o = cmd.options[k] - o.default == v - end - command << Thor::Options.to_switches(options_to_print.sort_by(&:first)).strip + command << Thor::Options.to_switches(options.sort_by(&:first)).strip command.reject!(&:empty?) - Bundler.ui.info "Running `#{command * " "}` with bundler #{Bundler::VERSION}" + Bundler.ui.info "Running `#{command * " "}` with bundler #{Bundler.verbose_version}" end def warn_on_outdated_bundler diff --git a/lib/bundler/cli/config.rb b/lib/bundler/cli/config.rb index 77b502fe60..d963679085 100644 --- a/lib/bundler/cli/config.rb +++ b/lib/bundler/cli/config.rb @@ -26,8 +26,8 @@ module Bundler end message = "Using the `config` command without a subcommand [list, get, set, unset] is deprecated and will be removed in the future. Use `bundle #{new_args.join(" ")}` instead." - removed_message = "Using the `config` command without a subcommand [list, get, set, unset] is has been removed. Use `bundle #{new_args.join(" ")}` instead." - SharedHelpers.major_deprecation 3, message, removed_message: removed_message + removed_message = "Using the `config` command without a subcommand [list, get, set, unset] has been removed. Use `bundle #{new_args.join(" ")}` instead." + SharedHelpers.major_deprecation 4, message, removed_message: removed_message Base.new(options, name, value, self).run end diff --git a/lib/bundler/cli/doctor/diagnose.rb b/lib/bundler/cli/doctor/diagnose.rb index c5da23acb8..a878025dda 100644 --- a/lib/bundler/cli/doctor/diagnose.rb +++ b/lib/bundler/cli/doctor/diagnose.rb @@ -24,7 +24,7 @@ module Bundler def dylibs_darwin(path) output = `/usr/bin/otool -L #{path.shellescape}`.chomp - dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq + dylibs = output.split("\n")[1..-1].filter_map {|l| l.match(DARWIN_REGEX)&.match(1) }.uniq # ignore @rpath and friends dylibs.reject {|dylib| dylib.start_with? "@" } end diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb index 22bcf0e47a..34f6a22652 100644 --- a/lib/bundler/cli/gem.rb +++ b/lib/bundler/cli/gem.rb @@ -31,7 +31,6 @@ module Bundler @extension = options[:ext] validate_ext_name if @extension - validate_rust_builder_rubygems_version if @extension == "rust" end def run @@ -69,12 +68,14 @@ module Bundler test: options[:test], ext: extension, exe: options[:exe], + bundle: options[:bundle], bundler_version: bundler_dependency_version, git: use_git, github_username: github_username.empty? ? "[USERNAME]" : github_username, required_ruby_version: required_ruby_version, rust_builder_required_rubygems_version: rust_builder_required_rubygems_version, minitest_constant_name: minitest_constant_name, + ignore_paths: %w[bin/], } ensure_safe_gem_name(name, constant_array) @@ -95,7 +96,18 @@ module Bundler bin/setup ] - templates.merge!("gitignore.tt" => ".gitignore") if use_git + case Bundler.preferred_gemfile_name + when "Gemfile" + config[:ignore_paths] << "Gemfile" + when "gems.rb" + config[:ignore_paths] << "gems.rb" + config[:ignore_paths] << "gems.locked" + end + + if use_git + templates.merge!("gitignore.tt" => ".gitignore") + config[:ignore_paths] << ".gitignore" + end if test_framework = ask_and_set_test_framework config[:test] = test_framework @@ -109,6 +121,8 @@ module Bundler "spec/newgem_spec.rb.tt" => "spec/#{namespaced_path}_spec.rb" ) config[:test_task] = :spec + config[:ignore_paths] << ".rspec" + config[:ignore_paths] << "spec/" when "minitest" # Generate path for minitest target file (FileList["test/**/test_*.rb"]) # foo => test/test_foo.rb @@ -123,12 +137,14 @@ module Bundler "test/minitest/test_newgem.rb.tt" => "test/#{minitest_namespaced_path}.rb" ) config[:test_task] = :test + config[:ignore_paths] << "test/" when "test-unit" templates.merge!( "test/test-unit/test_helper.rb.tt" => "test/test_helper.rb", "test/test-unit/newgem_test.rb.tt" => "test/#{namespaced_path}_test.rb" ) config[:test_task] = :test + config[:ignore_paths] << "test/" end end @@ -136,13 +152,13 @@ module Bundler case config[:ci] when "github" templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml") - config[:ci_config_path] = ".github " + config[:ignore_paths] << ".github/" when "gitlab" templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml") - config[:ci_config_path] = ".gitlab-ci.yml " + config[:ignore_paths] << ".gitlab-ci.yml" when "circle" templates.merge!("circleci/config.yml.tt" => ".circleci/config.yml") - config[:ci_config_path] = ".circleci " + config[:ignore_paths] << ".circleci/" end if ask_and_set(:mit, "Do you want to license your code permissively under the MIT license?", @@ -185,10 +201,12 @@ module Bundler config[:linter_version] = rubocop_version Bundler.ui.info "RuboCop enabled in config" templates.merge!("rubocop.yml.tt" => ".rubocop.yml") + config[:ignore_paths] << ".rubocop.yml" when "standard" config[:linter_version] = standard_version Bundler.ui.info "Standard enabled in config" templates.merge!("standard.yml.tt" => ".standard.yml") + config[:ignore_paths] << ".standard.yml" end if config[:exe] @@ -241,6 +259,13 @@ module Bundler IO.popen(%w[git add .], { chdir: target }, &:read) end + if config[:bundle] + Bundler.ui.info "Running bundle install in the new gem directory." + Dir.chdir(target) do + system("bundle install") + end + end + # Open gemspec in editor open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit] @@ -446,7 +471,7 @@ module Bundler end def required_ruby_version - "3.1.0" + "3.2.0" end def rubocop_version @@ -456,12 +481,5 @@ module Bundler def standard_version "1.3" end - - def validate_rust_builder_rubygems_version - if Gem::Version.new(rust_builder_required_rubygems_version) > Gem.rubygems_version - Bundler.ui.error "Your RubyGems version (#{Gem.rubygems_version}) is too old to build Rust extension. Please update your RubyGems using `gem update --system` or any other way and try again." - exit 1 - end - end end end diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index b0b354cf10..94d485682d 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -66,7 +66,9 @@ module Bundler Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins? - definition = Bundler.definition + # For install we want to enable strict validation + # (rather than some optimizations we perform at app runtime). + definition = Bundler.definition(strict: true) definition.validate_runtime! installer = Installer.install(Bundler.root, definition, options) diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb index 1be44ff4b4..0c8ba3ebf7 100644 --- a/lib/bundler/cli/outdated.rb +++ b/lib/bundler/cli/outdated.rb @@ -155,7 +155,7 @@ module Bundler return active_spec if strict - active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version) + active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.installable_on_platform?(current_spec.platform) }.sort_by(&:version) if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1 active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? } end diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb index 985e8db051..ba3f1ec056 100644 --- a/lib/bundler/cli/update.rb +++ b/lib/bundler/cli/update.rb @@ -26,7 +26,7 @@ module Bundler if Bundler.feature_flag.update_requires_all_flag? raise InvalidOption, "To update everything, pass the `--all` flag." end - SharedHelpers.major_deprecation 3, "Pass --all to `bundle update` to update everything" + SharedHelpers.major_deprecation 4, "Pass --all to `bundle update` to update everything" elsif !full_update && options[:all] raise InvalidOption, "Cannot specify --all along with specific options." end @@ -92,7 +92,7 @@ module Bundler locked_spec = locked_info[:spec] new_spec = Bundler.definition.specs[name].first unless new_spec - unless locked_spec.match_platform(Bundler.local_platform) + unless locked_spec.installable_on_platform?(Bundler.local_platform) Bundler.ui.warn "Bundler attempted to update #{name} but it was not considered because it is for a different platform from the current one" end diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb index e7c872031f..faec695369 100644 --- a/lib/bundler/current_ruby.rb +++ b/lib/bundler/current_ruby.rb @@ -32,7 +32,7 @@ module Bundler end.freeze def ruby? - return true if Bundler::GemHelpers.generic_local_platform_is_ruby? + return true if Bundler::MatchPlatform.generic_local_platform_is_ruby? !windows? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby") end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index e9b67005a9..32006af109 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -4,8 +4,6 @@ require_relative "lockfile_parser" module Bundler class Definition - include GemHelpers - class << self # Do not create or modify a lockfile (Makes #lock a noop) attr_accessor :no_lock @@ -62,6 +60,7 @@ module Bundler if unlock == true @unlocking_all = true + strict = false @unlocking_bundler = false @unlocking = unlock @sources_to_unlock = [] @@ -70,6 +69,7 @@ module Bundler conservative = false else @unlocking_all = false + strict = unlock.delete(:strict) @unlocking_bundler = unlock.delete(:bundler) @unlocking = unlock.any? {|_k, v| !Array(v).empty? } @sources_to_unlock = unlock.delete(:sources) || [] @@ -99,7 +99,7 @@ module Bundler if lockfile_exists? @lockfile_contents = Bundler.read_file(lockfile) - @locked_gems = LockfileParser.new(@lockfile_contents) + @locked_gems = LockfileParser.new(@lockfile_contents, strict: strict) @locked_platforms = @locked_gems.platforms @most_specific_locked_platform = @locked_gems.most_specific_locked_platform @platforms = @locked_platforms.dup @@ -282,7 +282,7 @@ module Bundler end def filter_relevant(dependencies) - platforms_array = [generic_local_platform].freeze + platforms_array = [Bundler.generic_local_platform].freeze dependencies.select do |d| d.should_include? && !d.gem_platforms(platforms_array).empty? end @@ -456,8 +456,8 @@ module Bundler return if current_platform_locked? || @platforms.include?(Gem::Platform::RUBY) raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \ - "but your local platform is #{local_platform}. " \ - "Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again." + "but your local platform is #{Bundler.local_platform}. " \ + "Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again." end def normalize_platforms @@ -568,7 +568,7 @@ module Bundler end def should_add_extra_platforms? - !lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform] + !lockfile_exists? && Bundler::MatchPlatform.generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform] end def lockfile_exists? @@ -632,7 +632,7 @@ module Bundler @resolution_base ||= begin last_resolve = converge_locked_specs remove_invalid_platforms! - new_resolution_platforms = @current_platform_missing ? @new_platforms + [local_platform] : @new_platforms + new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms base = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms) base = additional_base_requirements_to_prevent_downgrades(base) base = additional_base_requirements_to_force_updates(base) @@ -738,8 +738,8 @@ module Bundler end def start_resolution - local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && [email protected]?(local_platform) - @platforms << local_platform if local_platform_needed_for_resolvability + local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && [email protected]?(Bundler.local_platform) + @platforms << Bundler.local_platform if local_platform_needed_for_resolvability add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby" result = SpecSet.new(resolver.start) @@ -758,7 +758,7 @@ module Bundler if result.incomplete_for_platform?(current_dependencies, @most_specific_non_local_locked_platform) @platforms.delete(@most_specific_non_local_locked_platform) elsif local_platform_needed_for_resolvability - @platforms.delete(local_platform) + @platforms.delete(Bundler.local_platform) end end @@ -777,17 +777,17 @@ module Bundler def current_platform_locked? @platforms.any? do |bundle_platform| - generic_local_platform == bundle_platform || local_platform === bundle_platform + Bundler.generic_local_platform == bundle_platform || Bundler.local_platform === bundle_platform end end def add_current_platform - return if @platforms.include?(local_platform) + return if @platforms.include?(Bundler.local_platform) @most_specific_non_local_locked_platform = find_most_specific_locked_platform return if @most_specific_non_local_locked_platform - @platforms << local_platform + @platforms << Bundler.local_platform true end @@ -1037,17 +1037,16 @@ module Bundler lockfile_source = s.source if dep - gemfile_source = dep.source || default_source - - deps << dep if !dep.source || lockfile_source.include?(dep.source) || new_deps.include?(dep) + replacement_source = dep.source - # Replace the locked dependency's source with the equivalent source from the Gemfile - s.source = gemfile_source + deps << dep if !replacement_source || lockfile_source.include?(replacement_source) || new_deps.include?(dep) else - # Replace the locked dependency's source with the default source, if the locked source is no longer in the Gemfile - s.source = default_source unless sources.get(lockfile_source) + replacement_source = sources.get(lockfile_source) end + # Replace the locked dependency's source with the equivalent source from the Gemfile + s.source = replacement_source || default_source + source = s.source next if @sources_to_unlock.include?(source.name) @@ -1168,7 +1167,7 @@ module Bundler def remove_invalid_platforms! return if Bundler.frozen_bundle? - skips = (@new_platforms + [local_platform]).uniq + skips = (@new_platforms + [Bundler.local_platform]).uniq # We should probably avoid removing non-ruby platforms, since that means # lockfile will no longer install on those platforms, so a error to give diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index e81696ff42..cb9c7a76ea 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -99,7 +99,7 @@ module Bundler return RUBY_PLATFORM_ARRAY if force_ruby_platform return valid_platforms if platforms.empty? - valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) } + valid_platforms.select {|p| expanded_platforms.include?(Gem::Platform.generic(p)) } end def expanded_platforms diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 32f45d97ec..4f9fbc55b1 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -73,7 +73,7 @@ module Bundler case specs_by_name_and_version.size when 1 specs = specs_by_name_and_version.values.first - spec = specs.find {|s| s.match_platform(Bundler.local_platform) } || specs.first + spec = specs.find {|s| s.installable_on_platform?(Bundler.local_platform) } || specs.first @gemspecs << spec @@ -521,7 +521,7 @@ module Bundler end def multiple_global_source_warning - if Bundler.feature_flag.bundler_3_mode? + if Bundler.feature_flag.bundler_4_mode? msg = "This Gemfile contains multiple global sources. " \ "Each source after the first must include a block to indicate which gems " \ "should come from that source" diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb index b19cf42cc3..b36d7e73e9 100644 --- a/lib/bundler/feature_flag.rb +++ b/lib/bundler/feature_flag.rb @@ -27,20 +27,27 @@ module Bundler (1..10).each {|v| define_method("bundler_#{v}_mode?") { @major_version >= v } } - settings_flag(:allow_offline_install) { bundler_3_mode? } - 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(:forget_cli_options) { bundler_3_mode? } - settings_flag(:global_gem_cache) { bundler_3_mode? } - settings_flag(:lockfile_checksums) { bundler_3_mode? } - settings_flag(:path_relative_to_cwd) { bundler_3_mode? } + settings_flag(:allow_offline_install) { bundler_4_mode? } + settings_flag(:auto_clean_without_path) { bundler_4_mode? } + settings_flag(:cache_all) { bundler_4_mode? } + settings_flag(:default_install_uses_path) { bundler_4_mode? } + settings_flag(:forget_cli_options) { bundler_4_mode? } + settings_flag(:global_gem_cache) { bundler_4_mode? } + settings_flag(:lockfile_checksums) { bundler_4_mode? } + settings_flag(:path_relative_to_cwd) { bundler_4_mode? } settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") } - settings_flag(:print_only_version_number) { bundler_3_mode? } - settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? } - settings_flag(:update_requires_all_flag) { bundler_4_mode? } + settings_flag(:setup_makes_kernel_gem_public) { !bundler_4_mode? } + settings_flag(:update_requires_all_flag) { bundler_5_mode? } - settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install } + settings_option(:default_cli_command) { bundler_4_mode? ? :cli_help : :install } + + def removed_major?(target_major_version) + @major_version > target_major_version + end + + def deprecated_major?(target_major_version) + @major_version >= target_major_version + end def initialize(bundler_version) @bundler_version = Gem::Version.create(bundler_version) diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 9992b20c47..0b6ced6f39 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -72,19 +72,57 @@ module Bundler end end + HTTP_ERRORS = (Downloader::HTTP_RETRYABLE_ERRORS + Downloader::HTTP_NON_RETRYABLE_ERRORS).freeze + deprecate_constant :HTTP_ERRORS + + NET_ERRORS = [ + :HTTPBadGateway, + :HTTPBadRequest, + :HTTPFailedDependency, + :HTTPForbidden, + :HTTPInsufficientStorage, + :HTTPMethodNotAllowed, + :HTTPMovedPermanently, + :HTTPNoContent, + :HTTPNotFound, + :HTTPNotImplemented, + :HTTPPreconditionFailed, + :HTTPRequestEntityTooLarge, + :HTTPRequestURITooLong, + :HTTPUnauthorized, + :HTTPUnprocessableEntity, + :HTTPUnsupportedMediaType, + :HTTPVersionNotSupported, + ].freeze + deprecate_constant :NET_ERRORS + # Exceptions classes that should bypass retry attempts. If your password didn't work the # first time, it's not going to the third time. - NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency, - :HTTPForbidden, :HTTPInsufficientStorage, :HTTPMethodNotAllowed, - :HTTPMovedPermanently, :HTTPNoContent, :HTTPNotFound, - :HTTPNotImplemented, :HTTPPreconditionFailed, :HTTPRequestEntityTooLarge, - :HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity, - :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze - FAIL_ERRORS = begin - fail_errors = [AuthenticationRequiredError, BadAuthenticationError, AuthenticationForbiddenError, FallbackError, SecurityError] - fail_errors << Gem::Requirement::BadRequirementError - fail_errors.concat(NET_ERRORS.map {|e| Gem::Net.const_get(e) }) - end.freeze + FAIL_ERRORS = [ + AuthenticationRequiredError, + BadAuthenticationError, + AuthenticationForbiddenError, + FallbackError, + SecurityError, + Gem::Requirement::BadRequirementError, + Gem::Net::HTTPBadGateway, + Gem::Net::HTTPBadRequest, + Gem::Net::HTTPFailedDependency, + Gem::Net::HTTPForbidden, + Gem::Net::HTTPInsufficientStorage, + Gem::Net::HTTPMethodNotAllowed, + Gem::Net::HTTPMovedPermanently, + Gem::Net::HTTPNoContent, + Gem::Net::HTTPNotFound, + Gem::Net::HTTPNotImplemented, + Gem::Net::HTTPPreconditionFailed, + Gem::Net::HTTPRequestEntityTooLarge, + Gem::Net::HTTPRequestURITooLong, + Gem::Net::HTTPUnauthorized, + Gem::Net::HTTPUnprocessableEntity, + Gem::Net::HTTPUnsupportedMediaType, + Gem::Net::HTTPVersionNotSupported, + ].freeze class << self attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries @@ -293,13 +331,6 @@ module Bundler paths.find {|path| File.file? path } end - HTTP_ERRORS = [ - Gem::Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH, - Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN, - Gem::Net::HTTPBadResponse, Gem::Net::HTTPHeaderSyntaxError, Gem::Net::ProtocolError, - Gem::Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH - ].freeze - def bundler_cert_store store = OpenSSL::X509::Store.new ssl_ca_cert = Bundler.settings[:ssl_ca_cert] || diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb index c23fa160f4..994b415e9c 100644 --- a/lib/bundler/fetcher/dependency.rb +++ b/lib/bundler/fetcher/dependency.rb @@ -1,11 +1,8 @@ # frozen_string_literal: true require_relative "base" -begin - require "cgi/escape" -rescue LoadError - require "cgi/util" -end +require "cgi/escape" +require "cgi/util" unless defined?(CGI::EscapeExt) module Bundler class Fetcher diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb index 868b39b959..2eac6e7975 100644 --- a/lib/bundler/fetcher/downloader.rb +++ b/lib/bundler/fetcher/downloader.rb @@ -3,6 +3,28 @@ module Bundler class Fetcher class Downloader + HTTP_NON_RETRYABLE_ERRORS = [ + SocketError, + Errno::EADDRNOTAVAIL, + Errno::ENETDOWN, + Errno::ENETUNREACH, + Gem::Net::HTTP::Persistent::Error, + Errno::EHOSTUNREACH, + ].freeze + + HTTP_RETRYABLE_ERRORS = [ + Gem::Timeout::Error, + EOFError, + Errno::EINVAL, + Errno::ECONNRESET, + Errno::ETIMEDOUT, + Errno::EAGAIN, + Gem::Net::HTTPBadResponse, + Gem::Net::HTTPHeaderSyntaxError, + Gem::Net::ProtocolError, + Zlib::BufError, + ].freeze + attr_reader :connection attr_reader :redirect_limit @@ -67,15 +89,19 @@ module Bundler connection.request(uri, req) rescue OpenSSL::SSL::SSLError raise CertificateFailureError.new(uri) - rescue *HTTP_ERRORS => e + rescue *HTTP_NON_RETRYABLE_ERRORS => e Bundler.ui.trace e - if e.is_a?(SocketError) || e.message.to_s.include?("host down:") - raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \ - "connection and try again." - else - raise HTTPError, "Network error while fetching #{filtered_uri}" \ + + host = uri.host + host_port = "#{host}:#{uri.port}" + host = host_port if filtered_uri.to_s.include?(host_port) + raise NetworkDownError, "Could not reach host #{host}. Check your network " \ + "connection and try again." + rescue *HTTP_RETRYABLE_ERRORS => e + Bundler.ui.trace e + + raise HTTPError, "Network error while fetching #{filtered_uri}" \ " (#{e})" - end end private diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb index 99893ed1f1..8a5ab2e025 100644 --- a/lib/bundler/friendly_errors.rb +++ b/lib/bundler/friendly_errors.rb @@ -102,11 +102,8 @@ module Bundler def issues_url(exception) message = exception.message.lines.first.tr(":", " ").chomp message = message.split("-").first if exception.is_a?(Errno) - begin - require "cgi/escape" - rescue LoadError - require "cgi/util" - end + require "cgi/escape" + require "cgi/util" unless defined?(CGI::EscapeExt) "https://github.com/rubygems/rubygems/search?q=" \ "#{CGI.escape(message)}&type=Issues" end diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb deleted file mode 100644 index ad12bf89a4..0000000000 --- a/lib/bundler/gem_helpers.rb +++ /dev/null @@ -1,144 +0,0 @@ -# frozen_string_literal: true - -module Bundler - module GemHelpers - GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant - GENERICS = [ - Gem::Platform::JAVA, - *Gem::Platform::WINDOWS, - ].freeze - - def generic(p) - GENERIC_CACHE[p] ||= begin - found = GENERICS.find do |match| - p === match - end - found || Gem::Platform::RUBY - end - end - module_function :generic - - def generic_local_platform - generic(local_platform) - end - module_function :generic_local_platform - - def local_platform - Bundler.local_platform - end - module_function :local_platform - - def generic_local_platform_is_ruby? - generic_local_platform == Gem::Platform::RUBY - end - module_function :generic_local_platform_is_ruby? - - def platform_specificity_match(spec_platform, user_platform) - spec_platform = Gem::Platform.new(spec_platform) - - PlatformMatch.specificity_score(spec_platform, user_platform) - end - module_function :platform_specificity_match - - def select_all_platform_match(specs, platform, force_ruby: false, prefer_locked: false) - matching = if force_ruby - specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! } - else - specs.select {|spec| spec.match_platform(platform) } - end - - if prefer_locked - locked_originally = matching.select {|spec| spec.is_a?(LazySpecification) } - return locked_originally if locked_originally.any? - end - - matching - end - module_function :select_all_platform_match - - def select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false) - matching = select_all_platform_match(specs, platform, force_ruby: force_ruby, prefer_locked: prefer_locked) - - sort_and_filter_best_platform_match(matching, platform) - end - module_function :select_best_platform_match - - def select_best_local_platform_match(specs, force_ruby: false) - matching = select_all_platform_match(specs, local_platform, force_ruby: force_ruby).filter_map(&:materialized_for_installation) - - sort_best_platform_match(matching, local_platform) - end - module_function :select_best_local_platform_match - - def sort_and_filter_best_platform_match(matching, platform) - return matching if matching.one? - - exact = matching.select {|spec| spec.platform == platform } - return exact if exact.any? - - sorted_matching = sort_best_platform_match(matching, platform) - exemplary_spec = sorted_matching.first - - sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) } - end - module_function :sort_and_filter_best_platform_match - - def sort_best_platform_match(matching, platform) - matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) } - end - module_function :sort_best_platform_match - - class PlatformMatch - def self.specificity_score(spec_platform, user_platform) - return -1 if spec_platform == user_platform - return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY - - os_match(spec_platform, user_platform) + - cpu_match(spec_platform, user_platform) * 10 + - platform_version_match(spec_platform, user_platform) * 100 - end - - def self.os_match(spec_platform, user_platform) - if spec_platform.os == user_platform.os - 0 - else - 1 - end - end - - def self.cpu_match(spec_platform, user_platform) - if spec_platform.cpu == user_platform.cpu - 0 - elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm") - 0 - elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal" - 1 - else - 2 - end - end - - def self.platform_version_match(spec_platform, user_platform) - if spec_platform.version == user_platform.version - 0 - elsif spec_platform.version.nil? - 1 - else - 2 - end - end - end - - def same_specificity(platform, spec, exemplary_spec) - platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform) - end - module_function :same_specificity - - def same_deps(spec, exemplary_spec) - same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort - same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version - same_runtime_deps && same_metadata_deps - end - module_function :same_deps - end -end diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index df46facc88..d591b34cc7 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -131,6 +131,11 @@ module Bundler return unless other other.each do |spec| if existing = find_by_spec(spec) + unless dependencies_eql?(existing, spec) + Bundler.ui.warn "Local specification for #{spec.full_name} has different dependencies than the remote gem, ignoring it" + next + end + add_duplicate(existing) end add spec @@ -153,8 +158,8 @@ module Bundler end def dependencies_eql?(spec, other_spec) - deps = spec.dependencies.select {|d| d.type != :development } - other_deps = other_spec.dependencies.select {|d| d.type != :development } + deps = spec.runtime_dependencies + other_deps = other_spec.runtime_dependencies deps.sort == other_deps.sort end diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 061e4bb91e..81ded54797 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -33,7 +33,7 @@ module Bundler lazy_spec end - def initialize(name, version, platform, source = nil) + def initialize(name, version, platform, source = nil, **materialization_options) @name = name @version = version @dependencies = [] @@ -43,6 +43,7 @@ module Bundler @original_source = source @source = source + @materialization_options = materialization_options @force_ruby_platform = default_force_ruby_platform @most_specific_locked_platform = nil @@ -142,15 +143,15 @@ module Bundler end else materialize([name, version]) do |matching_specs| - target_platform = source.is_a?(Source::Path) ? platform : local_platform + target_platform = source.is_a?(Source::Path) ? platform : Bundler.local_platform - installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform) + installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, target_platform) specification = choose_compatible(installable_candidates, fallback_to_non_installable: false) return specification unless specification.nil? if target_platform != platform - installable_candidates = GemHelpers.select_best_platform_match(matching_specs, platform) + installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, platform) end choose_compatible(installable_candidates) @@ -190,7 +191,7 @@ module Bundler end def ruby_platform_materializes_to_ruby_platform? - generic_platform = generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY + generic_platform = Bundler.generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY (most_specific_locked_platform != generic_platform) || force_ruby_platform || Bundler.settings[:force_ruby_platform] end @@ -226,12 +227,13 @@ module Bundler # Validate dependencies of this locked spec are consistent with dependencies # of the actual spec that was materialized. # - # Note that we don't validate dependencies of locally installed gems but + # Note that unless we are in strict mode (which we set during installation) + # we don't validate dependencies of locally installed gems but # accept what's in the lockfile instead for performance, since loading # dependencies of locally installed gems would mean evaluating all gemspecs, # which would affect `bundler/setup` performance. def validate_dependencies(spec) - if spec.is_a?(StubSpecification) + if !@materialization_options[:strict] && spec.is_a?(StubSpecification) spec.dependencies = dependencies else if !source.is_a?(Source::Path) && spec.runtime_dependencies.sort != dependencies.sort diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 7d57ec724d..9ab9d73ae2 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true +require_relative "shared_helpers" + module Bundler class LockfileParser - include GemHelpers - class Position attr_reader :line, :column def initialize(line, column) @@ -94,7 +94,7 @@ module Bundler lockfile_contents.split(BUNDLED).last.strip end - def initialize(lockfile) + def initialize(lockfile, strict: false) @platforms = [] @sources = [] @dependencies = {} @@ -106,6 +106,7 @@ module Bundler "Gemfile.lock" end @pos = Position.new(1, 1) + @strict = strict if lockfile.match?(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/) raise LockfileError, "Your #{@lockfile_path} contains merge conflicts.\n" \ @@ -139,8 +140,23 @@ module Bundler end @pos.advance!(line) end + + if !Bundler.frozen_bundle? && @platforms.include?(Gem::Platform::X64_MINGW_LEGACY) + if @platforms.include?(Gem::Platform::X64_MINGW) + @platforms.delete(Gem::Platform::X64_MINGW_LEGACY) + SharedHelpers.major_deprecation(2, + "Found x64-mingw32 in lockfile, which is deprecated. Removing it. Support for x64-mingw32 will be removed in Bundler 4.0.", + removed_message: "Found x64-mingw32 in lockfile, which is no longer supported as of Bundler 4.0.") + else + @platforms[@platforms.index(Gem::Platform::X64_MINGW_LEGACY)] = Gem::Platform::X64_MINGW + SharedHelpers.major_deprecation(2, + "Found x64-mingw32 in lockfile, which is deprecated. Using x64-mingw-ucrt, the replacement for x64-mingw32 in modern rubies, instead. Support for x64-mingw32 will be removed in Bundler 4.0.", + removed_message: "Found x64-mingw32 in lockfile, which is no longer supported as of Bundler 4.0.") + end + end + @most_specific_locked_platform = @platforms.min_by do |bundle_platform| - platform_specificity_match(bundle_platform, local_platform) + Gem::Platform.platform_specificity_match(bundle_platform, Bundler.local_platform) end @specs = @specs.values.sort_by!(&:full_name).each do |spec| spec.most_specific_locked_platform = @most_specific_locked_platform @@ -271,7 +287,7 @@ module Bundler version = Gem::Version.new(version) platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY - @current_spec = LazySpecification.new(name, version, platform, @current_source) + @current_spec = LazySpecification.new(name, version, platform, @current_source, strict: @strict) @current_source.add_dependency_names(name) @specs[@current_spec.full_name] = @current_spec diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1 index 176e8b117e..5a27a70173 100644 --- a/lib/bundler/man/bundle-add.1 +++ b/lib/bundler/man/bundle-add.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-ADD" "1" "March 2025" "" +.TH "BUNDLE\-ADD" "1" "June 2025" "" .SH "NAME" \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1 index 146c1c021e..3ab9584653 100644 --- a/lib/bundler/man/bundle-binstubs.1 +++ b/lib/bundler/man/bundle-binstubs.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-BINSTUBS" "1" "March 2025" "" +.TH "BUNDLE\-BINSTUBS" "1" "June 2025" "" .SH "NAME" \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1 index 64e806029b..54cbd8ebc6 100644 --- a/lib/bundler/man/bundle-cache.1 +++ b/lib/bundler/man/bundle-cache.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-CACHE" "1" "March 2025" "" +.TH "BUNDLE\-CACHE" "1" "June 2025" "" .SH "NAME" \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1 index bf16a22461..122299a99b 100644 --- a/lib/bundler/man/bundle-check.1 +++ b/lib/bundler/man/bundle-check.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-CHECK" "1" "March 2025" "" +.TH "BUNDLE\-CHECK" "1" "June 2025" "" .SH "NAME" \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1 index 83f7661482..52e1096c18 100644 --- a/lib/bundler/man/bundle-clean.1 +++ b/lib/bundler/man/bundle-clean.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-CLEAN" "1" "March 2025" "" +.TH "BUNDLE\-CLEAN" "1" "June 2025" "" .SH "NAME" \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index 190177eb37..a77e4ac264 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-CONFIG" "1" "March 2025" "" +.TH "BUNDLE\-CONFIG" "1" "June 2025" "" .SH "NAME" \fBbundle\-config\fR \- Set bundler configuration options .SH "SYNOPSIS" @@ -42,29 +42,201 @@ Executing \fBbundle config unset \-\-global <name>\fR will delete the configurat Executing \fBbundle config unset \-\-local <name>\fR will delete the configuration only from the local application\. .P Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\. +.SH "CONFIGURATION KEYS" +Configuration keys in bundler have two forms: the canonical form and the environment variable form\. +.P +For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn't install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\. +.P +The canonical form of this configuration is \fB"without"\fR\. To convert the canonical form to the environment variable form, capitalize it, and prepend \fBBUNDLE_\fR\. The environment variable form of \fB"without"\fR is \fBBUNDLE_WITHOUT\fR\. +.P +Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\. +.SH "LIST OF AVAILABLE KEYS" +The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\. +.TP +\fBallow_offline_install\fR (\fBBUNDLE_ALLOW_OFFLINE_INSTALL\fR) +Allow Bundler to use cached data when installing without network access\. +.TP +\fBauto_clean_without_path\fR (\fBBUNDLE_AUTO_CLEAN_WITHOUT_PATH\fR) +Automatically run \fBbundle clean\fR after installing when an explicit \fBpath\fR has not been set and Bundler is not installing into the system gems\. +.TP +\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR) +Automatically run \fBbundle install\fR when gems are missing\. +.TP +\fBbin\fR (\fBBUNDLE_BIN\fR) +Install executables from gems in the bundle to the specified directory\. Defaults to \fBfalse\fR\. +.TP +\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR) +Cache all gems, including path and git gems\. This needs to be explicitly before bundler 4, but will be the default on bundler 4\. +.TP +\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR) +Cache gems for all platforms\. +.TP +\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR) +The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\. +.TP +\fBclean\fR (\fBBUNDLE_CLEAN\fR) +Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. +.TP +\fBconsole\fR (\fBBUNDLE_CONSOLE\fR) +The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\. +.TP +\fBdefault_install_uses_path\fR (\fBBUNDLE_DEFAULT_INSTALL_USES_PATH\fR) +Whether a \fBbundle install\fR without an explicit \fB\-\-path\fR argument defaults to installing gems in \fB\.bundle\fR\. +.TP +\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\fR) +Equivalent to setting \fBfrozen\fR to \fBtrue\fR and \fBpath\fR to \fBvendor/bundle\fR\. +.TP +\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR) +Allow installing gems even if they do not match the checksum provided by RubyGems\. +.TP +\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR) +Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\. +.TP +\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR) +Allow Bundler to use a local git override without a branch specified in the Gemfile\. +.TP +\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR) +Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\. +.TP +\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR) +Stop Bundler from accessing gems installed to RubyGems' normal location\. +.TP +\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR) +Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\. +.TP +\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR) +Ignore the current machine's platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\. +.TP +\fBfrozen\fR (\fBBUNDLE_FROZEN\fR) +Disallow any automatic changes to \fBGemfile\.lock\fR\. Bundler commands will be blocked unless the lockfile can be installed exactly as written\. Usually this will happen when changing the \fBGemfile\fR manually and forgetting to update the lockfile through \fBbundle lock\fR or \fBbundle install\fR\. +.TP +\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 overridden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\. +.TP +\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\. +.TP +\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR) +The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\. +.TP +\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR) +Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\. +.TP +\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR) +When set, no funding requests will be printed\. +.TP +\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR) +When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\. +.TP +\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR) +Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\. +.TP +\fBjobs\fR (\fBBUNDLE_JOBS\fR) +The number of gems Bundler can install in parallel\. Defaults to the number of available processors\. +.TP +\fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR) +Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. +.TP +\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR) +Whether \fBbundle package\fR should skip installing gems\. +.TP +\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR) +Whether Bundler should leave outdated gems unpruned when caching\. +.TP +\fBonly\fR (\fBBUNDLE_ONLY\fR) +A space\-separated list of groups to install only gems of the specified groups\. +.TP +\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\. +.TP +\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR) +Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\. +.TP +\fBpath_relative_to_cwd\fR (\fBBUNDLE_PATH_RELATIVE_TO_CWD\fR) +Makes \fB\-\-path\fR relative to the CWD instead of the \fBGemfile\fR\. +.TP +\fBplugins\fR (\fBBUNDLE_PLUGINS\fR) +Enable Bundler's experimental plugin system\. +.TP +\fBprefer_patch\fR (BUNDLE_PREFER_PATCH) +Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\. +.TP +\fBredirect\fR (\fBBUNDLE_REDIRECT\fR) +The number of redirects allowed for network requests\. Defaults to \fB5\fR\. +.TP +\fBretry\fR (\fBBUNDLE_RETRY\fR) +The number of times to retry failed network requests\. Defaults to \fB3\fR\. +.TP +\fBsetup_makes_kernel_gem_public\fR (\fBBUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC\fR) +Have \fBBundler\.setup\fR make the \fBKernel#gem\fR method public, even though RubyGems declares it as private\. +.TP +\fBshebang\fR (\fBBUNDLE_SHEBANG\fR) +The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\. +.TP +\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR) +Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\. +.TP +\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR) +Silence the warning Bundler prints when installing gems as root\. +.TP +\fBsimulate_version\fR (\fBBUNDLE_SIMULATE_VERSION\fR) +The virtual version Bundler should use for activating feature flags\. Can be used to simulate all the new functionality that will be enabled in a future major version\. +.TP +\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR) +Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\. +.TP +\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR) +Path to a designated file containing a X\.509 client certificate and key in PEM format\. +.TP +\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR) +The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\. +.TP +\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR) +The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\. +.TP +\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR) +The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\. +.TP +\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR) +Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\. +.TP +\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR) +The custom user agent fragment Bundler includes in API requests\. +.TP +\fBverbose\fR (\fBBUNDLE_VERBOSE\fR) +Whether Bundler should print verbose output\. Defaults to \fBfalse\fR, unless the \fB\-\-verbose\fR CLI flag is used\. +.TP +\fBversion\fR (\fBBUNDLE_VERSION\fR) +The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\. +.TP +\fBwith\fR (\fBBUNDLE_WITH\fR) +A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\. +.TP +\fBwithout\fR (\fBBUNDLE_WITHOUT\fR) +A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\. .SH "REMEMBERING OPTIONS" Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application's configuration (normally, \fB\./\.bundle/config\fR)\. .P -However, this will be changed in bundler 3, so it's better not to rely on this behavior\. If these options must be remembered, it's better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\. +However, this will be changed in bundler 4, so it's better not to rely on this behavior\. If these options must be remembered, it's better to set them using \fBbundle config\fR (e\.g\., \fBbundle config set \-\-local path foo\fR)\. .P -The options that can be configured are: +The flags that can be configured are: .TP -\fBbin\fR +\fB\-\-bin\fR Creates a directory (defaults to \fB~/bin\fR) and place any executables from the gem there\. These executables run in Bundler's context\. If used, you might add this directory to your environment's \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, this flag will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\. .TP -\fBdeployment\fR +\fB\-\-deployment\fR In deployment mode, Bundler will 'roll\-out' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\. .TP -\fBonly\fR +\fB\-\-only\fR A space\-separated list of groups to install only gems of the specified groups\. Please check carefully if you want to install also gems without a group, cause they get put inside \fBdefault\fR group\. For example \fBonly test:default\fR will install all gems specified in test group and without one\. .TP -\fBpath\fR +\fB\-\-path\fR The location to install the specified gems to\. This defaults to Rubygems' setting\. Bundler shares this location with Rubygems, \fBgem install \|\.\|\.\|\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \|\.\|\.\|\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\. .TP -\fBwithout\fR +\fB\-\-without\fR A space\-separated or \fB:\fR\-separated list of groups referencing gems to skip during installation\. .TP -\fBwith\fR +\fB\-\-with\fR A space\-separated or \fB:\fR\-separated list of \fBoptional\fR groups referencing gems to include during installation\. .SH "BUILD OPTIONS" You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\. @@ -84,123 +256,6 @@ bundle config set \-\-global build\.mysql \-\-with\-mysql\-config=/usr/local/mys .IP "" 0 .P After running this command, every time bundler needs to install the \fBmysql\fR gem, it will pass along the flags you specified\. -.SH "CONFIGURATION KEYS" -Configuration keys in bundler have two forms: the canonical form and the environment variable form\. -.P -For instance, passing the \fB\-\-without\fR flag to bundle install(1) \fIbundle\-install\.1\.html\fR prevents Bundler from installing certain groups specified in the Gemfile(5)\. Bundler persists this value in \fBapp/\.bundle/config\fR so that calls to \fBBundler\.setup\fR do not try to find gems from the \fBGemfile\fR that you didn't install\. Additionally, subsequent calls to bundle install(1) \fIbundle\-install\.1\.html\fR remember this setting and skip those groups\. -.P -The canonical form of this configuration is \fB"without"\fR\. To convert the canonical form to the environment variable form, capitalize it, and prepend \fBBUNDLE_\fR\. The environment variable form of \fB"without"\fR is \fBBUNDLE_WITHOUT\fR\. -.P -Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\. -.SH "LIST OF AVAILABLE KEYS" -The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\. -.IP "\(bu" 4 -\fBallow_offline_install\fR (\fBBUNDLE_ALLOW_OFFLINE_INSTALL\fR): Allow Bundler to use cached data when installing without network access\. -.IP "\(bu" 4 -\fBauto_clean_without_path\fR (\fBBUNDLE_AUTO_CLEAN_WITHOUT_PATH\fR): Automatically run \fBbundle clean\fR after installing when an explicit \fBpath\fR has not been set and Bundler is not installing into the system gems\. -.IP "\(bu" 4 -\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\. -.IP "\(bu" 4 -\fBbin\fR (\fBBUNDLE_BIN\fR): Install executables from gems in the bundle to the specified directory\. Defaults to \fBfalse\fR\. -.IP "\(bu" 4 -\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR): Cache all gems, including path and git gems\. This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3\. -.IP "\(bu" 4 -\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR): Cache gems for all platforms\. -.IP "\(bu" 4 -\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\. -.IP "\(bu" 4 -\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. -.IP "\(bu" 4 -\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\. -.IP "\(bu" 4 -\fBdefault_install_uses_path\fR (\fBBUNDLE_DEFAULT_INSTALL_USES_PATH\fR): Whether a \fBbundle install\fR without an explicit \fB\-\-path\fR argument defaults to installing gems in \fB\.bundle\fR\. -.IP "\(bu" 4 -\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\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\. -.IP "\(bu" 4 -\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR): Allow installing gems even if they do not match the checksum provided by RubyGems\. -.IP "\(bu" 4 -\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR): Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\. -.IP "\(bu" 4 -\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\. -.IP "\(bu" 4 -\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\. -.IP "\(bu" 4 -\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems' normal location\. -.IP "\(bu" 4 -\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR): Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\. -.IP "\(bu" 4 -\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine's platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\. -.IP "\(bu" 4 -\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 overridden 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 -\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR): The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\. -.IP "\(bu" 4 -\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems globally, rather than locally to the installing Ruby installation\. -.IP "\(bu" 4 -\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR): When set, no funding requests will be printed\. -.IP "\(bu" 4 -\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\. -.IP "\(bu" 4 -\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\. -.IP "\(bu" 4 -\fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can install in parallel\. Defaults to the number of available processors\. -.IP "\(bu" 4 -\fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR): Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. -.IP "\(bu" 4 -\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\. -.IP "\(bu" 4 -\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\. -.IP "\(bu" 4 -\fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\. -.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 -\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\. -.IP "\(bu" 4 -\fBpath_relative_to_cwd\fR (\fBBUNDLE_PATH_RELATIVE_TO_CWD\fR) Makes \fB\-\-path\fR relative to the CWD instead of the \fBGemfile\fR\. -.IP "\(bu" 4 -\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler's experimental plugin system\. -.IP "\(bu" 4 -\fBprefer_patch\fR (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\. -.IP "\(bu" 4 -\fBprint_only_version_number\fR (\fBBUNDLE_PRINT_ONLY_VERSION_NUMBER\fR): Print only version number from \fBbundler \-\-version\fR\. -.IP "\(bu" 4 -\fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\. -.IP "\(bu" 4 -\fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\. -.IP "\(bu" 4 -\fBsetup_makes_kernel_gem_public\fR (\fBBUNDLE_SETUP_MAKES_KERNEL_GEM_PUBLIC\fR): Have \fBBundler\.setup\fR make the \fBKernel#gem\fR method public, even though RubyGems declares it as private\. -.IP "\(bu" 4 -\fBshebang\fR (\fBBUNDLE_SHEBANG\fR): The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\. -.IP "\(bu" 4 -\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR): Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\. -.IP "\(bu" 4 -\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\. -.IP "\(bu" 4 -\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\. -.IP "\(bu" 4 -\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR): Path to a designated file containing a X\.509 client certificate and key in PEM format\. -.IP "\(bu" 4 -\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR): The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\. -.IP "\(bu" 4 -\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\. -.IP "\(bu" 4 -\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\. -.IP "\(bu" 4 -\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\. -.IP "\(bu" 4 -\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\. -.IP "\(bu" 4 -\fBversion\fR (\fBBUNDLE_VERSION\fR): The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\. -.IP "\(bu" 4 -\fBwith\fR (\fBBUNDLE_WITH\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\. -.IP "\(bu" 4 -\fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\. -.IP "" 0 .SH "LOCAL GIT REPOS" Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override: .IP "" 4 diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index 44c31cd10d..2386fe9dcd 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -52,71 +52,6 @@ only from the local application. Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will cause it to ignore all configuration. -## REMEMBERING OPTIONS - -Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or -`--without production`, are remembered between commands and saved to your local -application's configuration (normally, `./.bundle/config`). - -However, this will be changed in bundler 3, so it's better not to rely on this -behavior. If these options must be remembered, it's better to set them using -`bundle config` (e.g., `bundle config set --local path foo`). - -The options that can be configured are: - -* `bin`: - Creates a directory (defaults to `~/bin`) and place any executables from the - gem there. These executables run in Bundler's context. If used, you might add - this directory to your environment's `PATH` variable. For instance, if the - `rails` gem comes with a `rails` executable, this flag will create a - `bin/rails` executable that ensures that all referred dependencies will be - resolved using the bundled gems. - -* `deployment`: - In deployment mode, Bundler will 'roll-out' the bundle for - `production` use. Please check carefully if you want to have this option - enabled in `development` or `test` environments. - -* `only`: - A space-separated list of groups to install only gems of the specified groups. - Please check carefully if you want to install also gems without a group, cause - they get put inside `default` group. For example `only test:default` will install - all gems specified in test group and without one. - -* `path`: - The location to install the specified gems to. This defaults to Rubygems' - setting. Bundler shares this location with Rubygems, `gem install ...` will - have gem installed there, too. Therefore, gems installed without a - `--path ...` setting will show up by calling `gem list`. Accordingly, gems - installed to other locations will not get listed. - -* `without`: - A space-separated or `:`-separated list of groups referencing gems to skip during - installation. - -* `with`: - A space-separated or `:`-separated list of **optional** groups referencing gems to - include during installation. - -## BUILD OPTIONS - -You can use `bundle config` to give Bundler the flags to pass to the gem -installer every time bundler tries to install a particular gem. - -A very common example, the `mysql` gem, requires Snow Leopard users to -pass configuration flags to `gem install` to specify where to find the -`mysql_config` executable. - - gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config - -Since the specific location of that executable can change from machine -to machine, you can specify these flags on a per-machine basis. - - bundle config set --global build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config - -After running this command, every time bundler needs to install the -`mysql` gem, it will pass along the flags you specified. - ## CONFIGURATION KEYS Configuration keys in bundler have two forms: the canonical form and the @@ -154,7 +89,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). Defaults to `false`. * `cache_all` (`BUNDLE_CACHE_ALL`): Cache all gems, including path and git gems. This needs to be explicitly - configured on bundler 1 and bundler 2, but will be the default on bundler 3. + before bundler 4, but will be the default on bundler 4. * `cache_all_platforms` (`BUNDLE_CACHE_ALL_PLATFORMS`): Cache gems for all platforms. * `cache_path` (`BUNDLE_CACHE_PATH`): @@ -170,8 +105,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). Whether a `bundle install` without an explicit `--path` argument defaults to installing gems in `.bundle`. * `deployment` (`BUNDLE_DEPLOYMENT`): - Disallow changes to the `Gemfile`. When the `Gemfile` is changed and the - lockfile has not been updated, running Bundler commands will be blocked. + Equivalent to setting `frozen` to `true` and `path` to `vendor/bundle`. * `disable_checksum_validation` (`BUNDLE_DISABLE_CHECKSUM_VALIDATION`): Allow installing gems even if they do not match the checksum provided by RubyGems. @@ -193,9 +127,10 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). Ignore the current machine's platform and install only `ruby` platform gems. As a result, gems with native extensions will be compiled from source. * `frozen` (`BUNDLE_FROZEN`): - 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. + Disallow any automatic changes to `Gemfile.lock`. Bundler commands will + be blocked unless the lockfile can be installed exactly as written. + Usually this will happen when changing the `Gemfile` manually and forgetting + to update the lockfile through `bundle lock` or `bundle install`. * `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 overridden by passing an @@ -233,18 +168,15 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). * `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 - will be installed by `bundle install`. Defaults to `Gem.dir`. When --deployment - is used, defaults to vendor/bundle. + will be installed by `bundle install`. Defaults to `Gem.dir`. * `path.system` (`BUNDLE_PATH__SYSTEM`): Whether Bundler will install gems into the default system path (`Gem.dir`). -* `path_relative_to_cwd` (`BUNDLE_PATH_RELATIVE_TO_CWD`) +* `path_relative_to_cwd` (`BUNDLE_PATH_RELATIVE_TO_CWD`): Makes `--path` relative to the CWD instead of the `Gemfile`. * `plugins` (`BUNDLE_PLUGINS`): Enable Bundler's experimental plugin system. * `prefer_patch` (BUNDLE_PREFER_PATCH): Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`. -* `print_only_version_number` (`BUNDLE_PRINT_ONLY_VERSION_NUMBER`): - Print only version number from `bundler --version`. * `redirect` (`BUNDLE_REDIRECT`): The number of redirects allowed for network requests. Defaults to `5`. * `retry` (`BUNDLE_RETRY`): @@ -260,6 +192,10 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). be changed in the next major version. * `silence_root_warning` (`BUNDLE_SILENCE_ROOT_WARNING`): Silence the warning Bundler prints when installing gems as root. +* `simulate_version` (`BUNDLE_SIMULATE_VERSION`): + The virtual version Bundler should use for activating feature flags. Can be + used to simulate all the new functionality that will be enabled in a future + major version. * `ssl_ca_cert` (`BUNDLE_SSL_CA_CERT`): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format. @@ -278,6 +214,9 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). and disallow passing no options to `bundle update`. * `user_agent` (`BUNDLE_USER_AGENT`): The custom user agent fragment Bundler includes in API requests. +* `verbose` (`BUNDLE_VERBOSE`): + Whether Bundler should print verbose output. Defaults to `false`, unless the + `--verbose` CLI flag is used. * `version` (`BUNDLE_VERSION`): The version of Bundler to use when running under Bundler environment. Defaults to `lockfile`. You can also specify `system` or `x.y.z`. @@ -289,6 +228,71 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html). * `without` (`BUNDLE_WITHOUT`): A space-separated or `:`-separated list of groups whose gems bundler should not install. +## REMEMBERING OPTIONS + +Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or +`--without production`, are remembered between commands and saved to your local +application's configuration (normally, `./.bundle/config`). + +However, this will be changed in bundler 4, so it's better not to rely on this +behavior. If these options must be remembered, it's better to set them using +`bundle config` (e.g., `bundle config set --local path foo`). + +The flags that can be configured are: + +* `--bin`: + Creates a directory (defaults to `~/bin`) and place any executables from the + gem there. These executables run in Bundler's context. If used, you might add + this directory to your environment's `PATH` variable. For instance, if the + `rails` gem comes with a `rails` executable, this flag will create a + `bin/rails` executable that ensures that all referred dependencies will be + resolved using the bundled gems. + +* `--deployment`: + In deployment mode, Bundler will 'roll-out' the bundle for + `production` use. Please check carefully if you want to have this option + enabled in `development` or `test` environments. + +* `--only`: + A space-separated list of groups to install only gems of the specified groups. + Please check carefully if you want to install also gems without a group, cause + they get put inside `default` group. For example `only test:default` will install + all gems specified in test group and without one. + +* `--path`: + The location to install the specified gems to. This defaults to Rubygems' + setting. Bundler shares this location with Rubygems, `gem install ...` will + have gem installed there, too. Therefore, gems installed without a + `--path ...` setting will show up by calling `gem list`. Accordingly, gems + installed to other locations will not get listed. + +* `--without`: + A space-separated or `:`-separated list of groups referencing gems to skip during + installation. + +* `--with`: + A space-separated or `:`-separated list of **optional** groups referencing gems to + include during installation. + +## BUILD OPTIONS + +You can use `bundle config` to give Bundler the flags to pass to the gem +installer every time bundler tries to install a particular gem. + +A very common example, the `mysql` gem, requires Snow Leopard users to +pass configuration flags to `gem install` to specify where to find the +`mysql_config` executable. + + gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config + +Since the specific location of that executable can change from machine +to machine, you can specify these flags on a per-machine basis. + + bundle config set --global build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config + +After running this command, every time bundler needs to install the +`mysql` gem, it will pass along the flags you specified. + ## LOCAL GIT REPOS Bundler also allows you to work against a git repository locally diff --git a/lib/bundler/man/bundle-console.1 b/lib/bundler/man/bundle-console.1 index de9eeac907..1dd6b278de 100644 --- a/lib/bundler/man/bundle-console.1 +++ b/lib/bundler/man/bundle-console.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-CONSOLE" "1" "March 2025" "" +.TH "BUNDLE\-CONSOLE" "1" "June 2025" "" .SH "NAME" \fBbundle\-console\fR \- Open an IRB session with the bundle pre\-loaded .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1 index cd831f2fee..433f43b100 100644 --- a/lib/bundler/man/bundle-doctor.1 +++ b/lib/bundler/man/bundle-doctor.1 @@ -1,14 +1,21 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-DOCTOR" "1" "March 2025" "" +.TH "BUNDLE\-DOCTOR" "1" "June 2025" "" .SH "NAME" \fBbundle\-doctor\fR \- Checks the bundle for common problems .SH "SYNOPSIS" -\fBbundle doctor\fR [\-\-quiet] [\-\-gemfile=GEMFILE] +\fBbundle doctor [diagnose]\fR [\-\-quiet] [\-\-gemfile=GEMFILE] [\-\-ssl] +.br +\fBbundle doctor ssl\fR [\-\-host=HOST] [\-\-tls\-version=VERSION] [\-\-verify\-mode=MODE] +.br +\fBbundle doctor\fR help [COMMAND] .SH "DESCRIPTION" +You can diagnose common Bundler problems with this command such as checking gem environment or SSL/TLS issue\. +.SH "SUB\-COMMANDS" +.SS "diagnose (default command)" Checks your Gemfile and gem environment for common problems\. If issues are detected, Bundler prints them and exits status 1\. Otherwise, Bundler prints a success message and exits status 0\. .P -Examples of common problems caught by bundle\-doctor include: +Examples of common problems caught include: .IP "\(bu" 4 Invalid Bundler settings .IP "\(bu" 4 @@ -20,11 +27,43 @@ Uninstalled gems .IP "\(bu" 4 Missing dependencies .IP "" 0 -.SH "OPTIONS" +.P +\fBOPTIONS\fR .TP \fB\-\-quiet\fR Only output warnings and errors\. .TP \fB\-\-gemfile=GEMFILE\fR The location of the Gemfile(5) which Bundler should use\. This defaults to a Gemfile(5) in the current working directory\. In general, Bundler will assume that the location of the Gemfile(5) is also the project's root and will try to find \fBGemfile\.lock\fR and \fBvendor/cache\fR relative to this location\. +.TP +\fB\-\-ssl\fR +Diagnose common SSL problems when connecting to https://rubygems\.org\. +.IP +This flag runs the \fBbundle doctor ssl\fR subcommand with default values underneath\. +.SS "ssl" +If you've experienced issues related to SSL certificates and/or TLS versions while connecting to https://rubygems\.org, this command can help troubleshoot common problems\. The diagnostic will perform a few checks such as: +.IP "\(bu" 4 +Verify the Ruby OpenSSL version installed on your system\. +.IP "\(bu" 4 +Check the OpenSSL library version used for compilation\. +.IP "\(bu" 4 +Ensure CA certificates are correctly setup on your machine\. +.IP "\(bu" 4 +Open a TLS connection and verify the outcome\. +.IP "" 0 +.P +\fBOPTIONS\fR +.TP +\fB\-\-host=HOST\fR +Perform the diagnostic on HOST\. Defaults to \fBrubygems\.org\fR\. +.TP +\fB\-\-tls\-version=VERSION\fR +Specify the TLS version when opening the connection to HOST\. +.IP +Accepted values are: \fB1\.1\fR or \fB1\.2\fR\. +.TP +\fB\-\-verify\-mode=MODE\fR +Specify the TLS verify mode when opening the connection to HOST\. Defaults to \fBSSL_VERIFY_PEER\fR\. +.IP +Accepted values are: \fBCLIENT_ONCE\fR, \fBFAIL_IF_NO_PEER_CERT\fR, \fBNONE\fR, \fBPEER\fR\. diff --git a/lib/bundler/man/bundle-doctor.1.ronn b/lib/bundler/man/bundle-doctor.1.ronn index 5970f6188b..7e8a21b1c5 100644 --- a/lib/bundler/man/bundle-doctor.1.ronn +++ b/lib/bundler/man/bundle-doctor.1.ronn @@ -3,16 +3,27 @@ bundle-doctor(1) -- Checks the bundle for common problems ## SYNOPSIS -`bundle doctor` [--quiet] - [--gemfile=GEMFILE] +`bundle doctor [diagnose]` [--quiet] + [--gemfile=GEMFILE] + [--ssl]<br> +`bundle doctor ssl` [--host=HOST] + [--tls-version=VERSION] + [--verify-mode=MODE]<br> +`bundle doctor` help [COMMAND] ## DESCRIPTION +You can diagnose common Bundler problems with this command such as checking gem environment or SSL/TLS issue. + +## SUB-COMMANDS + +### diagnose (default command) + Checks your Gemfile and gem environment for common problems. If issues are detected, Bundler prints them and exits status 1. Otherwise, Bundler prints a success message and exits status 0. -Examples of common problems caught by bundle-doctor include: +Examples of common problems caught include: * Invalid Bundler settings * Mismatched Ruby versions @@ -20,7 +31,7 @@ Examples of common problems caught by bundle-doctor include: * Uninstalled gems * Missing dependencies -## OPTIONS +**OPTIONS** * `--quiet`: Only output warnings and errors. @@ -31,3 +42,36 @@ Examples of common problems caught by bundle-doctor include: will assume that the location of the Gemfile(5) is also the project's root and will try to find `Gemfile.lock` and `vendor/cache` relative to this location. + +* `--ssl`: + Diagnose common SSL problems when connecting to https://rubygems.org. + + This flag runs the `bundle doctor ssl` subcommand with default values + underneath. + +### ssl + +If you've experienced issues related to SSL certificates and/or TLS versions while connecting +to https://rubygems.org, this command can help troubleshoot common problems. +The diagnostic will perform a few checks such as: + +* Verify the Ruby OpenSSL version installed on your system. +* Check the OpenSSL library version used for compilation. +* Ensure CA certificates are correctly setup on your machine. +* Open a TLS connection and verify the outcome. + +**OPTIONS** + +* `--host=HOST`: + Perform the diagnostic on HOST. Defaults to `rubygems.org`. + +* `--tls-version=VERSION`: + Specify the TLS version when opening the connection to HOST. + + Accepted values are: `1.1` or `1.2`. + +* `--verify-mode=MODE`: + Specify the TLS verify mode when opening the connection to HOST. + Defaults to `SSL_VERIFY_PEER`. + + Accepted values are: `CLIENT_ONCE`, `FAIL_IF_NO_PEER_CERT`, `NONE`, `PEER`. diff --git a/lib/bundler/man/bundle-env.1 b/lib/bundler/man/bundle-env.1 index c936294827..167d902c99 100644 --- a/lib/bundler/man/bundle-env.1 +++ b/lib/bundler/man/bundle-env.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-ENV" "1" "March 2025" "" +.TH "BUNDLE\-ENV" "1" "June 2025" "" .SH "NAME" \fBbundle\-env\fR \- Print information about the environment Bundler is running under .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1 index 0ebbb4c198..062944b3ca 100644 --- a/lib/bundler/man/bundle-exec.1 +++ b/lib/bundler/man/bundle-exec.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-EXEC" "1" "March 2025" "" +.TH "BUNDLE\-EXEC" "1" "June 2025" "" .SH "NAME" \fBbundle\-exec\fR \- Execute a command in the context of the bundle .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-fund.1 b/lib/bundler/man/bundle-fund.1 index 641d8cf864..131b0e9d2d 100644 --- a/lib/bundler/man/bundle-fund.1 +++ b/lib/bundler/man/bundle-fund.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-FUND" "1" "March 2025" "" +.TH "BUNDLE\-FUND" "1" "June 2025" "" .SH "NAME" \fBbundle\-fund\fR \- Lists information about gems seeking funding assistance .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1 index 65882afa4f..672c04cafa 100644 --- a/lib/bundler/man/bundle-gem.1 +++ b/lib/bundler/man/bundle-gem.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-GEM" "1" "March 2025" "" +.TH "BUNDLE\-GEM" "1" "June 2025" "" .SH "NAME" \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem .SH "SYNOPSIS" @@ -19,67 +19,90 @@ The generated project skeleton can be customized with OPTIONS, as explained belo \fBgem\.test\fR .IP "" 0 .SH "OPTIONS" -.IP "\(bu" 4 -\fB\-\-exe\fR, \fB\-\-bin\fR, \fB\-b\fR: Specify that Bundler should create a binary executable (as \fBexe/GEM_NAME\fR) in the generated rubygem project\. This binary will also be added to the \fBGEM_NAME\.gemspec\fR manifest\. This behavior is disabled by default\. -.IP "\(bu" 4 -\fB\-\-no\-exe\fR: Do not create a binary (overrides \fB\-\-exe\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-coc\fR: Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\. -.IP "\(bu" 4 -\fB\-\-no\-coc\fR: Do not create a \fBCODE_OF_CONDUCT\.md\fR (overrides \fB\-\-coc\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-changelog\fR Add a \fBCHANGELOG\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\. -.IP "\(bu" 4 -\fB\-\-no\-changelog\fR: Do not create a \fBCHANGELOG\.md\fR (overrides \fB\-\-changelog\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-ext=c\fR, \fB\-\-ext=rust\fR: Add boilerplate for C or Rust (currently magnus \fIhttps://docs\.rs/magnus\fR based) extension code to the generated project\. This behavior is disabled by default\. -.IP "\(bu" 4 -\fB\-\-no\-ext\fR: Do not add extension code (overrides \fB\-\-ext\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-git\fR: Initialize a git repo inside your library\. -.IP "\(bu" 4 -\fB\-\-github\-username=GITHUB_USERNAME\fR: Fill in GitHub username on README so that you don't have to do it manually\. Set a default with \fBbundle config set \-\-global gem\.github_username <your_username>\fR\. -.IP "\(bu" 4 -\fB\-\-mit\fR: Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\. -.IP "\(bu" 4 -\fB\-\-no\-mit\fR: Do not create a \fBLICENSE\.txt\fR (overrides \fB\-\-mit\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-t\fR, \fB\-\-test=minitest\fR, \fB\-\-test=rspec\fR, \fB\-\-test=test\-unit\fR: Specify the test framework that Bundler should use when generating the project\. Acceptable values are \fBminitest\fR, \fBrspec\fR and \fBtest\-unit\fR\. The \fBGEM_NAME\.gemspec\fR will be configured and a skeleton test/spec directory will be created based on this option\. Given no option is specified: +.TP +\fB\-\-exe\fR, \fB\-\-bin\fR, \fB\-b\fR +Specify that Bundler should create a binary executable (as \fBexe/GEM_NAME\fR) in the generated rubygem project\. This binary will also be added to the \fBGEM_NAME\.gemspec\fR manifest\. This behavior is disabled by default\. +.TP +\fB\-\-no\-exe\fR +Do not create a binary (overrides \fB\-\-exe\fR specified in the global config)\. +.TP +\fB\-\-coc\fR +Add a \fBCODE_OF_CONDUCT\.md\fR file to the root of the generated project\. If this option is unspecified, 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\-\-no\-coc\fR +Do not create a \fBCODE_OF_CONDUCT\.md\fR (overrides \fB\-\-coc\fR specified in the global config)\. +.TP +\fB\-\-changelog\fR +Add a \fBCHANGELOG\.md\fR file to the root of the generated project\. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future \fBbundle gem\fR use\. Update the default with \fBbundle config set \-\-global gem\.changelog <true|false>\fR\. +.TP +\fB\-\-no\-changelog\fR +Do not create a \fBCHANGELOG\.md\fR (overrides \fB\-\-changelog\fR specified in the global config)\. +.TP +\fB\-\-ext=c\fR, \fB\-\-ext=rust\fR +Add boilerplate for C or Rust (currently magnus \fIhttps://docs\.rs/magnus\fR based) extension code to the generated project\. This behavior is disabled by default\. +.TP +\fB\-\-no\-ext\fR +Do not add extension code (overrides \fB\-\-ext\fR specified in the global config)\. +.TP +\fB\-\-git\fR +Initialize a git repo inside your library\. +.TP +\fB\-\-github\-username=GITHUB_USERNAME\fR +Fill in GitHub username on README so that you don't have to do it manually\. Set a default with \fBbundle config set \-\-global gem\.github_username <your_username>\fR\. +.TP +\fB\-\-mit\fR +Add an MIT license to a \fBLICENSE\.txt\fR file in the root of the generated project\. Your name from the global git config is used for the copyright statement\. If this option is unspecified, 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\-\-no\-mit\fR +Do not create a \fBLICENSE\.txt\fR (overrides \fB\-\-mit\fR specified in the global config)\. +.TP +\fB\-t\fR, \fB\-\-test=minitest\fR, \fB\-\-test=rspec\fR, \fB\-\-test=test\-unit\fR +Specify the test framework that Bundler should use when generating the project\. Acceptable values are \fBminitest\fR, \fBrspec\fR and \fBtest\-unit\fR\. The \fBGEM_NAME\.gemspec\fR will be configured and a skeleton test/spec directory will be created based on this option\. Given no option is specified: .IP When Bundler is configured to generate tests, this defaults to Bundler's global config setting \fBgem\.test\fR\. .IP When Bundler is configured to not generate tests, 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\. -.IP "\(bu" 4 -\fB\-\-no\-test\fR: Do not use a test framework (overrides \fB\-\-test\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-changelog\fR: Generate changelog file\. Set a default with \fBbundle config set \-\-global gem\.changelog true\fR\. -.IP "\(bu" 4 -\fB\-\-ci\fR, \fB\-\-ci=circle\fR, \fB\-\-ci=github\fR, \fB\-\-ci=gitlab\fR: Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified: +.TP +\fB\-\-no\-test\fR +Do not use a test framework (overrides \fB\-\-test\fR specified in the global config)\. +.TP +\fB\-\-ci\fR, \fB\-\-ci=circle\fR, \fB\-\-ci=github\fR, \fB\-\-ci=gitlab\fR +Specify the continuous integration service that Bundler should use when generating the project\. Acceptable values are \fBgithub\fR, \fBgitlab\fR and \fBcircle\fR\. A configuration file will be generated in the project directory\. Given no option is specified: .IP When Bundler is configured to generate CI files, this defaults to Bundler's global config setting \fBgem\.ci\fR\. .IP When Bundler is configured to not generate CI files, 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\. -.IP "\(bu" 4 -\fB\-\-no\-ci\fR: Do not use a continuous integration service (overrides \fB\-\-ci\fR specified in the global config)\. -.IP "\(bu" 4 -\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: +.TP +\fB\-\-no\-ci\fR +Do not use a continuous integration service (overrides \fB\-\-ci\fR specified in the global config)\. +.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\. -.IP "\(bu" 4 -\fB\-\-no\-linter\fR: Do not add a linter (overrides \fB\-\-linter\fR specified in the global config)\. -.IP "\(bu" 4 -\fB\-\-rubocop\fR: Add rubocop to the generated Rakefile and gemspec\. Set a default with \fBbundle config set \-\-global gem\.rubocop true\fR\. -.IP "\(bu" 4 -\fB\-\-edit=EDIT\fR, \fB\-e=EDIT\fR: Open the resulting GEM_NAME\.gemspec in EDIT, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\. -.IP "" 0 +.TP +\fB\-\-no\-linter\fR +Do not add a linter (overrides \fB\-\-linter\fR specified in the global config)\. +.TP +\fB\-\-rubocop\fR +Add rubocop to the generated Rakefile and gemspec\. Set a default with \fBbundle config set \-\-global gem\.rubocop true\fR\. +.TP +\fB\-\-edit=EDIT\fR, \fB\-e=EDIT\fR +Open the resulting GEM_NAME\.gemspec in EDIT, or the default editor if not specified\. The default is \fB$BUNDLER_EDITOR\fR, \fB$VISUAL\fR, or \fB$EDITOR\fR\. +.TP +\fB\-\-bundle\fR +Run \fBbundle install\fR after creating the gem\. +.TP +\fB\-\-no\-bundle\fR +Do not run \fBbundle install\fR after creating the gem\. .SH "SEE ALSO" .IP "\(bu" 4 bundle config(1) \fIbundle\-config\.1\.html\fR diff --git a/lib/bundler/man/bundle-gem.1.ronn b/lib/bundler/man/bundle-gem.1.ronn index 13dc55c310..b1327aa342 100644 --- a/lib/bundler/man/bundle-gem.1.ronn +++ b/lib/bundler/man/bundle-gem.1.ronn @@ -41,10 +41,11 @@ configuration file using the following names: Do not create a `CODE_OF_CONDUCT.md` (overrides `--coc` specified in the global config). -* `--changelog` +* `--changelog`: Add a `CHANGELOG.md` file to the root of the generated project. If this option is unspecified, an interactive prompt will be displayed and the answer will be saved in Bundler's global config for future `bundle gem` use. + Update the default with `bundle config set --global gem.changelog <true|false>`. * `--no-changelog`: Do not create a `CHANGELOG.md` (overrides `--changelog` specified in the @@ -95,9 +96,6 @@ configuration file using the following names: Do not use a test framework (overrides `--test` specified in the global config). -* `--changelog`: - Generate changelog file. Set a default with `bundle config set --global gem.changelog true`. - * `--ci`, `--ci=circle`, `--ci=github`, `--ci=gitlab`: Specify the continuous integration service that Bundler should use when generating the project. Acceptable values are `github`, `gitlab` @@ -144,6 +142,12 @@ configuration file using the following names: Open the resulting GEM_NAME.gemspec in EDIT, or the default editor if not specified. The default is `$BUNDLER_EDITOR`, `$VISUAL`, or `$EDITOR`. +* `--bundle`: + Run `bundle install` after creating the gem. + +* `--no-bundle`: + Do not run `bundle install` after creating the gem. + ## SEE ALSO * [bundle config(1)](bundle-config.1.html) diff --git a/lib/bundler/man/bundle-help.1 b/lib/bundler/man/bundle-help.1 index d8dd4660dc..f24b050d37 100644 --- a/lib/bundler/man/bundle-help.1 +++ b/lib/bundler/man/bundle-help.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-HELP" "1" "March 2025" "" +.TH "BUNDLE\-HELP" "1" "June 2025" "" .SH "NAME" \fBbundle\-help\fR \- Displays detailed help for each subcommand .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1 index 8124836519..82f39ebd0c 100644 --- a/lib/bundler/man/bundle-info.1 +++ b/lib/bundler/man/bundle-info.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-INFO" "1" "March 2025" "" +.TH "BUNDLE\-INFO" "1" "June 2025" "" .SH "NAME" \fBbundle\-info\fR \- Show information for the given gem in your bundle .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1 index 2e4b99b28a..4571e09718 100644 --- a/lib/bundler/man/bundle-init.1 +++ b/lib/bundler/man/bundle-init.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-INIT" "1" "March 2025" "" +.TH "BUNDLE\-INIT" "1" "June 2025" "" .SH "NAME" \fBbundle\-init\fR \- Generates a Gemfile into the current working directory .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1 index 54cacaa56d..7a1ddcf27e 100644 --- a/lib/bundler/man/bundle-inject.1 +++ b/lib/bundler/man/bundle-inject.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-INJECT" "1" "March 2025" "" +.TH "BUNDLE\-INJECT" "1" "June 2025" "" .SH "NAME" \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile .SH "SYNOPSIS" @@ -20,7 +20,7 @@ bundle inject 'rack' '> 0' .P This will inject the 'rack' gem with a version greater than 0 in your [\fBGemfile(5)\fR][Gemfile(5)] and Gemfile\.lock\. .P -The \fBbundle inject\fR command was deprecated in Bundler 2\.1 and will be removed in Bundler 3\.0\. +The \fBbundle inject\fR command was deprecated in Bundler 2\.1 and will be removed in Bundler 4\.0\. .SH "OPTIONS" .TP \fB\-\-source=SOURCE\fR diff --git a/lib/bundler/man/bundle-inject.1.ronn b/lib/bundler/man/bundle-inject.1.ronn index e2a911b6d8..7f6f0fb5b6 100644 --- a/lib/bundler/man/bundle-inject.1.ronn +++ b/lib/bundler/man/bundle-inject.1.ronn @@ -21,7 +21,7 @@ Example: This will inject the 'rack' gem with a version greater than 0 in your [`Gemfile(5)`][Gemfile(5)] and Gemfile.lock. -The `bundle inject` command was deprecated in Bundler 2.1 and will be removed in Bundler 3.0. +The `bundle inject` command was deprecated in Bundler 2.1 and will be removed in Bundler 4.0. ## OPTIONS diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1 index 272f4187ed..67a8df96fe 100644 --- a/lib/bundler/man/bundle-install.1 +++ b/lib/bundler/man/bundle-install.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-INSTALL" "1" "March 2025" "" +.TH "BUNDLE\-INSTALL" "1" "June 2025" "" .SH "NAME" \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-issue.1 b/lib/bundler/man/bundle-issue.1 index 02d28c91ba..62973e9892 100644 --- a/lib/bundler/man/bundle-issue.1 +++ b/lib/bundler/man/bundle-issue.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-ISSUE" "1" "March 2025" "" +.TH "BUNDLE\-ISSUE" "1" "June 2025" "" .SH "NAME" \fBbundle\-issue\fR \- Get help reporting Bundler issues .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-licenses.1 b/lib/bundler/man/bundle-licenses.1 index d0dbf3913c..75e2b93d35 100644 --- a/lib/bundler/man/bundle-licenses.1 +++ b/lib/bundler/man/bundle-licenses.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-LICENSES" "1" "March 2025" "" +.TH "BUNDLE\-LICENSES" "1" "June 2025" "" .SH "NAME" \fBbundle\-licenses\fR \- Print the license of all gems in the bundle .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1 index cd09ccab31..ed4e09e48e 100644 --- a/lib/bundler/man/bundle-list.1 +++ b/lib/bundler/man/bundle-list.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-LIST" "1" "March 2025" "" +.TH "BUNDLE\-LIST" "1" "June 2025" "" .SH "NAME" \fBbundle\-list\fR \- List all the gems in the bundle .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1 index 8c9b94e8e2..0d78414aa4 100644 --- a/lib/bundler/man/bundle-lock.1 +++ b/lib/bundler/man/bundle-lock.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-LOCK" "1" "March 2025" "" +.TH "BUNDLE\-LOCK" "1" "June 2025" "" .SH "NAME" \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1 index eb4ac2e859..b3016a5bbd 100644 --- a/lib/bundler/man/bundle-open.1 +++ b/lib/bundler/man/bundle-open.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-OPEN" "1" "March 2025" "" +.TH "BUNDLE\-OPEN" "1" "June 2025" "" .SH "NAME" \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1 index 4f8a2cc56f..f98038ce69 100644 --- a/lib/bundler/man/bundle-outdated.1 +++ b/lib/bundler/man/bundle-outdated.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-OUTDATED" "1" "March 2025" "" +.TH "BUNDLE\-OUTDATED" "1" "June 2025" "" .SH "NAME" \fBbundle\-outdated\fR \- List installed gems with newer versions available .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1 index bdac52f937..e9c40b8556 100644 --- a/lib/bundler/man/bundle-platform.1 +++ b/lib/bundler/man/bundle-platform.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-PLATFORM" "1" "March 2025" "" +.TH "BUNDLE\-PLATFORM" "1" "June 2025" "" .SH "NAME" \fBbundle\-platform\fR \- Displays platform compatibility information .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1 index ded328dbd8..c1f95b05c6 100644 --- a/lib/bundler/man/bundle-plugin.1 +++ b/lib/bundler/man/bundle-plugin.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-PLUGIN" "1" "March 2025" "" +.TH "BUNDLE\-PLUGIN" "1" "June 2025" "" .SH "NAME" \fBbundle\-plugin\fR \- Manage Bundler plugins .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1 index 294ef179a7..84a02dfd47 100644 --- a/lib/bundler/man/bundle-pristine.1 +++ b/lib/bundler/man/bundle-pristine.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-PRISTINE" "1" "March 2025" "" +.TH "BUNDLE\-PRISTINE" "1" "June 2025" "" .SH "NAME" \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1 index 2e42a12de3..00d9cf4319 100644 --- a/lib/bundler/man/bundle-remove.1 +++ b/lib/bundler/man/bundle-remove.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-REMOVE" "1" "March 2025" "" +.TH "BUNDLE\-REMOVE" "1" "June 2025" "" .SH "NAME" \fBbundle\-remove\fR \- Removes gems from the Gemfile .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1 index d460e7a256..d556c738f6 100644 --- a/lib/bundler/man/bundle-show.1 +++ b/lib/bundler/man/bundle-show.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-SHOW" "1" "March 2025" "" +.TH "BUNDLE\-SHOW" "1" "June 2025" "" .SH "NAME" \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1 index 855a5049aa..080d9b889f 100644 --- a/lib/bundler/man/bundle-update.1 +++ b/lib/bundler/man/bundle-update.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-UPDATE" "1" "March 2025" "" +.TH "BUNDLE\-UPDATE" "1" "June 2025" "" .SH "NAME" \fBbundle\-update\fR \- Update your gems to the latest available versions .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-version.1 b/lib/bundler/man/bundle-version.1 index 17add566d8..e3ccd023b6 100644 --- a/lib/bundler/man/bundle-version.1 +++ b/lib/bundler/man/bundle-version.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-VERSION" "1" "March 2025" "" +.TH "BUNDLE\-VERSION" "1" "June 2025" "" .SH "NAME" \fBbundle\-version\fR \- Prints Bundler version information .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1 index 17e6f90cca..34a2cf1fff 100644 --- a/lib/bundler/man/bundle-viz.1 +++ b/lib/bundler/man/bundle-viz.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE\-VIZ" "1" "March 2025" "" +.TH "BUNDLE\-VIZ" "1" "June 2025" "" .SH "NAME" \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile .SH "SYNOPSIS" diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1 index 3b40f58210..5c42b06547 100644 --- a/lib/bundler/man/bundle.1 +++ b/lib/bundler/man/bundle.1 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "BUNDLE" "1" "March 2025" "" +.TH "BUNDLE" "1" "June 2025" "" .SH "NAME" \fBbundle\fR \- Ruby Dependency Management .SH "SYNOPSIS" diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5 index f52864a2bf..8262ee0afc 100644 --- a/lib/bundler/man/gemfile.5 +++ b/lib/bundler/man/gemfile.5 @@ -1,6 +1,6 @@ .\" generated with Ronn-NG/v0.10.1 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1 -.TH "GEMFILE" "5" "March 2025" "" +.TH "GEMFILE" "5" "June 2025" "" .SH "NAME" \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs .SH "SYNOPSIS" diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb index ece9fb8679..479818e5ec 100644 --- a/lib/bundler/match_platform.rb +++ b/lib/bundler/match_platform.rb @@ -1,23 +1,42 @@ # frozen_string_literal: true -require_relative "gem_helpers" - module Bundler module MatchPlatform - include GemHelpers + def installable_on_platform?(target_platform) # :nodoc: + return true if [Gem::Platform::RUBY, nil, target_platform].include?(platform) + return true if Gem::Platform.new(platform) === target_platform - def match_platform(p) - MatchPlatform.platforms_match?(platform, p) + false end - def self.platforms_match?(gemspec_platform, local_platform) - return true if gemspec_platform.nil? - return true if gemspec_platform == Gem::Platform::RUBY - return true if local_platform == gemspec_platform - gemspec_platform = Gem::Platform.new(gemspec_platform) - return true if gemspec_platform === local_platform + def self.select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false) + matching = select_all_platform_match(specs, platform, force_ruby: force_ruby, prefer_locked: prefer_locked) - false + Gem::Platform.sort_and_filter_best_platform_match(matching, platform) + end + + def self.select_best_local_platform_match(specs, force_ruby: false) + local = Bundler.local_platform + matching = select_all_platform_match(specs, local, force_ruby: force_ruby).filter_map(&:materialized_for_installation) + + Gem::Platform.sort_best_platform_match(matching, local) + end + + def self.select_all_platform_match(specs, platform, force_ruby: false, prefer_locked: false) + matching = specs.select {|spec| spec.installable_on_platform?(force_ruby ? Gem::Platform::RUBY : platform) } + + specs.each(&:force_ruby_platform!) if force_ruby + + if prefer_locked + locked_originally = matching.select {|spec| spec.is_a?(::Bundler::LazySpecification) } + return locked_originally if locked_originally.any? + end + + matching + end + + def self.generic_local_platform_is_ruby? + Bundler.generic_local_platform == Gem::Platform::RUBY end end end diff --git a/lib/bundler/materialization.rb b/lib/bundler/materialization.rb index 6542c07649..43124f25fb 100644 --- a/lib/bundler/materialization.rb +++ b/lib/bundler/materialization.rb @@ -22,9 +22,9 @@ module Bundler @specs ||= if @candidates.nil? [] elsif platform - GemHelpers.select_best_platform_match(@candidates, platform, force_ruby: dep.force_ruby_platform) + MatchPlatform.select_best_platform_match(@candidates, platform, force_ruby: dep.force_ruby_platform) else - GemHelpers.select_best_local_platform_match(@candidates, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform) + MatchPlatform.select_best_local_platform_match(@candidates, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform) end end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index f5d1c57a11..fba9badec7 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -14,8 +14,6 @@ module Bundler require_relative "resolver/root" require_relative "resolver/strategy" - include GemHelpers - def initialize(base, gem_version_promoter, most_specific_locked_platform = nil) @source_requirements = base.source_requirements @base = base @@ -273,7 +271,7 @@ module Bundler next groups if platform_specs.all?(&:empty?) end - ruby_specs = select_best_platform_match(specs, Gem::Platform::RUBY) + ruby_specs = MatchPlatform.select_best_platform_match(specs, Gem::Platform::RUBY) ruby_group = Resolver::SpecGroup.new(ruby_specs) unless ruby_group.empty? diff --git a/lib/bundler/resolver/package.rb b/lib/bundler/resolver/package.rb index 0e86a4f84d..ff75e7b6bc 100644 --- a/lib/bundler/resolver/package.rb +++ b/lib/bundler/resolver/package.rb @@ -30,7 +30,7 @@ module Bundler def platform_specs(specs) platforms.map do |platform| prefer_locked = @new_platforms.include?(platform) ? false : !unlock? - GemHelpers.select_best_platform_match(specs, platform, prefer_locked: prefer_locked) + MatchPlatform.select_best_platform_match(specs, platform, prefer_locked: prefer_locked) end end diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index 1f3fb0fdde..8cf3b56b83 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -13,15 +13,6 @@ require "rubygems" unless defined?(Gem) # `Gem::Source` from the redefined `Gem::Specification#source`. require "rubygems/source" -# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler -# versions and ignore patchlevels -# (https://github.com/rubygems/rubygems/pull/5472, -# https://github.com/rubygems/rubygems/pull/5486). May be removed once RubyGems -# 3.3.12 support is dropped. -unless Gem.ruby_version.to_s == RUBY_VERSION || RUBY_PATCHLEVEL == -1 - Gem.instance_variable_set(:@ruby_version, Gem::Version.new(RUBY_VERSION)) -end - module Gem # Can be removed once RubyGems 3.5.11 support is dropped unless Gem.respond_to?(:freebsd_platform?) @@ -61,81 +52,122 @@ module Gem require "rubygems/platform" class Platform - JAVA = Gem::Platform.new("java") - MSWIN = Gem::Platform.new("mswin32") - MSWIN64 = Gem::Platform.new("mswin64") - MINGW = Gem::Platform.new("x86-mingw32") - X64_MINGW = [Gem::Platform.new("x64-mingw32"), - Gem::Platform.new("x64-mingw-ucrt")].freeze - UNIVERSAL_MINGW = Gem::Platform.new("universal-mingw") - WINDOWS = [MSWIN, MSWIN64, UNIVERSAL_MINGW].flatten.freeze - X64_LINUX = Gem::Platform.new("x86_64-linux") - X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl") - - if X64_LINUX === X64_LINUX_MUSL - remove_method :=== - - def ===(other) - return nil unless Gem::Platform === other - - # universal-mingw32 matches x64-mingw-ucrt - return true if (@cpu == "universal" || other.cpu == "universal") && - @os.start_with?("mingw") && other.os.start_with?("mingw") - - # cpu - ([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu || - (@cpu == "arm" && other.cpu.start_with?("armv"))) && - - # os - @os == other.os && - - # version - ( - (@os != "linux" && (@version.nil? || other.version.nil?)) || - (@os == "linux" && (normalized_linux_version_ext == other.normalized_linux_version_ext || ["musl#{@version}", "musleabi#{@version}", "musleabihf#{@version}"].include?(other.version))) || - @version == other.version - ) - end + # Can be removed once RubyGems 3.6.9 support is dropped + unless respond_to?(:generic) + JAVA = Gem::Platform.new("java") # :nodoc: + MSWIN = Gem::Platform.new("mswin32") # :nodoc: + MSWIN64 = Gem::Platform.new("mswin64") # :nodoc: + MINGW = Gem::Platform.new("x86-mingw32") # :nodoc: + X64_MINGW_LEGACY = Gem::Platform.new("x64-mingw32") # :nodoc: + X64_MINGW = Gem::Platform.new("x64-mingw-ucrt") # :nodoc: + UNIVERSAL_MINGW = Gem::Platform.new("universal-mingw") # :nodoc: + WINDOWS = [MSWIN, MSWIN64, UNIVERSAL_MINGW].freeze # :nodoc: + X64_LINUX = Gem::Platform.new("x86_64-linux") # :nodoc: + X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl") # :nodoc: + + GENERICS = [JAVA, *WINDOWS].freeze # :nodoc: + private_constant :GENERICS + + GENERIC_CACHE = GENERICS.each_with_object({}) {|g, h| h[g] = g } # :nodoc: + private_constant :GENERIC_CACHE - # This is a copy of RubyGems 3.3.23 or higher `normalized_linux_method`. - # Once only 3.3.23 is supported, we can use the method in RubyGems. - def normalized_linux_version_ext - return nil unless @version + class << self + ## + # Returns the generic platform for the given platform. - without_gnu_nor_abi_modifiers = @version.sub(/\Agnu/, "").sub(/eabi(hf)?\Z/, "") - return nil if without_gnu_nor_abi_modifiers.empty? + def generic(platform) + return Gem::Platform::RUBY if platform.nil? || platform == Gem::Platform::RUBY - without_gnu_nor_abi_modifiers - end - end - end + GENERIC_CACHE[platform] ||= begin + found = GENERICS.find do |match| + platform === match + end + found || Gem::Platform::RUBY + end + end - Platform.singleton_class.module_eval do - unless Platform.singleton_methods.include?(:match_spec?) - def match_spec?(spec) - match_gem?(spec.platform, spec.name) - end + ## + # Returns the platform specificity match for the given spec platform and user platform. - def match_gem?(platform, gem_name) - match_platforms?(platform, Gem.platforms) - end - end + def platform_specificity_match(spec_platform, user_platform) + return -1 if spec_platform == user_platform + return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY + + os_match(spec_platform, user_platform) + + cpu_match(spec_platform, user_platform) * 10 + + version_match(spec_platform, user_platform) * 100 + end + + ## + # Sorts and filters the best platform match for the given matching specs and platform. - match_platforms_defined = Gem::Platform.respond_to?(:match_platforms?, true) + def sort_and_filter_best_platform_match(matching, platform) + return matching if matching.one? - if !match_platforms_defined || Gem::Platform.send(:match_platforms?, Gem::Platform::X64_LINUX_MUSL, [Gem::Platform::X64_LINUX]) + exact = matching.select {|spec| spec.platform == platform } + return exact if exact.any? - private + sorted_matching = sort_best_platform_match(matching, platform) + exemplary_spec = sorted_matching.first - remove_method :match_platforms? if match_platforms_defined + sorted_matching.take_while {|spec| same_specificity?(platform, spec, exemplary_spec) && same_deps?(spec, exemplary_spec) } + end + + ## + # Sorts the best platform match for the given matching specs and platform. + + def sort_best_platform_match(matching, platform) + matching.sort_by.with_index do |spec, i| + [ + platform_specificity_match(spec.platform, platform), + i, # for stable sort + ] + end + end + + private + + def same_specificity?(platform, spec, exemplary_spec) + platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform) + end - def match_platforms?(platform, platforms) - platforms.any? do |local_platform| - platform.nil? || - local_platform == platform || - (local_platform != Gem::Platform::RUBY && platform =~ local_platform) + def same_deps?(spec, exemplary_spec) + spec.required_ruby_version == exemplary_spec.required_ruby_version && + spec.required_rubygems_version == exemplary_spec.required_rubygems_version && + spec.dependencies.sort == exemplary_spec.dependencies.sort + end + + def os_match(spec_platform, user_platform) + if spec_platform.os == user_platform.os + 0 + else + 1 + end + end + + def cpu_match(spec_platform, user_platform) + if spec_platform.cpu == user_platform.cpu + 0 + elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm") + 0 + elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal" + 1 + else + 2 + end + end + + def version_match(spec_platform, user_platform) + if spec_platform.version == user_platform.version + 0 + elsif spec_platform.version.nil? + 1 + else + 2 + end end end + end end @@ -144,9 +176,6 @@ module Gem # Can be removed once RubyGems 3.5.14 support is dropped VALIDATES_FOR_RESOLUTION = Specification.new.respond_to?(:validate_for_resolution).freeze - # Can be removed once RubyGems 3.3.15 support is dropped - FLATTENS_REQUIRED_PATHS = Specification.new.respond_to?(:flatten_require_paths).freeze - class Specification # Can be removed once RubyGems 3.5.15 support is dropped correct_array_attributes = @@default_value.select {|_k,v| v.is_a?(Array) }.keys @@ -158,7 +187,6 @@ module Gem require_relative "match_platform" include ::Bundler::MatchMetadata - include ::Bundler::MatchPlatform attr_accessor :remote, :relative_loaded_from @@ -214,23 +242,6 @@ module Gem full_gem_path end - unless const_defined?(:LATEST_RUBY_WITHOUT_PATCH_VERSIONS) - LATEST_RUBY_WITHOUT_PATCH_VERSIONS = Gem::Version.new("2.1") - - alias_method :rg_required_ruby_version=, :required_ruby_version= - def required_ruby_version=(req) - self.rg_required_ruby_version = req - - @required_ruby_version.requirements.map! do |op, v| - if v >= LATEST_RUBY_WITHOUT_PATCH_VERSIONS && v.release.segments.size == 4 - [op == "~>" ? "=" : op, Gem::Version.new(v.segments.tap {|s| s.delete_at(3) }.join("."))] - else - [op, v] - end - end - end - end - def insecurely_materialized? false end @@ -272,25 +283,16 @@ module Gem end end - unless FLATTENS_REQUIRED_PATHS - def flatten_require_paths - return unless raw_require_paths.first.is_a?(Array) - - warn "#{name} #{version} includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this" - raw_require_paths.flatten! - end + if Gem.rubygems_version < Gem::Version.new("3.5.22") + module FixPathSourceMissingExtensions + def missing_extensions? + return false if %w[Bundler::Source::Path Bundler::Source::Gemspec].include?(source.class.name) - class << self - module RequirePathFlattener - def from_yaml(input) - spec = super(input) - spec.flatten_require_paths - spec - end + super end - - prepend RequirePathFlattener end + + prepend FixPathSourceMissingExtensions end private @@ -401,6 +403,11 @@ module Gem @ignored = missing_extensions? end end + + # Can be removed once RubyGems 3.6.9 support is dropped + unless new.respond_to?(:installable_on_platform?) + include(::Bundler::MatchPlatform) + end end require "rubygems/name_tuple" @@ -471,15 +478,4 @@ module Gem Package::TarReader::Entry.prepend(FixFullNameEncoding) end - - require "rubygems/uri" - - # Can be removed once RubyGems 3.3.15 support is dropped - unless Gem::Uri.respond_to?(:redact) - class Uri - def self.redact(uri) - new(uri).redacted - end - end - end end diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index eddf36278c..5342c3dbf9 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -222,8 +222,6 @@ module Bundler # Used to give better error messages when activating specs outside of the current bundle def replace_bin_path(specs_by_name) - gem_class = (class << Gem; self; end) - redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args| exec_name = args.first raise ArgumentError, "you must supply exec_name" unless exec_name @@ -345,9 +343,13 @@ module Bundler Gem::Specification.all = specs end - redefine_method((class << Gem; self; end), :finish_resolve) do |*| + redefine_method(gem_class, :finish_resolve) do |*| [] end + + redefine_method(gem_class, :load_plugins) do |*| + load_plugin_files specs.flat_map(&:plugins) + end end def plain_specs @@ -447,6 +449,12 @@ module Bundler def default_stubs Gem::Specification.default_stubs("*.gemspec") end + + private + + def gem_class + class << Gem; self; end + end end def self.rubygems diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index 444b085bed..9b2416402b 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -71,7 +71,7 @@ module Bundler raise Bundler::GemRequireError.new e, "There was an error while trying to load the gem '#{file}'." end - rescue RuntimeError => e + rescue StandardError => e raise Bundler::GemRequireError.new e, "There was an error while trying to load the gem '#{file}'." end diff --git a/lib/bundler/self_manager.rb b/lib/bundler/self_manager.rb index 2aeac6be52..7db6c9f6f1 100644 --- a/lib/bundler/self_manager.rb +++ b/lib/bundler/self_manager.rb @@ -7,13 +7,15 @@ module Bundler # class SelfManager def restart_with_locked_bundler_if_needed - return unless needs_switching? && installed? + restart_version = find_restart_version + return unless restart_version && installed?(restart_version) restart_with(restart_version) end def install_locked_bundler_and_restart_with_it_if_needed - return unless needs_switching? + restart_version = find_restart_version + return unless restart_version if restart_version == lockfile_version Bundler.ui.info \ @@ -29,8 +31,6 @@ module Bundler end def update_bundler_and_restart_with_it_if_needed(target) - return unless autoswitching_applies? - spec = resolve_update_version_from(target) return unless spec @@ -38,7 +38,7 @@ module Bundler Bundler.ui.info "Updating bundler to #{version}." - install(spec) + install(spec) unless installed?(version) restart_with(version) end @@ -68,47 +68,37 @@ module Bundler def restart_with(version) configured_gem_home = ENV["GEM_HOME"] + configured_orig_gem_home = ENV["BUNDLER_ORIG_GEM_HOME"] configured_gem_path = ENV["GEM_PATH"] + configured_orig_gem_path = ENV["BUNDLER_ORIG_GEM_PATH"] - # Bundler specs need some stuff to be required before Bundler starts - # running, for example, for faking the compact index API. However, these - # flags are lost when we reexec to a different version of Bundler. In the - # future, we may be able to properly reconstruct the original Ruby - # invocation (see https://bugs.ruby-lang.org/issues/6648), but for now - # there's no way to do it, so we need to be explicit about how to re-exec. - # This may be a feature end users request at some point, but maybe by that - # time, we have builtin tools to do. So for now, we use an undocumented - # ENV variable only for our specs. - bundler_spec_original_cmd = ENV["BUNDLER_SPEC_ORIGINAL_CMD"] - if bundler_spec_original_cmd - require "shellwords" - cmd = [*Shellwords.shellsplit(bundler_spec_original_cmd), *ARGV] - else - argv0 = File.exist?($PROGRAM_NAME) ? $PROGRAM_NAME : Process.argv0 - cmd = [argv0, *ARGV] - cmd.unshift(Gem.ruby) unless File.executable?(argv0) - end + argv0 = File.exist?($PROGRAM_NAME) ? $PROGRAM_NAME : Process.argv0 + cmd = [argv0, *ARGV] + cmd.unshift(Gem.ruby) unless File.executable?(argv0) Bundler.with_original_env do Kernel.exec( - { "GEM_HOME" => configured_gem_home, "GEM_PATH" => configured_gem_path, "BUNDLER_VERSION" => version.to_s }, + { + "GEM_HOME" => configured_gem_home, + "BUNDLER_ORIG_GEM_HOME" => configured_orig_gem_home, + "GEM_PATH" => configured_gem_path, + "BUNDLER_ORIG_GEM_PATH" => configured_orig_gem_path, + "BUNDLER_VERSION" => version.to_s, + }, *cmd ) end end - def needs_switching? + def needs_switching?(restart_version) autoswitching_applies? && - Bundler.settings[:version] != "system" && released?(restart_version) && - !running?(restart_version) && - !updating? + !running?(restart_version) end def autoswitching_applies? ENV["BUNDLER_VERSION"].nil? && ruby_can_restart_with_same_arguments? && - SharedHelpers.in_bundle? && lockfile_version end @@ -142,6 +132,7 @@ module Bundler end def find_latest_matching_spec(requirement) + Bundler.configure local_result = find_latest_matching_spec_from_collection(local_specs, requirement) return local_result if local_result && requirement.specific? @@ -171,18 +162,14 @@ module Bundler $PROGRAM_NAME != "-e" end - def updating? - "update".start_with?(ARGV.first || " ") && ARGV[1..-1].any? {|a| a.start_with?("--bundler") } - end - - def installed? + def installed?(restart_version) Bundler.configure Bundler.rubygems.find_bundler(restart_version.to_s) end def current_version - @current_version ||= Gem::Version.new(Bundler::VERSION) + @current_version ||= Bundler.gem_version end def lockfile_version @@ -194,13 +181,16 @@ module Bundler @lockfile_version = nil end - def restart_version - return @restart_version if defined?(@restart_version) - # BUNDLE_VERSION=x.y.z - @restart_version = Gem::Version.new(Bundler.settings[:version]) - rescue ArgumentError - # BUNDLE_VERSION=lockfile - @restart_version = lockfile_version + def find_restart_version + return unless SharedHelpers.in_bundle? + + configured_version = Bundler.settings[:version] + return if configured_version == "system" + + restart_version = configured_version == "lockfile" ? lockfile_version : Gem::Version.new(configured_version) + return unless needs_switching?(restart_version) + + restart_version end end end diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index cde01e0181..6f6bb59747 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -27,6 +27,7 @@ module Bundler gem.changelog gem.coc gem.mit + gem.bundle git.allow_insecure global_gem_cache ignore_messages @@ -39,11 +40,11 @@ module Bundler path.system plugins prefer_patch - print_only_version_number setup_makes_kernel_gem_public silence_deprecations silence_root_warning update_requires_all_flag + verbose ].freeze REMEMBERED_KEYS = %w[ @@ -86,6 +87,7 @@ module Bundler gemfile path shebang + simulate_version system_bindir trust-policy version diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 1ef9d61361..2bdaabdaa7 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -133,13 +133,16 @@ module Bundler removed_message += suffix if removed_message end - bundler_major_version = Bundler.bundler_major_version - if bundler_major_version > major_version + require_relative "../bundler" + + feature_flag = Bundler.feature_flag + + if feature_flag.removed_major?(major_version) require_relative "errors" raise DeprecatedError, "[REMOVED] #{removed_message || message}" end - return unless bundler_major_version >= major_version && prints_major_deprecations? + return unless feature_flag.deprecated_major?(major_version) && prints_major_deprecations? Bundler.ui.warn("[DEPRECATED] #{message}") end @@ -386,7 +389,6 @@ module Bundler end def prints_major_deprecations? - require_relative "../bundler" return false if Bundler.settings[:silence_deprecations] require_relative "deprecate" return false if Bundler::Deprecate.skip diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 8230584260..f613377cb2 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -305,8 +305,8 @@ module Bundler end def has_revision_cached? - return unless @revision && path.exist? - git("cat-file", "-e", @revision, dir: path) + return unless commit && path.exist? + git("cat-file", "-e", commit, dir: path) true rescue GitError false @@ -408,7 +408,7 @@ module Bundler def capture3_args_for(cmd, dir) return ["git", *cmd] unless dir - if Bundler.feature_flag.bundler_3_mode? || supports_minus_c? + if Bundler.feature_flag.bundler_4_mode? || supports_minus_c? ["git", "-C", dir.to_s, *cmd] else ["git", *cmd, { chdir: dir.to_s }] diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 885dd96d85..ac76ae1fa0 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -167,6 +167,13 @@ module Bundler next unless spec = load_gemspec(file) spec.source = self + # The ignore attribute is for ignoring installed gems that don't + # have extensions correctly compiled for activation. In the case of + # path sources, there's a single version of each gem in the path + # source available to Bundler, so we always certainly want to + # consider that for activation and never makes sense to ignore it. + spec.ignored = false + # Validation causes extension_dir to be calculated, which depends # on #source, so we validate here instead of load_gemspec validate_spec(spec) diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb index d1308b1dfb..2f16281045 100644 --- a/lib/bundler/source_list.rb +++ b/lib/bundler/source_list.rb @@ -103,7 +103,7 @@ module Bundler end def get(source) - source_list_for(source).find {|s| equivalent_source?(source, s) } + source_list_for(source).find {|s| s.include?(source) } end def lock_sources @@ -265,9 +265,5 @@ module Bundler def equivalent_sources?(lock_sources, replacement_sources) lock_sources.sort_by(&:identifier) == replacement_sources.sort_by(&:identifier) end - - def equivalent_source?(source, other_source) - source == other_source - end end end diff --git a/lib/bundler/source_map.rb b/lib/bundler/source_map.rb index ca73e01f9d..a8e12d08c3 100644 --- a/lib/bundler/source_map.rb +++ b/lib/bundler/source_map.rb @@ -23,7 +23,7 @@ module Bundler if previous_source.nil? requirements[indirect_dependency_name] = source else - no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode? + no_ambiguous_sources = Bundler.feature_flag.bundler_4_mode? msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."] msg.concat [previous_source, source].map {|s| " * #{s}" }.sort diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 5fa179b978..411393ce1b 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -76,7 +76,7 @@ module Bundler new_platforms = all_platforms.select do |platform| next if platforms.include?(platform) - next unless GemHelpers.generic(platform) == Gem::Platform::RUBY + next unless Gem::Platform.generic(platform) == Gem::Platform::RUBY complete_platform(platform) end @@ -179,11 +179,13 @@ module Bundler end def -(other) + SharedHelpers.major_deprecation 2, "SpecSet#- has been removed with no replacement" + SpecSet.new(to_a - other.to_a) end def find_by_name_and_platform(name, platform) - @specs.detect {|spec| spec.name == name && spec.match_platform(platform) } + @specs.detect {|spec| spec.name == name && spec.installable_on_platform?(platform) } end def specs_with_additional_variants_from(other) @@ -210,6 +212,8 @@ module Bundler end def <<(spec) + SharedHelpers.major_deprecation 2, "SpecSet#<< has been removed with no replacement" + @specs << spec end @@ -280,7 +284,7 @@ module Bundler valid_platform = lookup.all? do |_, specs| spec = specs.first matching_specs = spec.source.specs.search([spec.name, spec.version]) - platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).find do |s| + platform_spec = MatchPlatform.select_best_platform_match(matching_specs, platform).find do |s| valid?(s) end diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt index d1b5ae0534..9224ee0ca2 100644 --- a/lib/bundler/templates/newgem/github/workflows/main.yml.tt +++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt @@ -18,6 +18,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false <%- if config[:ext] == 'rust' -%> - name: Set up Ruby & Rust uses: oxidize-rb/actions/setup-ruby-and-rust@v1 diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index ced300f379..214db0f62e 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -31,7 +31,7 @@ Gem::Specification.new do |spec| spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls| ls.readlines("\x0", chomp: true).reject do |f| (f == gemspec) || - f.start_with?(*%w[bin/ test/ spec/ features/ .git <%= config[:ci_config_path] %>appveyor Gemfile]) + f.start_with?(*%w[<%= config[:ignore_paths].join(" ") %>]) end end spec.bindir = "exe" diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb index 115b49f452..03909a298b 100644 --- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb @@ -1,10 +1,7 @@ require_relative '../../../../../vendored_net_http' require_relative '../../../../../vendored_uri' -begin - require 'cgi/escape' -rescue LoadError - require 'cgi/util' # for escaping -end +require 'cgi/escape' +require 'cgi/util' unless defined?(CGI::EscapeExt) require_relative '../../../../connection_pool/lib/connection_pool' autoload :OpenSSL, 'openssl' @@ -46,9 +43,8 @@ autoload :OpenSSL, 'openssl' # # perform the POST, the Gem::URI is always required # response http.request post_uri, post # -# Note that for GET, HEAD and other requests that do not have a body you want -# to use Gem::URI#request_uri not Gem::URI#path. The request_uri contains the query -# params which are sent in the body for other requests. +# âš Note that for GET, HEAD and other requests that do not have a body, +# it uses Gem::URI#request_uri as default to send query params # # == TLS/SSL # @@ -64,6 +60,7 @@ autoload :OpenSSL, 'openssl' # #ca_path :: Directory with certificate-authorities # #cert_store :: An SSL certificate store # #ciphers :: List of SSl ciphers allowed +# #extra_chain_cert :: Extra certificates to be added to the certificate chain # #private_key :: The client's SSL private key # #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new # connection @@ -180,7 +177,7 @@ class Gem::Net::HTTP::Persistent ## # The version of Gem::Net::HTTP::Persistent you are using - VERSION = '4.0.4' + VERSION = '4.0.6' ## # Error class for errors raised by Gem::Net::HTTP::Persistent. Various @@ -272,6 +269,11 @@ class Gem::Net::HTTP::Persistent attr_reader :ciphers ## + # Extra certificates to be added to the certificate chain + + attr_reader :extra_chain_cert + + ## # Sends debug_output to this IO via Gem::Net::HTTP#set_debug_output. # # Never use this method in production code, it causes a serious security @@ -591,6 +593,21 @@ class Gem::Net::HTTP::Persistent reconnect_ssl end + if Gem::Net::HTTP.method_defined?(:extra_chain_cert=) + ## + # Extra certificates to be added to the certificate chain. + # It is only supported starting from Gem::Net::HTTP version 0.1.1 + def extra_chain_cert= extra_chain_cert + @extra_chain_cert = extra_chain_cert + + reconnect_ssl + end + else + def extra_chain_cert= _extra_chain_cert + raise "extra_chain_cert= is not supported by this version of Gem::Net::HTTP" + end + end + ## # Creates a new connection for +uri+ @@ -609,47 +626,49 @@ class Gem::Net::HTTP::Persistent connection = @pool.checkout net_http_args - http = connection.http + begin + http = connection.http - connection.ressl @ssl_generation if - connection.ssl_generation != @ssl_generation + connection.ressl @ssl_generation if + connection.ssl_generation != @ssl_generation - if not http.started? then - ssl http if use_ssl - start http - elsif expired? connection then - reset connection - end + if not http.started? then + ssl http if use_ssl + start http + elsif expired? connection then + reset connection + end - http.keep_alive_timeout = @idle_timeout if @idle_timeout - http.max_retries = @max_retries if http.respond_to?(:max_retries=) - http.read_timeout = @read_timeout if @read_timeout - http.write_timeout = @write_timeout if - @write_timeout && http.respond_to?(:write_timeout=) + http.keep_alive_timeout = @idle_timeout if @idle_timeout + http.max_retries = @max_retries if http.respond_to?(:max_retries=) + http.read_timeout = @read_timeout if @read_timeout + http.write_timeout = @write_timeout if + @write_timeout && http.respond_to?(:write_timeout=) + + return yield connection + rescue Errno::ECONNREFUSED + if http.proxy? + address = http.proxy_address + port = http.proxy_port + else + address = http.address + port = http.port + end - return yield connection - rescue Errno::ECONNREFUSED - if http.proxy? - address = http.proxy_address - port = http.proxy_port - else - address = http.address - port = http.port - end + raise Error, "connection refused: #{address}:#{port}" + rescue Errno::EHOSTDOWN + if http.proxy? + address = http.proxy_address + port = http.proxy_port + else + address = http.address + port = http.port + end - raise Error, "connection refused: #{address}:#{port}" - rescue Errno::EHOSTDOWN - if http.proxy? - address = http.proxy_address - port = http.proxy_port - else - address = http.address - port = http.port + raise Error, "host down: #{address}:#{port}" + ensure + @pool.checkin net_http_args end - - raise Error, "host down: #{address}:#{port}" - ensure - @pool.checkin net_http_args end ## @@ -957,7 +976,8 @@ class Gem::Net::HTTP::Persistent end ## - # Shuts down all connections + # Shuts down all connections. Attempting to checkout a connection after + # shutdown will raise an error. # # *NOTE*: Calling shutdown for can be dangerous! # @@ -969,6 +989,17 @@ class Gem::Net::HTTP::Persistent end ## + # Discard all existing connections. Subsequent checkouts will create + # new connections as needed. + # + # If any thread is still using a connection it may cause an error! Call + # #reload when you are completely done making requests! + + def reload + @pool.reload { |http| http.finish } + end + + ## # Enables SSL on +connection+ def ssl connection @@ -1025,6 +1056,10 @@ application: connection.key = @private_key end + if defined?(@extra_chain_cert) and @extra_chain_cert + connection.extra_chain_cert = @extra_chain_cert + end + connection.cert_store = if @cert_store then @cert_store else diff --git a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb index 214804fcd9..034fbe39b8 100644 --- a/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +++ b/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb @@ -63,7 +63,8 @@ class Gem::Net::HTTP::Persistent::TimedStackMulti < Bundler::ConnectionPool::Tim if @created >= @max && @enqueued >= 1 oldest, = @lru.first @lru.delete oldest - @ques[oldest].pop + connection = @ques[oldest].pop + connection.close if connection.respond_to?(:close) @created -= 1 end diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index fa24b4966e..f2e654b08a 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -4,10 +4,18 @@ module Bundler VERSION = "2.7.0.dev".freeze def self.bundler_major_version - @bundler_major_version ||= VERSION.split(".").first.to_i + @bundler_major_version ||= gem_version.segments.first end def self.gem_version @gem_version ||= Gem::Version.create(VERSION) end + + def self.verbose_version + @verbose_version ||= "#{VERSION}#{simulated_version ? " (simulating Bundler #{simulated_version})" : ""}" + end + + def self.simulated_version + @simulated_version ||= Bundler.settings[:simulate_version] + end end diff --git a/lib/cgi.rb b/lib/cgi.rb index 71b52b6267..b041c1bed1 100644 --- a/lib/cgi.rb +++ b/lib/cgi.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "cgi/escape" -warn <<-WARNING, uplevel: 1 if $VERBOSE +warn <<-WARNING, uplevel: Gem::BUNDLED_GEMS.uplevel if $VERBOSE CGI library is removed from Ruby 3.5. Please use cgi/escape instead for CGI.escape and CGI.unescape features. If you need to use the full features of CGI library, Please install cgi gem. WARNING diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb index b862341e90..389a04acd2 100644 --- a/lib/cgi/util.rb +++ b/lib/cgi/util.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "cgi/escape" -warn <<-WARNING, uplevel: 1 if $VERBOSE +warn <<-WARNING, uplevel: Gem::BUNDLED_GEMS.uplevel if $VERBOSE CGI::Util is removed from Ruby 3.5. Please use cgi/escape instead for CGI.escape and CGI.unescape features. +If you are using CGI.parse, please install and use the cgi gem instead. WARNING diff --git a/lib/erb.rb b/lib/erb.rb index dffc6d943e..ebf91e4792 100644 --- a/lib/erb.rb +++ b/lib/erb.rb @@ -12,11 +12,6 @@ # # You can redistribute it and/or modify it under the same terms as Ruby. -begin - require 'cgi/escape' -rescue LoadError - require 'cgi/util' -end require 'erb/version' require 'erb/compiler' require 'erb/def_method' diff --git a/lib/erb/def_method.rb b/lib/erb/def_method.rb index aee989a926..e503b37140 100644 --- a/lib/erb/def_method.rb +++ b/lib/erb/def_method.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -#-- + # ERB::DefMethod # # Utility module to define eRuby script as instance method. diff --git a/lib/erb.gemspec b/lib/erb/erb.gemspec index 94a8fd5c3e..94edc68682 100644 --- a/lib/erb.gemspec +++ b/lib/erb/erb.gemspec @@ -2,19 +2,18 @@ begin require_relative 'lib/erb/version' rescue LoadError # for Ruby core repository - require_relative 'erb/version' + require_relative 'version' end Gem::Specification.new do |spec| spec.name = 'erb' - spec.version = ERB.const_get(:VERSION, false) + spec.version = ERB::VERSION spec.authors = ['Masatoshi SEKI', 'Takashi Kokubun'] spec.email = ['[email protected]', '[email protected]'] spec.summary = %q{An easy to use but powerful templating system for Ruby.} spec.description = %q{An easy to use but powerful templating system for Ruby.} spec.homepage = 'https://github.com/ruby/erb' - spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0') spec.licenses = ['Ruby', 'BSD-2-Clause'] spec.metadata['homepage_uri'] = spec.homepage @@ -27,12 +26,11 @@ Gem::Specification.new do |spec| spec.executables = ['erb'] spec.require_paths = ['lib'] + spec.required_ruby_version = '>= 3.2.0' + if RUBY_ENGINE == 'jruby' spec.platform = 'java' else - spec.required_ruby_version = '>= 2.7.0' spec.extensions = ['ext/erb/escape/extconf.rb'] end - - spec.add_dependency 'cgi', '>= 0.3.3' end diff --git a/lib/erb/util.rb b/lib/erb/util.rb index 1d2a36275d..42c7a57622 100644 --- a/lib/erb/util.rb +++ b/lib/erb/util.rb @@ -1,17 +1,23 @@ # frozen_string_literal: true -#-- -# ERB::Escape -# -# A subset of ERB::Util. Unlike ERB::Util#html_escape, we expect/hope -# Rails will not monkey-patch ERB::Escape#html_escape. + +# Load CGI.escapeHTML and CGI.escapeURIComponent. +# CRuby: +# cgi.gem v0.1.0+ (Ruby 2.7-3.4) and Ruby 3.5+ stdlib have 'cgi/escape' and CGI.escapeHTML. +# cgi.gem v0.3.3+ (Ruby 3.2-3.4) and Ruby 3.5+ stdlib have CGI.escapeURIComponent. +# JRuby: cgi.gem has a Java extension 'cgi/escape'. +# TruffleRuby: lib/truffle/cgi/escape.rb requires 'cgi/util'. +require 'cgi/escape' + +# Load or define ERB::Escape#html_escape. +# We don't build the C extention 'cgi/escape' for JRuby, TruffleRuby, and WASM. +# miniruby (used by CRuby build scripts) also fails to load erb/escape.so. begin - # We don't build the C extension for JRuby, TruffleRuby, and WASM - if $LOAD_PATH.resolve_feature_path('erb/escape') - require 'erb/escape' - end -rescue LoadError # resolve_feature_path raises LoadError on TruffleRuby 22.3.0 -end -unless defined?(ERB::Escape) + require 'erb/escape' +rescue LoadError + # ERB::Escape + # + # A subset of ERB::Util. Unlike ERB::Util#html_escape, we expect/hope + # Rails will not monkey-patch ERB::Escape#html_escape. module ERB::Escape def html_escape(s) CGI.escapeHTML(s.to_s) @@ -20,7 +26,6 @@ unless defined?(ERB::Escape) end end -#-- # ERB::Util # # A utility module for conversion routines, often handy in HTML generation. @@ -54,8 +59,16 @@ module ERB::Util # # Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide # - def url_encode(s) - CGI.escapeURIComponent(s.to_s) + if CGI.respond_to?(:escapeURIComponent) + def url_encode(s) + CGI.escapeURIComponent(s.to_s) + end + else # cgi.gem <= v0.3.2 + def url_encode(s) + s.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) do |m| + sprintf("%%%02X", m.unpack1("C")) + end + end end alias u url_encode module_function :u diff --git a/lib/erb/version.rb b/lib/erb/version.rb index b5fe39b330..3d0cedcd48 100644 --- a/lib/erb/version.rb +++ b/lib/erb/version.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true class ERB - VERSION = '4.0.4' - private_constant :VERSION + VERSION = '5.0.1' end diff --git a/lib/net/http.rb b/lib/net/http.rb index 40ff06edab..85051a4468 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1529,7 +1529,7 @@ module Net #:nodoc: :verify_hostname, ] # :nodoc: - SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym } # :nodoc: + SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc: # Sets or returns the path to a CA certification file in PEM format. attr_accessor :ca_file @@ -1917,11 +1917,8 @@ module Net #:nodoc: private def unescape(value) - begin - require "cgi/escape" - rescue LoadError - require "cgi/util" - end + require 'cgi/escape' + require 'cgi/util' unless defined?(CGI::EscapeExt) CGI.unescape(value) end diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb index 44e329a0c8..c92004e557 100644 --- a/lib/net/http/generic_request.rb +++ b/lib/net/http/generic_request.rb @@ -102,6 +102,31 @@ class Net::HTTPGenericRequest "\#<#{self.class} #{@method}>" end + # Returns a string representation of the request with the details for pp: + # + # require 'pp' + # post = Net::HTTP::Post.new(uri) + # post.inspect # => "#<Net::HTTP::Post POST>" + # post.pretty_inspect + # # => #<Net::HTTP::Post + # POST + # path="/" + # headers={"accept-encoding" => ["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], + # "accept" => ["*/*"], + # "user-agent" => ["Ruby"], + # "host" => ["www.ruby-lang.org"]}> + # + def pretty_print(q) + q.object_group(self) { + q.breakable + q.text @method + q.breakable + q.text "path="; q.pp @path + q.breakable + q.text "headers="; q.pp to_hash + } + end + ## # Don't automatically decode response content-encoding if the user indicates # they want to handle it. @@ -260,7 +285,6 @@ class Net::HTTPGenericRequest def send_request_with_body(sock, ver, path, body) self.content_length = body.bytesize delete 'Transfer-Encoding' - supply_default_content_type write_header sock, ver, path wait_for_continue sock, ver if sock.continue_timeout sock.write body @@ -271,7 +295,6 @@ class Net::HTTPGenericRequest raise ArgumentError, "Content-Length not given and Transfer-Encoding is not `chunked'" end - supply_default_content_type write_header sock, ver, path wait_for_continue sock, ver if sock.continue_timeout if chunked? @@ -373,12 +396,6 @@ class Net::HTTPGenericRequest buf.clear end - def supply_default_content_type - return if content_type() - warn 'net/http: Content-Type did not set; using application/x-www-form-urlencoded', uplevel: 1 if $VERBOSE - set_content_type 'application/x-www-form-urlencoded' - end - ## # Waits up to the continue timeout for a response from the server provided # we're speaking HTTP 1.1 and are expecting a 100-continue response. @@ -411,4 +428,3 @@ class Net::HTTPGenericRequest end end - diff --git a/lib/net/http/responses.rb b/lib/net/http/responses.rb index 6f6fb8d055..5e2f8ce1aa 100644 --- a/lib/net/http/responses.rb +++ b/lib/net/http/responses.rb @@ -1104,7 +1104,7 @@ class Net::HTTPResponse '3' => Net::HTTPRedirection, '4' => Net::HTTPClientError, '5' => Net::HTTPServerError - } + }.freeze CODE_TO_OBJ = { '100' => Net::HTTPContinue, '101' => Net::HTTPSwitchProtocol, @@ -1170,5 +1170,5 @@ class Net::HTTPResponse '508' => Net::HTTPLoopDetected, '510' => Net::HTTPNotExtended, '511' => Net::HTTPNetworkAuthenticationRequired, - } + }.freeze end diff --git a/lib/optparse.rb b/lib/optparse.rb index e1069b3505..332aea2148 100644 --- a/lib/optparse.rb +++ b/lib/optparse.rb @@ -7,6 +7,7 @@ # # See OptionParser for documentation. # +require 'set' unless defined?(Set) #-- # == Developer Documentation (not for RDoc output) @@ -1293,7 +1294,15 @@ XXX # to $0. # def program_name - @program_name || File.basename($0, '.*') + @program_name || strip_ext(File.basename($0)) + end + + private def strip_ext(name) # :nodoc: + exts = /#{ + require "rbconfig" + Regexp.union(*RbConfig::CONFIG["EXECUTABLE_EXTS"]&.split(" ")) + }\z/o + name.sub(exts, "") end # for experimental cascading :-) @@ -1500,7 +1509,7 @@ XXX case o when Proc, Method block = notwice(o, block, 'block') - when Array, Hash + when Array, Hash, Set if Array === o o, v = o.partition {|v,| Completion.completable?(v)} values = notwice(v, values, 'values') unless v.empty? diff --git a/lib/optparse/optparse.gemspec b/lib/optparse/optparse.gemspec index 8589f1857c..6ea6b88395 100644 --- a/lib/optparse/optparse.gemspec +++ b/lib/optparse/optparse.gemspec @@ -25,8 +25,9 @@ Gem::Specification.new do |spec| spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage - spec.files = Dir["{doc,lib,misc}/**/{*,.document}"] + - %w[README.md ChangeLog COPYING .document .rdoc_options] + dir, gemspec = File.split(__FILE__) + excludes = %W[#{gemspec} rakelib test/ Gemfile Rakefile .git* .editor*].map {|n| ":^"+n} + spec.files = IO.popen(%w[git ls-files -z --] + excludes, chdir: dir, &:read).split("\x0") spec.bindir = "exe" spec.executables = [] spec.require_paths = ["lib"] diff --git a/lib/prism.rb b/lib/prism.rb index eaab5cbfed..dceba4b1f5 100644 --- a/lib/prism.rb +++ b/lib/prism.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown # The Prism Ruby parser. # diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb index e3b15fc3b0..5d7d38d841 100644 --- a/lib/prism/desugar_compiler.rb +++ b/lib/prism/desugar_compiler.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism class DesugarAndWriteNode # :nodoc: diff --git a/lib/prism/ffi.rb b/lib/prism/ffi.rb index a0da0b6195..5a4ba09a4f 100644 --- a/lib/prism/ffi.rb +++ b/lib/prism/ffi.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown # typed: ignore # This file is responsible for mirroring the API provided by the C extension by diff --git a/lib/prism/lex_compat.rb b/lib/prism/lex_compat.rb index a83c24cb41..9b3f025ab6 100644 --- a/lib/prism/lex_compat.rb +++ b/lib/prism/lex_compat.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown require "delegate" require "ripper" diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb index b007a051ea..469e54ca0c 100644 --- a/lib/prism/node_ext.rb +++ b/lib/prism/node_ext.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true +# :markup: markdown +#-- # Here we are reopening the prism module to provide methods on nodes that aren't # templated and are meant as convenience methods. +#++ module Prism class Node def deprecated(*replacements) # :nodoc: diff --git a/lib/prism/pack.rb b/lib/prism/pack.rb index c0de8ab8b7..166c04c3c0 100644 --- a/lib/prism/pack.rb +++ b/lib/prism/pack.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true +# :markup: markdown # typed: ignore +# module Prism # A parser for the pack template language. module Pack diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 9a3e7c5b79..05c14e33f5 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism # This represents a source of Ruby code that has been parsed. It is used in diff --git a/lib/prism/parse_result/comments.rb b/lib/prism/parse_result/comments.rb index 22c4148b2c..3e93316aff 100644 --- a/lib/prism/parse_result/comments.rb +++ b/lib/prism/parse_result/comments.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism class ParseResult < Result diff --git a/lib/prism/parse_result/errors.rb b/lib/prism/parse_result/errors.rb index eb4f317248..26c376b3ce 100644 --- a/lib/prism/parse_result/errors.rb +++ b/lib/prism/parse_result/errors.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown require "stringio" diff --git a/lib/prism/parse_result/newlines.rb b/lib/prism/parse_result/newlines.rb index 37f64f8ae2..e7fd62cafe 100644 --- a/lib/prism/parse_result/newlines.rb +++ b/lib/prism/parse_result/newlines.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism class ParseResult < Result diff --git a/lib/prism/pattern.rb b/lib/prism/pattern.rb index 03fec26789..6ad2d9e5b9 100644 --- a/lib/prism/pattern.rb +++ b/lib/prism/pattern.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism # A pattern is an object that wraps a Ruby pattern matching expression. The diff --git a/lib/prism/polyfill/scan_byte.rb b/lib/prism/polyfill/scan_byte.rb new file mode 100644 index 0000000000..2def4572c4 --- /dev/null +++ b/lib/prism/polyfill/scan_byte.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require "strscan" + +# Polyfill for StringScanner#scan_byte, which didn't exist until Ruby 3.4. +if !(StringScanner.instance_methods.include?(:scan_byte)) + StringScanner.include( + Module.new { + def scan_byte # :nodoc: + get_byte&.b&.ord + end + } + ) +end diff --git a/lib/prism/prism.gemspec b/lib/prism/prism.gemspec index 5cb5a98057..4daa511300 100644 --- a/lib/prism/prism.gemspec +++ b/lib/prism/prism.gemspec @@ -88,6 +88,7 @@ Gem::Specification.new do |spec| "lib/prism/pattern.rb", "lib/prism/polyfill/append_as_bytes.rb", "lib/prism/polyfill/byteindex.rb", + "lib/prism/polyfill/scan_byte.rb", "lib/prism/polyfill/unpack1.rb", "lib/prism/polyfill/warn.rb", "lib/prism/reflection.rb", diff --git a/lib/prism/relocation.rb b/lib/prism/relocation.rb index 163d2012c5..3e9210a785 100644 --- a/lib/prism/relocation.rb +++ b/lib/prism/relocation.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism # Prism parses deterministically for the same input. This provides a nice diff --git a/lib/prism/string_query.rb b/lib/prism/string_query.rb index 9011051d2b..547f58d2fa 100644 --- a/lib/prism/string_query.rb +++ b/lib/prism/string_query.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism # Query methods that allow categorizing strings based on their context for diff --git a/lib/prism/translation.rb b/lib/prism/translation.rb index 511c80febc..d127f2006c 100644 --- a/lib/prism/translation.rb +++ b/lib/prism/translation.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism # This module is responsible for converting the prism syntax tree into other diff --git a/lib/prism/translation/parser.rb b/lib/prism/translation/parser.rb index d43ad7c1e4..a7888f77ec 100644 --- a/lib/prism/translation/parser.rb +++ b/lib/prism/translation/parser.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown begin required_version = ">= 3.3.7.2" diff --git a/lib/prism/translation/parser/builder.rb b/lib/prism/translation/parser/builder.rb index d3b51f4275..6b620c25bc 100644 --- a/lib/prism/translation/parser/builder.rb +++ b/lib/prism/translation/parser/builder.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism module Translation diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb index 0bd9d74f93..6e0618890d 100644 --- a/lib/prism/translation/parser/compiler.rb +++ b/lib/prism/translation/parser/compiler.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism module Translation diff --git a/lib/prism/translation/parser/lexer.rb b/lib/prism/translation/parser/lexer.rb index 8f2d065b73..dd4867415c 100644 --- a/lib/prism/translation/parser/lexer.rb +++ b/lib/prism/translation/parser/lexer.rb @@ -1,7 +1,9 @@ # frozen_string_literal: true +# :markup: markdown require "strscan" require_relative "../../polyfill/append_as_bytes" +require_relative "../../polyfill/scan_byte" module Prism module Translation @@ -423,7 +425,12 @@ module Prism end current_string << unescape_string(value, quote_stack.last) - if (backslash_count = token.value[/(\\{1,})\n/, 1]&.length).nil? || backslash_count.even? || !interpolation?(quote_stack.last) + relevant_backslash_count = if quote_stack.last.start_with?("%W", "%I") + 0 # the last backslash escapes the newline + else + token.value[/(\\{1,})\n/, 1]&.length || 0 + end + if relevant_backslash_count.even? || !interpolation?(quote_stack.last) tokens << [:tSTRING_CONTENT, [current_string, range(start_offset, start_offset + current_length)]] break end @@ -761,12 +768,12 @@ module Prism elsif (value = scanner.scan(/M-\\?(?=[[:print:]])/)) # \M-x where x is an ASCII printable character escape_read(result, scanner, control, true) - elsif (byte = scanner.get_byte) + elsif (byte = scanner.scan_byte) # Something else after an escape. - if control && byte == "?" + if control && byte == 0x3f # ASCII '?' result.append_as_bytes(escape_build(0x7f, false, meta)) else - result.append_as_bytes(escape_build(byte.ord, control, meta)) + result.append_as_bytes(escape_build(byte, control, meta)) end end end diff --git a/lib/prism/translation/parser33.rb b/lib/prism/translation/parser33.rb index b09266e06a..0a59669465 100644 --- a/lib/prism/translation/parser33.rb +++ b/lib/prism/translation/parser33.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism module Translation diff --git a/lib/prism/translation/parser34.rb b/lib/prism/translation/parser34.rb index 0ead70ad3c..566a23fadb 100644 --- a/lib/prism/translation/parser34.rb +++ b/lib/prism/translation/parser34.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism module Translation diff --git a/lib/prism/translation/parser35.rb b/lib/prism/translation/parser35.rb index a6abc12589..79cd59cbd9 100644 --- a/lib/prism/translation/parser35.rb +++ b/lib/prism/translation/parser35.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown module Prism module Translation diff --git a/lib/prism/translation/parser_current.rb b/lib/prism/translation/parser_current.rb index b44769fde7..1b1794abbe 100644 --- a/lib/prism/translation/parser_current.rb +++ b/lib/prism/translation/parser_current.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true +# :markup: markdown # typed: ignore +# module Prism module Translation case RUBY_VERSION diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb index 95f366ac91..6ea98fc1ea 100644 --- a/lib/prism/translation/ripper.rb +++ b/lib/prism/translation/ripper.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown require "ripper" diff --git a/lib/prism/translation/ripper/sexp.rb b/lib/prism/translation/ripper/sexp.rb index dc26a639a3..8cfefc8472 100644 --- a/lib/prism/translation/ripper/sexp.rb +++ b/lib/prism/translation/ripper/sexp.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown require_relative "../ripper" diff --git a/lib/prism/translation/ruby_parser.rb b/lib/prism/translation/ruby_parser.rb index 8784e22d10..3808cd3130 100644 --- a/lib/prism/translation/ruby_parser.rb +++ b/lib/prism/translation/ruby_parser.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# :markup: markdown begin require "ruby_parser" @@ -15,7 +16,7 @@ module Prism # A prism visitor that builds Sexp objects. class Compiler < ::Prism::Compiler # This is the name of the file that we are compiling. We set it on every - # Sexp object that is generated, and also use it to compile __FILE__ + # Sexp object that is generated, and also use it to compile `__FILE__` # nodes. attr_reader :file @@ -34,26 +35,34 @@ module Prism @in_pattern = in_pattern end + # ``` # alias foo bar # ^^^^^^^^^^^^^ + # ``` def visit_alias_method_node(node) s(node, :alias, visit(node.new_name), visit(node.old_name)) end + # ``` # alias $foo $bar # ^^^^^^^^^^^^^^^ + # ``` def visit_alias_global_variable_node(node) s(node, :valias, node.new_name.name, node.old_name.name) end + # ``` # foo => bar | baz # ^^^^^^^^^ + # ``` def visit_alternation_pattern_node(node) s(node, :or, visit(node.left), visit(node.right)) end + # ``` # a and b # ^^^^^^^ + # ``` def visit_and_node(node) left = visit(node.left) @@ -70,8 +79,10 @@ module Prism end end + # ``` # [] # ^^ + # ``` def visit_array_node(node) if in_pattern s(node, :array_pat, nil).concat(visit_all(node.elements)) @@ -80,8 +91,10 @@ module Prism end end + # ``` # foo => [bar] # ^^^^^ + # ``` def visit_array_pattern_node(node) if node.constant.nil? && node.requireds.empty? && node.rest.nil? && node.posts.empty? s(node, :array_pat) @@ -103,23 +116,29 @@ module Prism end end + # ``` # foo(bar) # ^^^ + # ``` def visit_arguments_node(node) raise "Cannot visit arguments directly" end + # ``` # { a: 1 } # ^^^^ + # ``` def visit_assoc_node(node) [visit(node.key), visit(node.value)] end + # ``` # def foo(**); bar(**); end # ^^ # # { **foo } # ^^^^^ + # ``` def visit_assoc_splat_node(node) if node.value.nil? [s(node, :kwsplat)] @@ -128,14 +147,18 @@ module Prism end end + # ``` # $+ # ^^ + # ``` def visit_back_reference_read_node(node) s(node, :back_ref, node.name.name.delete_prefix("$").to_sym) end + # ``` # begin end # ^^^^^^^^^ + # ``` def visit_begin_node(node) result = node.statements.nil? ? s(node, :nil) : visit(node.statements) @@ -167,16 +190,20 @@ module Prism result end + # ``` # foo(&bar) # ^^^^ + # ``` def visit_block_argument_node(node) s(node, :block_pass).tap do |result| result << visit(node.expression) unless node.expression.nil? end end + # ``` # foo { |; bar| } # ^^^ + # ``` def visit_block_local_variable_node(node) node.name end @@ -186,8 +213,10 @@ module Prism s(node, :block_pass, visit(node.expression)) end + # ``` # def foo(&bar); end # ^^^^ + # ``` def visit_block_parameter_node(node) :"&#{node.name}" end @@ -228,11 +257,13 @@ module Prism result end + # ``` # break # ^^^^^ # # break foo # ^^^^^^^^^ + # ``` def visit_break_node(node) if node.arguments.nil? s(node, :break) @@ -243,6 +274,7 @@ module Prism end end + # ``` # foo # ^^^ # @@ -251,6 +283,7 @@ module Prism # # foo.bar() {} # ^^^^^^^^^^^^ + # ``` def visit_call_node(node) case node.name when :!~ @@ -289,8 +322,10 @@ module Prism visit_block(node, result, block) end + # ``` # foo.bar += baz # ^^^^^^^^^^^^^^^ + # ``` def visit_call_operator_write_node(node) if op_asgn?(node) s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, node.binary_operator) @@ -299,8 +334,10 @@ module Prism end end + # ``` # foo.bar &&= baz # ^^^^^^^^^^^^^^^ + # ``` def visit_call_and_write_node(node) if op_asgn?(node) s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, :"&&") @@ -309,8 +346,10 @@ module Prism end end + # ``` # foo.bar ||= baz # ^^^^^^^^^^^^^^^ + # ``` def visit_call_or_write_node(node) if op_asgn?(node) s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, :"||") @@ -332,32 +371,42 @@ module Prism node.safe_navigation? ? :"safe_#{type}" : type end + # ``` # foo.bar, = 1 # ^^^^^^^ + # ``` def visit_call_target_node(node) s(node, :attrasgn, visit(node.receiver), node.name) end + # ``` # foo => bar => baz # ^^^^^^^^^^ + # ``` def visit_capture_pattern_node(node) visit(node.target) << visit(node.value) end + # ``` # case foo; when bar; end # ^^^^^^^^^^^^^^^^^^^^^^^ + # ``` def visit_case_node(node) s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause) end + # ``` # case foo; in bar; end # ^^^^^^^^^^^^^^^^^^^^^ + # ``` def visit_case_match_node(node) s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause) end + # ``` # class Foo; end # ^^^^^^^^^^^^^^ + # ``` def visit_class_node(node) name = if node.constant_path.is_a?(ConstantReadNode) @@ -376,41 +425,53 @@ module Prism end end + # ``` # @@foo # ^^^^^ + # ``` def visit_class_variable_read_node(node) s(node, :cvar, node.name) end + # ``` # @@foo = 1 # ^^^^^^^^^ # # @@foo, @@bar = 1 # ^^^^^ ^^^^^ + # ``` def visit_class_variable_write_node(node) s(node, class_variable_write_type, node.name, visit_write_value(node.value)) end + # ``` # @@foo += bar # ^^^^^^^^^^^^ + # ``` def visit_class_variable_operator_write_node(node) s(node, class_variable_write_type, node.name, s(node, :call, s(node, :cvar, node.name), node.binary_operator, visit_write_value(node.value))) end + # ``` # @@foo &&= bar # ^^^^^^^^^^^^^ + # ``` def visit_class_variable_and_write_node(node) s(node, :op_asgn_and, s(node, :cvar, node.name), s(node, class_variable_write_type, node.name, visit_write_value(node.value))) end + # ``` # @@foo ||= bar # ^^^^^^^^^^^^^ + # ``` def visit_class_variable_or_write_node(node) s(node, :op_asgn_or, s(node, :cvar, node.name), s(node, class_variable_write_type, node.name, visit_write_value(node.value))) end + # ``` # @@foo, = bar # ^^^^^ + # ``` def visit_class_variable_target_node(node) s(node, class_variable_write_type, node.name) end @@ -421,47 +482,61 @@ module Prism in_def ? :cvasgn : :cvdecl end + # ``` # Foo # ^^^ + # ``` def visit_constant_read_node(node) s(node, :const, node.name) end + # ``` # Foo = 1 # ^^^^^^^ # # Foo, Bar = 1 # ^^^ ^^^ + # ``` def visit_constant_write_node(node) s(node, :cdecl, node.name, visit_write_value(node.value)) end + # ``` # Foo += bar # ^^^^^^^^^^^ + # ``` def visit_constant_operator_write_node(node) s(node, :cdecl, node.name, s(node, :call, s(node, :const, node.name), node.binary_operator, visit_write_value(node.value))) end + # ``` # Foo &&= bar # ^^^^^^^^^^^^ + # ``` def visit_constant_and_write_node(node) s(node, :op_asgn_and, s(node, :const, node.name), s(node, :cdecl, node.name, visit(node.value))) end + # ``` # Foo ||= bar # ^^^^^^^^^^^^ + # ``` def visit_constant_or_write_node(node) s(node, :op_asgn_or, s(node, :const, node.name), s(node, :cdecl, node.name, visit(node.value))) end + # ``` # Foo, = bar # ^^^ + # ``` def visit_constant_target_node(node) s(node, :cdecl, node.name) end + # ``` # Foo::Bar # ^^^^^^^^ + # ``` def visit_constant_path_node(node) if node.parent.nil? s(node, :colon3, node.name) @@ -470,35 +545,45 @@ module Prism end end + # ``` # Foo::Bar = 1 # ^^^^^^^^^^^^ # # Foo::Foo, Bar::Bar = 1 # ^^^^^^^^ ^^^^^^^^ + # ``` def visit_constant_path_write_node(node) s(node, :cdecl, visit(node.target), visit_write_value(node.value)) end + # ``` # Foo::Bar += baz # ^^^^^^^^^^^^^^^ + # ``` def visit_constant_path_operator_write_node(node) s(node, :op_asgn, visit(node.target), node.binary_operator, visit_write_value(node.value)) end + # ``` # Foo::Bar &&= baz # ^^^^^^^^^^^^^^^^ + # ``` def visit_constant_path_and_write_node(node) s(node, :op_asgn_and, visit(node.target), visit_write_value(node.value)) end + # ``` # Foo::Bar ||= baz # ^^^^^^^^^^^^^^^^ + # ``` def visit_constant_path_or_write_node(node) s(node, :op_asgn_or, visit(node.target), visit_write_value(node.value)) end + # ``` # Foo::Bar, = baz # ^^^^^^^^ + # ``` def visit_constant_path_target_node(node) inner = if node.parent.nil? @@ -510,11 +595,13 @@ module Prism s(node, :const, inner) end + # ``` # def foo; end # ^^^^^^^^^^^^ # # def self.foo; end # ^^^^^^^^^^^^^^^^^ + # ``` def visit_def_node(node) name = node.name_loc.slice.to_sym result = @@ -541,55 +628,71 @@ module Prism end end + # ``` # defined? a # ^^^^^^^^^^ # # defined?(a) # ^^^^^^^^^^^ + # ``` def visit_defined_node(node) s(node, :defined, visit(node.value)) end + # ``` # if foo then bar else baz end # ^^^^^^^^^^^^ + # ``` def visit_else_node(node) visit(node.statements) end + # ``` # "foo #{bar}" # ^^^^^^ + # ``` def visit_embedded_statements_node(node) result = s(node, :evstr) result << visit(node.statements) unless node.statements.nil? result end + # ``` # "foo #@bar" # ^^^^^ + # ``` def visit_embedded_variable_node(node) s(node, :evstr, visit(node.variable)) end + # ``` # begin; foo; ensure; bar; end # ^^^^^^^^^^^^ + # ``` def visit_ensure_node(node) node.statements.nil? ? s(node, :nil) : visit(node.statements) end + # ``` # false # ^^^^^ + # ``` def visit_false_node(node) s(node, :false) end + # ``` # foo => [*, bar, *] # ^^^^^^^^^^^ + # ``` def visit_find_pattern_node(node) s(node, :find_pat, visit_pattern_constant(node.constant), :"*#{node.left.expression&.name}", *visit_all(node.requireds), :"*#{node.right.expression&.name}") end + # ``` # if foo .. bar; end # ^^^^^^^^^^ + # ``` def visit_flip_flop_node(node) if node.left.is_a?(IntegerNode) && node.right.is_a?(IntegerNode) s(node, :lit, Range.new(node.left.value, node.right.value, node.exclude_end?)) @@ -598,86 +701,112 @@ module Prism end end + # ``` # 1.0 # ^^^ + # ``` def visit_float_node(node) s(node, :lit, node.value) end + # ``` # for foo in bar do end # ^^^^^^^^^^^^^^^^^^^^^ + # ``` def visit_for_node(node) s(node, :for, visit(node.collection), visit(node.index), visit(node.statements)) end + # ``` # def foo(...); bar(...); end # ^^^ + # ``` def visit_forwarding_arguments_node(node) s(node, :forward_args) end + # ``` # def foo(...); end # ^^^ + # ``` def visit_forwarding_parameter_node(node) s(node, :forward_args) end + # ``` # super # ^^^^^ # # super {} # ^^^^^^^^ + # ``` def visit_forwarding_super_node(node) visit_block(node, s(node, :zsuper), node.block) end + # ``` # $foo # ^^^^ + # ``` def visit_global_variable_read_node(node) s(node, :gvar, node.name) end + # ``` # $foo = 1 # ^^^^^^^^ # # $foo, $bar = 1 # ^^^^ ^^^^ + # ``` def visit_global_variable_write_node(node) s(node, :gasgn, node.name, visit_write_value(node.value)) end + # ``` # $foo += bar # ^^^^^^^^^^^ + # ``` def visit_global_variable_operator_write_node(node) s(node, :gasgn, node.name, s(node, :call, s(node, :gvar, node.name), node.binary_operator, visit(node.value))) end + # ``` # $foo &&= bar # ^^^^^^^^^^^^ + # ``` def visit_global_variable_and_write_node(node) s(node, :op_asgn_and, s(node, :gvar, node.name), s(node, :gasgn, node.name, visit_write_value(node.value))) end + # ``` # $foo ||= bar # ^^^^^^^^^^^^ + # ``` def visit_global_variable_or_write_node(node) s(node, :op_asgn_or, s(node, :gvar, node.name), s(node, :gasgn, node.name, visit_write_value(node.value))) end + # ``` # $foo, = bar # ^^^^ + # ``` def visit_global_variable_target_node(node) s(node, :gasgn, node.name) end + # ``` # {} # ^^ + # ``` def visit_hash_node(node) s(node, :hash).concat(node.elements.flat_map { |element| visit(element) }) end + # ``` # foo => {} # ^^ + # ``` def visit_hash_pattern_node(node) result = s(node, :hash_pat, visit_pattern_constant(node.constant)).concat(node.elements.flat_map { |element| visit(element) }) @@ -691,6 +820,7 @@ module Prism result end + # ``` # if foo then bar end # ^^^^^^^^^^^^^^^^^^^ # @@ -699,6 +829,7 @@ module Prism # # foo ? bar : baz # ^^^^^^^^^^^^^^^ + # ``` def visit_if_node(node) s(node, :if, visit(node.predicate), visit(node.statements), visit(node.subsequent)) end @@ -708,18 +839,24 @@ module Prism s(node, :lit, node.value) end + # ``` # { foo: } # ^^^^ + # ``` def visit_implicit_node(node) end + # ``` # foo { |bar,| } # ^ + # ``` def visit_implicit_rest_node(node) end + # ``` # case foo; in bar; end # ^^^^^^^^^^^^^^^^^^^^^ + # ``` def visit_in_node(node) pattern = if node.pattern.is_a?(ConstantPathNode) @@ -731,8 +868,10 @@ module Prism s(node, :in, pattern).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) end + # ``` # foo[bar] += baz # ^^^^^^^^^^^^^^^ + # ``` def visit_index_operator_write_node(node) arglist = nil @@ -744,8 +883,10 @@ module Prism s(node, :op_asgn1, visit(node.receiver), arglist, node.binary_operator, visit_write_value(node.value)) end + # ``` # foo[bar] &&= baz # ^^^^^^^^^^^^^^^^ + # ``` def visit_index_and_write_node(node) arglist = nil @@ -757,8 +898,10 @@ module Prism s(node, :op_asgn1, visit(node.receiver), arglist, :"&&", visit_write_value(node.value)) end + # ``` # foo[bar] ||= baz # ^^^^^^^^^^^^^^^^ + # ``` def visit_index_or_write_node(node) arglist = nil @@ -770,8 +913,10 @@ module Prism s(node, :op_asgn1, visit(node.receiver), arglist, :"||", visit_write_value(node.value)) end + # ``` # foo[bar], = 1 # ^^^^^^^^ + # ``` def visit_index_target_node(node) arguments = visit_all(node.arguments&.arguments || []) arguments << visit(node.block) unless node.block.nil? @@ -779,53 +924,69 @@ module Prism s(node, :attrasgn, visit(node.receiver), :[]=).concat(arguments) end + # ``` # @foo # ^^^^ + # ``` def visit_instance_variable_read_node(node) s(node, :ivar, node.name) end + # ``` # @foo = 1 # ^^^^^^^^ # # @foo, @bar = 1 # ^^^^ ^^^^ + # ``` def visit_instance_variable_write_node(node) s(node, :iasgn, node.name, visit_write_value(node.value)) end + # ``` # @foo += bar # ^^^^^^^^^^^ + # ``` def visit_instance_variable_operator_write_node(node) s(node, :iasgn, node.name, s(node, :call, s(node, :ivar, node.name), node.binary_operator, visit_write_value(node.value))) end + # ``` # @foo &&= bar # ^^^^^^^^^^^^ + # ``` def visit_instance_variable_and_write_node(node) s(node, :op_asgn_and, s(node, :ivar, node.name), s(node, :iasgn, node.name, visit(node.value))) end + # ``` # @foo ||= bar # ^^^^^^^^^^^^ + # ``` def visit_instance_variable_or_write_node(node) s(node, :op_asgn_or, s(node, :ivar, node.name), s(node, :iasgn, node.name, visit(node.value))) end + # ``` # @foo, = bar # ^^^^ + # ``` def visit_instance_variable_target_node(node) s(node, :iasgn, node.name) end + # ``` # 1 # ^ + # ``` def visit_integer_node(node) s(node, :lit, node.value) end + # ``` # if /foo #{bar}/ then end # ^^^^^^^^^^^^ + # ``` def visit_interpolated_match_last_line_node(node) parts = visit_interpolated_parts(node.parts) regexp = @@ -841,8 +1002,10 @@ module Prism s(node, :match, regexp) end + # ``` # /foo #{bar}/ # ^^^^^^^^^^^^ + # ``` def visit_interpolated_regular_expression_node(node) parts = visit_interpolated_parts(node.parts) @@ -856,22 +1019,28 @@ module Prism end end + # ``` # "foo #{bar}" # ^^^^^^^^^^^^ + # ``` def visit_interpolated_string_node(node) parts = visit_interpolated_parts(node.parts) parts.length == 1 ? s(node, :str, parts.first) : s(node, :dstr).concat(parts) end + # ``` # :"foo #{bar}" # ^^^^^^^^^^^^^ + # ``` def visit_interpolated_symbol_node(node) parts = visit_interpolated_parts(node.parts) parts.length == 1 ? s(node, :lit, parts.first.to_sym) : s(node, :dsym).concat(parts) end + # ``` # `foo #{bar}` # ^^^^^^^^^^^^ + # ``` def visit_interpolated_x_string_node(node) source = node.heredoc? ? node.parts.first : node parts = visit_interpolated_parts(node.parts) @@ -951,23 +1120,29 @@ module Prism results end + # ``` # -> { it } # ^^ + # ``` def visit_it_local_variable_read_node(node) s(node, :call, nil, :it) end + # ``` # foo(bar: baz) # ^^^^^^^^ + # ``` def visit_keyword_hash_node(node) s(node, :hash).concat(node.elements.flat_map { |element| visit(element) }) end + # ``` # def foo(**bar); end # ^^^^^ # # def foo(**); end # ^^ + # ``` def visit_keyword_rest_parameter_node(node) :"**#{node.name}" end @@ -989,8 +1164,10 @@ module Prism end end + # ``` # foo # ^^^ + # ``` def visit_local_variable_read_node(node) if node.name.match?(/^_\d$/) s(node, :call, nil, node.name) @@ -999,59 +1176,77 @@ module Prism end end + # ``` # foo = 1 # ^^^^^^^ # # foo, bar = 1 # ^^^ ^^^ + # ``` def visit_local_variable_write_node(node) s(node, :lasgn, node.name, visit_write_value(node.value)) end + # ``` # foo += bar # ^^^^^^^^^^ + # ``` def visit_local_variable_operator_write_node(node) s(node, :lasgn, node.name, s(node, :call, s(node, :lvar, node.name), node.binary_operator, visit_write_value(node.value))) end + # ``` # foo &&= bar # ^^^^^^^^^^^ + # ``` def visit_local_variable_and_write_node(node) s(node, :op_asgn_and, s(node, :lvar, node.name), s(node, :lasgn, node.name, visit_write_value(node.value))) end + # ``` # foo ||= bar # ^^^^^^^^^^^ + # ``` def visit_local_variable_or_write_node(node) s(node, :op_asgn_or, s(node, :lvar, node.name), s(node, :lasgn, node.name, visit_write_value(node.value))) end + # ``` # foo, = bar # ^^^ + # ``` def visit_local_variable_target_node(node) s(node, :lasgn, node.name) end + # ``` # if /foo/ then end # ^^^^^ + # ``` def visit_match_last_line_node(node) s(node, :match, s(node, :lit, Regexp.new(node.unescaped, node.options))) end + # ``` # foo in bar # ^^^^^^^^^^ + # ``` def visit_match_predicate_node(node) s(node, :case, visit(node.value), s(node, :in, node.pattern.accept(copy_compiler(in_pattern: true)), nil), nil) end + # ``` # foo => bar # ^^^^^^^^^^ + # ``` def visit_match_required_node(node) s(node, :case, visit(node.value), s(node, :in, node.pattern.accept(copy_compiler(in_pattern: true)), nil), nil) end + # ``` # /(?<foo>foo)/ =~ bar # ^^^^^^^^^^^^^^^^^^^^ + # ``` def visit_match_write_node(node) s(node, :match2, visit(node.call.receiver), visit(node.call.arguments.arguments.first)) end @@ -1063,8 +1258,10 @@ module Prism raise "Cannot visit missing node directly" end + # ``` # module Foo; end # ^^^^^^^^^^^^^^^ + # ``` def visit_module_node(node) name = if node.constant_path.is_a?(ConstantReadNode) @@ -1083,8 +1280,10 @@ module Prism end end + # ``` # foo, bar = baz # ^^^^^^^^ + # ``` def visit_multi_target_node(node) targets = [*node.lefts] targets << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) @@ -1093,8 +1292,10 @@ module Prism s(node, :masgn, s(node, :array).concat(visit_all(targets))) end + # ``` # foo, bar = baz # ^^^^^^^^^^^^^^ + # ``` def visit_multi_write_node(node) targets = [*node.lefts] targets << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) @@ -1114,11 +1315,13 @@ module Prism s(node, :masgn, s(node, :array).concat(visit_all(targets)), value) end + # ``` # next # ^^^^ # # next foo # ^^^^^^^^ + # ``` def visit_next_node(node) if node.arguments.nil? s(node, :next) @@ -1130,44 +1333,58 @@ module Prism end end + # ``` # nil # ^^^ + # ``` def visit_nil_node(node) s(node, :nil) end + # ``` # def foo(**nil); end # ^^^^^ + # ``` def visit_no_keywords_parameter_node(node) in_pattern ? s(node, :kwrest, :"**nil") : :"**nil" end + # ``` # -> { _1 + _2 } # ^^^^^^^^^^^^^^ + # ``` def visit_numbered_parameters_node(node) raise "Cannot visit numbered parameters directly" end + # ``` # $1 # ^^ + # ``` def visit_numbered_reference_read_node(node) s(node, :nth_ref, node.number) end + # ``` # def foo(bar: baz); end # ^^^^^^^^ + # ``` def visit_optional_keyword_parameter_node(node) s(node, :kwarg, node.name, visit(node.value)) end + # ``` # def foo(bar = 1); end # ^^^^^^^ + # ``` def visit_optional_parameter_node(node) s(node, :lasgn, node.name, visit(node.value)) end + # ``` # a or b # ^^^^^^ + # ``` def visit_or_node(node) left = visit(node.left) @@ -1184,8 +1401,10 @@ module Prism end end + # ``` # def foo(bar, *baz); end # ^^^^^^^^^ + # ``` def visit_parameters_node(node) children = node.compact_child_nodes.map do |element| @@ -1199,8 +1418,10 @@ module Prism s(node, :args).concat(children) end + # ``` # def foo((bar, baz)); end # ^^^^^^^^^^ + # ``` private def visit_destructured_parameter(node) children = [*node.lefts, *node.rest, *node.rights].map do |child| @@ -1219,11 +1440,13 @@ module Prism s(node, :masgn).concat(children) end + # ``` # () # ^^ # # (1) # ^^^ + # ``` def visit_parentheses_node(node) if node.body.nil? s(node, :nil) @@ -1232,14 +1455,18 @@ module Prism end end + # ``` # foo => ^(bar) # ^^^^^^ + # ``` def visit_pinned_expression_node(node) node.expression.accept(copy_compiler(in_pattern: false)) end + # ``` # foo = 1 and bar => ^foo # ^^^^ + # ``` def visit_pinned_variable_node(node) if node.variable.is_a?(LocalVariableReadNode) && node.variable.name.match?(/^_\d$/) s(node, :lvar, node.variable.name) @@ -1263,8 +1490,10 @@ module Prism visit(node.statements) end + # ``` # 0..5 # ^^^^ + # ``` def visit_range_node(node) if !in_pattern && !node.left.nil? && !node.right.nil? && ([node.left.type, node.right.type] - %i[nil_node integer_node]).empty? left = node.left.value if node.left.is_a?(IntegerNode) @@ -1285,44 +1514,58 @@ module Prism end end + # ``` # 1r # ^^ + # ``` def visit_rational_node(node) s(node, :lit, node.value) end + # ``` # redo # ^^^^ + # ``` def visit_redo_node(node) s(node, :redo) end + # ``` # /foo/ # ^^^^^ + # ``` def visit_regular_expression_node(node) s(node, :lit, Regexp.new(node.unescaped, node.options)) end + # ``` # def foo(bar:); end # ^^^^ + # ``` def visit_required_keyword_parameter_node(node) s(node, :kwarg, node.name) end + # ``` # def foo(bar); end # ^^^ + # ``` def visit_required_parameter_node(node) node.name end + # ``` # foo rescue bar # ^^^^^^^^^^^^^^ + # ``` def visit_rescue_modifier_node(node) s(node, :rescue, visit(node.expression), s(node.rescue_expression, :resbody, s(node.rescue_expression, :array), visit(node.rescue_expression))) end + # ``` # begin; rescue; end # ^^^^^^^ + # ``` def visit_rescue_node(node) exceptions = if node.exceptions.length == 1 && node.exceptions.first.is_a?(SplatNode) @@ -1338,26 +1581,32 @@ module Prism s(node, :resbody, exceptions).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) end + # ``` # def foo(*bar); end # ^^^^ # # def foo(*); end # ^ + # ``` def visit_rest_parameter_node(node) :"*#{node.name}" end + # ``` # retry # ^^^^^ + # ``` def visit_retry_node(node) s(node, :retry) end + # ``` # return # ^^^^^^ # # return 1 # ^^^^^^^^ + # ``` def visit_return_node(node) if node.arguments.nil? s(node, :return) @@ -1369,8 +1618,10 @@ module Prism end end + # ``` # self # ^^^^ + # ``` def visit_self_node(node) s(node, :self) end @@ -1380,33 +1631,42 @@ module Prism visit(node.write) end + # ``` # class << self; end # ^^^^^^^^^^^^^^^^^^ + # ``` def visit_singleton_class_node(node) s(node, :sclass, visit(node.expression)).tap do |sexp| sexp << node.body.accept(copy_compiler(in_def: false)) unless node.body.nil? end end + # ``` # __ENCODING__ # ^^^^^^^^^^^^ + # ``` def visit_source_encoding_node(node) # TODO s(node, :colon2, s(node, :const, :Encoding), :UTF_8) end + # ``` # __FILE__ # ^^^^^^^^ + # ``` def visit_source_file_node(node) s(node, :str, node.filepath) end + # ``` # __LINE__ # ^^^^^^^^ + # ``` def visit_source_line_node(node) s(node, :lit, node.location.start_line) end + # ``` # foo(*bar) # ^^^^ # @@ -1415,6 +1675,7 @@ module Prism # # def foo(*); bar(*); end # ^ + # ``` def visit_splat_node(node) if node.expression.nil? s(node, :splat) @@ -1434,8 +1695,10 @@ module Prism end end + # ``` # "foo" # ^^^^^ + # ``` def visit_string_node(node) unescaped = node.unescaped @@ -1447,8 +1710,10 @@ module Prism s(node, :str, unescaped) end + # ``` # super(foo) # ^^^^^^^^^^ + # ``` def visit_super_node(node) arguments = node.arguments&.arguments || [] block = node.block @@ -1461,60 +1726,76 @@ module Prism visit_block(node, s(node, :super).concat(visit_all(arguments)), block) end + # ``` # :foo # ^^^^ + # ``` def visit_symbol_node(node) node.value == "!@" ? s(node, :lit, :"!@") : s(node, :lit, node.unescaped.to_sym) end + # ``` # true # ^^^^ + # ``` def visit_true_node(node) s(node, :true) end + # ``` # undef foo # ^^^^^^^^^ + # ``` def visit_undef_node(node) names = node.names.map { |name| s(node, :undef, visit(name)) } names.length == 1 ? names.first : s(node, :block).concat(names) end + # ``` # unless foo; bar end # ^^^^^^^^^^^^^^^^^^^ # # bar unless foo # ^^^^^^^^^^^^^^ + # ``` def visit_unless_node(node) s(node, :if, visit(node.predicate), visit(node.else_clause), visit(node.statements)) end + # ``` # until foo; bar end # ^^^^^^^^^^^^^^^^^ # # bar until foo # ^^^^^^^^^^^^^ + # ``` def visit_until_node(node) s(node, :until, visit(node.predicate), visit(node.statements), !node.begin_modifier?) end + # ``` # case foo; when bar; end # ^^^^^^^^^^^^^ + # ``` def visit_when_node(node) s(node, :when, s(node, :array).concat(visit_all(node.conditions))).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) end + # ``` # while foo; bar end # ^^^^^^^^^^^^^^^^^^ # # bar while foo # ^^^^^^^^^^^^^ + # ``` def visit_while_node(node) s(node, :while, visit(node.predicate), visit(node.statements), !node.begin_modifier?) end + # ``` # `foo` # ^^^^^ + # ``` def visit_x_string_node(node) result = s(node, :xstr, node.unescaped) @@ -1526,11 +1807,13 @@ module Prism result end + # ``` # yield # ^^^^^ # # yield 1 # ^^^^^^^ + # ``` def visit_yield_node(node) s(node, :yield).concat(visit_all(node.arguments&.arguments || [])) end diff --git a/lib/resolv.rb b/lib/resolv.rb index ca72f41c5c..17004b224b 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -33,7 +33,7 @@ require 'securerandom' class Resolv - VERSION = "0.6.0" + VERSION = "0.6.1" ## # Looks up the first IP address for +name+. @@ -2601,7 +2601,7 @@ class Resolv end ## - # Flags for this proprty: + # Flags for this property: # - Bit 0 : 0 = not critical, 1 = critical attr_reader :flags diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 1225cbe5cb..fc97f5ff25 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -1144,7 +1144,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path) require_relative "rubygems/user_interaction" - require "bundler" + require_relative "rubygems/bundler_integration" begin Gem::DefaultUserInteraction.use_ui(ui) do Bundler.ui.silence do diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index a09e8ed0e1..a0b552f63c 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -256,6 +256,13 @@ class Gem::BasicSpecification raise NotImplementedError end + def installable_on_platform?(target_platform) # :nodoc: + return true if [Gem::Platform::RUBY, nil, target_platform].include?(platform) + return true if Gem::Platform.new(platform) === target_platform + + false + end + def raw_require_paths # :nodoc: raise NotImplementedError end diff --git a/lib/rubygems/bundler_integration.rb b/lib/rubygems/bundler_integration.rb new file mode 100644 index 0000000000..28228e2398 --- /dev/null +++ b/lib/rubygems/bundler_integration.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "bundler/version" + +if Bundler::VERSION > "2.6.9" + require "bundler" +else + previous_platforms = {} + + platform_const_list = ["JAVA", "MSWIN", "MSWIN64", "MINGW", "X64_MINGW_LEGACY", "X64_MINGW", "UNIVERSAL_MINGW", "WINDOWS", "X64_LINUX", "X64_LINUX_MUSL"] + + platform_const_list.each do |platform| + previous_platforms[platform] = Gem::Platform.const_get(platform) + Gem::Platform.send(:remove_const, platform) + end + + require "bundler" + + platform_const_list.each do |platform| + Gem::Platform.send(:remove_const, platform) if Gem::Platform.const_defined?(platform) + Gem::Platform.const_set(platform, previous_platforms[platform]) + end +end diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb index 97f1646ba0..93503d2b69 100644 --- a/lib/rubygems/commands/pristine_command.rb +++ b/lib/rubygems/commands/pristine_command.rb @@ -137,11 +137,14 @@ extensions will be restored. specs.group_by(&:full_name_with_location).values.each do |grouped_specs| spec = grouped_specs.find {|s| !s.default_gem? } || grouped_specs.first - unless only_executables_or_plugins? + only_executables = options[:only_executables] + only_plugins = options[:only_plugins] + + unless only_executables || only_plugins # Default gemspecs include changes provided by ruby-core installer that # can't currently be pristined (inclusion of compiled extension targets in # the file list). So stick to resetting executables if it's a default gem. - options[:only_executables] = true if spec.default_gem? + only_executables = true if spec.default_gem? end if options.key? :skip @@ -151,14 +154,14 @@ extensions will be restored. end end - unless spec.extensions.empty? || options[:extensions] || only_executables_or_plugins? + unless spec.extensions.empty? || options[:extensions] || only_executables || only_plugins say "Skipped #{spec.full_name_with_location}, it needs to compile an extension" next end gem = spec.cache_file - unless File.exist?(gem) || only_executables_or_plugins? + unless File.exist?(gem) || only_executables || only_plugins require_relative "../remote_fetcher" say "Cached gem for #{spec.full_name_with_location} not found, attempting to fetch..." @@ -194,10 +197,10 @@ extensions will be restored. bin_dir: bin_dir, } - if options[:only_executables] + if only_executables installer = Gem::Installer.for_spec(spec, installer_options) installer.generate_bin - elsif options[:only_plugins] + elsif only_plugins installer = Gem::Installer.for_spec(spec, installer_options) installer.generate_plugins else @@ -208,10 +211,4 @@ extensions will be restored. say "Restored #{spec.full_name_with_location}" end end - - private - - def only_executables_or_plugins? - options[:only_executables] || options[:only_plugins] - end end diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index 301ce25314..85e28ccedd 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -7,8 +7,8 @@ require_relative "../command" # RubyGems checkout or tarball. class Gem::Commands::SetupCommand < Gem::Command - HISTORY_HEADER = %r{^#\s*[\d.a-zA-Z]+\s*/\s*\d{4}-\d{2}-\d{2}\s*$} - VERSION_MATCHER = %r{^#\s*([\d.a-zA-Z]+)\s*/\s*\d{4}-\d{2}-\d{2}\s*$} + HISTORY_HEADER = %r{^##\s*[\d.a-zA-Z]+\s*/\s*\d{4}-\d{2}-\d{2}\s*$} + VERSION_MATCHER = %r{^##\s*([\d.a-zA-Z]+)\s*/\s*\d{4}-\d{2}-\d{2}\s*$} ENV_PATHS = %w[/usr/bin/env /bin/env].freeze diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb index 03024a640e..21b50f394d 100644 --- a/lib/rubygems/ext/cargo_builder.rb +++ b/lib/rubygems/ext/cargo_builder.rb @@ -158,6 +158,10 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder # mkmf work properly. def linker_args cc_flag = self.class.shellsplit(makefile_config("CC")) + # Avoid to ccache like tool from Rust build + # see https://github.com/rubygems/rubygems/pull/8521#issuecomment-2689854359 + # ex. CC="ccache gcc" or CC="sccache clang --any --args" + cc_flag.shift if cc_flag.size >= 2 && !cc_flag[1].start_with?("-") linker = cc_flag.shift link_args = cc_flag.flat_map {|a| ["-C", "link-arg=#{a}"] } diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 8d9a9b2d35..afe7957f43 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -319,7 +319,7 @@ module Gem::GemcutterUtilities end def get_scope_params(scope) - scope_params = { index_rubygems: true } + scope_params = { index_rubygems: true, push_rubygem: true } if scope scope_params = { scope => true } diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 7f5d913ac4..da93f33230 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -953,11 +953,8 @@ TEXT end def ensure_writable_dir(dir) # :nodoc: - begin - Dir.mkdir dir, *[options[:dir_mode] && 0o755].compact - rescue SystemCallError - raise unless File.directory? dir - end + require "fileutils" + FileUtils.mkdir_p dir, mode: options[:dir_mode] && 0o755 raise Gem::FilePermissionError.new(dir) unless File.writable? dir end diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 60a8ab24ba..c855423ed7 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -219,7 +219,6 @@ class Gem::Package # Adds a checksum for each entry in the gem to checksums.yaml.gz. def add_checksums(tar) - require 'psych' Gem.load_yaml checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} } @@ -553,7 +552,6 @@ EOM # Reads and loads checksums.yaml.gz from the tar file +gem+ def read_checksums(gem) - require_relative 'safe_yaml' Gem.load_yaml @checksums = gem.seek "checksums.yaml.gz" do |entry| diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index 450c214167..8b82292a46 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -88,56 +88,45 @@ class Gem::Platform when Array then @cpu, @os, @version = arch when String then - arch = arch.split "-" + cpu, os = arch.sub(/-+$/, "").split("-", 2) - if arch.length > 2 && !arch.last.match?(/\d+(\.\d+)?$/) # reassemble x86-linux-{libc} - extra = arch.pop - arch.last << "-#{extra}" - end - - cpu = arch.shift - - @cpu = case cpu - when /i\d86/ then "x86" - else cpu - end - - if arch.length == 2 && arch.last.match?(/^\d+(\.\d+)?$/) # for command-line - @os, @version = arch - return + @cpu = if cpu.match?(/i\d86/) + "x86" + else + cpu end - os, = arch if os.nil? @cpu = nil os = cpu end # legacy jruby @os, @version = case os - when /aix(\d+)?/ then ["aix", $1] - when /cygwin/ then ["cygwin", nil] - when /darwin(\d+)?/ then ["darwin", $1] - when /^macruby$/ then ["macruby", nil] - when /freebsd(\d+)?/ then ["freebsd", $1] - when /^java$/, /^jruby$/ then ["java", nil] - when /^java([\d.]*)/ then ["java", $1] - when /^dalvik(\d+)?$/ then ["dalvik", $1] - when /^dotnet$/ then ["dotnet", nil] - when /^dotnet([\d.]*)/ then ["dotnet", $1] - when /linux-?(\w+)?/ then ["linux", $1] - when /mingw32/ then ["mingw32", nil] - when /mingw-?(\w+)?/ then ["mingw", $1] - when /(mswin\d+)(\_(\d+))?/ then + when /aix-?(\d+)?/ then ["aix", $1] + when /cygwin/ then ["cygwin", nil] + when /darwin-?(\d+)?/ then ["darwin", $1] + when "macruby" then ["macruby", nil] + when /^macruby-?(\d+(?:\.\d+)*)?/ then ["macruby", $1] + when /freebsd-?(\d+)?/ then ["freebsd", $1] + when "java", "jruby" then ["java", nil] + when /^java-?(\d+(?:\.\d+)*)?/ then ["java", $1] + when /^dalvik-?(\d+)?$/ then ["dalvik", $1] + when /^dotnet$/ then ["dotnet", nil] + when /^dotnet-?(\d+(?:\.\d+)*)?/ then ["dotnet", $1] + when /linux-?(\w+)?/ then ["linux", $1] + when /mingw32/ then ["mingw32", nil] + when /mingw-?(\w+)?/ then ["mingw", $1] + when /(mswin\d+)(?:[_-](\d+))?/ then os = $1 - version = $3 - @cpu = "x86" if @cpu.nil? && os =~ /32$/ + version = $2 + @cpu = "x86" if @cpu.nil? && os.end_with?("32") [os, version] - when /netbsdelf/ then ["netbsdelf", nil] - when /openbsd(\d+\.\d+)?/ then ["openbsd", $1] - when /solaris(\d+\.\d+)?/ then ["solaris", $1] - when /wasi/ then ["wasi", nil] + when /netbsdelf/ then ["netbsdelf", nil] + when /openbsd-?(\d+\.\d+)?/ then ["openbsd", $1] + when /solaris-?(\d+\.\d+)?/ then ["solaris", $1] + when /wasi/ then ["wasi", nil] # test - when /^(\w+_platform)(\d+)?/ then [$1, $2] + when /^(\w+_platform)-?(\d+)?/ then [$1, $2] else ["unknown", nil] end when Gem::Platform then @@ -154,7 +143,7 @@ class Gem::Platform end def to_s - to_a.compact.join "-" + to_a.compact.join(@cpu.nil? ? "" : "-") end ## @@ -266,4 +255,118 @@ class Gem::Platform # This will be replaced with Gem::Platform::local. CURRENT = "current" + + JAVA = Gem::Platform.new("java") # :nodoc: + MSWIN = Gem::Platform.new("mswin32") # :nodoc: + MSWIN64 = Gem::Platform.new("mswin64") # :nodoc: + MINGW = Gem::Platform.new("x86-mingw32") # :nodoc: + X64_MINGW_LEGACY = Gem::Platform.new("x64-mingw32") # :nodoc: + X64_MINGW = Gem::Platform.new("x64-mingw-ucrt") # :nodoc: + UNIVERSAL_MINGW = Gem::Platform.new("universal-mingw") # :nodoc: + WINDOWS = [MSWIN, MSWIN64, UNIVERSAL_MINGW].freeze # :nodoc: + X64_LINUX = Gem::Platform.new("x86_64-linux") # :nodoc: + X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl") # :nodoc: + + GENERICS = [JAVA, *WINDOWS].freeze # :nodoc: + private_constant :GENERICS + + GENERIC_CACHE = GENERICS.each_with_object({}) {|g, h| h[g] = g } # :nodoc: + private_constant :GENERIC_CACHE + + class << self + ## + # Returns the generic platform for the given platform. + + def generic(platform) + return Gem::Platform::RUBY if platform.nil? || platform == Gem::Platform::RUBY + + GENERIC_CACHE[platform] ||= begin + found = GENERICS.find do |match| + platform === match + end + found || Gem::Platform::RUBY + end + end + + ## + # Returns the platform specificity match for the given spec platform and user platform. + + def platform_specificity_match(spec_platform, user_platform) + return -1 if spec_platform == user_platform + return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY + + os_match(spec_platform, user_platform) + + cpu_match(spec_platform, user_platform) * 10 + + version_match(spec_platform, user_platform) * 100 + end + + ## + # Sorts and filters the best platform match for the given matching specs and platform. + + def sort_and_filter_best_platform_match(matching, platform) + return matching if matching.one? + + exact = matching.select {|spec| spec.platform == platform } + return exact if exact.any? + + sorted_matching = sort_best_platform_match(matching, platform) + exemplary_spec = sorted_matching.first + + sorted_matching.take_while {|spec| same_specificity?(platform, spec, exemplary_spec) && same_deps?(spec, exemplary_spec) } + end + + ## + # Sorts the best platform match for the given matching specs and platform. + + def sort_best_platform_match(matching, platform) + matching.sort_by.with_index do |spec, i| + [ + platform_specificity_match(spec.platform, platform), + i, # for stable sort + ] + end + end + + private + + def same_specificity?(platform, spec, exemplary_spec) + platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform) + end + + def same_deps?(spec, exemplary_spec) + spec.required_ruby_version == exemplary_spec.required_ruby_version && + spec.required_rubygems_version == exemplary_spec.required_rubygems_version && + spec.dependencies.sort == exemplary_spec.dependencies.sort + end + + def os_match(spec_platform, user_platform) + if spec_platform.os == user_platform.os + 0 + else + 1 + end + end + + def cpu_match(spec_platform, user_platform) + if spec_platform.cpu == user_platform.cpu + 0 + elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm") + 0 + elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal" + 1 + else + 2 + end + end + + def version_match(spec_platform, user_platform) + if spec_platform.version == user_platform.version + 0 + elsif spec_platform.version.nil? + 1 + else + 2 + end + end + end end diff --git a/lib/rubygems/request_set.rb b/lib/rubygems/request_set.rb index 875df7e019..5a855fdb10 100644 --- a/lib/rubygems/request_set.rb +++ b/lib/rubygems/request_set.rb @@ -181,13 +181,10 @@ class Gem::RequestSet # Install requested gems after they have been downloaded sorted_requests.each do |req| - if req.installed? + if req.installed? && @always_install.none? {|spec| spec == req.spec.spec } req.spec.spec.build_extensions - - if @always_install.none? {|spec| spec == req.spec.spec } - yield req, nil if block_given? - next - end + yield req, nil if block_given? + next end spec = diff --git a/lib/rubygems/resolver.rb b/lib/rubygems/resolver.rb index 35d83abd2d..9bf5f80930 100644 --- a/lib/rubygems/resolver.rb +++ b/lib/rubygems/resolver.rb @@ -241,7 +241,7 @@ class Gem::Resolver sources.each do |source| groups[source]. - sort_by {|spec| [spec.version, spec.platform =~ Gem::Platform.local ? 1 : 0] }. # rubocop:disable Performance/RegexpMatch + sort_by {|spec| [spec.version, -Gem::Platform.platform_specificity_match(spec.platform, Gem::Platform.local)] }. map {|spec| ActivationRequest.new spec, dependency }. each {|activation_request| activation_requests << activation_request } end diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb index e2307f6e02..e647a2c11b 100644 --- a/lib/rubygems/resolver/best_set.rb +++ b/lib/rubygems/resolver/best_set.rb @@ -21,7 +21,7 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet def pick_sets # :nodoc: @sources.each_source do |source| - @sets << source.dependency_resolver_set + @sets << source.dependency_resolver_set(@prerelease) end end diff --git a/lib/rubygems/resolver/source_set.rb b/lib/rubygems/resolver/source_set.rb index 296cf41078..074b473edc 100644 --- a/lib/rubygems/resolver/source_set.rb +++ b/lib/rubygems/resolver/source_set.rb @@ -42,6 +42,6 @@ class Gem::Resolver::SourceSet < Gem::Resolver::Set def get_set(name) link = @links[name] - @sets[link] ||= Gem::Source.new(link).dependency_resolver_set if link + @sets[link] ||= Gem::Source.new(link).dependency_resolver_set(@prerelease) if link end end diff --git a/lib/rubygems/safe_yaml.rb b/lib/rubygems/safe_yaml.rb index ba1a5bcbed..6a02a48230 100644 --- a/lib/rubygems/safe_yaml.rb +++ b/lib/rubygems/safe_yaml.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'psych' - module Gem ### # This module is used for safely loading YAML specs from a gem. The diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb index bee5681dab..772ad04bc9 100644 --- a/lib/rubygems/source.rb +++ b/lib/rubygems/source.rb @@ -67,28 +67,11 @@ class Gem::Source ## # Returns a Set that can fetch specifications from this source. - - def dependency_resolver_set # :nodoc: - return Gem::Resolver::IndexSet.new self if uri.scheme == "file" - - fetch_uri = if uri.host == "rubygems.org" - index_uri = uri.dup - index_uri.host = "index.rubygems.org" - index_uri - else - uri - end - - bundler_api_uri = enforce_trailing_slash(fetch_uri) + "versions" - - begin - fetcher = Gem::RemoteFetcher.fetcher - response = fetcher.fetch_path bundler_api_uri, nil, true - rescue Gem::RemoteFetcher::FetchError - Gem::Resolver::IndexSet.new self - else - Gem::Resolver::APISet.new response.uri + "./info/" - end + # + # The set will optionally fetch prereleases if requested. + # + def dependency_resolver_set(prerelease = false) + new_dependency_resolver_set.tap {|set| set.prerelease = prerelease } end def hash # :nodoc: @@ -234,6 +217,29 @@ class Gem::Source private + def new_dependency_resolver_set + return Gem::Resolver::IndexSet.new self if uri.scheme == "file" + + fetch_uri = if uri.host == "rubygems.org" + index_uri = uri.dup + index_uri.host = "index.rubygems.org" + index_uri + else + uri + end + + bundler_api_uri = enforce_trailing_slash(fetch_uri) + "versions" + + begin + fetcher = Gem::RemoteFetcher.fetcher + response = fetcher.fetch_path bundler_api_uri, nil, true + rescue Gem::RemoteFetcher::FetchError + Gem::Resolver::IndexSet.new self + else + Gem::Resolver::APISet.new response.uri + "./info/" + end + end + def enforce_trailing_slash(uri) uri.merge(uri.path.gsub(%r{/+$}, "") + "/") end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 0b905a7ea7..68ebbf8bc3 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1002,7 +1002,7 @@ class Gem::Specification < Gem::BasicSpecification def self.find_in_unresolved_tree(path) unresolved_specs.each do |spec| spec.traverse do |_from_spec, _dep, to_spec, trail| - if to_spec.has_conflicts? || to_spec.conficts_when_loaded_with?(trail) + if to_spec.has_conflicts? || to_spec.conflicts_when_loaded_with?(trail) :next else return trail.reverse if to_spec.contains_requirable_file? path @@ -1649,7 +1649,7 @@ class Gem::Specification < Gem::BasicSpecification ## # return true if there will be conflict when spec if loaded together with the list of specs. - def conficts_when_loaded_with?(list_of_specs) # :nodoc: + def conflicts_when_loaded_with?(list_of_specs) # :nodoc: result = list_of_specs.any? do |spec| spec.runtime_dependencies.any? {|dep| (dep.name == name) && !satisfies_requirement?(dep) } end diff --git a/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem b/lib/rubygems/ssl_certs/rubygems.org/GlobalSign.pem index 8afb219058..8afb219058 100644 --- a/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem +++ b/lib/rubygems/ssl_certs/rubygems.org/GlobalSign.pem diff --git a/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem b/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem deleted file mode 100644 index f4ce4ca43d..0000000000 --- a/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw -MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT -aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ -jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp -xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp -1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG -snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ -U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 -9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B -AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz -yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE -38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP -AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad -DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME -HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- diff --git a/lib/rubygems/uri_formatter.rb b/lib/rubygems/uri_formatter.rb index 2022757689..8856fdadd2 100644 --- a/lib/rubygems/uri_formatter.rb +++ b/lib/rubygems/uri_formatter.rb @@ -17,11 +17,8 @@ class Gem::UriFormatter # Creates a new URI formatter for +uri+. def initialize(uri) - begin - require "cgi/escape" - rescue LoadError - require "cgi/util" - end + require "cgi/escape" + require "cgi/util" unless defined?(CGI::EscapeExt) @uri = uri end diff --git a/lib/rubygems/vendor/net-http/lib/net/http.rb b/lib/rubygems/vendor/net-http/lib/net/http.rb index 2edfcb1723..0e86056614 100644 --- a/lib/rubygems/vendor/net-http/lib/net/http.rb +++ b/lib/rubygems/vendor/net-http/lib/net/http.rb @@ -46,7 +46,7 @@ module Gem::Net #:nodoc: # == Strategies # # - If you will make only a few GET requests, - # consider using {OpenURI}[rdoc-ref:OpenURI]. + # consider using {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html]. # - If you will make only a few requests of all kinds, # consider using the various singleton convenience methods in this class. # Each of the following methods automatically starts and finishes @@ -108,7 +108,7 @@ module Gem::Net #:nodoc: # It consists of some or all of: scheme, hostname, path, query, and fragment; # see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax]. # - # A Ruby {Gem::URI::Generic}[rdoc-ref:Gem::URI::Generic] object + # A Ruby {Gem::URI::Generic}[https://docs.ruby-lang.org/en/master/Gem/URI/Generic.html] object # represents an internet URI. # It provides, among others, methods # +scheme+, +hostname+, +path+, +query+, and +fragment+. @@ -460,7 +460,7 @@ module Gem::Net #:nodoc: # # First, what's elsewhere. Class Gem::Net::HTTP: # - # - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here]. + # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html#class-Object-label-What-27s+Here]. # # This is a categorized summary of methods and attributes. # @@ -475,8 +475,7 @@ module Gem::Net #:nodoc: # # - {::start}[rdoc-ref:Gem::Net::HTTP.start]: # Begins a new session in a new \Gem::Net::HTTP object. - # - {#started?}[rdoc-ref:Gem::Net::HTTP#started?] - # (aliased as {#active?}[rdoc-ref:Gem::Net::HTTP#active?]): + # - {#started?}[rdoc-ref:Gem::Net::HTTP#started?]: # Returns whether in a session. # - {#finish}[rdoc-ref:Gem::Net::HTTP#finish]: # Ends an active session. @@ -556,18 +555,15 @@ module Gem::Net #:nodoc: # Sends a PUT request and returns a response object. # - {#request}[rdoc-ref:Gem::Net::HTTP#request]: # Sends a request and returns a response object. - # - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get] - # (aliased as {#get2}[rdoc-ref:Gem::Net::HTTP#get2]): + # - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get]: # Sends a GET request and forms a response object; # if a block given, calls the block with the object, # otherwise returns the object. - # - {#request_head}[rdoc-ref:Gem::Net::HTTP#request_head] - # (aliased as {#head2}[rdoc-ref:Gem::Net::HTTP#head2]): + # - {#request_head}[rdoc-ref:Gem::Net::HTTP#request_head]: # Sends a HEAD request and forms a response object; # if a block given, calls the block with the object, # otherwise returns the object. - # - {#request_post}[rdoc-ref:Gem::Net::HTTP#request_post] - # (aliased as {#post2}[rdoc-ref:Gem::Net::HTTP#post2]): + # - {#request_post}[rdoc-ref:Gem::Net::HTTP#request_post]: # Sends a POST request and forms a response object; # if a block given, calls the block with the object, # otherwise returns the object. @@ -605,8 +601,7 @@ module Gem::Net #:nodoc: # Returns whether +self+ is a proxy class. # - {#proxy?}[rdoc-ref:Gem::Net::HTTP#proxy?]: # Returns whether +self+ has a proxy. - # - {#proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address] - # (aliased as {#proxyaddr}[rdoc-ref:Gem::Net::HTTP#proxyaddr]): + # - {#proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address]: # Returns the proxy address. # - {#proxy_from_env?}[rdoc-ref:Gem::Net::HTTP#proxy_from_env?]: # Returns whether the proxy is taken from an environment variable. @@ -718,8 +713,7 @@ module Gem::Net #:nodoc: # === \HTTP Version # # - {::version_1_2?}[rdoc-ref:Gem::Net::HTTP.version_1_2?] - # (aliased as {::is_version_1_2?}[rdoc-ref:Gem::Net::HTTP.is_version_1_2?] - # and {::version_1_2}[rdoc-ref:Gem::Net::HTTP.version_1_2]): + # (aliased as {::version_1_2}[rdoc-ref:Gem::Net::HTTP.version_1_2]): # Returns true; retained for compatibility. # # === Debugging @@ -1293,7 +1287,7 @@ module Gem::Net #:nodoc: # - The name of an encoding. # - An alias for an encoding name. # - # See {Encoding}[rdoc-ref:Encoding]. + # See {Encoding}[https://docs.ruby-lang.org/en/master/Encoding.html]. # # Examples: # @@ -1552,11 +1546,11 @@ module Gem::Net #:nodoc: attr_accessor :cert_store # Sets or returns the available SSL ciphers. - # See {OpenSSL::SSL::SSLContext#ciphers=}[rdoc-ref:OpenSSL::SSL::SSLContext#ciphers-3D]. + # See {OpenSSL::SSL::SSLContext#ciphers=}[OpenSSL::SSL::SSL::Context#ciphers=]. attr_accessor :ciphers # Sets or returns the extra X509 certificates to be added to the certificate chain. - # See {OpenSSL::SSL::SSLContext#add_certificate}[rdoc-ref:OpenSSL::SSL::SSLContext#add_certificate]. + # See {OpenSSL::SSL::SSLContext#add_certificate}[OpenSSL::SSL::SSL::Context#add_certificate]. attr_accessor :extra_chain_cert # Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object. @@ -1566,15 +1560,15 @@ module Gem::Net #:nodoc: attr_accessor :ssl_timeout # Sets or returns the SSL version. - # See {OpenSSL::SSL::SSLContext#ssl_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#ssl_version-3D]. + # See {OpenSSL::SSL::SSLContext#ssl_version=}[OpenSSL::SSL::SSL::Context#ssl_version=]. attr_accessor :ssl_version # Sets or returns the minimum SSL version. - # See {OpenSSL::SSL::SSLContext#min_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#min_version-3D]. + # See {OpenSSL::SSL::SSLContext#min_version=}[OpenSSL::SSL::SSL::Context#min_version=]. attr_accessor :min_version # Sets or returns the maximum SSL version. - # See {OpenSSL::SSL::SSLContext#max_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#max_version-3D]. + # See {OpenSSL::SSL::SSLContext#max_version=}[OpenSSL::SSL::SSL::Context#max_version=]. attr_accessor :max_version # Sets or returns the callback for the server certification verification. @@ -1590,7 +1584,7 @@ module Gem::Net #:nodoc: # Sets or returns whether to verify that the server certificate is valid # for the hostname. - # See {OpenSSL::SSL::SSLContext#verify_hostname=}[rdoc-ref:OpenSSL::SSL::SSLContext#attribute-i-verify_mode]. + # See {OpenSSL::SSL::SSLContext#verify_hostname=}[OpenSSL::SSL::SSL::Context#verify_hostname=]. attr_accessor :verify_hostname # Returns the X509 certificate chain (an array of strings) @@ -1923,11 +1917,8 @@ module Gem::Net #:nodoc: private def unescape(value) - begin - require "cgi/escape" - rescue LoadError - require "cgi/util" - end + require 'cgi/escape' + require 'cgi/util' unless defined?(CGI::EscapeExt) CGI.unescape(value) end diff --git a/lib/set/sorted_set.rb b/lib/set/sorted_set.rb deleted file mode 100644 index bc07bc1fb0..0000000000 --- a/lib/set/sorted_set.rb +++ /dev/null @@ -1,6 +0,0 @@ -begin - require 'sorted_set' -rescue ::LoadError - raise "The `SortedSet` class has been extracted from the `set` library. " \ - "You must use the `sorted_set` gem or other alternatives." -end diff --git a/lib/tempfile.rb b/lib/tempfile.rb index f3213c5684..7292e72c25 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -29,7 +29,7 @@ require 'tmpdir' # require 'tempfile' # # # Tempfile.create with a block -# # The filename are choosen automatically. +# # The filename are chosen automatically. # # (You can specify the prefix and suffix of the filename by an optional argument.) # Tempfile.create {|f| # f.puts "foo" diff --git a/lib/timeout.rb b/lib/timeout.rb index 4fd1fa46da..f5f232ad2a 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -123,6 +123,9 @@ module Timeout def self.ensure_timeout_thread_created unless @timeout_thread and @timeout_thread.alive? + # If the Mutex is already owned we are in a signal handler. + # In that case, just return and let the main thread create the @timeout_thread. + return if TIMEOUT_THREAD_MUTEX.owned? TIMEOUT_THREAD_MUTEX.synchronize do unless @timeout_thread and @timeout_thread.alive? @timeout_thread = create_timeout_thread diff --git a/lib/uri/common.rb b/lib/uri/common.rb index 1115736297..a59c844048 100644 --- a/lib/uri/common.rb +++ b/lib/uri/common.rb @@ -92,6 +92,40 @@ module URI end module Schemes # :nodoc: + class << self + ReservedChars = ".+-" + EscapedChars = "\u01C0\u01C1\u01C2" + # Use Lo category chars as escaped chars for TruffleRuby, which + # does not allow Symbol categories as identifiers. + + def escape(name) + unless name and name.ascii_only? + return nil + end + name.upcase.tr(ReservedChars, EscapedChars) + end + + def unescape(name) + name.tr(EscapedChars, ReservedChars).encode(Encoding::US_ASCII).upcase + end + + def find(name) + const_get(name, false) if name and const_defined?(name, false) + end + + def register(name, klass) + unless scheme = escape(name) + raise ArgumentError, "invalid character as scheme - #{name}" + end + const_set(scheme, klass) + end + + def list + constants.map { |name| + [unescape(name.to_s), const_get(name)] + }.to_h + end + end end private_constant :Schemes @@ -104,7 +138,7 @@ module URI # Note that after calling String#upcase on +scheme+, it must be a valid # constant name. def self.register_scheme(scheme, klass) - Schemes.const_set(scheme.to_s.upcase, klass) + Schemes.register(scheme, klass) end # Returns a hash of the defined schemes: @@ -122,9 +156,7 @@ module URI # # Related: URI.register_scheme. def self.scheme_list - Schemes.constants.map { |name| - [name.to_s.upcase, Schemes.const_get(name)] - }.to_h + Schemes.list end INITIAL_SCHEMES = scheme_list @@ -148,12 +180,10 @@ module URI # # => #<URI::HTTP foo://[email protected]:123/forum/questions/?tag=networking&order=newest#top> # def self.for(scheme, *arguments, default: Generic) - const_name = scheme.to_s.upcase + const_name = Schemes.escape(scheme) uri_class = INITIAL_SCHEMES[const_name] - uri_class ||= if /\A[A-Z]\w*\z/.match?(const_name) && Schemes.const_defined?(const_name, false) - Schemes.const_get(const_name, false) - end + uri_class ||= Schemes.find(const_name) uri_class ||= default return uri_class.new(scheme, *arguments) @@ -859,6 +889,7 @@ module Kernel # Returns a \URI object derived from the given +uri+, # which may be a \URI string or an existing \URI object: # + # require 'uri' # # Returns a new URI. # uri = URI('http://github.com/ruby/ruby') # # => #<URI::HTTP http://github.com/ruby/ruby> @@ -866,6 +897,8 @@ module Kernel # URI(uri) # # => #<URI::HTTP http://github.com/ruby/ruby> # + # You must require 'uri' to use this method. + # def URI(uri) if uri.is_a?(URI::Generic) uri diff --git a/lib/weakref.rb b/lib/weakref.rb index f0a7e7b318..0a09f7f993 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -17,7 +17,7 @@ require "delegate" # class WeakRef < Delegator - VERSION = "0.1.3" + VERSION = "0.1.4" ## # RefError is raised when a referenced object has been recycled by the |