diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2022-05-02 19:42:15 +0900 |
---|---|---|
committer | nagachika <nagachika@ruby-lang.org> | 2022-05-18 10:02:42 +0900 |
commit | 8ba584ff3c085251865c11c5d7deef0ddfc6d0ff (patch) | |
tree | 7574439a57c7ad4f9ee7decf7f8272f48e7fc343 | |
parent | ec5dae0d816261719b0b2f9595c072701c7036e0 (diff) |
Merge RubyGems-3.3.11 and Bundler-2.3.11
69 files changed, 1601 insertions, 117 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb index 0025dee720..47b352177d 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -370,7 +370,7 @@ EOF if env.key?("RUBYLIB") rubylib = env["RUBYLIB"].split(File::PATH_SEPARATOR) - rubylib.delete(File.expand_path("..", __FILE__)) + rubylib.delete(__dir__) env["RUBYLIB"] = rubylib.join(File::PATH_SEPARATOR) end diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb index 0846e82e06..8bffb2fae7 100644 --- a/lib/bundler/build_metadata.rb +++ b/lib/bundler/build_metadata.rb @@ -27,7 +27,7 @@ module Bundler # If Bundler has been installed without its .git directory and without a # commit instance variable then we can't determine its commits SHA. - git_dir = File.join(File.expand_path("../../../..", __FILE__), ".git") + git_dir = File.expand_path("../../../.git", __dir__) if File.directory?(git_dir) return @git_commit_sha = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze } end diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 922ba469a4..e1c284130b 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -610,7 +610,7 @@ module Bundler private :gem def self.source_root - File.expand_path(File.join(File.dirname(__FILE__), "templates")) + File.expand_path("templates", __dir__) end desc "clean [OPTIONS]", "Cleans up unused gems in your bundler directory", :hide => true diff --git a/lib/bundler/cli/info.rb b/lib/bundler/cli/info.rb index 38bc008cb5..0545ce8c75 100644 --- a/lib/bundler/cli/info.rb +++ b/lib/bundler/cli/info.rb @@ -47,7 +47,7 @@ module Bundler def print_gem_path(spec) name = spec.name if name == "bundler" - path = File.expand_path("../../../..", __FILE__) + path = File.expand_path("../../..", __dir__) else path = spec.full_gem_path if spec.deleted_gem? diff --git a/lib/bundler/cli/init.rb b/lib/bundler/cli/init.rb index d851d02d42..e4f8229c48 100644 --- a/lib/bundler/cli/init.rb +++ b/lib/bundler/cli/init.rb @@ -32,7 +32,7 @@ module Bundler file << spec.to_gemfile end else - FileUtils.cp(File.expand_path("../../templates/#{gemfile}", __FILE__), gemfile) + FileUtils.cp(File.expand_path("../templates/#{gemfile}", __dir__), gemfile) end puts "Writing new #{gemfile} to #{SharedHelpers.pwd}/#{gemfile}" diff --git a/lib/bundler/cli/show.rb b/lib/bundler/cli/show.rb index 5eaaba1ef7..2df13db1fa 100644 --- a/lib/bundler/cli/show.rb +++ b/lib/bundler/cli/show.rb @@ -18,7 +18,7 @@ module Bundler if gem_name if gem_name == "bundler" - path = File.expand_path("../../../..", __FILE__) + path = File.expand_path("../../..", __dir__) else spec = Bundler::CLI::Common.select_spec(gem_name, :regex_match) return unless spec diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 61bf1e06d4..ca9df4a21e 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -119,7 +119,7 @@ module Bundler relative_gemfile_path = relative_gemfile_path ruby_command = Thor::Util.ruby_command ruby_command = ruby_command - template_path = File.expand_path("../templates/Executable", __FILE__) + template_path = File.expand_path("templates/Executable", __dir__) if spec.name == "bundler" template_path += ".bundler" spec.executables = %(bundle) @@ -172,7 +172,7 @@ module Bundler end standalone_path = Bundler.root.join(path).relative_path_from(bin_path) standalone_path = standalone_path - template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__)) + template = File.read(File.expand_path("templates/Executable.standalone", __dir__)) ruby_command = Thor::Util.ruby_command ruby_command = ruby_command diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1 index c84a2b106e..d657910e83 100644 --- a/lib/bundler/man/bundle-config.1 +++ b/lib/bundler/man/bundle-config.1 @@ -36,13 +36,13 @@ Executing \fBbundle config list\fR with will print a list of all bundler configu Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\. . .P -Executing \fBbundle config set <name> <value>\fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\. +Executing \fBbundle config set <name> <value>\fR defaults to setting \fBlocal\fR configuration if executing from within a local application, otherwise it will set \fBglobal\fR configuration\. See \fB\-\-local\fR and \fB\-\-global\fR options below\. . .P -Executing \fBbundle config set \-\-global <name> <value>\fR works the same as above\. +Executing \fBbundle config set \-\-local <name> <value>\fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB<project_root>/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\. . .P -Executing \fBbundle config set \-\-local <name> <value>\fR will set that configuration in the directory for the local application\. The configuration will be stored in \fB<project_root>/\.bundle/config\fR\. If \fBBUNDLE_APP_CONFIG\fR is set, the configuration will be stored in \fB$BUNDLE_APP_CONFIG/config\fR\. +Executing \fBbundle config set \-\-global <name> <value>\fR will set that configuration to the value specified for all bundles executed as the current user\. The configuration will be stored in \fB~/\.bundle/config\fR\. If \fIname\fR already is set, \fIname\fR will be overridden and user will be warned\. . .P Executing \fBbundle config unset <name>\fR will delete the configuration in both local and global sources\. diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn index e0533e05be..7d1cb271a9 100644 --- a/lib/bundler/man/bundle-config.1.ronn +++ b/lib/bundler/man/bundle-config.1.ronn @@ -23,18 +23,20 @@ was set. Executing `bundle config get <name>` will print the value of that configuration setting, and where it was set. -Executing `bundle config set <name> <value>` will set that configuration to the -value specified for all bundles executed as the current user. The configuration -will be stored in `~/.bundle/config`. If <name> already is set, <name> will be -overridden and user will be warned. - -Executing `bundle config set --global <name> <value>` works the same as above. +Executing `bundle config set <name> <value>` defaults to setting `local` +configuration if executing from within a local application, otherwise it will +set `global` configuration. See `--local` and `--global` options below. Executing `bundle config set --local <name> <value>` will set that configuration in the directory for the local application. The configuration will be stored in `<project_root>/.bundle/config`. If `BUNDLE_APP_CONFIG` is set, the configuration will be stored in `$BUNDLE_APP_CONFIG/config`. +Executing `bundle config set --global <name> <value>` will set that +configuration to the value specified for all bundles executed as the current +user. The configuration will be stored in `~/.bundle/config`. If <name> already +is set, <name> will be overridden and user will be warned. + Executing `bundle config unset <name>` will delete the configuration in both local and global sources. diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 8b476c9135..ffdbdee503 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -274,10 +274,10 @@ module Bundler def set_bundle_variables # bundler exe & lib folders have same root folder, typical gem installation - exe_file = File.expand_path("../../../exe/bundle", __FILE__) + exe_file = File.expand_path("../../exe/bundle", __dir__) # for Ruby core repository testing - exe_file = File.expand_path("../../../libexec/bundle", __FILE__) unless File.exist?(exe_file) + exe_file = File.expand_path("../../libexec/bundle", __dir__) unless File.exist?(exe_file) # bundler is a default gem, exe path is separate exe_file = Bundler.rubygems.bin_path("bundler", "bundle", VERSION) unless File.exist?(exe_file) @@ -309,7 +309,7 @@ module Bundler end def bundler_ruby_lib - resolve_path File.expand_path("../..", __FILE__) + File.expand_path("..", __dir__) end def clean_load_path @@ -325,7 +325,7 @@ module Bundler def resolve_path(path) expanded = File.expand_path(path) - return expanded unless File.respond_to?(:realpath) && File.exist?(expanded) + return expanded unless File.exist?(expanded) File.realpath(expanded) end diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb index 8bdbaa5527..524afd750a 100644 --- a/lib/bundler/source/metadata.rb +++ b/lib/bundler/source/metadata.rb @@ -22,7 +22,7 @@ module Bundler s.summary = "The best way to manage your application's dependencies" s.executables = %w[bundle] # can't point to the actual gemspec or else the require paths will be wrong - s.loaded_from = File.expand_path("..", __FILE__) + s.loaded_from = __dir__ end if local_spec = Bundler.rubygems.find_bundler(VERSION) diff --git a/lib/bundler/templates/Executable b/lib/bundler/templates/Executable index 3e8d5b317a..f6487e3c89 100644 --- a/lib/bundler/templates/Executable +++ b/lib/bundler/templates/Executable @@ -8,11 +8,9 @@ # this file is here to facilitate running it. # -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../<%= relative_gemfile_path %>", - Pathname.new(__FILE__).realpath) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir__) -bundle_binstub = File.expand_path("../bundle", __FILE__) +bundle_binstub = File.expand_path("bundle", __dir__) if File.file?(bundle_binstub) if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ diff --git a/lib/bundler/templates/Executable.bundler b/lib/bundler/templates/Executable.bundler index 6bb5c51090..51650c7664 100644 --- a/lib/bundler/templates/Executable.bundler +++ b/lib/bundler/templates/Executable.bundler @@ -41,7 +41,7 @@ m = Module.new do gemfile = ENV["BUNDLE_GEMFILE"] return gemfile if gemfile && !gemfile.empty? - File.expand_path("../<%= relative_gemfile_path %>", __FILE__) + File.expand_path("<%= relative_gemfile_path %>", __dir__) end def lockfile diff --git a/lib/bundler/templates/Executable.standalone b/lib/bundler/templates/Executable.standalone index 4bf0753f44..d591e3fc04 100644 --- a/lib/bundler/templates/Executable.standalone +++ b/lib/bundler/templates/Executable.standalone @@ -6,9 +6,7 @@ # this file is here to facilitate running it. # -require "pathname" -path = Pathname.new(__FILE__) -$:.unshift File.expand_path "../<%= standalone_path %>", path.realpath +$:.unshift File.expand_path "<%= standalone_path %>", __dir__ require "bundler/setup" -load File.expand_path "../<%= executable_path %>", path.realpath +load File.expand_path "<%= executable_path %>", __dir__ diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt index 6570d177af..1ff4b58b7b 100644 --- a/lib/bundler/templates/newgem/github/workflows/main.yml.tt +++ b/lib/bundler/templates/newgem/github/workflows/main.yml.tt @@ -17,7 +17,7 @@ jobs: - '<%= RUBY_VERSION %>' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index 546a28b78a..ceb2e9b28d 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -24,7 +24,7 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path(__dir__)) do + spec.files = Dir.chdir(__dir__) do `git ls-files -z`.split("\x0").reject do |f| (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) end diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index 6a5af6c296..f8d69d73e6 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.3.10".freeze + VERSION = "2.3.11".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 68c0781a50..a99281fef5 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = "3.3.10".freeze + VERSION = "3.3.11".freeze end # Must be first since it unloads the prelude from 1.9.2 @@ -112,7 +112,7 @@ require_relative 'rubygems/errors' # -The RubyGems Team module Gem - RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__) + RUBYGEMS_DIR = __dir__ # Taint support is deprecated in Ruby 2.7. # This allows switching ".untaint" to ".tap(&Gem::UNTAINT)", diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index 01714f0342..7b6890013c 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -341,7 +341,7 @@ By default, this RubyGems will install gem as: fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION def fake_spec.full_gem_path - File.expand_path '../../../..', __FILE__ + File.expand_path '../../..', __dir__ end generate_ri = options[:document].include? 'ri' diff --git a/lib/rubygems/ext.rb b/lib/rubygems/ext.rb index bdd5bd9d82..59fd830437 100644 --- a/lib/rubygems/ext.rb +++ b/lib/rubygems/ext.rb @@ -16,3 +16,4 @@ require_relative 'ext/configure_builder' require_relative 'ext/ext_conf_builder' require_relative 'ext/rake_builder' require_relative 'ext/cmake_builder' +require_relative 'ext/cargo_builder' diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index 6d32be6515..d9aa68c067 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -123,6 +123,9 @@ class Gem::Ext::Builder Gem::Ext::RakeBuilder when /CMakeLists.txt/ then Gem::Ext::CmakeBuilder + when /Cargo.toml/ then + # We use the spec name here to ensure we invoke the correct init function later + Gem::Ext::CargoBuilder.new(@spec) else build_error("No builder for extension '#{extension}'") end diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb new file mode 100644 index 0000000000..4c16063224 --- /dev/null +++ b/lib/rubygems/ext/cargo_builder.rb @@ -0,0 +1,305 @@ +# frozen_string_literal: true + +# This class is used by rubygems to build Rust extensions. It is a thin-wrapper +# over the `cargo rustc` command which takes care of building Rust code in a way +# that Ruby can use. +class Gem::Ext::CargoBuilder < Gem::Ext::Builder + attr_reader :spec + + def initialize(spec) + @spec = spec + end + + def build(_extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd) + require "rubygems/command" + require "fileutils" + require "shellwords" + + build_crate(dest_path, results, args, cargo_dir) + ext_path = rename_cdylib_for_ruby_compatibility(dest_path) + finalize_directory(ext_path, dest_path, lib_dir, cargo_dir) + results + end + + private + + def build_crate(dest_path, results, args, cargo_dir) + manifest = File.join(cargo_dir, "Cargo.toml") + + given_ruby_static = ENV["RUBY_STATIC"] + + ENV["RUBY_STATIC"] = "true" if ruby_static? && !given_ruby_static + + cargo = ENV.fetch("CARGO", "cargo") + + cmd = [] + cmd += [cargo, "rustc"] + cmd += ["--target-dir", dest_path] + cmd += ["--manifest-path", manifest] + cmd += ["--lib", "--release", "--locked"] + cmd += ["--"] + cmd += [*cargo_rustc_args(dest_path)] + cmd += Gem::Command.build_args + cmd += args + + self.class.run cmd, results, self.class.class_name, cargo_dir + results + ensure + ENV["RUBY_STATIC"] = given_ruby_static + end + + def cargo_rustc_args(dest_dir) + [ + *linker_args, + *mkmf_libpath, + *rustc_dynamic_linker_flags(dest_dir), + *rustc_lib_flags(dest_dir), + *platform_specific_rustc_args(dest_dir), + *debug_flags, + ] + end + + def platform_specific_rustc_args(dest_dir, flags = []) + if mingw_target? + # On mingw platforms, mkmf adds libruby to the linker flags + flags += libruby_args(dest_dir) + + # Make sure ALSR is used on mingw + # see https://github.com/rust-lang/rust/pull/75406/files + flags += ["-C", "link-arg=-Wl,--dynamicbase"] + flags += ["-C", "link-arg=-Wl,--disable-auto-image-base"] + + # If the gem is installed on a host with build tools installed, but is + # run on one that isn't the missing libraries will cause the extension + # to fail on start. + flags += ["-C", "link-arg=-static-libgcc"] + end + + flags + end + + # We want to use the same linker that Ruby uses, so that the linker flags from + # mkmf work properly. + def linker_args + # Have to handle CC="cl /nologo" on mswin + cc_flag = Shellwords.split(makefile_config("CC")) + linker = cc_flag.shift + link_args = cc_flag.flat_map {|a| ["-C", "link-arg=#{a}"] } + + ["-C", "linker=#{linker}", *link_args] + end + + def libruby_args(dest_dir) + libs = makefile_config(ruby_static? ? "LIBRUBYARG_STATIC" : "LIBRUBYARG_SHARED") + raw_libs = Shellwords.split(libs) + raw_libs.flat_map {|l| ldflag_to_link_modifier(l, dest_dir) } + end + + def ruby_static? + return true if %w[1 true].include?(ENV["RUBY_STATIC"]) + + makefile_config("ENABLE_SHARED") == "no" + end + + # Ruby expects the dylib to follow a file name convention for loading + def rename_cdylib_for_ruby_compatibility(dest_path) + dylib_path = validate_cargo_build!(dest_path) + dlext_name = "#{spec.name}.#{makefile_config("DLEXT")}" + new_name = dylib_path.gsub(File.basename(dylib_path), dlext_name) + FileUtils.cp(dylib_path, new_name) + new_name + end + + def validate_cargo_build!(dir) + prefix = so_ext == "dll" ? "" : "lib" + dylib_path = File.join(dir, "release", "#{prefix}#{cargo_crate_name}.#{so_ext}") + + raise DylibNotFoundError, dir unless File.exist?(dylib_path) + + dylib_path + end + + def cargo_crate_name + spec.metadata.fetch('cargo_crate_name', spec.name).tr('-', '_') + end + + def rustc_dynamic_linker_flags(dest_dir) + split_flags("DLDFLAGS") + .map {|arg| maybe_resolve_ldflag_variable(arg, dest_dir) } + .compact + .flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) } + end + + def rustc_lib_flags(dest_dir) + split_flags("LIBS").flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) } + end + + def split_flags(var) + Shellwords.split(RbConfig::CONFIG.fetch(var, "")) + end + + def ldflag_to_link_modifier(arg, dest_dir) + flag = arg[0..1] + val = arg[2..-1] + + case flag + when "-L" then ["-L", "native=#{val}"] + when "-l" then ["-l", val.to_s] + when "-F" then ["-l", "framework=#{val}"] + else ["-C", "link_arg=#{arg}"] + end + end + + def link_flag(link_name) + # These are provided by the CRT with MSVC + # @see https://github.com/rust-lang/pkg-config-rs/blob/49a4ac189aafa365167c72e8e503565a7c2697c2/src/lib.rs#L622 + return [] if msvc_target? && ["m", "c", "pthread"].include?(link_name) + + if link_name.include?("ruby") + # Specify the lib kind and give it the name "ruby" for linking + kind = ruby_static? ? "static" : "dylib" + + ["-l", "#{kind}=ruby:#{link_name}"] + else + ["-l", link_name] + end + end + + def msvc_target? + makefile_config("target_os").include?("msvc") + end + + def darwin_target? + makefile_config("target_os").include?("darwin") + end + + def mingw_target? + makefile_config("target_os").include?("mingw") + end + + def win_target? + target_platform = RbConfig::CONFIG["target_os"] + !!Gem::WIN_PATTERNS.find {|r| target_platform =~ r } + end + + # Intepolate substition vars in the arg (i.e. $(DEFFILE)) + def maybe_resolve_ldflag_variable(input_arg, dest_dir) + str = input_arg.gsub(/\$\((\w+)\)/) do |var_name| + case var_name + # On windows, it is assumed that mkmf has setup an exports file for the + # extension, so we have to to create one ourselves. + when "DEFFILE" + write_deffile(dest_dir) + else + RbConfig::CONFIG[var_name] + end + end.strip + + str == "" ? nil : str + end + + def write_deffile(dest_dir) + deffile_path = File.join(dest_dir, "#{spec.name}-#{RbConfig::CONFIG["arch"]}.def") + export_prefix = makefile_config("EXPORT_PREFIX") || "" + + File.open(deffile_path, "w") do |f| + f.puts "EXPORTS" + f.puts "#{export_prefix.strip}Init_#{spec.name}" + end + + deffile_path + end + + # We have to basically reimplement RbConfig::CONFIG['SOEXT'] here to support + # Ruby < 2.5 + # + # @see https://github.com/ruby/ruby/blob/c87c027f18c005460746a74c07cd80ee355b16e4/configure.ac#L3185 + def so_ext + return RbConfig::CONFIG["SOEXT"] if RbConfig::CONFIG.key?("SOEXT") + + if win_target? + "dll" + elsif darwin_target? + "dylib" + else + "so" + end + end + + # Corresponds to $(LIBPATH) in mkmf + def mkmf_libpath + ["-L", "native=#{makefile_config("libdir")}"] + end + + def makefile_config(var_name) + val = RbConfig::MAKEFILE_CONFIG[var_name] + + return unless val + + RbConfig.expand(val.dup) + end + + # Good balance between binary size and debugability + def debug_flags + ["-C", "debuginfo=1"] + end + + # Copied from ExtConfBuilder + def finalize_directory(ext_path, dest_path, lib_dir, extension_dir) + require "fileutils" + require "tempfile" + + begin + tmp_dest = Dir.mktmpdir(".gem.", extension_dir) + + # Some versions of `mktmpdir` return absolute paths, which will break make + # if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative + # paths cause all C extension builds to fail. + # + # As such, we convert to a relative path unless we are using Ruby 1.9.x on + # Windows. This means that when using Ruby 1.9.x on Windows, paths with + # spaces do not work. + # + # Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940 + tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir) + + if tmp_dest_relative + full_tmp_dest = File.join(extension_dir, tmp_dest_relative) + + # TODO: remove in RubyGems 3 + if Gem.install_extension_in_lib && lib_dir + FileUtils.mkdir_p lib_dir + FileUtils.cp_r ext_path, lib_dir, remove_destination: true + end + + FileUtils::Entry_.new(full_tmp_dest).traverse do |ent| + destent = ent.class.new(dest_path, ent.rel) + destent.exist? || FileUtils.mv(ent.path, destent.path) + end + end + ensure + FileUtils.rm_rf tmp_dest if tmp_dest + end + end + + def get_relative_path(path, base) + path[0..base.length - 1] = "." if path.start_with?(base) + path + end + + # Error raised when no cdylib artifact was created + class DylibNotFoundError < StandardError + def initialize(dir) + files = Dir.glob(File.join(dir, "**", "*")).map {|f| "- #{f}" }.join "\n" + + super <<~MSG + Dynamic library not found for Rust extension (in #{dir}) + + Make sure you set "crate-type" in Cargo.toml to "cdylib" + + Found files: + #{files} + MSG + end + end +end diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb index 3ca3463615..3e8aa950c9 100644 --- a/lib/rubygems/ext/ext_conf_builder.rb +++ b/lib/rubygems/ext/ext_conf_builder.rb @@ -39,7 +39,7 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder # workaround for https://github.com/oracle/truffleruby/issues/2115 siteconf_path = RUBY_ENGINE == "truffleruby" ? siteconf.path.dup : siteconf.path require "shellwords" - cmd = Gem.ruby.shellsplit << "-I" << File.expand_path("../../..", __FILE__) << + cmd = Gem.ruby.shellsplit << "-I" << File.expand_path('../..', __dir__) << "-r" << get_relative_path(siteconf_path, extension_dir) << File.basename(extension) cmd.push(*args) diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 0968e1a6f9..7cb5fe9448 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -163,12 +163,14 @@ module Gem::GemcutterUtilities key_name = get_key_name(scope) scope_params = get_scope_params(scope) + mfa_params = get_mfa_params(email, password) + all_params = scope_params.merge(mfa_params) response = rubygems_api_request(:post, "api/v1/api_key", sign_in_host, scope: scope) do |request| request.basic_auth email, password request["OTP"] = otp if otp - request.body = URI.encode_www_form({ name: key_name }.merge(scope_params)) + request.body = URI.encode_www_form({ name: key_name }.merge(all_params)) end with_response response do |resp| @@ -219,7 +221,7 @@ module Gem::GemcutterUtilities # +response+ text and no otp provided by options. def set_api_key(host, key) - if host == Gem::DEFAULT_HOST + if default_host? Gem.configuration.rubygems_api_key = key else Gem.configuration.set_api_key host, key @@ -243,7 +245,7 @@ module Gem::GemcutterUtilities end def pretty_host(host) - if Gem::DEFAULT_HOST == host + if default_host? 'RubyGems.org' else host @@ -258,8 +260,8 @@ module Gem::GemcutterUtilities else say "Please select scopes you want to enable for the API key (y/n)" API_SCOPES.each do |scope| - selected = ask "#{scope} [y/N]: " - scope_params[scope] = true if selected =~ /^[yY](es)?$/ + selected = ask_yes_no("#{scope}", false) + scope_params[scope] = true if selected end say "\n" end @@ -267,6 +269,33 @@ module Gem::GemcutterUtilities scope_params end + def default_host? + self.host == Gem::DEFAULT_HOST + end + + def get_mfa_params(email, password) + return {} unless default_host? + + mfa_level = get_user_mfa_level(email, password) + params = {} + if mfa_level == "ui_only" || mfa_level == "ui_and_gem_signin" + selected = ask_yes_no("Would you like to enable MFA for this key? (strongly recommended)") + params["mfa"] = true if selected + end + params + end + + def get_user_mfa_level(email, password) + response = rubygems_api_request(:get, "api/v1/profile/me.yaml") do |request| + request.basic_auth email, password + end + + with_response response do |resp| + body = Gem::SafeYAML.load clean_text(resp.body) + body["mfa"] + end + end + def get_key_name(scope) hostname = Socket.gethostname || "unknown-host" user = ENV["USER"] || ENV["USERNAME"] || "unknown-user" diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index d6100c914b..136b154bee 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -39,7 +39,7 @@ class Gem::Request def cert_files; @connection_pool.cert_files; end def self.get_cert_files - pattern = File.expand_path("./ssl_certs/*/*.pem", File.dirname(__FILE__)) + pattern = File.expand_path("./ssl_certs/*/*.pem", __dir__) Dir.glob(pattern) end diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index cda5aa8073..8d5dc1f69d 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -102,6 +102,7 @@ class Gem::Source::Git < Gem::Source success = system @git, 'reset', '--quiet', '--hard', rev_parse if @need_submodules + require "open3" _, status = Open3.capture2e(@git, 'submodule', 'update', '--quiet', '--init', '--recursive') success &&= status.success? diff --git a/libexec/bundler b/libexec/bundler index d9131fe834..a6826a8c89 100755 --- a/libexec/bundler +++ b/libexec/bundler @@ -1,4 +1,4 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../bundle", __FILE__) +load File.expand_path("bundle", __dir__) diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 85fc8cc046..610b8c189a 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -778,7 +778,7 @@ RSpec.describe "bundle install with gem sources" do it "includes the standalone path" do bundle "binstubs rack", :standalone => true standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip - expect(standalone_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath) + expect(standalone_line).to eq %($:.unshift File.expand_path "../bundle", __dir__) end end diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index ee5d53c527..d013d5bd73 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -1147,7 +1147,7 @@ RSpec.describe "bundle update --bundler" do end it "updates the bundler version in the lockfile without re-resolving if the highest version is already installed" do - system_gems "bundler-2.3.3" + system_gems "bundler-2.3.9" build_repo4 do build_gem "rack", "1.0" @@ -1157,7 +1157,7 @@ RSpec.describe "bundle update --bundler" do source "#{file_uri_for(gem_repo4)}" gem "rack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.3") + lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") bundle :update, :bundler => true, :artifice => "compact_index", :verbose => true expect(out).to include("Using bundler #{Bundler::VERSION}") @@ -1182,7 +1182,7 @@ RSpec.describe "bundle update --bundler" do end it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo, :realworld do - pristine_system_gems "bundler-2.3.3" + pristine_system_gems "bundler-2.3.9" build_repo4 do build_gem "rack", "1.0" @@ -1192,16 +1192,16 @@ RSpec.describe "bundle update --bundler" do source "#{file_uri_for(gem_repo4)}" gem "rack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.3") + lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") bundle :update, :bundler => true, :artifice => "vcr", :verbose => true # Only updates properly on modern RubyGems. if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") - expect(out).to include("Updating bundler to 2.3.4") - expect(out).to include("Using bundler 2.3.4") - expect(out).not_to include("Installing Bundler 2.3.3 and restarting using that version.") + expect(out).to include("Updating bundler to 2.3.10") + expect(out).to include("Using bundler 2.3.10") + expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.") expect(lockfile).to eq <<~L GEM @@ -1216,17 +1216,17 @@ RSpec.describe "bundle update --bundler" do rack BUNDLED WITH - 2.3.4 + 2.3.10 L - expect(the_bundle).to include_gems "bundler 2.3.4" + expect(the_bundle).to include_gems "bundler 2.3.10" end expect(the_bundle).to include_gems "rack 1.0" end it "errors if the explicit target version does not exist", :realworld do - pristine_system_gems "bundler-2.3.3" + pristine_system_gems "bundler-2.3.9" build_repo4 do build_gem "rack", "1.0" @@ -1236,7 +1236,7 @@ RSpec.describe "bundle update --bundler" do source "#{file_uri_for(gem_repo4)}" gem "rack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.3") + lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") bundle :update, :bundler => "999.999.999", :artifice => "vcr", :raise_on_error => false @@ -1286,7 +1286,7 @@ RSpec.describe "bundle update --bundler" do end it "does not touch the network if not necessary" do - system_gems "bundler-2.3.3" + system_gems "bundler-2.3.9" build_repo4 do build_gem "rack", "1.0" @@ -1297,7 +1297,7 @@ RSpec.describe "bundle update --bundler" do gem "rack" G - bundle :update, :bundler => "2.3.3", :raise_on_error => false + bundle :update, :bundler => "2.3.9", :raise_on_error => false expect(out).not_to include("Fetching gem metadata from https://rubygems.org/") @@ -1317,10 +1317,10 @@ RSpec.describe "bundle update --bundler" do rack BUNDLED WITH - 2.3.3 + 2.3.9 L - expect(out).to include("Using bundler 2.3.3") + expect(out).to include("Using bundler 2.3.9") end end end diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index 365a84f39e..07995d013b 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1180,7 +1180,7 @@ RSpec.describe "bundle install with git sources" do s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/foo.rb", "w") do |f| f.puts "FOO = 'YES'" @@ -1273,7 +1273,7 @@ In Gemfile: s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) cur_time = Time.now.to_f.to_s File.open("\#{path}/foo.rb", "w") do |f| @@ -1314,7 +1314,7 @@ In Gemfile: s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) cur_time = Time.now.to_f.to_s File.open("\#{path}/foo.rb", "w") do |f| @@ -1357,7 +1357,7 @@ In Gemfile: s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) cur_time = Time.now.to_f.to_s File.open("\#{path}/foo.rb", "w") do |f| diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index bea7c11dec..515901064f 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -137,7 +137,7 @@ RSpec.describe "bundle install with explicit source paths" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem 'foo', :path => File.expand_path("../foo-1.0", __FILE__) + gem 'foo', :path => File.expand_path("foo-1.0", __dir__) G bundle "config set --local frozen true" diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 66f755c18f..72ad40e24f 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -258,7 +258,7 @@ The checksum of /versions does not match the checksum provided by the server! So s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/net_build_extensions.rb", "w") do |f| f.puts "NET_BUILD_EXTENSIONS = 'YES'" @@ -761,8 +761,6 @@ The checksum of /versions does not match the checksum provided by the server! So end it "performs partial update with a non-empty range" do - skip "HTTP_RANGE not set" if Gem.win_platform? - gemfile <<-G source "#{source_uri}" gem 'rack', '0.9.1' diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index b0209489b9..209996f61f 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -7,7 +7,7 @@ RSpec.describe "bundle install with install-time dependencies" do s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/implicit_rake_dep.rb", "w") do |f| f.puts "IMPLICIT_RAKE_DEP = 'YES'" @@ -20,7 +20,7 @@ RSpec.describe "bundle install with install-time dependencies" do s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f| f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'" @@ -42,7 +42,7 @@ RSpec.describe "bundle install with install-time dependencies" do s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/net_build_extensions.rb", "w") do |f| f.puts "NET_BUILD_EXTENSIONS = 'YES'" diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb index c7efc836a8..66dd7f534a 100644 --- a/spec/bundler/install/gems/standalone_spec.rb +++ b/spec/bundler/install/gems/standalone_spec.rb @@ -205,7 +205,7 @@ RSpec.shared_examples "bundle install --standalone" do build_git "bar", :gemspec => false do |s| s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0') s.write "bar.gemspec", <<-G - lib = File.expand_path('../lib/', __FILE__) + lib = File.expand_path('lib/', __dir__) $:.unshift lib unless $:.include?(lib) require 'bar/version' @@ -419,7 +419,7 @@ RSpec.shared_examples "bundle install --standalone" do it "creates stubs with the correct load path" do extension_line = File.read(bundled_app("bin/rails")).each_line.find {|line| line.include? "$:.unshift" }.strip - expect(extension_line).to eq %($:.unshift File.expand_path "../../bundle", path.realpath) + expect(extension_line).to eq %($:.unshift File.expand_path "../bundle", __dir__) end end end diff --git a/spec/bundler/install/gems/sudo_spec.rb b/spec/bundler/install/gems/sudo_spec.rb index 3e5d38ea4c..41b241da25 100644 --- a/spec/bundler/install/gems/sudo_spec.rb +++ b/spec/bundler/install/gems/sudo_spec.rb @@ -54,7 +54,7 @@ RSpec.describe "when using sudo", :sudo => true do s.extensions << "Rakefile" s.write "Rakefile", <<-RUBY task :default do - path = File.expand_path("../lib", __FILE__) + path = File.expand_path("lib", __dir__) FileUtils.mkdir_p(path) File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f| f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'" diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 561de9f3bc..8ec0a80bd0 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -897,7 +897,7 @@ RSpec.describe "the lockfile format" do install_gemfile <<-G source "#{file_uri_for(gem_repo1)}" - path File.expand_path("../foo", __FILE__) do + path File.expand_path("foo", __dir__) do gem "foo" end G diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index d97d930476..be9016b831 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -3,7 +3,7 @@ require 'rubygems' # If bundler gemspec exists, add to stubs -bundler_gemspec = File.expand_path("../../../bundler/bundler.gemspec", __FILE__) +bundler_gemspec = File.expand_path('../../bundler/bundler.gemspec', __dir__) if File.exist?(bundler_gemspec) Gem::Specification.dirs.unshift File.dirname(bundler_gemspec) Gem::Specification.class_variable_set :@@stubs, nil @@ -302,11 +302,15 @@ class Gem::TestCase < Test::Unit::TestCase # or <tt>i686-darwin8.10.1</tt> otherwise. def setup + @orig_hooks = {} @orig_env = ENV.to_hash @tmp = File.expand_path("tmp") FileUtils.mkdir_p @tmp + @tempdir = Dir.mktmpdir("test_rubygems_", @tmp) + @tempdir.tap(&Gem::UNTAINT) + ENV['GEM_VENDOR'] = nil ENV['GEMRC'] = nil ENV['XDG_CACHE_HOME'] = nil @@ -324,9 +328,6 @@ class Gem::TestCase < Test::Unit::TestCase # capture output Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new - @tempdir = Dir.mktmpdir("test_rubygems_", @tmp) - @tempdir.tap(&Gem::UNTAINT) - ENV["TMPDIR"] = @tempdir @orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE @@ -426,7 +427,6 @@ class Gem::TestCase < Test::Unit::TestCase util_set_arch 'i686-darwin8.10.1' end - @orig_hooks = {} %w[post_install_hooks done_installing_hooks post_uninstall_hooks pre_uninstall_hooks pre_install_hooks pre_reset_hooks post_reset_hooks post_build_hooks].each do |name| @orig_hooks[name] = Gem.send(name).dup end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index cc4772a0c6..a8be078046 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -10,7 +10,7 @@ require 'rbconfig' class TestGem < Gem::TestCase PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant - PROJECT_DIR = File.expand_path('../../..', __FILE__).tap(&Gem::UNTAINT) + PROJECT_DIR = File.expand_path('../..', __dir__).tap(&Gem::UNTAINT) def setup super diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index ff1f955c6c..bee635d67e 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -3,7 +3,7 @@ require_relative 'helper' require 'rubygems/command_manager' class TestGemCommandManager < Gem::TestCase - PROJECT_DIR = File.expand_path('../../..', __FILE__).tap(&Gem::UNTAINT) + PROJECT_DIR = File.expand_path('../..', __dir__).tap(&Gem::UNTAINT) def setup super diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb index a70dd770e1..98e5b62be0 100644 --- a/test/rubygems/test_gem_commands_help_command.rb +++ b/test/rubygems/test_gem_commands_help_command.rb @@ -11,7 +11,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase @cmd = Gem::Commands::HelpCommand.new - load File.expand_path('../rubygems_plugin.rb', __FILE__) unless Gem::Commands.const_defined? :InterruptCommand + load File.expand_path('rubygems_plugin.rb', __dir__) unless Gem::Commands.const_defined? :InterruptCommand end def test_gem_help_bad diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb index fa3968ffce..1bbd341eca 100644 --- a/test/rubygems/test_gem_commands_push_command.rb +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -435,6 +435,7 @@ class TestGemCommandsPushCommand < Gem::TestCase response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." response_success = 'Successfully registered gem: freewill (1.0.0)' + response_profile = "mfa: disabled\n" @fetcher.data["#{@host}/api/v1/gems"] = [ [response_success, 200, "OK"], @@ -445,6 +446,10 @@ class TestGemCommandsPushCommand < Gem::TestCase ["", 200, "OK"], ] + @fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [ + [response_profile, 200, "OK"], + ] + @cmd.instance_variable_set :@scope, :push_rubygem @cmd.options[:args] = [@path] @cmd.options[:host] = @host diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index 934c76b1d1..ab563b28ee 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -4,7 +4,7 @@ require_relative 'helper' require 'rubygems/commands/setup_command' class TestGemCommandsSetupCommand < Gem::TestCase - bundler_gemspec = File.expand_path("../../../bundler/lib/bundler/version.rb", __FILE__) + bundler_gemspec = File.expand_path('../../bundler/lib/bundler/version.rb', __dir__) if File.exist?(bundler_gemspec) BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1] else diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb index 0f856a53ba..cfc0b570e3 100644 --- a/test/rubygems/test_gem_commands_signin_command.rb +++ b/test/rubygems/test_gem_commands_signin_command.rb @@ -92,31 +92,120 @@ class TestGemCommandsSigninCommand < Gem::TestCase user = ENV["USER"] || ENV["USERNAME"] assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output - assert_match "index_rubygems [y/N]", key_name_ui.output - assert_match "push_rubygem [y/N]", key_name_ui.output - assert_match "yank_rubygem [y/N]", key_name_ui.output - assert_match "add_owner [y/N]", key_name_ui.output - assert_match "remove_owner [y/N]", key_name_ui.output - assert_match "access_webhooks [y/N]", key_name_ui.output - assert_match "show_dashboard [y/N]", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "show_dashboard [yN]", key_name_ui.output assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body credentials = load_yaml_file Gem.configuration.credentials_path assert_equal api_key, credentials[:rubygems_api_key] end - # Utility method to capture IO/UI within the block passed + def test_execute_with_key_name_scope_and_mfa_level_of_ui_only + email = 'you@example.com' + password = 'secret' + api_key = '1234' + fetcher = Gem::RemoteFetcher.fetcher + mfa_level = "ui_only" + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny" + util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "show_dashboard [yN]", key_name_ui.output + assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end - def util_capture(ui_stub = nil, host = nil, api_key = nil, fetcher = Gem::FakeFetcher.new) - api_key ||= 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - response = [api_key, 200, 'OK'] + def test_execute_with_key_name_scope_and_mfa_level_of_gem_signin email = 'you@example.com' password = 'secret' + api_key = '1234' + fetcher = Gem::RemoteFetcher.fetcher + mfa_level = "ui_and_gem_signin" + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny" + util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "show_dashboard [yN]", key_name_ui.output + assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_execute_on_gemserver_without_profile_me_endpoint + host = 'http://some-gemcutter-compatible-host.org' + + email = 'you@example.com' + password = 'secret' + api_key = '1234' + fetcher = Gem::RemoteFetcher.fetcher + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny" + + # Set the expected response for the Web-API supplied + ENV['RUBYGEMS_HOST'] = host + data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key" + fetcher.data[data_key] = [api_key, 200, 'OK'] + + use_ui key_name_ui do + @cmd.execute + end + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "show_dashboard [yN]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body + end + + # Utility method to capture IO/UI within the block passed + + def util_capture(ui_stub = nil, host = nil, api_key = nil, fetcher = Gem::FakeFetcher.new, mfa_level = "disabled") + api_key ||= 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + response = [api_key, 200, 'OK'] + profile_response = [ "mfa: #{mfa_level}\n" , 200, 'OK'] + email = 'you@example.com' + password = 'secret' # Set the expected response for the Web-API supplied ENV['RUBYGEMS_HOST'] = host || Gem::DEFAULT_HOST data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key" fetcher.data[data_key] = response + profile = "#{ENV['RUBYGEMS_HOST']}/api/v1/profile/me.yaml" + fetcher.data[profile] = profile_response Gem::RemoteFetcher.fetcher = fetcher sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n") diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 9cbdcefea4..f2404d61c7 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -941,7 +941,7 @@ class TestGemDependencyInstaller < Gem::TestCase end def test_install_legacy_spec_with_nil_required_ruby_version - path = File.expand_path "../data/null-required-ruby-version.gemspec.rz", __FILE__ + path = File.expand_path 'data/null-required-ruby-version.gemspec.rz', __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end @@ -966,7 +966,7 @@ class TestGemDependencyInstaller < Gem::TestCase end def test_install_legacy_spec_with_nil_required_rubygems_version - path = File.expand_path "../data/null-required-rubygems-version.gemspec.rz", __FILE__ + path = File.expand_path 'data/null-required-rubygems-version.gemspec.rz', __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb index 165194510e..7e19782e61 100644 --- a/test/rubygems/test_gem_ext_builder.rb +++ b/test/rubygems/test_gem_ext_builder.rb @@ -291,7 +291,7 @@ install: File.open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f| f.write <<-'RUBY' puts "IN EXTCONF" - extconf_args = File.join File.dirname(__FILE__), 'extconf_args' + extconf_args = File.join __dir__, 'extconf_args' File.open extconf_args, 'w' do |f| f.puts ARGV.inspect end diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb new file mode 100644 index 0000000000..0c8de2ff6c --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true +require_relative 'helper' +require 'rubygems/ext' + +class TestGemExtCargoBuilder < Gem::TestCase + def setup + @orig_env = ENV.to_hash + + @rust_envs = { + 'CARGO_HOME' => File.join(@orig_env['HOME'], '.cargo'), + 'RUSTUP_HOME' => File.join(@orig_env['HOME'], '.rustup'), + } + + system(@rust_envs, 'cargo', '-V', out: IO::NULL, err: [:child, :out]) + pend 'cargo not present' unless $?.success? + + super + end + + def setup_rust_gem(name) + @ext = File.join(@tempdir, 'ext') + @dest_path = File.join(@tempdir, 'prefix') + @fixture_dir = Pathname.new(File.expand_path("test_gem_ext_cargo_builder/#{name}/", __dir__)) + + FileUtils.mkdir_p @dest_path + FileUtils.cp_r(@fixture_dir.to_s, @ext) + end + + def test_build_staticlib + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + content = @fixture_dir.join('Cargo.toml').read.gsub("cdylib", "staticlib") + File.write(File.join(@ext, 'Cargo.toml'), content) + + output = [] + + Dir.chdir @ext do + ENV.update(@rust_envs) + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + assert_raise(Gem::Ext::CargoBuilder::DylibNotFoundError) do + builder.build nil, @dest_path, output + end + end + end + + def test_build_cdylib + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + output = [] + + Dir.chdir @ext do + ENV.update(@rust_envs) + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + builder.build nil, @dest_path, output + end + + output = output.join "\n" + + bundle = File.join(@dest_path, "release/rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}") + + require(bundle) + + assert_match RustRubyExample.reverse('hello'), 'olleh' + + assert_match "Compiling rust_ruby_example v0.1.0", output + assert_match "Finished release [optimized] target(s)", output + rescue Exception => e + pp output if output + + raise(e) + end + + def test_build_fail + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + output = [] + + FileUtils.rm(File.join(@ext, 'src/lib.rs')) + + error = assert_raise(Gem::InstallError) do + Dir.chdir @ext do + ENV.update(@rust_envs) + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + builder.build nil, @dest_path, output + end + end + + output = output.join "\n" + + assert_match 'cargo failed', error.message + end + + def test_full_integration + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + Dir.chdir @ext do + require 'tmpdir' + + gem = [@rust_envs, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] + + Dir.mktmpdir("rust_ruby_example") do |dir| + built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem")) + Open3.capture2e(*gem, "build", "rust_ruby_example.gemspec", "--output", built_gem) + Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) + end + + stdout_and_stderr_str, status = Open3.capture2e(@rust_envs, *ruby_with_rubygems_in_load_path, "-rrust_ruby_example", "-e", "puts 'Result: ' + RustRubyExample.reverse('hello world')") + + assert status.success?, stdout_and_stderr_str + assert_match "Result: #{"hello world".reverse}", stdout_and_stderr_str + end + end + + def test_custom_name + skip_unsupported_platforms! + setup_rust_gem "custom_name" + + Dir.chdir @ext do + require 'tmpdir' + + gem = [@rust_envs, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] + + Dir.mktmpdir("custom_name") do |dir| + built_gem = File.expand_path(File.join(dir, "custom_name.gem")) + Open3.capture2e(*gem, "build", "custom_name.gemspec", "--output", built_gem) + Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) + end + + stdout_and_stderr_str, status = Open3.capture2e(@rust_envs, *ruby_with_rubygems_in_load_path, "-rcustom_name", "-e", "puts 'Result: ' + CustomName.say_hello") + + assert status.success?, stdout_and_stderr_str + assert_match "Result: Hello world!", stdout_and_stderr_str + end + end + + def skip_unsupported_platforms! + pend "jruby not supported" if java_platform? + pend "truffleruby not supported (yet)" if RUBY_ENGINE == 'truffleruby' + pend "mswin not supported (yet)" if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') + end +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore b/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock new file mode 100644 index 0000000000..efee4b2f2c --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock @@ -0,0 +1,374 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bindgen" +version = "0.59.2" +source = "git+https://github.com/rust-lang/rust-bindgen?rev=f34e4103f304500c96d332f5cecc9067c980d0f9#f34e4103f304500c96d332f5cecc9067c980d0f9" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" +dependencies = [ + "atty", + "bitflags", + "indexmap", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "custom-name-ext" +version = "0.1.0" +dependencies = [ + "rb-sys", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rb-sys" +version = "0.6.0" +source = "git+https://github.com/ianks/rb-sys?tag=v0.6.0#1aa5b589e86a14e01aba806511818c19f85d71f6" +dependencies = [ + "bindgen", + "libc", + "pkg-config", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "which" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml new file mode 100644 index 0000000000..e0232f729d --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "custom-name-ext" +version = "0.1.0" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +# Needed until bindgen has the `allowlist_file` feature +rb-sys = { git = "https://github.com/ianks/rb-sys", tag = "v0.6.0" } diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb b/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb new file mode 100644 index 0000000000..4d2f8488a4 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb @@ -0,0 +1,21 @@ +if ENV['RUBYOPT'] or defined? Gem + ENV.delete 'RUBYOPT' + + require 'rbconfig' + cmd = [RbConfig.ruby, '--disable-gems', 'build.rb', *ARGV] + + exec(*cmd) +end + +require 'tmpdir' + +lp = File.expand_path('../../../../lib', __dir__) +gem = ["ruby", "-I#{lp}", File.expand_path('../../../../bin/gem', __dir__)] +gemspec = File.expand_path('custom_name.gemspec', __dir__) + +Dir.mktmpdir("custom_name") do |dir| + built_gem = File.expand_path(File.join(dir, "custom_name.gem")) + system *gem, "build", gemspec, "--output", built_gem + system *gem, "install", "--verbose", "--local", built_gem, *ARGV + system %q(ruby -rcustom_name -e "puts 'Result: ' + CustomName.say_hello") +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec new file mode 100644 index 0000000000..1ecdae2c33 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec @@ -0,0 +1,10 @@ +Gem::Specification.new do |s| + s.name = "custom_name" + s.version = "0.1.0" + s.summary = "A Rust extension for Ruby" + s.extensions = ["Cargo.toml"] + s.authors = ["Ian Ker-Seymer"] + s.files = ["Cargo.toml", "Cargo.lock", "src/lib.rs"] + + s.metadata['cargo_crate_name'] = 'custom-name-ext' +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs new file mode 100644 index 0000000000..ca9cf4e656 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs @@ -0,0 +1,30 @@ +#[macro_use] +extern crate rb_sys; + +use rb_sys::{rb_define_module, rb_define_module_function, rb_utf8_str_new, VALUE}; +use std::ffi::CString; + +ruby_extension!(); + +#[no_mangle] +unsafe extern "C" fn say_hello(_klass: VALUE) -> VALUE { + let cstr = CString::new("Hello world!").unwrap(); + + rb_utf8_str_new(cstr.as_ptr(), 12) +} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn Init_custom_name() { + let name = CString::new("CustomName").unwrap(); + let function_name = CString::new("say_hello").unwrap(); + // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute + let callback = unsafe { + std::mem::transmute::<unsafe extern "C" fn(VALUE) -> VALUE, unsafe extern "C" fn() -> VALUE>( + say_hello, + ) + }; + let klass = unsafe { rb_define_module(name.as_ptr()) }; + + unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 0) } +} diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock new file mode 100644 index 0000000000..9248f7101c --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -0,0 +1,374 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bindgen" +version = "0.59.2" +source = "git+https://github.com/rust-lang/rust-bindgen?rev=f34e4103f304500c96d332f5cecc9067c980d0f9#f34e4103f304500c96d332f5cecc9067c980d0f9" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" +dependencies = [ + "atty", + "bitflags", + "indexmap", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rb-sys" +version = "0.6.0" +source = "git+https://github.com/ianks/rb-sys?tag=v0.6.0#1aa5b589e86a14e01aba806511818c19f85d71f6" +dependencies = [ + "bindgen", + "libc", + "pkg-config", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rust_ruby_example" +version = "0.1.0" +dependencies = [ + "rb-sys", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "which" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml new file mode 100644 index 0000000000..66a98f3885 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rust_ruby_example" +version = "0.1.0" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +# Needed until bindgen has the `allowlist_file` feature +rb-sys = { git = "https://github.com/ianks/rb-sys", tag = "v0.6.0" } diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb new file mode 100644 index 0000000000..da9e82315e --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb @@ -0,0 +1,21 @@ +if ENV['RUBYOPT'] or defined? Gem + ENV.delete 'RUBYOPT' + + require 'rbconfig' + cmd = [RbConfig.ruby, '--disable-gems', 'build.rb', *ARGV] + + exec(*cmd) +end + +require 'tmpdir' + +lp = File.expand_path('../../../../lib', __dir__) +gem = ["ruby", "-I#{lp}", File.expand_path('../../../../bin/gem', __dir__)] +gemspec = File.expand_path('rust_ruby_example.gemspec', __dir__) + +Dir.mktmpdir("rust_ruby_example") do |dir| + built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem")) + system *gem, "build", gemspec, "--output", built_gem + system *gem, "install", "--verbose", "--local", built_gem, *ARGV + system %q(ruby -rrust_ruby_example -e "puts 'Result: ' + RustRubyExample.reverse('hello world')") +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec new file mode 100644 index 0000000000..82c84ba818 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec @@ -0,0 +1,8 @@ +Gem::Specification.new do |s| + s.name = "rust_ruby_example" + s.version = "0.1.0" + s.summary = "A Rust extension for Ruby" + s.extensions = ["Cargo.toml"] + s.authors = ["Ian Ker-Seymer"] + s.files = ["Cargo.toml", "Cargo.lock", "src/lib.rs"] +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs new file mode 100644 index 0000000000..26bddaeaf1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs @@ -0,0 +1,42 @@ +#[macro_use] +extern crate rb_sys; + +use rb_sys::{ + rb_define_module, rb_define_module_function, rb_string_value_cstr, rb_utf8_str_new, VALUE, +}; +use std::ffi::{CStr, CString}; +use std::os::raw::{c_char, c_long}; + +ruby_extension!(); + +#[inline] +unsafe fn cstr_to_string(str: *const c_char) -> String { + CStr::from_ptr(str).to_string_lossy().into_owned() +} + +#[no_mangle] +unsafe extern "C" fn pub_reverse(_klass: VALUE, mut input: VALUE) -> VALUE { + let ruby_string = cstr_to_string(rb_string_value_cstr(&mut input)); + let reversed = ruby_string.to_string().chars().rev().collect::<String>(); + let reversed_cstring = CString::new(reversed).unwrap(); + let size = ruby_string.len() as c_long; + + rb_utf8_str_new(reversed_cstring.as_ptr(), size) +} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn Init_rust_ruby_example() { + let name = CString::new("RustRubyExample").unwrap(); + let function_name = CString::new("reverse").unwrap(); + // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute + let callback = unsafe { + std::mem::transmute::< + unsafe extern "C" fn(VALUE, VALUE) -> VALUE, + unsafe extern "C" fn() -> VALUE, + >(pub_reverse) + }; + let klass = unsafe { rb_define_module(name.as_ptr()) }; + + unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 1) } +} diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb index 5ab82c545f..b4d7cf2d30 100644 --- a/test/rubygems/test_gem_ext_cmake_builder.rb +++ b/test/rubygems/test_gem_ext_cmake_builder.rb @@ -9,6 +9,8 @@ class TestGemExtCmakeBuilder < Gem::TestCase # Details: https://github.com/rubygems/rubygems/issues/1270#issuecomment-177368340 pend "CmakeBuilder doesn't work on Windows." if Gem.win_platform? + require "open3" + begin _, status = Open3.capture2e('cmake') pend 'cmake not present' unless status.success? diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index 0bcd1504e9..667aba4701 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -227,8 +227,9 @@ class TestGemGemcutterUtilities < Gem::TestCase end def util_sign_in(response, host = nil, args = [], extra_input = '') - email = 'you@example.com' - password = 'secret' + email = 'you@example.com' + password = 'secret' + profile_response = [ "mfa: disabled\n" , 200, 'OK'] if host ENV['RUBYGEMS_HOST'] = host @@ -238,6 +239,7 @@ class TestGemGemcutterUtilities < Gem::TestCase @fetcher = Gem::FakeFetcher.new @fetcher.data["#{host}/api/v1/api_key"] = response + @fetcher.data["#{host}/api/v1/profile/me.yaml"] = profile_response Gem::RemoteFetcher.fetcher = @fetcher @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input) diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb index 73ed8dd2ef..b97556d61d 100644 --- a/test/rubygems/test_gem_source_git.rb +++ b/test/rubygems/test_gem_source_git.rb @@ -68,6 +68,7 @@ class TestGemSourceGit < Gem::TestCase git_gem 'b' Dir.chdir 'git/a' do + require "open3" output, status = Open3.capture2e(@git, 'submodule', '--quiet', 'add', File.expand_path('../b'), 'b') assert status.success?, output diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 8b4a07d23b..55dd7f0ff2 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -1068,7 +1068,7 @@ dependencies: [] end def test_handles_private_null_type - path = File.expand_path "../data/null-type.gemspec.rz", __FILE__ + path = File.expand_path 'data/null-type.gemspec.rz', __dir__ data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) diff --git a/test/rubygems/test_project_sanity.rb b/test/rubygems/test_project_sanity.rb index 38c2541df6..27b1f11d62 100644 --- a/test/rubygems/test_project_sanity.rb +++ b/test/rubygems/test_project_sanity.rb @@ -5,7 +5,7 @@ require "open3" class TestProjectSanity < Gem::TestCase def test_manifest_is_up_to_date - pend unless File.exist?(File.expand_path("../../../Rakefile", __FILE__)) + pend unless File.exist?(File.expand_path('../../Rakefile', __dir__)) _, status = Open3.capture2e("rake check_manifest") diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index 5b826d052b..90b943dff3 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -230,7 +230,7 @@ class TestGemRequire < Gem::TestCase pend "not installed yet" unless RbConfig::TOPDIR - lib_dir = File.expand_path("../../lib", File.dirname(__FILE__)) + lib_dir = File.expand_path("../lib", __dir__) rubylibdir = File.realdirpath(RbConfig::CONFIG["rubylibdir"]) if rubylibdir == lib_dir # testing in the ruby repository where RubyGems' lib/ == stdlib lib/ diff --git a/tool/bundler/dev_gems.rb b/tool/bundler/dev_gems.rb index 20a9594f4f..8a858c1e67 100644 --- a/tool/bundler/dev_gems.rb +++ b/tool/bundler/dev_gems.rb @@ -16,7 +16,7 @@ gem "parallel_tests", "~> 2.29" gem "parallel", "1.19.2" # 1.20+ is required > Ruby 2.3 gem "rspec-core", "~> 3.8" gem "rspec-expectations", "~> 3.8" -gem "rspec-mocks", "~> 3.8" +gem "rspec-mocks", "~> 3.11.1" gem "uri", "~> 0.10.1" group :doc do diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock index 721e80e1f0..11bda60254 100644 --- a/tool/bundler/dev_gems.rb.lock +++ b/tool/bundler/dev_gems.rb.lock @@ -22,15 +22,15 @@ GEM hpricot (>= 0.8.2) mustache (>= 0.7.0) rdiscount (>= 1.5.8) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.3) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-support (3.10.3) + rspec-support (~> 3.11.0) + rspec-support (3.11.0) rubocop (0.80.1) jaro_winkler (~> 1.5.1) parallel (~> 1.10) @@ -64,7 +64,7 @@ DEPENDENCIES ronn (~> 0.7.3) rspec-core (~> 3.8) rspec-expectations (~> 3.8) - rspec-mocks (~> 3.8) + rspec-mocks (~> 3.11.1) rubocop (~> 0.80.1) rubocop-performance (~> 1.5.2) test-unit (~> 3.0) @@ -72,4 +72,4 @@ DEPENDENCIES webrick (~> 1.6) BUNDLED WITH - 2.3.10 + 2.3.11 diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock index 55b592094f..1510eb67ac 100644 --- a/tool/bundler/rubocop_gems.rb.lock +++ b/tool/bundler/rubocop_gems.rb.lock @@ -61,4 +61,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.10 + 2.3.11 diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock index c3d8c27eb8..1b749a35f5 100644 --- a/tool/bundler/standard_gems.rb.lock +++ b/tool/bundler/standard_gems.rb.lock @@ -67,4 +67,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.10 + 2.3.11 diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock index ad30ce10db..9269e56bc1 100644 --- a/tool/bundler/test_gems.rb.lock +++ b/tool/bundler/test_gems.rb.lock @@ -41,4 +41,4 @@ DEPENDENCIES webrick (= 1.7.0) BUNDLED WITH - 2.3.10 + 2.3.11 |