From 95683e5cb2d1ab8351402b09ef853dcdf875bf8d Mon Sep 17 00:00:00 2001 From: drbrain Date: Wed, 18 Sep 2013 21:29:41 +0000 Subject: * lib/rubygems: Update to RubyGems 2.2.0.preview.1 This brings several new features to RubyGems summarized here: https://github.com/rubygems/rubygems/blob/v2.2.0.preview.1/History.txt * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42967 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++ lib/rubygems.rb | 2 +- lib/rubygems/commands/list_command.rb | 8 +- lib/rubygems/commands/pristine_command.rb | 15 ++- lib/rubygems/commands/push_command.rb | 13 ++- lib/rubygems/commands/query_command.rb | 46 ++++++--- lib/rubygems/commands/search_command.rb | 6 -- lib/rubygems/commands/uninstall_command.rb | 6 +- lib/rubygems/commands/update_command.rb | 3 + lib/rubygems/commands/which_command.rb | 8 +- lib/rubygems/gemcutter_utilities.rb | 9 +- lib/rubygems/package.rb | 13 ++- lib/rubygems/request.rb | 24 +++-- lib/rubygems/requirement.rb | 22 +---- lib/rubygems/specification.rb | 22 ++++- test/rubygems/test_gem_commands_install_command.rb | 66 +++++-------- .../rubygems/test_gem_commands_pristine_command.rb | 54 +++++++++++ test/rubygems/test_gem_commands_push_command.rb | 84 +++++++++++++++-- test/rubygems/test_gem_commands_query_command.rb | 103 +++++++++++++++++++++ .../test_gem_commands_uninstall_command.rb | 40 ++++++-- test/rubygems/test_gem_commands_update_command.rb | 27 ++++++ test/rubygems/test_gem_package.rb | 18 ++++ test/rubygems/test_gem_request.rb | 47 ++++++++-- test/rubygems/test_gem_specification.rb | 49 ++++++++-- test/rubygems/test_gem_uninstaller.rb | 2 +- 25 files changed, 539 insertions(+), 158 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08b918a889..e0d852e192 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Sep 19 06:29:30 2013 Eric Hodel + + * lib/rubygems: Update to RubyGems 2.2.0.preview.1 + + This brings several new features to RubyGems summarized here: + + https://github.com/rubygems/rubygems/blob/v2.2.0.preview.1/History.txt + + * test/rubygems: ditto. + Wed Sep 18 23:14:58 2013 Masaki Matsushita * string.c (rb_str_enumerate_lines): make String#each_line and diff --git a/lib/rubygems.rb b/lib/rubygems.rb index fac38e4143..f63a9b77af 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.1.3' + VERSION = '2.2.0.preview.1' end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/commands/list_command.rb b/lib/rubygems/commands/list_command.rb index 0d15950475..4edeabef02 100644 --- a/lib/rubygems/commands/list_command.rb +++ b/lib/rubygems/commands/list_command.rb @@ -33,13 +33,7 @@ To search for remote gems use the search command. end def usage # :nodoc: - "#{program_name} [STRING]" - end - - def execute - string = get_one_optional_argument || '' - options[:name] = /^#{string}/i - super + "#{program_name} [STRING ...]" end end diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb index 3f3bca45be..b54e7eac93 100644 --- a/lib/rubygems/commands/pristine_command.rb +++ b/lib/rubygems/commands/pristine_command.rb @@ -12,6 +12,7 @@ class Gem::Commands::PristineCommand < Gem::Command 'Restores installed gems to pristine condition from files located in the gem cache', :version => Gem::Requirement.default, :extensions => true, + :extensions_set => false, :all => false add_option('--all', @@ -23,7 +24,8 @@ class Gem::Commands::PristineCommand < Gem::Command add_option('--[no-]extensions', 'Restore gems with extensions', 'in addition to regular gems') do |value, options| - options[:extensions] = value + options[:extensions_set] = true + options[:extensions] = value end add_option('--only-executables', @@ -62,6 +64,9 @@ If the cached gem cannot be found it will be downloaded. If --no-extensions is provided pristine will not attempt to restore a gem with an extension. + +If --extensions is given (but not --all or gem names) only gems with +extensions will be restored. EOF end @@ -72,6 +77,14 @@ with an extension. def execute specs = if options[:all] then Gem::Specification.map + + # `--extensions` must be explicitly given to pristine only gems + # with extensions. + elsif options[:extensions_set] and + options[:extensions] and options[:args].empty? then + Gem::Specification.select do |spec| + spec.extensions and not spec.extensions.empty? + end else get_all_gem_names.map do |gem_name| Gem::Specification.find_all_by_name gem_name, options[:version] diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb index b90be7bd10..6899b489ad 100644 --- a/lib/rubygems/commands/push_command.rb +++ b/lib/rubygems/commands/push_command.rb @@ -69,13 +69,18 @@ You can upgrade or downgrade to the latest release version with: terminate_interaction 1 end + gem_data = Gem::Package.new(name) + unless @host then - if gem_data = Gem::Package.new(name) then - @host = gem_data.spec.metadata['default_gem_server'] - end + @host = gem_data.spec.metadata['default_gem_server'] end - args << @host if @host + # Always include this, even if it's nil + args << @host + + if gem_data.spec.metadata.has_key?('allowed_push_host') + args << gem_data.spec.metadata['allowed_push_host'] + end say "Pushing gem to #{@host || Gem.host}..." diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb index c9c3014975..55b950c1b7 100644 --- a/lib/rubygems/commands/query_command.rb +++ b/lib/rubygems/commands/query_command.rb @@ -72,16 +72,26 @@ is too hard to use. def execute exit_code = 0 + if options[:args].to_a.empty? and options[:name].source.empty? + name = options[:name] + no_name = true + elsif !options[:name].source.empty? + name = Array(options[:name]) + else + name = options[:args].to_a.map{|arg| /#{arg}/i } + end - name = options[:name] prerelease = options[:prerelease] unless options[:installed].nil? then - if name.source.empty? then + if no_name then alert_error "You must specify a gem name" exit_code |= 4 + elsif name.count > 1 + alert_error "You must specify only ONE gem!" + exit_code |= 4 else - installed = installed? name, options[:version] + installed = installed? name.first, options[:version] installed = !installed unless options[:installed] if installed then @@ -95,6 +105,22 @@ is too hard to use. terminate_interaction exit_code end + names = Array(name) + names.each { |n| show_gems n, prerelease } + end + + private + + def display_header type + if (ui.outs.tty? and Gem.configuration.verbose) or both? then + say + say "*** #{type} GEMS ***" + say + end + end + + #Guts of original execute + def show_gems name, prerelease req = Gem::Requirement.default # TODO: deprecate for real dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req } @@ -105,11 +131,7 @@ is too hard to use. alert_warning "prereleases are always shown locally" end - if ui.outs.tty? or both? then - say - say "*** LOCAL GEMS ***" - say - end + display_header 'LOCAL' specs = Gem::Specification.find_all { |s| s.name =~ name and req =~ s.version @@ -123,11 +145,7 @@ is too hard to use. end if remote? then - if ui.outs.tty? or both? then - say - say "*** REMOTE GEMS ***" - say - end + display_header 'REMOTE' fetcher = Gem::SpecFetcher.fetcher @@ -155,8 +173,6 @@ is too hard to use. end end - private - ## # Check if gem +name+ version +version+ is installed. diff --git a/lib/rubygems/commands/search_command.rb b/lib/rubygems/commands/search_command.rb index 5bc9650672..5809690735 100644 --- a/lib/rubygems/commands/search_command.rb +++ b/lib/rubygems/commands/search_command.rb @@ -36,11 +36,5 @@ To list local gems use the list command. "#{program_name} [STRING]" end - def execute - string = get_one_optional_argument - options[:name] = /#{string}/i - super - end - end diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb index 8e6af2ba65..e62095a336 100644 --- a/lib/rubygems/commands/uninstall_command.rb +++ b/lib/rubygems/commands/uninstall_command.rb @@ -15,7 +15,7 @@ class Gem::Commands::UninstallCommand < Gem::Command def initialize super 'uninstall', 'Uninstall gems from the local repository', :version => Gem::Requirement.default, :user_install => true, - :install_dir => Gem.dir, :check_dev => false + :check_dev => false add_option('-a', '--[no-]all', 'Uninstall all matching versions' @@ -84,7 +84,6 @@ class Gem::Commands::UninstallCommand < Gem::Command def defaults_str # :nodoc: "--version '#{Gem::Requirement.default}' --no-force " + - "--install-dir #{Gem.dir}\n" + "--user-install" end @@ -104,8 +103,7 @@ that is a dependency of an existing gem. You can use the def execute if options[:all] and not options[:args].empty? then - alert_error 'Gem names and --all may not be used together' - terminate_interaction 1 + uninstall_specific elsif options[:all] then uninstall_all else diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 77bf5edb45..e53798db86 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -244,6 +244,9 @@ command to remove old versions. args << '--no-rdoc' unless options[:document].include? 'rdoc' args << '--no-ri' unless options[:document].include? 'ri' args << '--no-format-executable' if options[:no_format_executable] + args << '--previous-version' << Gem::VERSION if + options[:system] == true or + Gem::Version.new(options[:system]) >= Gem::Version.new(2) args end diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb index 99b9085b2b..18706afdf5 100644 --- a/lib/rubygems/commands/which_command.rb +++ b/lib/rubygems/commands/which_command.rb @@ -45,9 +45,9 @@ requiring to see why it does not behave as you expect. if spec then if options[:search_gems_first] then - dirs = gem_paths(spec) + $LOAD_PATH + dirs = spec.full_require_paths + $LOAD_PATH else - dirs = $LOAD_PATH + gem_paths(spec) + dirs = $LOAD_PATH + spec.full_require_paths end end @@ -81,10 +81,6 @@ requiring to see why it does not behave as you expect. result end - def gem_paths(spec) - spec.require_paths.collect { |d| File.join spec.full_gem_path, d } - end - def usage # :nodoc: "#{program_name} FILE [FILE ...]" end diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 9dbc18ba98..6a4da9e983 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -56,8 +56,10 @@ module Gem::GemcutterUtilities ## # Creates an RubyGems API to +host+ and +path+ with the given HTTP +method+. + # + # If +allowed_push_host+ metadata is present, then it will only allow that host. - def rubygems_api_request(method, path, host = nil, &block) + def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, &block) require 'net/http' self.host = host if host @@ -66,6 +68,11 @@ module Gem::GemcutterUtilities terminate_interaction 1 # TODO: question this end + if allowed_push_host and self.host != allowed_push_host + alert_error "#{self.host.inspect} is not allowed by the gemspec, which only allows #{allowed_push_host.inspect}" + terminate_interaction 1 + end + uri = URI.parse "#{self.host}/#{path}" request_method = Net::HTTP.const_get method.to_s.capitalize diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index ba379c24cb..1dbce5d526 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -349,11 +349,20 @@ EOM FileUtils.rm_rf destination - FileUtils.mkdir_p File.dirname destination + mkdir_options = {} + mkdir_options[:mode] = entry.header.mode if entry.directory? + mkdir = + if entry.directory? then + destination + else + File.dirname destination + end + + FileUtils.mkdir_p mkdir, mkdir_options open destination, 'wb', entry.header.mode do |out| out.write entry.read - end + end if entry.file? say destination if Gem.configuration.really_verbose end diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index b2e9dbc679..00407971dd 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -21,7 +21,7 @@ class Gem::Request @proxy_uri = case proxy when :no_proxy then nil - when nil then get_proxy_from_env + when nil then get_proxy_from_env uri.scheme when URI::HTTP then proxy else URI.parse(proxy) end @@ -203,19 +203,27 @@ class Gem::Request end ## - # Returns an HTTP proxy URI if one is set in the environment variables. + # Returns a proxy URI for the given +scheme+ if one is set in the + # environment variables. - def get_proxy_from_env - env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] + def get_proxy_from_env scheme = 'http' + _scheme = scheme.downcase + _SCHEME = scheme.upcase + env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"] - return nil if env_proxy.nil? or env_proxy.empty? + no_env_proxy = env_proxy.nil? || env_proxy.empty? + + return get_proxy_from_env 'http' if no_env_proxy and _scheme != 'http' + return nil if no_env_proxy uri = URI(Gem::UriFormatter.new(env_proxy).normalize) if uri and uri.user.nil? and uri.password.nil? then - # Probably we have http_proxy_* variables? - uri.user = Gem::UriFormatter.new(ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']).escape - uri.password = Gem::UriFormatter.new(ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']).escape + user = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"] + password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"] + + uri.user = Gem::UriFormatter.new(user).escape + uri.password = Gem::UriFormatter.new(password).escape end uri diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb index ed768924a8..4bf1ed914f 100644 --- a/lib/rubygems/requirement.rb +++ b/lib/rubygems/requirement.rb @@ -1,13 +1,3 @@ -## -# A Requirement is a set of one or more version restrictions. It supports a -# few (=, !=, >, <, >=, <=, ~>) different restriction operators. - -# REFACTOR: The fact that a requirement is singular or plural is kind of -# awkward. Is Requirement the right name for this? Or should it be one -# [op, number] pair, and we call the list of requirements something else? -# Since a Requirement is held by a Dependency, maybe this should be made -# singular and the list aspect should be pulled up into Dependency? - require "rubygems/version" require "rubygems/deprecate" @@ -15,6 +5,10 @@ require "rubygems/deprecate" # load our yaml + workarounds now. Gem.load_yaml if defined? ::YAML +## +# A Requirement is a set of one or more version restrictions. It supports a +# few (=, !=, >, <, >=, <=, ~>) different restriction operators. + class Gem::Requirement OPS = { #:nodoc: "=" => lambda { |v, r| v == r }, @@ -41,9 +35,6 @@ class Gem::Requirement # If the input is "weird", the default version requirement is # returned. - # REFACTOR: There's no reason that this can't be unified with .new. - # .new is the standard Ruby factory method. - def self.create input case input when Gem::Requirement then @@ -78,11 +69,6 @@ class Gem::Requirement # parse("1.0") # => ["=", "1.0"] # parse(Gem::Version.new("1.0")) # => ["=, "1.0"] - # REFACTOR: Little two element arrays like this have no real semantic - # value. I'd love to see something like this: - # Constraint = Struct.new(:operator, :version); (or similar) - # and have a Requirement be a list of Constraints. - def self.parse obj return ["=", obj] if Gem::Version === obj diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 12943a3e24..6de8c3bc77 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -327,7 +327,7 @@ class Gem::Specification < Gem::BasicSpecification add_bindir(@executables), @extra_rdoc_files, @extensions, - ].flatten.uniq.compact + ].flatten.sort.uniq.compact end ###################################################################### @@ -1321,9 +1321,7 @@ class Gem::Specification < Gem::BasicSpecification def add_self_to_load_path return if default_gem? - paths = require_paths.map do |path| - File.join full_gem_path, path - end + paths = full_require_paths # gem directories must come after -I and ENV['RUBYLIB'] insert_index = Gem.load_path_insert_index @@ -2016,6 +2014,17 @@ class Gem::Specification < Gem::BasicSpecification self.require_paths = [path] end + ## + # Full paths in the gem to add to $LOAD_PATH when this gem is + # activated. + # + + def full_require_paths + require_paths.map do |path| + File.join full_gem_path, path + end + end + ## # The RubyGems version required by this gem @@ -2380,6 +2389,11 @@ class Gem::Specification < Gem::BasicSpecification "[\"#{non_files.join "\", \""}\"] are not files" end + if files.include? file_name then + raise Gem::InvalidSpecificationException, + "#{full_name} contains itself (#{file_name}), check your files list" + end + unless specification_version.is_a?(Fixnum) raise Gem::InvalidSpecificationException, 'specification_version must be a Fixnum (did you mean version?)' diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index caf52f147d..1008033b6c 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -13,11 +13,15 @@ class TestGemCommandsInstallCommand < Gem::TestCase @gemdeps = "tmp_install_gemdeps" @orig_args = Gem::Command.build_args + + common_installer_setup end def teardown super + common_installer_teardown + Gem::Command.build_args = @orig_args File.unlink @gemdeps if File.file? @gemdeps end @@ -90,9 +94,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "1 gem installed", out.shift - assert out.empty?, out.inspect + assert_match "1 gem installed", @ui.output end def test_execute_no_user_install @@ -418,9 +420,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "1 gem installed", out.shift - assert out.empty?, out.inspect + assert_match "1 gem installed", @ui.output end def test_execute_remote_ignores_files @@ -457,9 +457,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[a-1], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "1 gem installed", out.shift - assert out.empty?, out.inspect + assert_match "1 gem installed", @ui.output fin = Dir["#{gemdir}/*"] @@ -491,9 +489,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[a-2 b-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "2 gems installed", out.shift - assert out.empty?, out.inspect + assert_match "2 gems installed", @ui.output end def test_execute_two_version @@ -543,10 +539,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[b-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" assert_equal "", @ui.error - assert_equal "1 gem installed", out.shift - assert out.empty?, out.inspect + assert_match "1 gem installed", @ui.output end def test_parses_requirement_from_gemname @@ -623,9 +617,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "1 gem installed", out.shift - assert out.empty?, out.inspect + assert_match "1 gem installed", @ui.output e = @ui.error @@ -657,9 +649,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "Using a (2)", out.shift - assert out.empty?, out.inspect + assert_match "Using a (2)", @ui.output end def test_execute_installs_from_a_gemdeps @@ -687,9 +677,7 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } - out = @ui.output.split "\n" - assert_equal "Installing a (2)", out.shift - assert out.empty?, out.inspect + assert_match "Installing a (2)", @ui.output end def test_execute_installs_deps_a_gemdeps @@ -722,10 +710,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[q-1.0 r-2.0], names - out = @ui.output.split "\n" - assert_equal "Installing q (1.0)", out.shift - assert_equal "Installing r (2.0)", out.shift - assert out.empty?, out.inspect + assert_match "Installing q (1.0)", @ui.output + assert_match "Installing r (2.0)", @ui.output end def test_execute_uses_deps_a_gemdeps @@ -759,10 +745,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[r-2.0], names - out = @ui.output.split "\n" - assert_equal "Using q (1.0)", out.shift - assert_equal "Installing r (2.0)", out.shift - assert out.empty?, out.inspect + assert_match "Using q (1.0)", @ui.output + assert_match "Installing r (2.0)", @ui.output end def test_execute_installs_deps_a_gemdeps_into_a_path @@ -796,10 +780,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[q-1.0 r-2.0], names - out = @ui.output.split "\n" - assert_equal "Installing q (1.0)", out.shift - assert_equal "Installing r (2.0)", out.shift - assert out.empty?, out.inspect + assert_match "Installing q (1.0)", @ui.output + assert_match "Installing r (2.0)", @ui.output assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed" assert File.file?("gf-path/specifications/r-2.0.gemspec"), "not installed" @@ -838,10 +820,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[q-1.0 r-2.0], names - out = @ui.output.split "\n" - assert_equal "Installing q (1.0)", out.shift - assert_equal "Installing r (2.0)", out.shift - assert out.empty?, out.inspect + assert_match "Installing q (1.0)", @ui.output + assert_match "Installing r (2.0)", @ui.output assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed" assert File.file?("gf-path/specifications/r-2.0.gemspec"), "not installed" @@ -882,10 +862,8 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[r-2.0], names - out = @ui.output.split "\n" - assert_equal "Using q (1.0)", out.shift - assert_equal "Installing r (2.0)", out.shift - assert out.empty?, out.inspect + assert_match "Using q (1.0)", @ui.output + assert_match "Installing r (2.0)", @ui.output end diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb index 78c3f85a5b..1767397d16 100644 --- a/test/rubygems/test_gem_commands_pristine_command.rb +++ b/test/rubygems/test_gem_commands_pristine_command.rb @@ -110,6 +110,41 @@ class TestGemCommandsPristineCommand < Gem::TestCase end end + def test_execute_extensions_explicit + a = quick_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end + + ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' + write_file ext_path do |io| + io.write <<-'RUBY' + File.open "Makefile", "w" do |f| + f.puts "all:\n\techo built\n" + f.puts "install:\n\techo built\n" + end + RUBY + end + + b = quick_spec 'b' + + install_gem a + install_gem b + + @cmd.options[:extensions] = true + @cmd.options[:extensions_set] = true + @cmd.options[:args] = [] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + + assert_equal 'Restoring gems to pristine condition...', out.shift + assert_equal 'Building native extensions. This could take a while...', + out.shift + assert_equal "Restored #{a.full_name}", out.shift + assert_empty out, out.inspect + end + def test_execute_no_extension a = quick_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end @@ -320,5 +355,24 @@ class TestGemCommandsPristineCommand < Gem::TestCase @ui.output.split("\n")) assert_empty(@ui.error) end + + def test_handle_options + @cmd.handle_options %w[] + + refute @cmd.options[:all] + + assert @cmd.options[:extensions] + refute @cmd.options[:extensions_set] + + assert_equal Gem::Requirement.default, @cmd.options[:version] + end + + def test_handle_options_extensions + @cmd.handle_options %w[--extensions] + + assert @cmd.options[:extensions] + assert @cmd.options[:extensions_set] + end + end diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb index 52109d0ae4..7d3d2efb88 100644 --- a/test/rubygems/test_gem_commands_push_command.rb +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -62,17 +62,15 @@ class TestGemCommandsPushCommand < Gem::TestCase end def test_execute - open 'example', 'w' do |io| io.write 'hello' end - @response = "Successfully registered gem: freewill (1.0.0)" @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] - @cmd.options[:args] = %w[example] + @cmd.options[:args] = [@path] @cmd.execute assert_equal Net::HTTP::Post, @fetcher.last_request.class - assert_equal 'hello', @fetcher.last_request.body + assert_equal Gem.read_binary(@path), @fetcher.last_request.body assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] end @@ -80,20 +78,18 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_execute_host host = 'https://other.example' - open 'example', 'w' do |io| io.write 'hello' end - @response = "Successfully registered gem: freewill (1.0.0)" @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK'] @fetcher.data["#{Gem.host}/api/v1/gems"] = ['fail', 500, 'Internal Server Error'] @cmd.options[:host] = host - @cmd.options[:args] = %w[example] + @cmd.options[:args] = [@path] @cmd.execute assert_equal Net::HTTP::Post, @fetcher.last_request.class - assert_equal 'hello', @fetcher.last_request.body + assert_equal Gem.read_binary(@path), @fetcher.last_request.body assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] end @@ -154,6 +150,78 @@ class TestGemCommandsPushCommand < Gem::TestCase send_battery end + def test_sending_gem_to_allowed_push_host + @host = "http://privategemserver.com" + + @spec, @path = util_gem "freebird", "1.0.1" do |spec| + spec.metadata['allowed_push_host'] = @host + end + + @api_key = "PRIVKEY" + + keys = { + :rubygems_api_key => 'KEY', + @host => @api_key + } + + FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path + open Gem.configuration.credentials_path, 'w' do |f| + f.write keys.to_yaml + end + Gem.configuration.load_api_keys + + FileUtils.rm Gem.configuration.credentials_path + + @response = "Successfully registered gem: freebird (1.0.1)" + @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] + send_battery + end + + def test_sending_gem_to_disallowed_default_host + @spec, @path = util_gem "freebird", "1.0.1" do |spec| + spec.metadata['allowed_push_host'] = "https://privategemserver.com" + end + + response = %{ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.com"} + + assert_raises Gem::MockGemUi::TermError do + send_battery + end + + assert_match response, @ui.error + end + + def test_sending_gem_to_disallowed_push_host + @host = "https://somebodyelse.com" + + @spec, @path = util_gem "freebird", "1.0.1" do |spec| + spec.metadata['allowed_push_host'] = "https://privategemserver.com" + end + + @api_key = "PRIVKEY" + + keys = { + :rubygems_api_key => 'KEY', + @host => @api_key + } + + FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path + open Gem.configuration.credentials_path, 'w' do |f| + f.write keys.to_yaml + end + Gem.configuration.load_api_keys + + FileUtils.rm Gem.configuration.credentials_path + + response = 'ERROR: "https://somebodyelse.com" is not allowed by the gemspec, which only allows "https://privategemserver.com"' + + assert_raises Gem::MockGemUi::TermError do + send_battery + end + + assert_match response, @ui.error + end + def test_raises_error_with_no_arguments def @cmd.sign_in(*); end assert_raises Gem::CommandLineError do diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index a7e5e01f09..519af595a0 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -281,6 +281,25 @@ pl (1) assert_equal 1, e.exit_code end + def test_execute_local + @cmd.options[:domain] = :local + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF + +*** LOCAL GEMS *** + +a (3.a, 2, 1) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + def test_execute_local_notty @cmd.handle_options %w[] @@ -299,6 +318,23 @@ pl (1 i386-linux) assert_equal '', @ui.error end + def test_execute_local_quiet + @cmd.options[:domain] = :local + Gem.configuration.verbose = false + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF +a (3.a, 2, 1) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + def test_execute_no_versions @cmd.handle_options %w[-r --no-versions] @@ -373,6 +409,60 @@ pl (1 i386-linux) assert_equal "WARNING: prereleases are always shown locally\n", @ui.error end + def test_execute_remote + @cmd.options[:domain] = :remote + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF + +*** REMOTE GEMS *** + +a (2) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + + def test_execute_remote_notty + @cmd.handle_options %w[] + + @ui.outs.tty = false + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF +a (3.a, 2, 1) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + + def test_execute_remote_quiet + @cmd.options[:domain] = :remote + Gem.configuration.verbose = false + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF +a (2) +pl (1 i386-linux) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + def test_execute_local_details @a1.platform = 'x86-linux' @@ -474,5 +564,18 @@ pl \(1\) assert_equal 'a (2)', entry end + # Test for multiple args handling! + def test_execute_multiple_args + @cmd.handle_options %w[a pl] + + use_ui @ui do + @cmd.execute + end + + assert_match %r%^a %, @ui.output + assert_match %r%^pl %, @ui.output + assert_equal '', @ui.error + end + end diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index 9ba1371b79..ff6e368414 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -16,18 +16,33 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase @executable = File.join(@gemhome, 'bin', 'executable') end - def test_execute_all_gem_names - @cmd.options[:args] = %w[a b] + def test_execute_all_named + util_make_gems + + default = new_default_spec 'default', '1' + install_default_gems default + + gemhome2 = "#{@gemhome}2" + + a_4 = quick_spec 'a', 4 + install_gem a_4, :install_dir => gemhome2 + + Gem::Specification.dirs = [@gemhome, gemhome2] + + assert_includes Gem::Specification.all_names, 'a-1' + assert_includes Gem::Specification.all_names, 'a-4' + assert_includes Gem::Specification.all_names, 'b-2' + assert_includes Gem::Specification.all_names, 'default-1' + @cmd.options[:all] = true + @cmd.options[:args] = %w[a] - assert_raises Gem::MockGemUi::TermError do - use_ui @ui do - @cmd.execute - end + use_ui @ui do + @cmd.execute end - assert_match(/\A(?:WARNING: Unable to use symlinks on Windows, installing wrapper\n)?ERROR: Gem names and --all may not be used together\n\z/, - @ui.error) + assert_equal %w[a-4 a_evil-9 b-2 c-1.2 default-1 dep_x-1 pl-1-x86-linux x-1], + Gem::Specification.all_names.sort end def test_execute_dependency_order @@ -217,5 +232,14 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase assert_equal %w[a-4 default-1], Gem::Specification.all_names.sort end + def test_handle_options + @cmd.handle_options %w[] + + assert_equal false, @cmd.options[:check_dev] + assert_equal nil, @cmd.options[:install_dir] + assert_equal true, @cmd.options[:user_install] + assert_equal Gem::Requirement.default, @cmd.options[:version] + end + end diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index d1c1b20c6e..189af0ee4b 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -405,4 +405,31 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_equal expected, @cmd.options end + def test_update_rubygems_arguments + @cmd.options[:system] = true + + arguments = @cmd.update_rubygems_arguments + + assert_equal '--prefix', arguments.shift + assert_equal Gem.prefix, arguments.shift + assert_equal '--no-rdoc', arguments.shift + assert_equal '--no-ri', arguments.shift + assert_equal '--previous-version', arguments.shift + assert_equal Gem::VERSION, arguments.shift + assert_empty arguments + end + + def test_update_rubygems_arguments_1_8_x + @cmd.options[:system] = '1.8.26' + + arguments = @cmd.update_rubygems_arguments + + assert_equal '--prefix', arguments.shift + assert_equal Gem.prefix, arguments.shift + assert_equal '--no-rdoc', arguments.shift + assert_equal '--no-ri', arguments.shift + assert_empty arguments + end + end + diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index af5319a150..79258ca3b4 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -396,6 +396,24 @@ class TestGemPackage < Gem::Package::TarTestCase "#{@destination} is not allowed", e.message) end + def test_extract_tar_gz_directory + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.mkdir 'lib', 0755 + tar.add_file 'lib/foo.rb', 0644 do |io| io.write 'hi' end + tar.mkdir 'lib/foo', 0755 + end + + package.extract_tar_gz tgz_io, @destination + + extracted = File.join @destination, 'lib/foo.rb' + assert_path_exists extracted + + extracted = File.join @destination, 'lib/foo' + assert_path_exists extracted + end + def test_extract_tar_gz_dot_slash package = Gem::Package.new @gem diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb index 869c6730a9..f8b9a90897 100644 --- a/test/rubygems/test_gem_request.rb +++ b/test/rubygems/test_gem_request.rb @@ -12,8 +12,9 @@ class TestGemRequest < Gem::TestCase super @proxy_uri = "http://localhost:1234" + @uri = URI('http://example') - @request = Gem::Request.new nil, nil, nil, nil + @request = Gem::Request.new @uri, nil, nil, nil end def teardown @@ -25,7 +26,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new nil, nil, nil, proxy_uri + request = Gem::Request.new @uri, nil, nil, proxy_uri assert_equal proxy_uri, request.proxy_uri.to_s end @@ -33,7 +34,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy_URI proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new nil, nil, nil, URI(proxy_uri) + request = Gem::Request.new @uri, nil, nil, URI(proxy_uri) assert_equal proxy_uri, request.proxy_uri.to_s end @@ -43,7 +44,7 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy_user'] = 'foo' ENV['http_proxy_pass'] = 'bar' - request = Gem::Request.new nil, nil, nil, nil + request = Gem::Request.new @uri, nil, nil, nil proxy = request.proxy_uri @@ -51,6 +52,32 @@ class TestGemRequest < Gem::TestCase assert_equal 'bar', proxy.password end + def test_initialize_proxy_ENV_https + ENV['https_proxy'] = @proxy_uri + + request = Gem::Request.new URI('https://example'), nil, nil, nil + + proxy = request.proxy_uri + + assert_equal URI(@proxy_uri), proxy + end + + def test_get_proxy_from_env_fallback + ENV['http_proxy'] = @proxy_uri + + proxy = @request.get_proxy_from_env 'https' + + assert_equal URI(@proxy_uri), proxy + end + + def test_get_proxy_from_env_https + ENV['https_proxy'] = @proxy_uri + + proxy = @request.get_proxy_from_env 'https' + + assert_equal URI(@proxy_uri), proxy + end + def test_get_proxy_from_env_domain ENV['http_proxy'] = @proxy_uri ENV['http_proxy_user'] = 'foo\user' @@ -112,7 +139,7 @@ class TestGemRequest < Gem::TestCase end def test_user_agent - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua @@ -127,7 +154,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'vroom' - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\) vroom%, ua ensure @@ -140,7 +167,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'ruby' - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\)%, ua ensure @@ -153,7 +180,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_PATCHLEVEL Object.send :const_set, :RUBY_PATCHLEVEL, 5 - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r% patchlevel 5\)%, ua ensure @@ -168,7 +195,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) Object.send :const_set, :RUBY_REVISION, 6 - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r% revision 6\)%, ua assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua @@ -183,7 +210,7 @@ class TestGemRequest < Gem::TestCase Object.send :const_set, :RUBY_PATCHLEVEL, -1 Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) - ua = Gem::Request.new(nil, nil, nil, nil).user_agent + ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua ensure diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index efda6f6f19..51c7be813f 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -75,6 +75,10 @@ end s.files = %w[lib/code.rb] end + @a3 = quick_spec 'a', '3' do |s| + s.metadata['allowed_push_host'] = "https://privategemserver.com" + end + @current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION load 'rubygems/syck_hack.rb' @@ -946,7 +950,7 @@ dependencies: [] assert_same spec.summary, new_spec.summary assert_equal %w[lib/file.rb test/file.rb bin/exec README.txt - ext/extconf.rb], + ext/extconf.rb].sort, spec.files refute_same spec.files, new_spec.files, 'files' @@ -1055,7 +1059,7 @@ dependencies: [] @a2.executable = 'app' assert_equal nil, @a2.bindir - assert_equal %w[lib/code.rb app], @a2.files + assert_equal %w[lib/code.rb app].sort, @a2.files end def test_date @@ -1155,7 +1159,7 @@ dependencies: [] def test_executable_equals @a2.executable = 'app' assert_equal 'app', @a2.executable - assert_equal %w[lib/code.rb bin/app], @a2.files + assert_equal %w[lib/code.rb bin/app].sort, @a2.files end def test_extensions @@ -1177,7 +1181,7 @@ dependencies: [] files test_files ] - assert_equal expected, @a1.files.sort + assert_equal expected, @a1.files end def test_files_append @@ -1195,14 +1199,14 @@ dependencies: [] files test_files ] - assert_equal expected, @a1.files.sort + assert_equal expected, @a1.files @a1.files << "generated_file.c" expected << "generated_file.c" expected.sort! - assert_equal expected, @a1.files.sort + assert_equal expected, @a1.files end def test_files_duplicate @@ -1228,7 +1232,7 @@ dependencies: [] @a1.extra_rdoc_files = "ERF" @a1.extensions = "E" - assert_equal %w[E ERF F TF bin/X], @a1.files.sort + assert_equal %w[E ERF F TF bin/X], @a1.files end def test_files_non_array_pathological @@ -1238,7 +1242,7 @@ dependencies: [] @a1.instance_variable_set :@extensions, "E" @a1.instance_variable_set :@executables, "X" - assert_equal %w[E ERF F TF bin/X], @a1.files.sort + assert_equal %w[E ERF F TF bin/X], @a1.files assert_kind_of Integer, @a1.hash end @@ -1428,6 +1432,12 @@ dependencies: [] assert_equal %w[lib], @a1.require_paths end + def test_full_require_paths + @a1.require_path = 'lib' + assert_equal [File.join(@gemhome, 'gems', @a1.original_name, 'lib')], + @a1.full_require_paths + end + def test_require_already_activated save_loaded_features do a1 = new_spec "a", "1", nil, "lib/d.rb" @@ -1472,6 +1482,11 @@ dependencies: [] assert_equal ['A working computer'], @a1.requirements end + def test_allowed_push_host + assert_equal nil, @a1.metadata['allowed_push_host'] + assert_equal 'https://privategemserver.com', @a3.metadata['allowed_push_host'] + end + def test_runtime_dependencies_legacy make_spec_c1 # legacy gems don't have a type @@ -1653,7 +1668,7 @@ Gem::Specification.new do |s| s.email = "example@example.com" s.executables = ["exec"] s.extensions = ["ext/a/extconf.rb"] - s.files = ["lib/code.rb", "test/suite.rb", "bin/exec", "ext/a/extconf.rb"] + s.files = ["bin/exec", "ext/a/extconf.rb", "lib/code.rb", "test/suite.rb"] s.homepage = "http://example.com" s.licenses = ["MIT"] s.require_paths = ["lib"] @@ -1985,10 +2000,24 @@ end assert_equal '["lib2"] are not files', e.message end - assert_equal %w[lib/code.rb test/suite.rb bin/exec ext/a/extconf.rb lib2], + assert_equal %w[lib/code.rb test/suite.rb bin/exec ext/a/extconf.rb lib2].sort, @a1.files end + def test_validate_files_recursive + util_setup_validate + FileUtils.touch @a1.file_name + + @a1.files = [@a1.file_name] + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal "#{@a1.full_name} contains itself (#{@a1.file_name}), check your files list", + e.message + end + def test_validate_homepage util_setup_validate diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index 1739614c67..bb17dbf266 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -240,7 +240,7 @@ class TestGemUninstaller < Gem::InstallerTestCase assert File.exist?(executable), 'executable must still exist' end - def test_uninstall_user + def test_uninstall_user_install @user_spec = Gem::Specification.find_by_name 'b' uninstaller = Gem::Uninstaller.new(@user_spec.name, -- cgit v1.2.3