diff options
55 files changed, 1052 insertions, 583 deletions
@@ -39,7 +39,7 @@ require 'rubygems/errors' # Further RubyGems documentation can be found at: # # * {RubyGems Guides}[http://guides.rubygems.org] -# * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from # <tt>gem server</tt>) # # == RubyGems Plugins @@ -47,15 +47,16 @@ require 'rubygems/errors' # As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or # $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and # placed at the root of your gem's #require_path. Plugins are discovered via -# Gem::find_files then loaded. Take care when implementing a plugin as your # plugin file may be loaded multiple times if multiple versions of your gem # are installed. # -# For an example plugin, see the graph gem which adds a `gem graph` command. # # == RubyGems Defaults, Packaging # -# RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging # RubyGems or implementing Ruby you can change RubyGems' defaults. # # For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb @@ -65,7 +66,7 @@ require 'rubygems/errors' # override any defaults from lib/rubygems/defaults.rb. # # If you need RubyGems to perform extra work on install or uninstall, your -# defaults override file can set pre and post install and uninstall hooks. # See Gem::pre_install, Gem::pre_uninstall, Gem::post_install, # Gem::post_uninstall. # @@ -106,6 +107,8 @@ require 'rubygems/errors' # # (If your name is missing, PLEASE let us know!) # # See {LICENSE.txt}[rdoc-ref:lib/rubygems/LICENSE.txt] for permissions. # # Thanks! @@ -130,6 +133,7 @@ module Gem GEM_DEP_FILES = %w[ gem.deps.rb Gemfile Isolate ] @@ -159,7 +163,7 @@ module Gem # these are defined in Ruby 1.8.7, hence the need for this convoluted setup. READ_BINARY_ERRORS = begin - read_binary_errors = [Errno::EACCES] read_binary_errors << Errno::ENOTSUP if Errno.const_defined?(:ENOTSUP) read_binary_errors end.freeze @@ -174,6 +178,8 @@ module Gem write_binary_errors end.freeze @@win_platform = nil @configuration = nil @@ -266,17 +272,22 @@ module Gem return loaded if loaded && dep.matches_spec?(loaded) - specs = dep.matching_specs(true) - - raise Gem::GemNotFoundException, - "can't find gem #{dep}" if specs.empty? specs = specs.find_all { |spec| spec.executables.include? exec_name } if exec_name unless spec = specs.first - msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}" raise Gem::GemNotFoundException, msg end @@ -297,7 +308,10 @@ module Gem def self.activate_bin_path name, exec_name, requirement # :nodoc: spec = find_spec_for_exe name, exec_name, [requirement] - Gem::LOADED_SPECS_MUTEX.synchronize { spec.activate } spec.bin_file exec_name end @@ -356,12 +370,16 @@ module Gem # package is not available as a gem, return nil. def self.datadir(gem_name) -# TODO: deprecate spec = @loaded_specs[gem_name] return nil if spec.nil? spec.datadir end ## # A Zlib::Deflate.deflate wrapper @@ -594,7 +612,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} # Zlib::GzipReader wrapper that unzips +data+. def self.gunzip(data) - require 'rubygems/util' Gem::Util.gunzip data end @@ -602,7 +619,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} # Zlib::GzipWriter wrapper that zips +data+. def self.gzip(data) - require 'rubygems/util' Gem::Util.gzip data end @@ -610,7 +626,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} # A Zlib::Inflate#inflate wrapper def self.inflate(data) - require 'rubygems/util' Gem::Util.inflate data end @@ -715,9 +730,20 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} ## # The file name and line number of the caller of the caller of this method. - def self.location_of_caller - caller[1] =~ /(.*?):(\d+).*?$/i file = $1 lineno = $2.to_i @@ -1148,8 +1174,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} path = path.dup if path == "-" then - require 'rubygems/util' - Gem::Util.traverse_parents Dir.pwd do |directory| dep_file = GEM_DEP_FILES.find { |f| File.file?(f) } @@ -1168,18 +1192,36 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} raise ArgumentError, "Unable to find gem dependencies file at #{path}" end - rs = Gem::RequestSet.new - @gemdeps = rs.load_gemdeps path - rs.resolve_current.map do |s| - sp = s.full_spec - sp.activate - sp end - rescue Gem::LoadError, Gem::UnsatisfiableDependencyError => e - warn e.message - warn "You may need to `gem install -g` to install missing gems" - warn "" end class << self @@ -1225,6 +1267,8 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} prefix_pattern = /^(#{prefix_group})/ end spec.files.each do |file| if new_format file = file.sub(prefix_pattern, "") @@ -1232,6 +1276,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} end @path_to_default_spec_map[file] = spec end end @@ -1239,11 +1284,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} # Find a Gem::Specification of default gem from +path+ def find_unresolved_default_spec(path) - Gem.suffixes.each do |suffix| - spec = @path_to_default_spec_map["#{path}#{suffix}"] - return spec if spec - end - nil end ## @@ -1314,6 +1355,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/" autoload :ConfigFile, 'rubygems/config_file' autoload :Dependency, 'rubygems/dependency' autoload :DependencyList, 'rubygems/dependency_list' @@ -1329,6 +1371,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} autoload :SourceList, 'rubygems/source_list' autoload :SpecFetcher, 'rubygems/spec_fetcher' autoload :Specification, 'rubygems/specification' autoload :Version, 'rubygems/version' require "rubygems/specification" @@ -71,7 +71,7 @@ class Gem::BasicSpecification elsif missing_extensions? then @ignored = true - warn "Ignoring #{full_name} because its extensions are not built. " + "Try: gem pristine #{name} --version #{version}" return false end @@ -275,10 +275,10 @@ class Gem::BasicSpecification # for this spec. def lib_dirs_glob - dirs = if self.require_paths.size > 1 then - "{#{self.require_paths.join(',')}}" else - self.require_paths.first end "#{self.full_gem_path}/#{dirs}".dup.untaint @@ -0,0 +1,112 @@ @@ -527,7 +527,7 @@ class Gem::Command end add_common_option("--silent", - "Silence rubygems output") do |value, options| options[:silent] = true end @@ -58,6 +58,8 @@ class Gem::CommandManager :rdoc, :search, :server, :sources, :specification, :stale, @@ -161,7 +163,7 @@ class Gem::CommandManager say Gem::VERSION terminate_interaction 0 when /^-/ then - alert_error "Invalid option: #{args.first}. See 'gem --help'." terminate_interaction 1 else cmd_name = args.shift.downcase @@ -84,6 +84,11 @@ class Gem::Commands::CertCommand < Gem::Command options[:sign] << cert_file end end def add_certificate certificate # :nodoc: @@ -105,16 +110,20 @@ class Gem::Commands::CertCommand < Gem::Command list_certificates_matching filter end - options[:build].each do |name| - build name end sign_certificates unless options[:sign].empty? end - def build name key, key_path = build_key - cert_path = build_cert name, key say "Certificate: #{cert_path}" @@ -124,8 +133,16 @@ class Gem::Commands::CertCommand < Gem::Command end end - def build_cert name, key # :nodoc: - cert = Gem::Security.create_cert_email name, key Gem::Security.write cert, "gem-public_cert.pem" end @@ -273,5 +290,13 @@ For further reading on signing gems see `ri Gem::Security`. end end end if defined?(OpenSSL::SSL) @@ -66,7 +66,7 @@ If no gems are named all gems in GEM_HOME are cleaned. clean_gems end - say "Clean Up Complete" verbose do skipped = @default_gems.map { |spec| spec.full_name } @@ -367,7 +367,7 @@ platform. elsif possibilities.size > 1 then alert_warning "Ambiguous command #{command_name} (#{possibilities.join(', ')})" else - alert_warning "Unknown command #{command_name}. Try: gem help commands" end end @@ -40,7 +40,9 @@ permission to. options[:remove] << value end - add_option '-h', '--host HOST', 'Use another gemcutter-compatible host' do |value, options| options[:host] = value end end @@ -125,14 +125,14 @@ extensions will be restored. next end - unless spec.extensions.empty? or options[:extensions] then say "Skipped #{spec.full_name}, it needs to compile an extension" next end gem = spec.cache_file - unless File.exist? gem then require 'rubygems/remote_fetcher' say "Cached gem for #{spec.full_name} not found, attempting to fetch..." @@ -157,16 +157,19 @@ extensions will be restored. install_defaults.to_s['--env-shebang'] end - installer = Gem::Installer.at(gem, - :wrappers => true, - :force => true, - :install_dir => spec.base_dir, - :env_shebang => env_shebang, - :build_args => spec.build_args) - if options[:only_executables] then installer.generate_bin else installer.install end @@ -33,7 +33,8 @@ command. For further discussion see the help for the yank command. add_key_option add_option('--host HOST', - 'Push to another gemcutter-compatible host') do |value, options| options[:host] = value end @@ -255,22 +255,21 @@ is too hard to use. name_tuples.map { |n| n.version }.uniq else platforms.sort.reverse.map do |version, pls| - if pls == [Gem::Platform::RUBY] then - if options[:domain] == :remote || specs.all? { |spec| spec.is_a? Gem::Source } - version - else - spec = specs.select { |s| s.version == version } - if spec.first.default_gem? - "default: #{version}" - else - version - end end - else - ruby = pls.delete Gem::Platform::RUBY - platform_list = [ruby, *pls.sort].compact - "#{version} #{platform_list.join ' '}" end end end @@ -15,10 +15,11 @@ class Gem::Commands::SetupCommand < Gem::Command super 'setup', 'Install RubyGems', :format_executable => true, :document => %w[ri], :site_or_vendor => 'sitelibdir', - :destdir => '', :prefix => '', :previous_version => '' add_option '--previous-version=VERSION', - 'Previous version of rubygems', 'Used for changelog processing' do |version, options| options[:previous_version] = version end @@ -42,7 +43,7 @@ class Gem::Commands::SetupCommand < Gem::Command add_option '--[no-]format-executable', 'Makes `gem` match ruby', - 'If ruby is ruby18, gem will be gem18' do |value, options| options[:format_executable] = value end @@ -79,6 +80,15 @@ class Gem::Commands::SetupCommand < Gem::Command options[:document].uniq! end @verbose = nil end @@ -92,7 +102,7 @@ class Gem::Commands::SetupCommand < Gem::Command end def defaults_str # :nodoc: - "--format-executable --document ri" end def description # :nodoc: @@ -142,8 +152,12 @@ By default, this RubyGems will install gem as: remove_old_lib_files lib_dir say "RubyGems #{Gem::VERSION} installed" uninstall_old_gemcutter documentation_success = install_rdoc @@ -190,7 +204,7 @@ By default, this RubyGems will install gem as: if options[:document].include? 'ri' then say "Ruby Interactive (ri) documentation was installed. ri is kind of like man " - say "pages for ruby libraries. You may access it like this:" say " ri Classname" say " ri Classname.class_method" say " ri Classname#instance_method" @@ -202,59 +216,64 @@ By default, this RubyGems will install gem as: end end - def install_executables(bin_dir) - say "Installing gem executable" if @verbose @bin_file_names = [] - Dir.chdir 'bin' do - bin_files = Dir['*'] - bin_files.delete 'update_rubygems' - bin_files.each do |bin_file| - bin_file_formatted = if options[:format_executable] then - Gem.default_exec_format % bin_file - else - bin_file - end - dest_file = File.join bin_dir, bin_file_formatted - bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}" - begin - bin = File.readlines bin_file - bin[0] = "#!#{Gem.ruby}\n" - File.open bin_tmp_file, 'w' do |fp| - fp.puts bin.join - end - - install bin_tmp_file, dest_file, :mode => 0755 - @bin_file_names << dest_file - ensure - rm bin_tmp_file - end - - next unless Gem.win_platform? - begin - bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat" - File.open bin_cmd_file, 'w' do |file| - file.puts <<-TEXT -@ECHO OFF -IF NOT "%~f0" == "~f0" GOTO :WinNT -@"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9 -GOTO :EOF -:WinNT -@"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %* -TEXT end - install bin_cmd_file, "#{dest_file}.bat", :mode => 0755 - ensure - rm bin_cmd_file end end end @@ -269,18 +288,22 @@ TEXT end def install_lib(lib_dir) - say "Installing RubyGems" if @verbose - lib_files = rb_files_in 'lib' - pem_files = pem_files_in 'lib' - Dir.chdir 'lib' do - lib_files.each do |lib_file| - install_file lib_file, lib_dir - end - pem_files.each do |pem_file| - install_file pem_file, lib_dir end end end @@ -326,6 +349,29 @@ TEXT return false end def make_destination_dirs(install_destdir) lib_dir, bin_dir = Gem.default_rubygems_dirs @@ -397,7 +443,7 @@ TEXT old_bin_path = File.join bin_dir, old_bin_file next unless File.exist? old_bin_path - deprecation_message = "`#{old_bin_file}` has been deprecated. Use `#{new_name}` instead." File.open old_bin_path, 'w' do |fp| fp.write <<-EOF @@ -416,23 +462,26 @@ abort "#{deprecation_message}" end def remove_old_lib_files lib_dir - rubygems_dir = File.join lib_dir, 'rubygems' - lib_files = rb_files_in 'lib/rubygems' - old_lib_files = rb_files_in rubygems_dir - to_remove = old_lib_files - lib_files - to_remove.delete_if do |file| - file.start_with? 'defaults' - end - Dir.chdir rubygems_dir do - to_remove.each do |file| - FileUtils.rm_f file - warn "unable to remove old file #{file} please remove it by hand" if - File.exist? file end end end @@ -480,5 +529,11 @@ abort "#{deprecation_message}" rescue Gem::InstallError end -end @@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@ @@ -30,7 +30,7 @@ class Gem::Commands::UninstallCommand < Gem::Command options[:ignore] = value end - add_option('-D', '--[no-]-check-development', 'Check development dependencies while uninstalling', '(default: false)') do |value, options| options[:check_dev] = value @@ -143,7 +143,9 @@ that is a dependency of an existing gem. You can use the deplist = Gem::DependencyList.new get_all_gem_names.uniq.each do |name| - Gem::Specification.find_all_by_name(name).each do |spec| deplist.add spec end end @@ -162,4 +164,3 @@ that is a dependency of an existing gem. You can use the end end - @@ -2,11 +2,20 @@ require 'rubygems/command' require 'rubygems/installer' require 'rubygems/version_option' require 'rubygems/remote_fetcher' class Gem::Commands::UnpackCommand < Gem::Command include Gem::VersionOption def initialize require 'fileutils' @@ -24,6 +33,7 @@ class Gem::Commands::UnpackCommand < Gem::Command options[:spec] = true end add_version_option end @@ -63,6 +73,8 @@ command help for an example. # at the same time.) def execute get_all_gem_names.each do |name| dependency = Gem::Dependency.new name, options[:version] path = get_path dependency @@ -73,7 +85,7 @@ command help for an example. end if @options[:spec] then - spec, metadata = get_metadata path if metadata.nil? then alert_error "--spec is unsupported on '#{name}' (old format gem)" @@ -89,7 +101,7 @@ command help for an example. basename = File.basename path, '.gem' target_dir = File.expand_path basename, options[:target] - package = Gem::Package.new path package.extract_files target_dir say "Unpacked gem: '#{target_dir}'" @@ -158,8 +170,8 @@ command help for an example. #-- # TODO move to Gem::Package as #raw_spec or something - def get_metadata path - format = Gem::Package.new path spec = format.spec metadata = nil @@ -70,7 +70,7 @@ command to remove old versions. def check_latest_rubygems version # :nodoc: if Gem.rubygems_version == version then - say "Latest version currently installed. Aborting." terminate_interaction end @@ -56,7 +56,7 @@ requiring to see why it does not behave as you expect. paths = find_paths arg, dirs if paths.empty? then - alert_error "Can't find ruby library file or shared library #{arg}" found &&= false else @@ -11,19 +11,11 @@ class Gem::Commands::YankCommand < Gem::Command def description # :nodoc: <<-EOF -The yank command removes a gem you pushed to a server from the server's -index. - -Note that if you push a gem to rubygems.org the yank command does not -prevent other people from downloading the gem via the download link. Once you have pushed a gem several downloads will happen automatically -via the webhooks. If you accidentally pushed passwords or other sensitive data you will need to change them immediately and yank your gem. - -If you are yanking a gem due to intellectual property reasons contact -http://help.rubygems.org for permanent removal. Be sure to mention this -as the reason for the removal request. EOF end @@ -42,7 +34,8 @@ as the reason for the removal request. add_platform_option("remove") add_option('--host HOST', - 'Yank from another gemcutter-compatible host') do |value, options| options[:host] = value end @@ -336,6 +336,15 @@ if you believe they were disclosed to a third party. load_api_keys # reload end def load_file(filename) Gem.load_yaml @@ -419,31 +428,11 @@ if you believe they were disclosed to a third party. # to_yaml only overwrites things you can't override on the command line. def to_yaml # :nodoc: yaml_hash = {} - yaml_hash[:backtrace] = if @hash.key?(:backtrace) - @hash[:backtrace] - else - DEFAULT_BACKTRACE - end - - yaml_hash[:bulk_threshold] = if @hash.key?(:bulk_threshold) - @hash[:bulk_threshold] - else - DEFAULT_BULK_THRESHOLD - end - yaml_hash[:sources] = Gem.sources.to_a - - yaml_hash[:update_sources] = if @hash.key?(:update_sources) - @hash[:update_sources] - else - DEFAULT_UPDATE_SOURCES - end - - yaml_hash[:verbose] = if @hash.key?(:verbose) - @hash[:verbose] - else - DEFAULT_VERBOSITY - end yaml_hash[:ssl_verify_mode] = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode @@ -41,8 +41,7 @@ module Kernel path = path.to_path if path.respond_to? :to_path - spec = Gem.find_unresolved_default_spec(path) - if spec Gem.remove_unresolved_default_spec(spec) begin Kernel.send(:gem, spec.name) @@ -66,12 +65,10 @@ module Kernel #-- # TODO request access to the C implementation of this to speed up RubyGems - spec = Gem::Specification.find_active_stub_by_path path - - begin RUBYGEMS_ACTIVATION_MONITOR.exit return gem_original_require(path) - end if spec # Attempt to find +path+ in any unresolved gems... @@ -109,7 +106,7 @@ module Kernel # Ok, now find a gem that has no conflicts, starting # at the highest version. - valid = found_specs.reject { |s| s.has_conflicts? }.first unless valid then le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate" @@ -143,4 +140,3 @@ module Kernel private :require end - @@ -280,6 +280,8 @@ class Gem::Dependency requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version) }.map(&:to_spec) if platform_only matches.reject! { |spec| spec.nil? || !Gem::Platform.match(spec.platform) @@ -7,6 +7,7 @@ require 'rubygems/spec_fetcher' require 'rubygems/user_interaction' require 'rubygems/source' require 'rubygems/available_set' ## # Installs a gem along with all its dependencies from local and remote gems. @@ -46,6 +47,9 @@ class Gem::DependencyInstaller attr_reader :gems_to_install # :nodoc: ## # List of gems installed by #install in alphabetic order @@ -58,6 +58,9 @@ module Gem private def build_message names = specs.map(&:full_name) "Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n" end @@ -154,6 +154,12 @@ class Gem::ImpossibleDependenciesError < Gem::Exception end class Gem::InstallError < Gem::Exception; end ## # Potentially raised when a specification is validated. @@ -183,7 +183,7 @@ EOF return if @spec.extensions.empty? if @build_args.empty? - say "Building native extensions. This could take a while..." else say "Building native extensions with: '#{@build_args.join ' '}'" say "This could take a while..." @@ -8,6 +8,7 @@ require 'rubygems' require 'rubygems/command_manager' require 'rubygems/config_file' ## # Load additional plugins from $LOAD_PATH @@ -26,7 +27,10 @@ Gem.load_env_plugins rescue nil class Gem::GemRunner def initialize(options={}) - # TODO: nuke these options @command_manager_class = options[:command_manager] || Gem::CommandManager @config_file_class = options[:config_file] || Gem::ConfigFile end @@ -6,37 +6,18 @@ #++ require 'rubygems' - -# forward-declare - -module Gem::Security # :nodoc: - class Policy # :nodoc: - end -end ## # Mixin methods for install and update options for Gem::Commands module Gem::InstallUpdateOptions ## # Add the install/update options to the option parser. def add_install_update_options - # TODO: use @parser.accept - OptionParser.accept Gem::Security::Policy do |value| - require 'rubygems/security' - - raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless - defined?(Gem::Security::HighSecurity) - - value = Gem::Security::Policies[value] - valid = Gem::Security::Policies.keys.sort - message = "#{value} (#{valid.join ', '} are valid)" - raise OptionParser::InvalidArgument, message if value.nil? - value - end - add_option(:"Install/Update", '-i', '--install-dir DIR', 'Gem repository directory to get installed', 'gems') do |value, options| @@ -124,11 +105,7 @@ module Gem::InstallUpdateOptions options[:wrappers] = value end - add_option(:"Install/Update", '-P', '--trust-policy POLICY', - Gem::Security::Policy, - 'Specify gem trust policy') do |value, options| - options[:security_policy] = value - end add_option(:"Install/Update", '--ignore-dependencies', 'Do not install any required dependent gems') do |value, options| @@ -136,8 +113,8 @@ module Gem::InstallUpdateOptions end add_option(:"Install/Update", '--[no-]format-executable', - 'Make installed executable names match ruby.', - 'If ruby is ruby18, foo_exec will be', 'foo_exec18') do |value, options| options[:format_executable] = value end @@ -136,8 +136,9 @@ class Gem::Installer end ## - # Constructs an Installer instance that will install the gem located at - # +gem+. +options+ is a Hash with the following keys: # # :bin_dir:: Where to put a bin wrapper if needed. # :development:: Whether or not development dependencies should be installed. @@ -157,6 +158,7 @@ class Gem::Installer # :wrappers:: Install wrappers if true, symlinks if false. # :build_args:: An Array of arguments to pass to the extension builder # process. If not set, then Gem::Command.build_args is used def initialize(package, options={}) require 'fileutils' @@ -471,7 +473,7 @@ class Gem::Installer unless File.exist? bin_path then # TODO change this to a more useful warning - warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?" next end @@ -608,7 +610,9 @@ class Gem::Installer def ensure_required_ruby_version_met # :nodoc: if rrv = spec.required_ruby_version then unless rrv.satisfied_by? Gem.ruby_version then - raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}." end end end @@ -616,8 +620,9 @@ class Gem::Installer def ensure_required_rubygems_version_met # :nodoc: if rrgv = spec.required_rubygems_version then unless rrgv.satisfied_by? Gem.rubygems_version then - raise Gem::InstallError, - "#{spec.name} requires RubyGems version #{rrgv}. " + "Try 'gem update --system' to update RubyGems itself." end end @@ -821,7 +826,7 @@ TEXT # # Version and dependency checks are skipped if this install is forced. # - # The dependent check will be skipped this install is ignoring dependencies. def pre_install_checks verify_gem_home options[:unpack] @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'rubygems/test_case' require 'rubygems/installer' class Gem::Installer @@ -72,7 +73,7 @@ class Gem::InstallerTestCase < Gem::TestCase # a spec named 'a', intended for regular installs # @user_spec:: # a spec named 'b', intended for user installs - # @gem:: # the path to a built gem from @spec # @user_spec:: @@ -107,15 +108,17 @@ class Gem::InstallerTestCase < Gem::TestCase end def util_gem_bindir spec = @spec # :nodoc: - # TODO: deprecate spec.bin_dir end def util_gem_dir spec = @spec # :nodoc: - # TODO: deprecate spec.gem_dir end ## # The path where installed executables live @@ -124,7 +124,7 @@ class Gem::Package::Old < Gem::Package break unless line end - raise Gem::Exception, "Failed to find end of ruby script while reading gem" end ## @@ -83,7 +83,7 @@ class Gem::Request e.message =~ / -- openssl$/ raise Gem::Exception.new( - 'Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources') end def self.verify_certificate store_context @@ -163,9 +163,26 @@ class Gem::RequestSet end end - spec = req.spec.install options do |installer| - yield req, installer if block_given? - end requests << spec end @@ -786,7 +786,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta engine_version = options[:engine_version] raise ArgumentError, - 'you must specify engine_version along with the ruby engine' if engine and not engine_version return true if @installing @@ -799,7 +799,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta end if engine and engine != Gem.ruby_engine then - message = "Your ruby engine is #{Gem.ruby_engine}, " + "but your #{gem_deps_file} requires #{engine}" raise Gem::RubyVersionMismatch, message @@ -810,7 +810,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta if engine_version != my_engine_version then message = - "Your ruby engine version is #{Gem.ruby_engine} #{my_engine_version}, " + "but your #{gem_deps_file} requires #{engine} #{engine_version}" raise Gem::RubyVersionMismatch, message @@ -51,7 +51,11 @@ class Gem::Requirement # If the input is "weird", the default version requirement is # returned. - def self.create input case input when Gem::Requirement then input @@ -230,8 +230,28 @@ class Gem::Resolver exc.errors = @set.errors raise exc end - possibles.sort_by { |s| [s.source, s.version, Gem::Platform.local =~ s.platform ? 1 : 0] }. - map { |s| ActivationRequest.new s, dependency, [] } end def dependencies_for(specification) @@ -41,6 +41,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set @ignore_dependencies = false @ignore_installed = false @local = {} @remote_set = Gem::Resolver::BestSet.new @specs = {} end @@ -136,13 +137,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set res.concat matching_local - local_source = Gem::Source::Local.new - begin - if local_spec = local_source.find_gem(name, dep.requirement) then res << Gem::Resolver::IndexSpecification.new( self, local_spec.name, local_spec.version, - local_source, local_spec.platform) end rescue Gem::Package::FormatError # ignore @@ -194,7 +193,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set # Has a local gem for +dep_name+ been added to this set? def local? dep_name # :nodoc: - spec, = @local[dep_name] spec end @@ -226,4 +225,3 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end end - @@ -340,7 +340,9 @@ module Gem::Security # Digest algorithm used to sign gems DIGEST_ALGORITHM = - if defined?(OpenSSL::Digest::SHA1) then OpenSSL::Digest::SHA1 end @@ -363,7 +365,7 @@ module Gem::Security ## # Length of keys created by KEY_ALGORITHM - KEY_LENGTH = 2048 ## # Cipher used to encrypt the key pair used to sign gems. @@ -372,9 +374,14 @@ module Gem::Security KEY_CIPHER = OpenSSL::Cipher.new('AES-256-CBC') if defined?(OpenSSL::Cipher) ## # One year in seconds - ONE_YEAR = 86400 * 365 ## # The default set of extensions are: @@ -0,0 +1,43 @@ @@ -573,19 +573,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } add_date res case req.request_uri.path - when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+[^-]*?)(-.*?)?\.gemspec\.rz$| then - marshal_format, name, version, platform = $1, $2, $3, $4 - specs = Gem::Specification.find_all_by_name name, version - selector = [name, version, platform].map(&:inspect).join ' ' - - platform = if platform then - Gem::Platform.new platform.sub(/^-/, '') - else - Gem::Platform::RUBY - end - - specs = specs.select { |s| s.platform == platform } if specs.empty? then res.status = 404 @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'uri' -require 'fileutils' ## # A Source knows how to list and fetch gems from a RubyGems marshal index. @@ -67,7 +67,11 @@ class Gem::Source return -1 if !other.uri - @uri.to_s <=> other.uri.to_s else nil end @@ -232,4 +236,3 @@ require 'rubygems/source/specific_file' require 'rubygems/source/local' require 'rubygems/source/lock' require 'rubygems/source/vendor' - @@ -1,5 +1,4 @@ # frozen_string_literal: true -require 'digest' require 'rubygems/util' ## @@ -226,6 +225,8 @@ class Gem::Source::Git < Gem::Source # A hash for the git gem based on the git repository URI. def uri_hash # :nodoc: normalized = if @repository =~ %r%^\w+://(\w+@)?% then uri = URI(@repository).normalize.to_s.sub %r%/$%,'' @@ -9,6 +9,7 @@ class Gem::Source::Local < Gem::Source @specs = nil @api_uri = nil @uri = nil end ## @@ -34,45 +35,47 @@ class Gem::Source::Local < Gem::Source end def load_specs type # :nodoc: - names = [] - - @specs = {} - - Dir["*.gem"].each do |file| - begin - pkg = Gem::Package.new(file) - rescue SystemCallError, Gem::Package::FormatError - # ignore - else - tup = pkg.spec.name_tuple - @specs[tup] = [File.expand_path(file), pkg] - - case type - when :released - unless pkg.spec.version.prerelease? - names << pkg.spec.name_tuple - end - when :prerelease - if pkg.spec.version.prerelease? - names << pkg.spec.name_tuple - end - when :latest - tup = pkg.spec.name_tuple - cur = names.find { |x| x.name == tup.name } - if !cur - names << tup - elsif cur.version < tup.version - names.delete cur - names << tup - end else - names << pkg.spec.name_tuple end end - end - names end def find_gem gem_name, version = Gem::Requirement.default, # :nodoc: @@ -88,7 +91,7 @@ class Gem::Source::Local < Gem::Source if version.satisfied_by?(s.version) if prerelease found << s - elsif !s.version.prerelease? found << s end end @@ -34,6 +34,10 @@ class Gem::Source::Lock < Gem::Source 0 == (self <=> other) end ## # Delegates to the wrapped source's fetch_spec method. @@ -46,4 +50,3 @@ class Gem::Source::Lock < Gem::Source end end - @@ -2,5 +2,7 @@ require 'rubygems/source' require 'rubygems/source_local' -# TODO warn upon require, this file is deprecated. @@ -1,5 +1,6 @@ # frozen_string_literal: true require 'rubygems/source/specific_file' -# TODO warn upon require, this file is deprecated. - @@ -184,10 +184,10 @@ class Gem::SpecFetcher # Suggests gems based on the supplied +gem_name+. Returns an array of # alternative gem names. - def suggest_gems_from_name gem_name gem_name = gem_name.downcase.tr('_-', '') max = gem_name.size / 2 - names = available_specs(:latest).first.values.flatten(1) matches = names.map { |n| next unless n.match_platform? @@ -201,7 +201,11 @@ class Gem::SpecFetcher [n.name, distance] }.compact - matches = matches.uniq.sort_by { |name, dist| dist } matches.first(5).map { |name, dist| name } end @@ -30,6 +30,7 @@ require 'stringio' # s.email = '[email protected]' # s.files = ["lib/example.rb"] # s.homepage = 'https://rubygems.org/gems/example' # end # # Starting in RubyGems 2.0, a Specification can hold arbitrary @@ -157,16 +158,20 @@ class Gem::Specification < Gem::BasicSpecification :summary => nil, :test_files => [], :version => nil, - } - Dupable = { } # :nodoc: @@default_value.each do |k,v| - case v - when Time, Numeric, Symbol, true, false, nil - Dupable[k] = false else - Dupable[k] = true end end @@ -209,43 +214,51 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :version ## - # Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is - # activated. - #-- - # See also #require_paths - #++ - # If you have an extension you do not need to add <code>"ext"</code> to the - # require path, the extension build process will copy the extension files - # into "lib" for you. # - # The default value is <code>"lib"</code> # # Usage: # - # # If all library files are in the root directory... - # spec.require_paths = ['.'] - def require_paths=(val) - @require_paths = Array(val) - end ## - # The version of RubyGems used to create this gem. # - # Do not set this, it is set automatically when the gem is packaged. - - attr_accessor :rubygems_version - - ## - # A short summary of this gem's description. Displayed in `gem list -d`. # - # The #description should be more detailed than the summary. # # Usage: # - # spec.summary = "This is a small summary of my gem" - attr_reader :summary ## # Singular writer for #authors @@ -270,6 +283,148 @@ class Gem::Specification < Gem::BasicSpecification end ## # The platform this gem runs on. # # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT. @@ -327,104 +482,26 @@ class Gem::Specification < Gem::BasicSpecification end ## - # Files included in this gem. You cannot append to this accessor, you must - # assign to it. - # - # Only add files you can require to this list, not directories, etc. # - # Directories are automatically stripped from this list when building a gem, - # other non-files cause an error. # # Usage: # - # require 'rake' - # spec.files = FileList['lib/**/*.rb', - # 'bin/*', - # '[A-Z]*', - # 'test/**/*'].to_a - # - # # or without Rake... - # spec.files = Dir['lib/**/*.rb'] + Dir['bin/*'] - # spec.files += Dir['[A-Z]*'] + Dir['test/**/*'] - # spec.files.reject! { |fn| fn.include? "CVS" } - def files - # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) - # DOC: Why isn't it normal? Why does it suck? How can we fix this? - @files = [@files, - @test_files, - add_bindir(@executables), - @extra_rdoc_files, - @extensions, - ].flatten.compact.uniq.sort end - ###################################################################### - # :section: Optional gemspec attributes - - ## - # The path in the gem for executable scripts. Usually 'bin' - # - # Usage: - # - # spec.bindir = 'bin' - - attr_accessor :bindir - - ## - # The certificate chain used to sign this gem. See Gem::Security for - # details. - - attr_accessor :cert_chain - - ## - # A long description of this gem - # - # The description should be more detailed than the summary but not - # excessively long. A few paragraphs is a recommended length with no - # examples or formatting. - # - # Usage: - # - # spec.description = <<-EOF - # Rake is a Make-like program implemented in Ruby. Tasks and - # dependencies are specified in standard Ruby syntax. - # EOF - - attr_reader :description - - ## - # :category: Recommended gemspec attributes - # - # A contact email address (or addresses) for this gem - # - # Usage: - # - # spec.email = '[email protected]' - # spec.email = ['[email protected]', '[email protected]'] - - attr_accessor :email - - ## - # :category: Recommended gemspec attributes - # - # The URL of this gem's home page - # - # Usage: - # - # spec.homepage = 'https://.com/ruby/rake' - - attr_accessor :homepage - - ## - # A message that gets displayed after the gem is installed. - # - # Usage: - # - # spec.post_install_message = "Thanks for installing!" - - attr_accessor :post_install_message - ## # The version of Ruby required by this gem @@ -436,30 +513,16 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :required_rubygems_version ## - # The key used to sign this gem. See Gem::Security for details. - attr_accessor :signing_key ## - # :attr_accessor: metadata - # - # The metadata holds extra data for this gem that may be useful to other - # consumers and is settable by gem authors without requiring an update to - # the rubygems software. - # - # Metadata items have the following restrictions: - # - # * The metadata must be a Hash object - # * All keys and values must be Strings - # * Keys can be a maximum of 128 bytes and values can be a maximum of 1024 - # bytes - # * All strings must be UTF-8, no binary data is allowed - # - # To add metadata for the location of a issue tracker: - # - # s.metadata = { "issue_tracker" => "https://example/issues" } - attr_accessor :metadata ## # Adds a development dependency named +gem+ with +requirements+ to this @@ -473,7 +536,7 @@ class Gem::Specification < Gem::BasicSpecification # activated when a gem is required. def add_development_dependency(gem, *requirements) - add_dependency_with_type(gem, :development, *requirements) end ## @@ -484,7 +547,7 @@ class Gem::Specification < Gem::BasicSpecification # spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4' def add_runtime_dependency(gem, *requirements) - add_dependency_with_type(gem, :runtime, *requirements) end ## @@ -557,56 +620,6 @@ class Gem::Specification < Gem::BasicSpecification end ## - # :category: Recommended gemspec attributes - # - # The license for this gem. - # - # The license must be no more than 64 characters. - # - # This should just be the name of your license. The full text of the license - # should be inside of the gem (at the top level) when you build it. - # - # The simplest way, is to specify the standard SPDX ID - # https://spdx.org/licenses/ for the license. - # Ideally you should pick one that is OSI (Open Source Initiative) - # http://opensource.org/licenses/alphabetical approved. - # - # The most commonly used OSI approved licenses are MIT and Apache-2.0. - # also provides a license picker at http://choosealicense.com/. - # - # You should specify a license for your gem so that people know how they are - # permitted to use it, and any restrictions you're placing on it. Not - # specifying a license means all rights are reserved; others have no rights - # to use the code for any purpose. - # - # You can set multiple licenses with #licenses= - # - # Usage: - # spec.license = 'MIT' - - def license=o - self.licenses = [o] - end - - ## - # :category: Recommended gemspec attributes - # The license(s) for the library. - # - # Each license must be a short name, no more than 64 characters. - # - # This should just be the name of your license. The full - # text of the license should be inside of the gem when you build it. - # - # See #license= for more discussion - # - # Usage: - # spec.licenses = ['MIT', 'GPL-2.0'] - - def licenses= licenses - @licenses = Array licenses - end - - ## # Specifies the rdoc options to be used when generating API documentation. # # Usage: @@ -885,7 +898,7 @@ class Gem::Specification < Gem::BasicSpecification # properly sorted. def self.add_spec spec - warn "Gem::Specification.add_spec is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip # TODO: find all extraneous adds # puts # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }] @@ -910,7 +923,7 @@ class Gem::Specification < Gem::BasicSpecification # Adds multiple specs to the known specifications. def self.add_specs *specs - warn "Gem::Specification.add_specs is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy @@ -1023,6 +1036,13 @@ class Gem::Specification < Gem::BasicSpecification end ## # Find the best specification matching a +name+ and +requirements+. Raises # if the dependency doesn't resolve to a valid specification. @@ -1040,6 +1060,7 @@ class Gem::Specification < Gem::BasicSpecification def self.find_by_path path path = path.dup.freeze spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s| s.contains_requirable_file? path } || NOT_FOUND) spec.to_spec @@ -1051,7 +1072,9 @@ class Gem::Specification < Gem::BasicSpecification def self.find_inactive_by_path path stub = stubs.find { |s| - s.contains_requirable_file? path unless s.activated? } stub && stub.to_spec end @@ -1250,7 +1273,7 @@ class Gem::Specification < Gem::BasicSpecification # Removes +spec+ from the known specs. def self.remove_spec spec - warn "Gem::Specification.remove_spec is deprecated and will be removed in Rubygems 3.0" unless Gem::Deprecate.skip _all.delete spec stubs.delete_if { |s| s.full_name == spec.full_name } (@@stubs_by_name[spec.name] || []).delete_if { |s| s.full_name == spec.full_name } @@ -1520,7 +1543,7 @@ class Gem::Specification < Gem::BasicSpecification # +requirements+. Valid types are currently <tt>:runtime</tt> and # <tt>:development</tt>. - def add_dependency_with_type(dependency, type, *requirements) requirements = if requirements.empty? then Gem::Requirement.default else @@ -2026,6 +2049,20 @@ class Gem::Specification < Gem::BasicSpecification yaml_initialize coder.tag, coder.map end ## # Specification constructor. Assigns the default values to the attributes # and yields itself for further initialization. Optionally takes +name+ and @@ -2041,15 +2078,8 @@ class Gem::Specification < Gem::BasicSpecification @original_platform = nil @installed_by_version = nil - @@nil_attributes.each do |key| - instance_variable_set "@#{key}", nil - end - - @@non_nil_attributes.each do |key| - default = default_value(key) - value = Dupable[key] ? default.dup : default - instance_variable_set "@#{key}", value - end @new_platform = Gem::Platform::RUBY @@ -2746,29 +2776,7 @@ class Gem::Specification < Gem::BasicSpecification 'metadata must be a hash' end - metadata.keys.each do |k| - if !k.kind_of?(String) - raise Gem::InvalidSpecificationException, - 'metadata keys must be a String' - end - - if k.size > 128 - raise Gem::InvalidSpecificationException, - "metadata key too large (#{k.size} > 128)" - end - end - - metadata.values.each do |k| - if !k.kind_of?(String) - raise Gem::InvalidSpecificationException, - 'metadata values must be a String' - end - - if k.size > 1024 - raise Gem::InvalidSpecificationException, - "metadata value too large (#{k.size} > 1024)" - end - end licenses.each { |license| if license.length > 64 @@ -2822,7 +2830,7 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li # Warnings - %w[author email homepage summary].each do |attribute| value = self.send attribute warning "no #{attribute} specified" if value.nil? or value.empty? end @@ -2855,6 +2863,48 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li end end ## # Checks that dependencies use requirements as we recommend. Warnings are # issued when dependencies are open-ended or overly strict for semantic @@ -188,9 +188,8 @@ class Gem::StubSpecification < Gem::BasicSpecification def to_spec @spec ||= if @data then - Gem.loaded_specs.values.find { |spec| - spec.name == name and spec.version == version - } end @spec ||= Gem::Specification.load(loaded_from) @@ -25,6 +25,7 @@ unless Gem::Dependency.new('rdoc', '>= 3.10').matching_specs.empty? gem 'json' end require 'minitest/autorun' require 'rubygems/deprecate' @@ -222,6 +223,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase @orig_gem_vendor = ENV['GEM_VENDOR'] @orig_gem_spec_cache = ENV['GEM_SPEC_CACHE'] @orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS'] @orig_rubygems_host = ENV['RUBYGEMS_HOST'] ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k| ENV.delete k @@ -232,7 +234,12 @@ class Gem::TestCase < MiniTest::Unit::TestCase @current_dir = Dir.pwd @fetcher = nil - @ui = Gem::MockGemUi.new tmpdir = File.expand_path Dir.tmpdir tmpdir.untaint @@ -323,6 +330,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase Gem.loaded_specs.clear Gem.clear_default_specs Gem::Specification.unresolved_deps.clear Gem.configuration.verbose = true Gem.configuration.update_sources = true @@ -394,6 +402,7 @@ class Gem::TestCase < MiniTest::Unit::TestCase ENV['GEM_VENDOR'] = @orig_gem_vendor ENV['GEM_SPEC_CACHE'] = @orig_gem_spec_cache ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps ENV['RUBYGEMS_HOST'] = @orig_rubygems_host Gem.ruby = @orig_ruby if @orig_ruby @@ -7,11 +7,6 @@ require 'rubygems/util' -begin - require 'io/console' -rescue LoadError -end - ## # Module that defines the default UserInteraction. Any class including this # module will have access to the +ui+ method that returns the default UI. @@ -314,12 +309,21 @@ class Gem::StreamUI password end - if IO.method_defined?(:noecho) then - def _gets_noecho - @ins.noecho {@ins.gets} end - elsif Gem.win_platform? - def _gets_noecho require "Win32API" password = '' @@ -332,9 +336,7 @@ class Gem::StreamUI end end password - end - else - def _gets_noecho system "stty -echo" begin @ins.gets @@ -109,26 +109,15 @@ module Gem::Util ## # Enumerates the parents of +directory+. - def self.traverse_parents directory return enum_for __method__, directory unless block_given? here = File.expand_path directory - start = here - - Dir.chdir start - - begin - loop do - yield here - - Dir.chdir '..' - - return if Dir.pwd == here # toplevel - - here = Dir.pwd - end - ensure - Dir.chdir start end end @@ -170,7 +170,7 @@ class Gem::Version # True if the +version+ string matches RubyGems' requirements. def self.correct? version - version.to_s =~ ANCHORED_VERSION_PATTERN end ## @@ -241,7 +241,7 @@ class Gem::Version end def hash # :nodoc: - @version.hash end def init_with coder # :nodoc: @@ -335,7 +335,7 @@ class Gem::Version def <=> other return unless Gem::Version === other - return 0 if @version == other._version lhsegments = _segments rhsegments = other._segments @@ -360,6 +360,13 @@ class Gem::Version return 0 end protected def _version @@ -375,4 +382,11 @@ class Gem::Version /^\d+$/ =~ s ? s.to_i : s end.freeze end end @@ -58,7 +58,12 @@ module Gem::VersionOption add_option('-v', '--version VERSION', Gem::Requirement, "Specify version of gem to #{task}", *wrap) do |value, options| - options[:version] = value explicit_prerelease_set = !options[:explicit_prerelease].nil? options[:explicit_prerelease] = false unless explicit_prerelease_set |