aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/commands
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 06:52:18 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-29 06:52:18 +0000
commit9694bb8cac12969300692dac5a1cf7aa4e3a46cd (patch)
treec3cb423d701f7049ba9382de052e2a937cd1302d /lib/rubygems/commands
parent3f606b7063fc7a8b191556365ad343a314719a8d (diff)
downloadruby-9694bb8cac12969300692dac5a1cf7aa4e3a46cd.tar.gz
* lib/rubygems*: Updated to RubyGems 2.0
* test/rubygems*: ditto. * common.mk (prelude): Updated for RubyGems 2.0 source rearrangement. * tool/change_maker.rb: Allow invalid UTF-8 characters in source files. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/commands')
-rw-r--r--lib/rubygems/commands/build_command.rb28
-rw-r--r--lib/rubygems/commands/cert_command.rb256
-rw-r--r--lib/rubygems/commands/check_command.rb53
-rw-r--r--lib/rubygems/commands/cleanup_command.rb7
-rw-r--r--lib/rubygems/commands/contents_command.rb40
-rw-r--r--lib/rubygems/commands/dependency_command.rb11
-rw-r--r--lib/rubygems/commands/environment_command.rb21
-rw-r--r--lib/rubygems/commands/fetch_command.rb19
-rw-r--r--lib/rubygems/commands/generate_index_command.rb54
-rw-r--r--lib/rubygems/commands/help_command.rb2
-rw-r--r--lib/rubygems/commands/install_command.rb105
-rw-r--r--lib/rubygems/commands/list_command.rb10
-rw-r--r--lib/rubygems/commands/lock_command.rb2
-rw-r--r--lib/rubygems/commands/mirror_command.rb17
-rw-r--r--lib/rubygems/commands/outdated_command.rb9
-rw-r--r--lib/rubygems/commands/owner_command.rb18
-rw-r--r--lib/rubygems/commands/pristine_command.rb21
-rw-r--r--lib/rubygems/commands/push_command.rb13
-rw-r--r--lib/rubygems/commands/query_command.rb70
-rw-r--r--lib/rubygems/commands/rdoc_command.rb51
-rw-r--r--lib/rubygems/commands/search_command.rb22
-rw-r--r--lib/rubygems/commands/server_command.rb2
-rw-r--r--lib/rubygems/commands/setup_command.rb145
-rw-r--r--lib/rubygems/commands/sources_command.rb32
-rw-r--r--lib/rubygems/commands/specification_command.rb24
-rw-r--r--lib/rubygems/commands/uninstall_command.rb31
-rw-r--r--lib/rubygems/commands/unpack_command.rb10
-rw-r--r--lib/rubygems/commands/update_command.rb58
-rw-r--r--lib/rubygems/commands/yank_command.rb98
29 files changed, 776 insertions, 453 deletions
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb
index 36a6fe48f2..64563ed3db 100644
--- a/lib/rubygems/commands/build_command.rb
+++ b/lib/rubygems/commands/build_command.rb
@@ -1,5 +1,5 @@
require 'rubygems/command'
-require 'rubygems/builder'
+require 'rubygems/package'
class Gem::Commands::BuildCommand < Gem::Command
@@ -22,11 +22,11 @@ class Gem::Commands::BuildCommand < Gem::Command
def execute
gemspec = get_one_gem_name
- if File.exist? gemspec
- spec = load_gemspec gemspec
+ if File.exist? gemspec then
+ spec = Gem::Specification.load gemspec
if spec then
- Gem::Builder.new(spec).build options[:force]
+ Gem::Package.build spec, options[:force]
else
alert_error "Error loading gemspec. Aborting."
terminate_interaction 1
@@ -37,23 +37,5 @@ class Gem::Commands::BuildCommand < Gem::Command
end
end
- def load_gemspec filename
- if yaml?(filename)
- open(filename) do |f|
- begin
- Gem::Specification.from_yaml(f)
- rescue Gem::EndOfYAMLException
- nil
- end
- end
- else
- Gem::Specification.load(filename) # can return nil
- end
- end
-
- def yaml?(filename)
- line = open(filename) { |f| line = f.gets }
- result = line =~ %r{!ruby/object:Gem::Specification}
- result
- end
end
+
diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb
index b416b3863d..371ab403c6 100644
--- a/lib/rubygems/commands/cert_command.rb
+++ b/lib/rubygems/commands/cert_command.rb
@@ -4,82 +4,224 @@ require 'rubygems/security'
class Gem::Commands::CertCommand < Gem::Command
def initialize
- super 'cert', 'Manage RubyGems certificates and signing settings'
-
- add_option('-a', '--add CERT',
- 'Add a trusted certificate.') do |value, options|
- cert = OpenSSL::X509::Certificate.new(File.read(value))
- Gem::Security.add_trusted_cert(cert)
- say "Added '#{cert.subject.to_s}'"
- end
-
- add_option('-l', '--list',
- 'List trusted certificates.') do |value, options|
- glob_str = File::join(Gem::Security::OPT[:trust_dir], '*.pem')
- Dir::glob(glob_str) do |path|
- begin
- cert = OpenSSL::X509::Certificate.new(File.read(path))
- # this could probably be formatted more gracefully
- say cert.subject.to_s
- rescue OpenSSL::X509::CertificateError
- next
- end
+ super 'cert', 'Manage RubyGems certificates and signing settings',
+ :add => [], :remove => [], :list => [], :build => [], :sign => []
+
+ OptionParser.accept OpenSSL::X509::Certificate do |certificate|
+ begin
+ OpenSSL::X509::Certificate.new File.read certificate
+ rescue Errno::ENOENT
+ raise OptionParser::InvalidArgument, "#{certificate}: does not exist"
+ rescue OpenSSL::X509::CertificateError
+ raise OptionParser::InvalidArgument,
+ "#{certificate}: invalid X509 certificate"
end
end
- add_option('-r', '--remove STRING',
- 'Remove trusted certificates containing',
- 'STRING.') do |value, options|
- trust_dir = Gem::Security::OPT[:trust_dir]
- glob_str = File::join(trust_dir, '*.pem')
-
- Dir::glob(glob_str) do |path|
- begin
- cert = OpenSSL::X509::Certificate.new(File.read(path))
- if cert.subject.to_s.downcase.index(value)
- say "Removed '#{cert.subject.to_s}'"
- File.unlink(path)
- end
- rescue OpenSSL::X509::CertificateError
- next
- end
+ OptionParser.accept OpenSSL::PKey::RSA do |key_file|
+ begin
+ key = OpenSSL::PKey::RSA.new File.read key_file
+ rescue Errno::ENOENT
+ raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
+ rescue OpenSSL::PKey::RSAError
+ raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
end
+
+ raise OptionParser::InvalidArgument,
+ "#{key_file}: private key not found" unless key.private?
+
+ key
+ end
+
+ add_option('-a', '--add CERT', OpenSSL::X509::Certificate,
+ 'Add a trusted certificate.') do |cert, options|
+ options[:add] << cert
+ end
+
+ add_option('-l', '--list [FILTER]',
+ 'List trusted certificates where the',
+ 'subject contains FILTER') do |filter, options|
+ filter ||= ''
+
+ options[:list] << filter
+ end
+
+ add_option('-r', '--remove FILTER',
+ 'Remove trusted certificates where the',
+ 'subject contains FILTER') do |filter, options|
+ options[:remove] << filter
end
add_option('-b', '--build EMAIL_ADDR',
'Build private key and self-signed',
- 'certificate for EMAIL_ADDR.') do |value, options|
- vals = Gem::Security.build_self_signed_cert(value)
- FileUtils.chmod 0600, vals[:key_path]
- say "Public Cert: #{vals[:cert_path]}"
- say "Private Key: #{vals[:key_path]}"
- say "Don't forget to move the key file to somewhere private..."
+ 'certificate for EMAIL_ADDR') do |email_address, options|
+ options[:build] << email_address
end
- add_option('-C', '--certificate CERT',
- 'Certificate for --sign command.') do |value, options|
- cert = OpenSSL::X509::Certificate.new(File.read(value))
+ add_option('-C', '--certificate CERT', OpenSSL::X509::Certificate,
+ 'Signing certificate for --sign') do |cert, options|
options[:issuer_cert] = cert
end
- add_option('-K', '--private-key KEY',
- 'Private key for --sign command.') do |value, options|
- key = OpenSSL::PKey::RSA.new(File.read(value))
- options[:issuer_key] = key
+ add_option('-K', '--private-key KEY', OpenSSL::PKey::RSA,
+ 'Key for --sign or --build') do |key, options|
+ options[:key] = key
end
- add_option('-s', '--sign NEWCERT',
- 'Sign a certificate with my key and',
- 'certificate.') do |value, options|
- cert = OpenSSL::X509::Certificate.new(File.read(value))
- my_cert = options[:issuer_cert]
- my_key = options[:issuer_key]
- cert = Gem::Security.sign_cert(cert, my_key, my_cert)
- File.open(value, 'wb') { |file| file.write(cert.to_pem) }
+ add_option('-s', '--sign CERT',
+ 'Signs CERT with the key from -K',
+ 'and the certificate from -C') do |cert_file, options|
+ raise OptionParser::InvalidArgument, "#{cert_file}: does not exist" unless
+ File.file? cert_file
+
+ options[:sign] << cert_file
end
end
def execute
+ options[:add].each do |certificate|
+ Gem::Security.trust_dir.trust_cert certificate
+
+ say "Added '#{certificate.subject}'"
+ end
+
+ options[:remove].each do |filter|
+ certificates_matching filter do |certificate, path|
+ FileUtils.rm path
+ say "Removed '#{certificate.subject}'"
+ end
+ end
+
+ options[:list].each do |filter|
+ certificates_matching filter do |certificate, _|
+ # this could probably be formatted more gracefully
+ say certificate.subject.to_s
+ end
+ end
+
+ options[:build].each do |name|
+ build name
+ end
+
+ unless options[:sign].empty? then
+ load_default_cert unless options[:issuer_cert]
+ load_default_key unless options[:key]
+ end
+
+ options[:sign].each do |cert_file|
+ sign cert_file
+ end
+ end
+
+ def build name
+ key = options[:key] || Gem::Security.create_key
+
+ cert = Gem::Security.create_cert_email name, key
+
+ key_path = Gem::Security.write key, "gem-private_key.pem"
+ cert_path = Gem::Security.write cert, "gem-public_cert.pem"
+
+ say "Certificate: #{cert_path}"
+ say "Private Key: #{key_path}"
+ say "Don't forget to move the key file to somewhere private!"
+ end
+
+ def certificates_matching filter
+ return enum_for __method__, filter unless block_given?
+
+ Gem::Security.trusted_certificates.select do |certificate, _|
+ subject = certificate.subject.to_s
+ subject.downcase.index filter
+ end.sort_by do |certificate, _|
+ certificate.subject.to_a.map { |name, data,| [name, data] }
+ end.each do |certificate, path|
+ yield certificate, path
+ end
+ end
+
+ def description # :nodoc:
+ <<-EOF
+The cert command manages signing keys and certificates for creating signed
+gems. Your signing certificate and private key are typically stored in
+~/.gem/gem-public_cert.pem and ~/.gem/gem-private_key.pem respectively.
+
+To build a certificate for signing gems:
+
+ gem cert --build you@example
+
+If you already have an RSA key, or are creating a new certificate for an
+existing key:
+
+ gem cert --build you@example --private-key /path/to/key.pem
+
+If you wish to trust a certificate you can add it to the trust list with:
+
+ gem cert --add /path/to/cert.pem
+
+You can list trusted certificates with:
+
+ gem cert --list
+
+or:
+
+ gem cert --list cert_subject_substring
+
+If you wish to remove a previously trusted certificate:
+
+ gem cert --remove cert_subject_substring
+
+To sign another gem author's certificate:
+
+ gem cert --sign /path/to/other_cert.pem
+
+For further reading on signing gems see `ri Gem::Security`.
+ EOF
+ end
+
+ def load_default_cert
+ cert_file = File.join Gem.user_home, 'gem-public_cert.pem'
+ cert = File.read cert_file
+ options[:issuer_cert] = OpenSSL::X509::Certificate.new cert
+ rescue Errno::ENOENT
+ alert_error \
+ "--certificate not specified and ~/.gem/gem-public_cert.pem does not exist"
+
+ terminate_interaction 1
+ rescue OpenSSL::X509::CertificateError
+ alert_error \
+ "--certificate not specified and ~/.gem/gem-public_cert.pem is not valid"
+
+ terminate_interaction 1
+ end
+
+ def load_default_key
+ key_file = File.join Gem.user_home, 'gem-private_key.pem'
+ key = File.read key_file
+ options[:key] = OpenSSL::PKey::RSA.new key
+ rescue Errno::ENOENT
+ alert_error \
+ "--private-key not specified and ~/.gem/gem-private_key.pem does not exist"
+
+ terminate_interaction 1
+ rescue OpenSSL::PKey::RSAError
+ alert_error \
+ "--private-key not specified and ~/.gem/gem-private_key.pem is not valid"
+
+ terminate_interaction 1
+ end
+
+ def sign cert_file
+ cert = File.read cert_file
+ cert = OpenSSL::X509::Certificate.new cert
+
+ permissions = File.stat(cert_file).mode & 0777
+
+ issuer_cert = options[:issuer_cert]
+ issuer_key = options[:key]
+
+ cert = Gem::Security.sign cert, issuer_key, issuer_cert
+
+ Gem::Security.write cert, cert_file, permissions
end
end
diff --git a/lib/rubygems/commands/check_command.rb b/lib/rubygems/commands/check_command.rb
index 5a1bfd4f12..4bdfcfa645 100644
--- a/lib/rubygems/commands/check_command.rb
+++ b/lib/rubygems/commands/check_command.rb
@@ -8,13 +8,7 @@ class Gem::Commands::CheckCommand < Gem::Command
def initialize
super 'check', 'Check installed gems',
- :verify => false, :alien => false
-
- add_option( '--verify FILE',
- 'Verify gem file against its internal',
- 'checksum') do |value, options|
- options[:verify] = value
- end
+ :alien => true
add_option('-a', '--alien', "Report 'unmanaged' or rogue files in the",
"gem repository") do |value, options|
@@ -25,40 +19,21 @@ class Gem::Commands::CheckCommand < Gem::Command
end
def execute
- if options[:alien]
- say "Performing the 'alien' operation"
- say
- gems = get_all_gem_names rescue []
- Gem::Validator.new.alien(gems).sort.each do |key, val|
- unless val.empty? then
- say "#{key} has #{val.size} problems"
- val.each do |error_entry|
- say " #{error_entry.path}:"
- say " #{error_entry.problem}"
- end
- else
- say "#{key} is error-free" if Gem.configuration.verbose
+ say "Checking gems..."
+ say
+ gems = get_all_gem_names rescue []
+
+ Gem::Validator.new.alien(gems).sort.each do |key, val|
+ unless val.empty? then
+ say "#{key} has #{val.size} problems"
+ val.each do |error_entry|
+ say " #{error_entry.path}:"
+ say " #{error_entry.problem}"
end
- say
- end
- end
-
- if options[:verify]
- gem_name = options[:verify]
- unless gem_name
- alert_error "Must specify a .gem file with --verify NAME"
- return
- end
- unless File.exist?(gem_name)
- alert_error "Unknown file: #{gem_name}."
- return
- end
- say "Verifying gem: '#{gem_name}'"
- begin
- Gem::Validator.new.verify_gem_file(gem_name)
- rescue Exception
- alert_error "#{gem_name} is invalid."
+ else
+ say "#{key} is error-free" if Gem.configuration.verbose
end
+ say
end
end
diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb
index 124c4c203a..dc919e5570 100644
--- a/lib/rubygems/commands/cleanup_command.rb
+++ b/lib/rubygems/commands/cleanup_command.rb
@@ -26,6 +26,9 @@ class Gem::Commands::CleanupCommand < Gem::Command
<<-EOF
The cleanup command removes old gems from GEM_HOME. If an older version is
installed elsewhere in GEM_PATH the cleanup command won't touch it.
+
+Older gems that are required to satisify the dependencies of gems
+are not removed.
EOF
end
@@ -56,6 +59,8 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it.
primary_gems[spec.name].version != spec.version
}
+ full = Gem::DependencyList.from_specs
+
deplist = Gem::DependencyList.new
gems_to_cleanup.uniq.each do |spec| deplist.add spec end
@@ -64,6 +69,8 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it.
original_path = Gem.path
deps.each do |spec|
+ next unless full.ok_to_remove?(spec.full_name)
+
if options[:dryrun] then
say "Dry Run Mode: Would uninstall #{spec.full_name}"
else
diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb
index e483484615..404c6745bd 100644
--- a/lib/rubygems/commands/contents_command.rb
+++ b/lib/rubygems/commands/contents_command.rb
@@ -1,3 +1,4 @@
+require 'English'
require 'rubygems/command'
require 'rubygems/version_option'
@@ -80,19 +81,36 @@ class Gem::Commands::ContentsCommand < Gem::Command
terminate_interaction 1 if gem_names.length == 1
end
- gem_path = spec.full_gem_path
- extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
- glob = "#{gem_path}#{extra}/**/*"
- files = Dir[glob]
-
- gem_path = File.join gem_path, '' # add trailing / if missing
-
- files.sort.each do |file|
- next if File.directory? file
+ if spec.default_gem?
+ files = spec.files.map do |file|
+ case file
+ when /\A#{spec.bindir}\//
+ [Gem::ConfigMap[:bindir], $POSTMATCH]
+ when /\.so\z/
+ [Gem::ConfigMap[:archdir], file]
+ else
+ [Gem::ConfigMap[:rubylibdir], file]
+ end
+ end
+ else
+ gem_path = spec.full_gem_path
+ extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only]
+ glob = "#{gem_path}#{extra}/**/*"
+ prefix_re = /#{Regexp.escape(gem_path)}\//
+ files = Dir[glob].map do |file|
+ [gem_path, file.sub(prefix_re, "")]
+ end
+ end
- file = file.sub gem_path, '' unless options[:prefix]
+ files.sort.each do |prefix, basename|
+ absolute_path = File.join(prefix, basename)
+ next if File.directory? absolute_path
- say file
+ if options[:prefix]
+ say absolute_path
+ else
+ say basename
+ end
end
end
end
diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb
index 67cbbc1d5e..4690b13a94 100644
--- a/lib/rubygems/commands/dependency_command.rb
+++ b/lib/rubygems/commands/dependency_command.rb
@@ -71,14 +71,9 @@ class Gem::Commands::DependencyCommand < Gem::Command
if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher
- # REFACTOR: fetcher.find_specs_matching => specs
- specs_and_sources = fetcher.find_matching(dependency,
- dependency.specific?, true,
- dependency.prerelease?)
-
- specs.concat specs_and_sources.map { |spec_tuple, source_uri|
- fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
- }
+ ss, _ = fetcher.spec_for_dependency dependency
+
+ ss.each { |s,o| specs << s }
end
if specs.empty? then
diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb
index 9585c71250..40e71cf094 100644
--- a/lib/rubygems/commands/environment_command.rb
+++ b/lib/rubygems/commands/environment_command.rb
@@ -24,33 +24,38 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
The RubyGems environment can be controlled through command line arguments,
gemrc files, environment variables and built-in defaults.
-Command line argument defaults and some RubyGems defaults can be set in
-~/.gemrc file for individual users and a /etc/gemrc for all users. A gemrc
-is a YAML file with the following YAML keys:
+Command line argument defaults and some RubyGems defaults can be set in a
+~/.gemrc file for individual users and a /etc/gemrc for all users. These
+files are YAML files with the following YAML keys:
:sources: A YAML array of remote gem repositories to install gems from
- :verbose: Verbosity of the gem command. false, true, and :really are the
+ :verbose: Verbosity of the gem command. false, true, and :really are the
levels
:update_sources: Enable/disable automatic updating of repository metadata
:backtrace: Print backtrace when RubyGems encounters an error
:gempath: The paths in which to look for gems
- gem_command: A string containing arguments for the specified gem command
+ :disable_default_gem_server: Force specification of gem server host on push
+ <gem_command>: A string containing arguments for the specified gem command
Example:
:verbose: false
install: --no-wrappers
update: --no-wrappers
+ :disable_default_gem_server: true
RubyGems' default local repository can be overridden with the GEM_PATH and
-GEM_HOME environment variables. GEM_HOME sets the default repository to
-install into. GEM_PATH allows multiple local repositories to be searched for
+GEM_HOME environment variables. GEM_HOME sets the default repository to
+install into. GEM_PATH allows multiple local repositories to be searched for
gems.
If you are behind a proxy server, RubyGems uses the HTTP_PROXY,
HTTP_PROXY_USER and HTTP_PROXY_PASS environment variables to discover the
proxy server.
+If you would like to push gems to a private gem server the RUBYGEMS_HOST
+environment variable can be set to the URI for that server.
+
If you are packaging RubyGems all of RubyGems' defaults are in
lib/rubygems/defaults.rb. You may override these in
lib/rubygems/defaults/operating_system.rb
@@ -74,7 +79,7 @@ lib/rubygems/defaults/operating_system.rb
when /^gempath/, /^path/, /^GEM_PATH/ then
out << Gem.path.join(File::PATH_SEPARATOR)
when /^remotesources/ then
- out << Gem.sources.join("\n")
+ out << Gem.sources.to_a.join("\n")
when /^platform/ then
out << Gem.platforms.join(File::PATH_SEPARATOR)
when nil then
diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb
index e7c9cc9525..ec021359b6 100644
--- a/lib/rubygems/commands/fetch_command.rb
+++ b/lib/rubygems/commands/fetch_command.rb
@@ -34,7 +34,6 @@ class Gem::Commands::FetchCommand < Gem::Command
def execute
version = options[:version] || Gem::Requirement.default
- all = Gem::Requirement.default != version
platform = Gem.platforms.last
gem_names = get_all_gem_names
@@ -43,32 +42,20 @@ class Gem::Commands::FetchCommand < Gem::Command
dep = Gem::Dependency.new gem_name, version
dep.prerelease = options[:prerelease]
- specs_and_sources, errors =
- Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true,
- dep.prerelease?)
-
+ specs_and_sources, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
if platform then
filtered = specs_and_sources.select { |s,| s.platform == platform }
specs_and_sources = filtered unless filtered.empty?
end
- spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
+ spec, source = specs_and_sources.sort_by { |s,| s.version }.first
if spec.nil? then
show_lookup_failure gem_name, version, errors, options[:domain]
next
end
- file = "#{spec.full_name}.gem"
- remote_path = URI.parse(source_uri) + "gems/#{file}"
-
- fetch = Gem::RemoteFetcher.fetcher
-
- gem = fetch.fetch_path remote_path.to_s
-
- File.open file, "wb" do |f|
- f.write gem
- end
+ source.download spec
say "Downloaded #{spec.full_name}"
end
diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb
index d4b4790649..a7db013caf 100644
--- a/lib/rubygems/commands/generate_index_command.rb
+++ b/lib/rubygems/commands/generate_index_command.rb
@@ -11,29 +11,16 @@ class Gem::Commands::GenerateIndexCommand < Gem::Command
def initialize
super 'generate_index',
'Generates the index files for a gem server directory',
- :directory => '.', :build_legacy => true, :build_modern => true
+ :directory => '.', :build_modern => true
add_option '-d', '--directory=DIRNAME',
'repository base dir containing gems subdir' do |dir, options|
options[:directory] = File.expand_path dir
end
- add_option '--[no-]legacy',
- 'Generate Marshal.4.8' do |value, options|
- unless options[:build_modern] or value then
- raise OptionParser::InvalidOption, 'no indicies will be built'
- end
-
- options[:build_legacy] = value
- end
-
add_option '--[no-]modern',
- 'Generate indexes for RubyGems newer',
- 'than 1.2.0' do |value, options|
- unless options[:build_legacy] or value then
- raise OptionParser::InvalidOption, 'no indicies will be built'
- end
-
+ 'Generate indexes for RubyGems',
+ '(always true)' do |value, options|
options[:build_modern] = value
end
@@ -42,27 +29,10 @@ class Gem::Commands::GenerateIndexCommand < Gem::Command
'since the last update' do |value, options|
options[:update] = value
end
-
- add_option :RSS, '--rss-gems-host=GEM_HOST',
- 'Host name where gems are served from,',
- 'used for GUID and enclosure values' do |value, options|
- options[:rss_gems_host] = value
- end
-
- add_option :RSS, '--rss-host=HOST',
- 'Host name for more gems information,',
- 'used for RSS feed link' do |value, options|
- options[:rss_host] = value
- end
-
- add_option :RSS, '--rss-title=TITLE',
- 'Set title for RSS feed' do |value, options|
- options[:rss_title] = value
- end
end
def defaults_str # :nodoc:
- "--directory . --legacy --modern"
+ "--directory . --modern"
end
def description # :nodoc:
@@ -85,25 +55,15 @@ When done, it will generate a set of files like this:
prerelease_specs.<version>.gz # prerelease specs index
quick/Marshal.<version>/<gemname>.gemspec.rz # Marshal quick index file
- # these files support legacy RubyGems
- Marshal.<version>
- Marshal.<version>.Z # Marshal full index
-
-The .Z and .rz extension files are compressed with the inflate algorithm.
+The .rz extension files are compressed with the inflate algorithm.
The Marshal version number comes from ruby's Marshal::MAJOR_VERSION and
Marshal::MINOR_VERSION constants. It is used to ensure compatibility.
-
-If --rss-host and --rss-gem-host are given an RSS feed will be generated at
-index.rss containing gems released in the last two days.
EOF
end
def execute
- if options[:update] and
- (options[:rss_host] or options[:rss_gems_host]) then
- alert_error '--update not compatible with RSS generation'
- terminate_interaction 1
- end
+ # This is always true becasue it's the only way now.
+ options[:build_modern] = true
if not File.exist?(options[:directory]) or
not File.directory?(options[:directory]) then
diff --git a/lib/rubygems/commands/help_command.rb b/lib/rubygems/commands/help_command.rb
index 20b52429b2..8e3d97edd3 100644
--- a/lib/rubygems/commands/help_command.rb
+++ b/lib/rubygems/commands/help_command.rb
@@ -37,7 +37,7 @@ Some examples of 'gem' usage.
* Create a gem:
- See http://rubygems.rubyforge.org/wiki/wiki.pl?CreateAGemInTenMinutes
+ See http://guides.rubygems.org/make-your-own-gem/
* See information about RubyGems:
diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb
index 003ba8601c..883526c2a5 100644
--- a/lib/rubygems/commands/install_command.rb
+++ b/lib/rubygems/commands/install_command.rb
@@ -1,10 +1,11 @@
require 'rubygems/command'
-require 'rubygems/doc_manager'
require 'rubygems/install_update_options'
require 'rubygems/dependency_installer'
require 'rubygems/local_remote_options'
require 'rubygems/validator'
require 'rubygems/version_option'
+require 'rubygems/install_message' # must come before rdoc for messaging
+require 'rubygems/rdoc'
##
# Gem installer command line tool
@@ -13,14 +14,14 @@ require 'rubygems/version_option'
class Gem::Commands::InstallCommand < Gem::Command
+ attr_reader :installed_specs # :nodoc:
+
include Gem::VersionOption
include Gem::LocalRemoteOptions
include Gem::InstallUpdateOptions
def initialize
defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({
- :generate_rdoc => true,
- :generate_ri => true,
:format_executable => false,
:version => Gem::Requirement.default,
})
@@ -32,6 +33,14 @@ class Gem::Commands::InstallCommand < Gem::Command
add_platform_option
add_version_option
add_prerelease_option "to be installed. (Only for listed gems)"
+
+ add_option(:"Install/Update", '-g', '--file FILE',
+ 'Read from a gem dependencies API file and',
+ 'install the listed gems') do |v,o|
+ o[:gemdeps] = v
+ end
+
+ @installed_specs = nil
end
def arguments # :nodoc:
@@ -39,7 +48,7 @@ class Gem::Commands::InstallCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--both --version '#{Gem::Requirement.default}' --rdoc --ri --no-force\n" \
+ "--both --version '#{Gem::Requirement.default}' --document --no-force\n" \
"--install-dir #{Gem.dir}"
end
@@ -100,31 +109,73 @@ to write the specification by hand. For example:
"#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags"
end
+ def install_from_gemdeps(gf)
+ require 'rubygems/request_set'
+ rs = Gem::RequestSet.new
+ rs.load_gemdeps gf
+
+ rs.resolve
+
+ specs = rs.install options do |req, inst|
+ s = req.full_spec
+
+ if inst
+ say "Installing #{s.name} (#{s.version})"
+ else
+ say "Using #{s.name} (#{s.version})"
+ end
+ end
+
+ @installed_specs = specs
+
+ raise Gem::SystemExitException, 0
+ end
+
def execute
- if options[:include_dependencies] then
- alert "`gem install -y` is now default and will be removed"
- alert "use --ignore-dependencies to install only the gems you list"
+ if gf = options[:gemdeps] then
+ install_from_gemdeps gf
+ return
end
- installed_gems = []
+ @installed_specs = []
ENV.delete 'GEM_PATH' if options[:install_dir].nil? and RUBY_VERSION > '1.9'
+ if options[:install_dir] and options[:user_install]
+ alert_error "Use --install-dir or --user-install but not both"
+ terminate_interaction 1
+ end
+
exit_code = 0
- get_all_gem_names.each do |gem_name|
+ if options[:version] != Gem::Requirement.default &&
+ get_all_gem_names.size > 1 then
+ alert_error "Can't use --version w/ multiple gems. Use name:ver instead."
+ terminate_interaction 1
+ end
+
+
+ get_all_gem_names_and_versions.each do |gem_name, gem_version|
+ gem_version ||= options[:version]
+
begin
next if options[:conservative] and
- not Gem::Dependency.new(gem_name, options[:version]).matching_specs.empty?
+ not Gem::Dependency.new(gem_name, gem_version).matching_specs.empty?
inst = Gem::DependencyInstaller.new options
- inst.install gem_name, options[:version]
+ inst.install gem_name, Gem::Requirement.create(gem_version)
- inst.installed_gems.each do |spec|
- say "Successfully installed #{spec.full_name}"
- end
+ @installed_specs.push(*inst.installed_gems)
- installed_gems.push(*inst.installed_gems)
+ next unless errs = inst.errors
+
+ errs.each do |x|
+ next unless Gem::SourceFetchProblem === x
+
+ msg = "Unable to pull data from '#{x.source.uri}': #{x.error.message}"
+
+ alert_warning msg
+ end
rescue Gem::InstallError => e
alert_error "Error installing #{gem_name}:\n\t#{e.message}"
exit_code |= 1
@@ -135,27 +186,9 @@ to write the specification by hand. For example:
end
end
- unless installed_gems.empty? then
- gems = installed_gems.length == 1 ? 'gem' : 'gems'
- say "#{installed_gems.length} #{gems} installed"
-
- # NOTE: *All* of the RI documents must be generated first. For some
- # reason, RI docs cannot be generated after any RDoc documents are
- # generated.
-
- if options[:generate_ri] then
- installed_gems.each do |gem|
- Gem::DocManager.new(gem, options[:rdoc_args]).generate_ri
- end
-
- Gem::DocManager.update_ri_cache
- end
-
- if options[:generate_rdoc] then
- installed_gems.each do |gem|
- Gem::DocManager.new(gem, options[:rdoc_args]).generate_rdoc
- end
- end
+ unless @installed_specs.empty? then
+ gems = @installed_specs.length == 1 ? 'gem' : 'gems'
+ say "#{@installed_specs.length} #{gems} installed"
end
raise Gem::SystemExitException, exit_code
diff --git a/lib/rubygems/commands/list_command.rb b/lib/rubygems/commands/list_command.rb
index f3e5da9551..d9b7a9535e 100644
--- a/lib/rubygems/commands/list_command.rb
+++ b/lib/rubygems/commands/list_command.rb
@@ -7,8 +7,9 @@ require 'rubygems/commands/query_command'
class Gem::Commands::ListCommand < Gem::Commands::QueryCommand
- def initialize
- super 'list', 'Display gems whose name starts with STRING'
+ def initialize(name = 'list',
+ summary = 'Display gems whose name starts with STRING')
+ super name, summary
remove_option('--name-matches')
end
@@ -26,8 +27,9 @@ class Gem::Commands::ListCommand < Gem::Commands::QueryCommand
end
def execute
- string = get_one_optional_argument || ''
- options[:name] = /^#{string}/i
+ name = get_one_optional_argument || ''
+ options[:name] = /^#{name}/i
+
super
end
diff --git a/lib/rubygems/commands/lock_command.rb b/lib/rubygems/commands/lock_command.rb
index a6dca320ef..6b4b25a281 100644
--- a/lib/rubygems/commands/lock_command.rb
+++ b/lib/rubygems/commands/lock_command.rb
@@ -30,7 +30,7 @@ generated.
Example:
- gemlock rails-1.0.0 > lockdown.rb
+ gem lock rails-1.0.0 > lockdown.rb
will produce in lockdown.rb:
diff --git a/lib/rubygems/commands/mirror_command.rb b/lib/rubygems/commands/mirror_command.rb
new file mode 100644
index 0000000000..0f98077cbd
--- /dev/null
+++ b/lib/rubygems/commands/mirror_command.rb
@@ -0,0 +1,17 @@
+require 'rubygems/command'
+
+class Gem::Commands::MirrorCommand < Gem::Command
+ def initialize
+ super('mirror', 'Mirror all gem files (requires rubygems-mirror)')
+ begin
+ Gem::Specification.find_by_name('rubygems-mirror').activate
+ rescue Gem::LoadError
+ # no-op
+ end
+ end
+
+ def execute
+ alert_error "Install the rubygems-mirror gem for the mirror command"
+ end
+
+end
diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb
index ea6b9f0abf..887faab0a2 100644
--- a/lib/rubygems/commands/outdated_command.rb
+++ b/lib/rubygems/commands/outdated_command.rb
@@ -19,12 +19,15 @@ class Gem::Commands::OutdatedCommand < Gem::Command
Gem::Specification.outdated.sort.each do |name|
local = Gem::Specification.find_all_by_name(name).max
dep = Gem::Dependency.new local.name, ">= #{local.version}"
- remotes = Gem::SpecFetcher.fetcher.fetch dep
+ remotes, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
next if remotes.empty?
- remote = remotes.last.first
- say "#{local.name} (#{local.version} < #{remote.version})"
+ remotes.sort! { |a,b| a[0].version <=> b[0].version }
+
+ highest = remotes.last.first
+
+ say "#{local.name} (#{local.version} < #{highest.version})"
end
end
end
diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb
index 6ebf9aa1aa..92674132e8 100644
--- a/lib/rubygems/commands/owner_command.rb
+++ b/lib/rubygems/commands/owner_command.rb
@@ -14,6 +14,10 @@ class Gem::Commands::OwnerCommand < Gem::Command
"GEM gem to manage owners for"
end
+ def usage # :nodoc:
+ "#{program_name} GEM"
+ end
+
def initialize
super 'owner', description
add_proxy_option
@@ -63,12 +67,16 @@ class Gem::Commands::OwnerCommand < Gem::Command
def manage_owners method, name, owners
owners.each do |owner|
- response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
- request.set_form_data 'email' => owner
- request.add_field "Authorization", api_key
+ begin
+ response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
+ request.set_form_data 'email' => owner
+ request.add_field "Authorization", api_key
+ end
+
+ with_response response
+ rescue
+ # ignore
end
-
- with_response response
end
end
diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb
index e3771b7212..f7eb9014ea 100644
--- a/lib/rubygems/commands/pristine_command.rb
+++ b/lib/rubygems/commands/pristine_command.rb
@@ -1,5 +1,5 @@
require 'rubygems/command'
-require 'rubygems/format'
+require 'rubygems/package'
require 'rubygems/installer'
require 'rubygems/version_option'
@@ -24,6 +24,11 @@ class Gem::Commands::PristineCommand < Gem::Command
options[:extensions] = value
end
+ add_option('--only-executables',
+ 'Only restore executables') do |value, options|
+ options[:only_executables] = value
+ end
+
add_version_option('restore to', 'pristine condition')
end
@@ -78,6 +83,11 @@ extensions.
say "Restoring gems to pristine condition..."
specs.each do |spec|
+ if spec.default_gem?
+ say "Skipped #{spec.full_name}, it is a default gem"
+ next
+ end
+
unless spec.extensions.empty? or options[:extensions] then
say "Skipped #{spec.full_name}, it needs to compile an extension"
next
@@ -101,8 +111,13 @@ extensions.
:wrappers => true,
:force => true,
:install_dir => spec.base_dir,
- :env_shebang => installer_env_shebang)
- installer.install
+ :env_shebang => installer_env_shebang,
+ :build_args => spec.build_args)
+ if options[:only_executables] then
+ installer.generate_bin
+ else
+ installer.install
+ end
say "Restored #{spec.full_name}"
end
diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb
index a7663edf4a..0667b47dc1 100644
--- a/lib/rubygems/commands/push_command.rb
+++ b/lib/rubygems/commands/push_command.rb
@@ -1,6 +1,7 @@
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
+require 'rubygems/package'
class Gem::Commands::PushCommand < Gem::Command
include Gem::LocalRemoteOptions
@@ -39,13 +40,23 @@ class Gem::Commands::PushCommand < Gem::Command
def send_gem name
args = [:post, "api/v1/gems"]
- args << options[:host] if options[:host]
if Gem.latest_rubygems_version < Gem::Version.new(Gem::VERSION) then
alert_error "Using beta/unreleased version of rubygems. Not pushing."
terminate_interaction 1
end
+ host = options[:host]
+ unless host
+ if gem_data = Gem::Package.new(name) then
+ host = gem_data.spec.metadata['default_gem_server']
+ end
+ end
+
+ args << host if host
+
+ say "Pushing gem to #{host || Gem.host}..."
+
response = rubygems_api_request(*args) do |request|
request.body = Gem.read_binary name
request.add_field "Content-Length", request.body.size
diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb
index 725da8787b..b6c910d449 100644
--- a/lib/rubygems/commands/query_command.rb
+++ b/lib/rubygems/commands/query_command.rb
@@ -21,6 +21,10 @@ class Gem::Commands::QueryCommand < Gem::Command
options[:installed] = value
end
+ add_option('-I', 'Equivalent to --no-installed') do |value, options|
+ options[:installed] = false
+ end
+
add_version_option command, "for use with --installed"
add_option('-n', '--name-matches REGEXP',
@@ -80,6 +84,7 @@ class Gem::Commands::QueryCommand < Gem::Command
req = Gem::Requirement.default
# TODO: deprecate for real
dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
+ dep.prerelease = prerelease
if local? then
if prerelease and not both? then
@@ -97,7 +102,7 @@ class Gem::Commands::QueryCommand < Gem::Command
}
spec_tuples = specs.map do |spec|
- [[spec.name, spec.version, spec.original_platform, spec], :local]
+ [spec.name_tuple, spec]
end
output_query_results spec_tuples
@@ -110,13 +115,27 @@ class Gem::Commands::QueryCommand < Gem::Command
say
end
- all = options[:all]
-
fetcher = Gem::SpecFetcher.fetcher
- spec_tuples = fetcher.find_matching dep, all, false, prerelease
- spec_tuples += fetcher.find_matching dep, false, false, true if
- prerelease and all
+ type = if options[:all]
+ if options[:prerelease]
+ :complete
+ else
+ :released
+ end
+ elsif options[:prerelease]
+ :prerelease
+ else
+ :latest
+ end
+
+ if options[:name].source.empty?
+ spec_tuples = fetcher.detect(type) { true }
+ else
+ spec_tuples = fetcher.detect(type) do |gem_name, ver, plat|
+ options[:name] === gem_name
+ end
+ end
output_query_results spec_tuples
end
@@ -135,32 +154,30 @@ class Gem::Commands::QueryCommand < Gem::Command
output = []
versions = Hash.new { |h,name| h[name] = [] }
- spec_tuples.each do |spec_tuple, source_uri|
- versions[spec_tuple.first] << [spec_tuple, source_uri]
+ spec_tuples.each do |spec_tuple, source|
+ versions[spec_tuple.name] << [spec_tuple, source]
end
- versions = versions.sort_by do |(name,_),_|
- name.downcase
+ versions = versions.sort_by do |(n,_),_|
+ n.downcase
end
versions.each do |gem_name, matching_tuples|
- matching_tuples = matching_tuples.sort_by do |(_, version,_),_|
- version
- end.reverse
+ matching_tuples = matching_tuples.sort_by { |n,_| n.version }.reverse
platforms = Hash.new { |h,version| h[version] = [] }
- matching_tuples.map do |(_, version, platform,_),_|
- platforms[version] << platform if platform
+ matching_tuples.map do |n,_|
+ platforms[n.version] << n.platform if n.platform
end
seen = {}
- matching_tuples.delete_if do |(_, version,_),_|
- if seen[version] then
+ matching_tuples.delete_if do |n,_|
+ if seen[n.version] then
true
else
- seen[version] = true
+ seen[n.version] = true
false
end
end
@@ -169,7 +186,7 @@ class Gem::Commands::QueryCommand < Gem::Command
if options[:versions] then
list = if platforms.empty? or options[:details] then
- matching_tuples.map { |(_, version,_),_| version }.uniq
+ matching_tuples.map { |n,_| n.version }.uniq
else
platforms.sort.reverse.map do |version, pls|
if pls == [Gem::Platform::RUBY] then
@@ -188,12 +205,11 @@ class Gem::Commands::QueryCommand < Gem::Command
if options[:details] then
detail_tuple = matching_tuples.first
- spec = if detail_tuple.first.length == 4 then
- detail_tuple.first.last
- else
- uri = URI.parse detail_tuple.last
- Gem::SpecFetcher.fetcher.fetch_spec detail_tuple.first, uri
- end
+ spec = detail_tuple.last
+
+ unless spec.kind_of? Gem::Specification
+ spec = spec.fetch_spec detail_tuple.first
+ end
entry << "\n"
@@ -243,9 +259,9 @@ class Gem::Commands::QueryCommand < Gem::Command
entry << "\n" << " Installed at: #{loaded_from}"
else
label = 'Installed at'
- matching_tuples.each do |(_,version,_,s),|
+ matching_tuples.each do |n,s|
loaded_from = File.dirname File.dirname(s.loaded_from)
- entry << "\n" << " #{label} (#{version}): #{loaded_from}"
+ entry << "\n" << " #{label} (#{n.version}): #{loaded_from}"
label = ' ' * label.length
end
end
diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb
index ea0f3ad592..9bb07245cd 100644
--- a/lib/rubygems/commands/rdoc_command.rb
+++ b/lib/rubygems/commands/rdoc_command.rb
@@ -1,6 +1,6 @@
require 'rubygems/command'
require 'rubygems/version_option'
-require 'rubygems/doc_manager'
+require 'rubygems/rdoc'
class Gem::Commands::RdocCommand < Gem::Command
include Gem::VersionOption
@@ -8,7 +8,7 @@ class Gem::Commands::RdocCommand < Gem::Command
def initialize
super 'rdoc', 'Generates RDoc for pre-installed gems',
:version => Gem::Requirement.default,
- :include_rdoc => true, :include_ri => true, :overwrite => false
+ :include_rdoc => false, :include_ri => true, :overwrite => false
add_option('--all',
'Generate RDoc/RI documentation for all',
@@ -39,7 +39,7 @@ class Gem::Commands::RdocCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--version '#{Gem::Requirement.default}' --rdoc --ri --no-overwrite"
+ "--version '#{Gem::Requirement.default}' --ri --no-overwrite"
end
def description # :nodoc:
@@ -54,37 +54,32 @@ The rdoc command builds RDoc and RI documentation for installed gems. Use
end
def execute
- if options[:all] then
- specs = Gem::SourceIndex.from_installed_gems.collect { |name, spec|
- spec
- }
- else
- gem_name = get_one_gem_name
- dep = Gem::Dependency.new gem_name, options[:version]
- specs = Gem::SourceIndex.from_installed_gems.search dep
+ specs = if options[:all] then
+ Gem::Specification.to_a
+ else
+ get_all_gem_names.map do |name|
+ Gem::Specification.find_by_name name, options[:version]
+ end.flatten.uniq
+ end
+
+ if specs.empty? then
+ alert_error 'No matching gems found'
+ terminate_interaction 1
end
- if specs.empty?
- raise "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}"
- end
+ specs.each do |spec|
+ doc = Gem::RDoc.new spec, options[:include_rdoc], options[:include_ri]
- if options[:include_ri]
- specs.sort.each do |spec|
- doc = Gem::DocManager.new(spec)
- doc.generate_ri if options[:overwrite] || !doc.ri_installed?
- end
+ doc.force = options[:overwrite]
- Gem::DocManager.update_ri_cache
- end
-
- if options[:include_rdoc]
- specs.sort.each do |spec|
- doc = Gem::DocManager.new(spec)
- doc.generate_rdoc if options[:overwrite] || !doc.rdoc_installed?
+ begin
+ doc.generate
+ rescue Errno::ENOENT => e
+ e.message =~ / - /
+ alert_error "Unable to document #{spec.full_name}, #{$'} is missing, skipping"
+ terminate_interaction 1 if specs.length == 1
end
end
-
- true
end
end
diff --git a/lib/rubygems/commands/search_command.rb b/lib/rubygems/commands/search_command.rb
index 52e96fd1ef..92d4b3672e 100644
--- a/lib/rubygems/commands/search_command.rb
+++ b/lib/rubygems/commands/search_command.rb
@@ -1,30 +1,16 @@
require 'rubygems/command'
-require 'rubygems/commands/query_command'
+require 'rubygems/commands/list_command'
-class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand
+class Gem::Commands::SearchCommand < Gem::Commands::ListCommand
def initialize
super 'search', 'Display all gems whose name contains STRING'
- remove_option '--name-matches'
- end
-
- def arguments # :nodoc:
- "STRING fragment of gem name to search for"
+ @defaults[:domain] = :remote
end
def defaults_str # :nodoc:
- "--local --no-details"
- end
-
- def usage # :nodoc:
- "#{program_name} [STRING]"
- end
-
- def execute
- string = get_one_optional_argument
- options[:name] = /#{string}/i
- super
+ "--remote --no-details"
end
end
diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb
index b65d48c4fc..4796ce2ad6 100644
--- a/lib/rubygems/commands/server_command.rb
+++ b/lib/rubygems/commands/server_command.rb
@@ -78,7 +78,7 @@ You can set up a shortcut to gem server documentation using the URL:
end
def execute
- options[:gemdir] << Gem.dir if options[:gemdir].empty?
+ options[:gemdir] = Gem.path if options[:gemdir].empty?
Gem::Server.run options
end
diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb
index 508ff84a0f..2f1cf0091d 100644
--- a/lib/rubygems/commands/setup_command.rb
+++ b/lib/rubygems/commands/setup_command.rb
@@ -5,14 +5,22 @@ require 'rubygems/command'
# RubyGems checkout or tarball.
class Gem::Commands::SetupCommand < Gem::Command
+ HISTORY_HEADER = /^===\s*[\d.]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
+ VERSION_MATCHER = /^===\s*([\d.]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/
def initialize
require 'tmpdir'
super 'setup', 'Install RubyGems',
- :format_executable => true, :rdoc => true, :ri => true,
+ :format_executable => true, :document => %w[ri],
:site_or_vendor => :sitelibdir,
- :destdir => '', :prefix => ''
+ :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
add_option '--prefix=PREFIX',
'Prefix path for installing RubyGems',
@@ -37,14 +45,37 @@ class Gem::Commands::SetupCommand < Gem::Command
options[:format_executable] = value
end
+ add_option '--[no-]document [TYPES]', Array,
+ 'Generate documentation for RubyGems.',
+ 'List the documentation types you wish to',
+ 'generate. For example: rdoc,ri' do |value, options|
+ options[:document] = case value
+ when nil then %w[rdoc ri]
+ when false then []
+ else value
+ end
+ end
+
add_option '--[no-]rdoc',
'Generate RDoc documentation for RubyGems' do |value, options|
- options[:rdoc] = value
+ if value then
+ options[:document] << 'rdoc'
+ else
+ options[:document].delete 'rdoc'
+ end
+
+ options[:document].uniq!
end
add_option '--[no-]ri',
'Generate RI documentation for RubyGems' do |value, options|
- options[:ri] = value
+ if value then
+ options[:document] << 'ri'
+ else
+ options[:document].delete 'ri'
+ end
+
+ options[:document].uniq!
end
end
@@ -58,7 +89,7 @@ class Gem::Commands::SetupCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--format-executable --rdoc --ri"
+ "--format-executable --document ri"
end
def description # :nodoc:
@@ -110,7 +141,7 @@ By default, this RubyGems will install gem as:
uninstall_old_gemcutter
- install_rdoc
+ documentation_success = install_rdoc
say
if @verbose then
@@ -118,14 +149,30 @@ By default, this RubyGems will install gem as:
say
end
+ if options[:previous_version].empty?
+ options[:previous_version] = Gem::VERSION.sub(/[0-9]+$/, '0')
+ end
+
+ options[:previous_version] = Gem::Version.new(options[:previous_version])
+
release_notes = File.join Dir.pwd, 'History.txt'
release_notes = if File.exist? release_notes then
- open release_notes do |io|
- text = io.gets '==='
- text << io.gets('===')
- text[0...-3].sub(/^# coding:.*?^=/m, '')
+ history = File.read release_notes
+ history = history.sub(/^# coding:.*?^=/m, '')
+
+ text = history.split(HISTORY_HEADER)
+ text.shift # correct an off-by-one generated by split
+ version_lines = history.scan(HISTORY_HEADER)
+ versions = history.scan(VERSION_MATCHER).flatten.map { |x| Gem::Version.new(x) }
+
+ history_string = ""
+
+ until versions.length == 0 or versions.shift < options[:previous_version]
+ history_string += version_lines.shift + text.shift
end
+
+ history_string
else
"Oh-no! Unable to find release notes!"
end
@@ -145,6 +192,31 @@ By default, this RubyGems will install gem as:
say "to remove it by hand."
say
end
+
+ if documentation_success
+ if options[:document].include? 'rdoc' then
+ say "Rdoc documentation was installed. You may now invoke:"
+ say " gem server"
+ say "and then peruse beautifully formatted documentation for your gems"
+ say "with your web browser."
+ say "If you do not wish to install this documentation in the future, use the"
+ say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
+ say "'gem help env' for details."
+ say
+ end
+
+ 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"
+ say "If you do not wish to install this documentation in the future, use the"
+ say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
+ say "'gem help env' for details."
+ say
+ end
+ end
end
def install_executables(bin_dir)
@@ -165,7 +237,7 @@ By default, this RubyGems will install gem as:
end
dest_file = File.join bin_dir, bin_file_formatted
- bin_tmp_file = File.join Dir.tmpdir, bin_file
+ bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
begin
bin = File.readlines bin_file
@@ -209,10 +281,7 @@ TEXT
say "Installing RubyGems" if @verbose
Dir.chdir 'lib' do
- lib_files = Dir[File.join('**', '*rb')]
-
- # Be sure to include our SSL ca bundles
- lib_files += Dir[File.join('**', '*pem')]
+ lib_files = Dir[File.join('**', '*rb')]
lib_files.each do |lib_file|
dest_file = File.join lib_dir, lib_file
@@ -229,6 +298,12 @@ TEXT
rubygems_name = "rubygems-#{Gem::VERSION}"
rubygems_doc_dir = File.join gem_doc_dir, rubygems_name
+ begin
+ Gem.ensure_gem_subdirectories Gem.dir
+ rescue SystemCallError
+ # ignore
+ end
+
if File.writable? gem_doc_dir and
(not File.exist? rubygems_doc_dir or
File.writable? rubygems_doc_dir) then
@@ -237,21 +312,26 @@ TEXT
rm_rf dir
end
- if options[:ri] then
- ri_dir = File.join rubygems_doc_dir, 'ri'
- say "Installing #{rubygems_name} ri into #{ri_dir}" if @verbose
- run_rdoc '--ri', '--op', ri_dir
- end
+ require 'rubygems/rdoc'
- if options[:rdoc] then
- rdoc_dir = File.join rubygems_doc_dir, 'rdoc'
- say "Installing #{rubygems_name} rdoc into #{rdoc_dir}" if @verbose
- run_rdoc '--op', rdoc_dir
+ fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION
+ def fake_spec.full_gem_path
+ File.expand_path '../../../..', __FILE__
end
+
+ generate_ri = options[:document].include? 'ri'
+ generate_rdoc = options[:document].include? 'rdoc'
+
+ rdoc = Gem::RDoc.new fake_spec, generate_rdoc, generate_ri
+ rdoc.generate
+
+ return true
elsif @verbose then
say "Skipping RDoc generation, #{gem_doc_dir} not writable"
say "Set the GEM_HOME environment variable if you want RDoc generated"
end
+
+ return false
end
def make_destination_dirs(install_destdir)
@@ -331,23 +411,6 @@ abort "#{deprecation_message}"
end
end
- def run_rdoc(*args)
- begin
- gem 'rdoc'
- rescue Gem::LoadError
- end
-
- require 'rdoc/rdoc'
-
- args << '--main' << 'README.rdoc' << '--quiet'
- args << '.'
- args << 'README.rdoc' << 'UPGRADING.rdoc'
- args << 'LICENSE.txt' << 'MIT.txt' << 'History.txt'
-
- r = RDoc::RDoc.new
- r.document args
- end
-
def uninstall_old_gemcutter
require 'rubygems/uninstaller'
diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb
index ac14313e9d..97ed7329ea 100644
--- a/lib/rubygems/commands/sources_command.rb
+++ b/lib/rubygems/commands/sources_command.rb
@@ -48,7 +48,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
options[:update])
if options[:clear_all] then
- path = Gem::SpecFetcher.fetcher.dir
+ path = File.join Gem.user_home, '.gem', 'specs'
FileUtils.rm_rf path
unless File.exist? path then
@@ -64,16 +64,19 @@ class Gem::Commands::SourcesCommand < Gem::Command
end
end
- if options[:add] then
- source_uri = options[:add]
- uri = URI.parse source_uri
+ if source_uri = options[:add] then
+ source = Gem::Source.new source_uri
begin
- Gem::SpecFetcher.fetcher.load_specs uri, 'specs'
- Gem.sources << source_uri
- Gem.configuration.write
+ if Gem.sources.include? source_uri then
+ say "source #{source_uri} already present in the cache"
+ else
+ source.load_specs :released
+ Gem.sources << source
+ Gem.configuration.write
- say "#{source_uri} added to sources"
+ say "#{source_uri} added to sources"
+ end
rescue URI::Error, ArgumentError
say "#{source_uri} is not a URI"
terminate_interaction 1
@@ -97,12 +100,9 @@ class Gem::Commands::SourcesCommand < Gem::Command
end
if options[:update] then
- fetcher = Gem::SpecFetcher.fetcher
-
- Gem.sources.each do |update_uri|
- update_uri = URI.parse update_uri
- fetcher.load_specs update_uri, 'specs'
- fetcher.load_specs update_uri, 'latest_specs'
+ Gem.sources.each_source do |src|
+ src.load_specs :released
+ src.load_specs :latest
end
say "source cache successfully updated"
@@ -112,8 +112,8 @@ class Gem::Commands::SourcesCommand < Gem::Command
say "*** CURRENT SOURCES ***"
say
- Gem.sources.each do |source|
- say source
+ Gem.sources.each do |src|
+ say src
end
end
end
diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb
index 566a9cc66e..63da5fef0f 100644
--- a/lib/rubygems/commands/specification_command.rb
+++ b/lib/rubygems/commands/specification_command.rb
@@ -1,7 +1,7 @@
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
-require 'rubygems/format'
+require 'rubygems/package'
class Gem::Commands::SpecificationCommand < Gem::Command
@@ -17,6 +17,7 @@ class Gem::Commands::SpecificationCommand < Gem::Command
add_version_option('examine')
add_platform_option
+ add_prerelease_option
add_option('--all', 'Output specifications for all versions of',
'the gem') do |value, options|
@@ -62,13 +63,13 @@ FIELD name of gemspec field to show
"Please specify a gem name or file on the command line"
end
- case options[:version]
+ case v = options[:version]
when String
- req = Gem::Requirement.parse options[:version]
+ req = Gem::Requirement.create v
when Gem::Requirement
- req = options[:version]
+ req = v
else
- raise Gem::CommandLineError, "Unsupported version type: #{options[:version]}"
+ raise Gem::CommandLineError, "Unsupported version type: '#{v}'"
end
if !req.none? and options[:all]
@@ -79,7 +80,7 @@ FIELD name of gemspec field to show
if options[:all]
dep = Gem::Dependency.new gem
else
- dep = Gem::Dependency.new gem, options[:version]
+ dep = Gem::Dependency.new gem, req
end
field = get_one_optional_argument
@@ -89,7 +90,7 @@ FIELD name of gemspec field to show
if local? then
if File.exist? gem then
- specs << Gem::Format.from_file_by_path(gem).spec rescue nil
+ specs << Gem::Package.new(gem).spec rescue nil
end
if specs.empty? then
@@ -98,17 +99,14 @@ FIELD name of gemspec field to show
end
if remote? then
- found = Gem::SpecFetcher.fetcher.fetch dep, true
-
- if dep.prerelease? or options[:prerelease]
- found += Gem::SpecFetcher.fetcher.fetch dep, false, true, true
- end
+ dep.prerelease = options[:prerelease]
+ found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
specs.push(*found.map { |spec,| spec })
end
if specs.empty? then
- alert_error "Unknown gem '#{gem}'"
+ alert_error "No gem matching '#{dep}' found"
terminate_interaction 1
end
diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb
index aaadb762b5..736574ddff 100644
--- a/lib/rubygems/commands/uninstall_command.rb
+++ b/lib/rubygems/commands/uninstall_command.rb
@@ -13,7 +13,8 @@ class Gem::Commands::UninstallCommand < Gem::Command
def initialize
super 'uninstall', 'Uninstall gems from the local repository',
- :version => Gem::Requirement.default, :user_install => true
+ :version => Gem::Requirement.default, :user_install => true,
+ :check_dev => false
add_option('-a', '--[no-]all',
'Uninstall all matching versions'
@@ -27,6 +28,12 @@ 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
+ end
+
add_option('-x', '--[no-]executables',
'Uninstall applicable executables without',
'confirmation') do |value, options|
@@ -54,6 +61,12 @@ class Gem::Commands::UninstallCommand < Gem::Command
options[:format_executable] = value
end
+ add_option('--[no-]force',
+ 'Uninstall all versions of the named gems',
+ 'ignoring dependencies') do |value, options|
+ options[:force] = value
+ end
+
add_version_option
add_platform_option
end
@@ -73,19 +86,23 @@ class Gem::Commands::UninstallCommand < Gem::Command
end
def execute
- original_path = Gem.path
+ # REFACTOR: stolen from cleanup_command
+ 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
+
+ deps = deplist.strongly_connected_components.flatten.reverse
- get_all_gem_names.each do |gem_name|
+ deps.map(&:name).uniq.each do |gem_name|
begin
Gem::Uninstaller.new(gem_name, options).uninstall
- rescue Gem::InstallError => e
- alert e.message
rescue Gem::GemNotInHomeException => e
spec = e.spec
alert("In order to remove #{spec.name}, please execute:\n" \
"\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
- ensure
- Gem.use_paths(*original_path)
end
end
end
diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb
index 64b8ad64f8..7eefd32a6e 100644
--- a/lib/rubygems/commands/unpack_command.rb
+++ b/lib/rubygems/commands/unpack_command.rb
@@ -69,8 +69,10 @@ class Gem::Commands::UnpackCommand < Gem::Command
else
basename = File.basename path, '.gem'
target_dir = File.expand_path basename, options[:target]
- FileUtils.mkdir_p target_dir
- Gem::Installer.new(path, :unpack => true).unpack target_dir
+
+ package = Gem::Package.new path
+ package.extract_files target_dir
+
say "Unpacked gem: '#{target_dir}'"
end
end
@@ -134,9 +136,11 @@ class Gem::Commands::UnpackCommand < Gem::Command
##
# Extracts the Gem::Specification and raw metadata from the .gem file at
# +path+.
+ #--
+ # TODO move to Gem::Package as #raw_spec or something
def get_metadata path
- format = Gem::Format.from_file_by_path path
+ format = Gem::Package.new path
spec = format.spec
metadata = nil
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index d63b943c56..02f9657435 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -1,10 +1,12 @@
require 'rubygems/command'
require 'rubygems/command_manager'
+require 'rubygems/dependency_installer'
require 'rubygems/install_update_options'
require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher'
require 'rubygems/version_option'
-require 'rubygems/commands/install_command'
+require 'rubygems/install_message' # must come before rdoc for messaging
+require 'rubygems/rdoc'
class Gem::Commands::UpdateCommand < Gem::Command
@@ -13,11 +15,9 @@ class Gem::Commands::UpdateCommand < Gem::Command
include Gem::VersionOption
def initialize
- super 'update',
- 'Update the named gems (or all installed gems) in the local repository',
- :generate_rdoc => true,
- :generate_ri => true,
- :force => false
+ super 'update', 'Update installed gems to the latest version',
+ :document => %w[rdoc ri],
+ :force => false
add_install_update_options
@@ -37,6 +37,9 @@ class Gem::Commands::UpdateCommand < Gem::Command
add_local_remote_options
add_platform_option
add_prerelease_option "as update targets"
+
+ @updated = []
+ @installer = Gem::DependencyInstaller.new options
end
def arguments # :nodoc:
@@ -44,7 +47,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
def defaults_str # :nodoc:
- "--rdoc --ri --no-force --install-dir #{Gem.dir}"
+ "--document --no-force --install-dir #{Gem.dir}"
end
def usage # :nodoc:
@@ -52,9 +55,6 @@ class Gem::Commands::UpdateCommand < Gem::Command
end
def execute
- @installer = Gem::DependencyInstaller.new options
- @updated = []
-
hig = {}
if options[:system] then
@@ -79,21 +79,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
if updated.empty? then
say "Nothing to update"
else
- say "Gems updated: #{updated.map { |spec| spec.name }.join ', '}"
-
- if options[:generate_ri] then
- updated.each do |gem|
- Gem::DocManager.new(gem, options[:rdoc_args]).generate_ri
- end
-
- Gem::DocManager.update_ri_cache
- end
-
- if options[:generate_rdoc] then
- updated.each do |gem|
- Gem::DocManager.new(gem, options[:rdoc_args]).generate_rdoc
- end
- end
+ say "Gems updated: #{updated.map { |spec| spec.name }.join ' '}"
end
end
@@ -112,7 +98,6 @@ class Gem::Commands::UpdateCommand < Gem::Command
@installer.installed_gems.each do |spec|
@updated << spec
- say "Successfully installed #{spec.full_name}" if success
end
end
@@ -178,8 +163,9 @@ class Gem::Commands::UpdateCommand < Gem::Command
args = []
args << '--prefix' << Gem.prefix if Gem.prefix
- args << '--no-rdoc' unless options[:generate_rdoc]
- args << '--no-ri' unless options[:generate_ri]
+ # TODO use --document for >= 1.9 , --no-rdoc --no-ri < 1.9
+ 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]
update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"
@@ -205,20 +191,20 @@ class Gem::Commands::UpdateCommand < Gem::Command
gem_names.all? { |name| /#{name}/ !~ l_spec.name }
dependency = Gem::Dependency.new l_spec.name, "> #{l_spec.version}"
+ dependency.prerelease = options[:prerelease]
fetcher = Gem::SpecFetcher.fetcher
- spec_tuples = fetcher.find_matching dependency
- matching_gems = spec_tuples.select do |(name, _, platform),|
- name == l_name and Gem::Platform.match platform
+ spec_tuples, _ = fetcher.search_for_dependency dependency
+
+ matching_gems = spec_tuples.select do |g,_|
+ g.name == l_name and g.match_platform?
end
- highest_remote_gem = matching_gems.sort_by do |(_, version),|
- version
- end.last
+ highest_remote_gem = matching_gems.sort_by { |g,_| g.version }.last
- highest_remote_gem ||= [[nil, Gem::Version.new(0), nil]] # "null" object
- highest_remote_ver = highest_remote_gem.first[1]
+ highest_remote_gem ||= [Gem::NameTuple.null]
+ highest_remote_ver = highest_remote_gem.first.version
if system or (l_spec.version < highest_remote_ver) then
result << [l_spec.name, [l_spec.version, highest_remote_ver].max]
diff --git a/lib/rubygems/commands/yank_command.rb b/lib/rubygems/commands/yank_command.rb
new file mode 100644
index 0000000000..da0cf7ad3b
--- /dev/null
+++ b/lib/rubygems/commands/yank_command.rb
@@ -0,0 +1,98 @@
+require 'rubygems/command'
+require 'rubygems/local_remote_options'
+require 'rubygems/version_option'
+require 'rubygems/gemcutter_utilities'
+
+class Gem::Commands::YankCommand < Gem::Command
+ include Gem::LocalRemoteOptions
+ include Gem::VersionOption
+ include Gem::GemcutterUtilities
+
+ def description # :nodoc:
+ 'Remove a specific gem version release from RubyGems.org'
+ end
+
+ def arguments # :nodoc:
+ "GEM name of gem"
+ end
+
+ def usage # :nodoc:
+ "#{program_name} GEM -v VERSION [-p PLATFORM] [--undo] [--key KEY_NAME]"
+ end
+
+ def initialize
+ super 'yank', description
+
+ add_version_option("remove")
+ add_platform_option("remove")
+
+ add_option('--undo') do |value, options|
+ options[:undo] = true
+ end
+
+ add_option('-k', '--key KEY_NAME',
+ 'Use API key from your gem credentials file') do |value, options|
+ options[:key] = value
+ end
+ end
+
+ def execute
+ sign_in
+
+ version = get_version_from_requirements(options[:version])
+ platform = get_platform_from_requirements(options)
+ api_key = Gem.configuration.rubygems_api_key
+ api_key = Gem.configuration.api_keys[options[:key].to_sym] if options[:key]
+
+ if version then
+ if options[:undo] then
+ unyank_gem(version, platform, api_key)
+ else
+ yank_gem(version, platform, api_key)
+ end
+ else
+ say "A version argument is required: #{usage}"
+ terminate_interaction
+ end
+ end
+
+ def yank_gem(version, platform, api_key)
+ say "Yanking gem from #{self.host}..."
+ yank_api_request(:delete, version, platform, "api/v1/gems/yank", api_key)
+ end
+
+ def unyank_gem(version, platform, api_key)
+ say "Unyanking gem from #{host}..."
+ yank_api_request(:put, version, platform, "api/v1/gems/unyank", api_key)
+ end
+
+ private
+
+ def yank_api_request(method, version, platform, api, api_key)
+ name = get_one_gem_name
+ response = rubygems_api_request(method, api) do |request|
+ request.add_field("Authorization", api_key)
+
+ data = {
+ 'gem_name' => name,
+ 'version' => version,
+ }
+ data['platform'] = platform if platform
+
+ request.set_form_data data
+ end
+ say response.body
+ end
+
+ def get_version_from_requirements(requirements)
+ requirements.requirements.first[1].version
+ rescue
+ nil
+ end
+
+ def get_platform_from_requirements(requirements)
+ Gem.platforms[1].to_s if requirements.key? :added_platform
+ end
+
+end
+