rubygems-update 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- data/ChangeLog +587 -0
- data/README +0 -1
- data/Rakefile +39 -12
- data/TODO +0 -5
- data/bin/gem +7 -7
- data/bin/update_rubygems +1 -1
- data/examples/application/an-app.gemspec +1 -1
- data/gemspecs/cgikit-1.1.0.gemspec +1 -2
- data/gemspecs/jabber4r.gemspec +1 -1
- data/gemspecs/linguistics.gemspec +1 -1
- data/gemspecs/ook.gemspec +1 -1
- data/gemspecs/progressbar.gemspec +1 -1
- data/gemspecs/redcloth.gemspec +1 -1
- data/gemspecs/rublog.gemspec +1 -1
- data/gemspecs/ruby-doom.gemspec +1 -1
- data/gemspecs/rubyjdwp.gemspec +1 -1
- data/gemspecs/statistics.gemspec +1 -1
- data/lib/rubygems.rb +167 -105
- data/lib/rubygems/builder.rb +12 -10
- data/lib/rubygems/command.rb +177 -60
- data/lib/rubygems/command_manager.rb +30 -38
- data/lib/rubygems/commands/build_command.rb +42 -46
- data/lib/rubygems/commands/cert_command.rb +72 -69
- data/lib/rubygems/commands/check_command.rb +63 -63
- data/lib/rubygems/commands/cleanup_command.rb +25 -7
- data/lib/rubygems/commands/contents_command.rb +70 -62
- data/lib/rubygems/commands/dependency_command.rb +131 -86
- data/lib/rubygems/commands/environment_command.rb +67 -46
- data/lib/rubygems/commands/fetch_command.rb +62 -0
- data/lib/rubygems/commands/generate_index_command.rb +57 -0
- data/lib/rubygems/commands/help_command.rb +163 -73
- data/lib/rubygems/commands/install_command.rb +114 -128
- data/lib/rubygems/commands/list_command.rb +10 -8
- data/lib/rubygems/commands/lock_command.rb +101 -0
- data/lib/rubygems/commands/mirror_command.rb +105 -0
- data/lib/rubygems/commands/outdated_command.rb +24 -15
- data/lib/rubygems/commands/pristine_command.rb +118 -88
- data/lib/rubygems/commands/query_command.rb +109 -77
- data/lib/rubygems/commands/rdoc_command.rb +13 -10
- data/lib/rubygems/commands/search_command.rb +10 -8
- data/lib/rubygems/commands/server_command.rb +48 -0
- data/lib/rubygems/commands/sources_command.rb +104 -83
- data/lib/rubygems/commands/specification_command.rb +65 -51
- data/lib/rubygems/commands/uninstall_command.rb +17 -12
- data/lib/rubygems/commands/unpack_command.rb +68 -68
- data/lib/rubygems/commands/update_command.rb +72 -25
- data/lib/rubygems/commands/which_command.rb +86 -0
- data/lib/rubygems/config_file.rb +202 -78
- data/lib/rubygems/custom_require.rb +7 -88
- data/lib/rubygems/dependency.rb +65 -0
- data/lib/rubygems/dependency_installer.rb +232 -0
- data/lib/rubygems/dependency_list.rb +133 -105
- data/lib/rubygems/digest/md5.rb +4 -1
- data/lib/rubygems/digest/sha2.rb +1 -1
- data/lib/rubygems/doc_manager.rb +41 -19
- data/lib/rubygems/exceptions.rb +63 -0
- data/lib/rubygems/ext.rb +18 -0
- data/lib/rubygems/ext/builder.rb +56 -0
- data/lib/rubygems/ext/configure_builder.rb +24 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +23 -0
- data/lib/rubygems/ext/rake_builder.rb +27 -0
- data/lib/rubygems/format.rb +16 -6
- data/lib/rubygems/gem_openssl.rb +43 -6
- data/lib/rubygems/gem_path_searcher.rb +84 -0
- data/lib/rubygems/gem_runner.rb +20 -5
- data/lib/rubygems/indexer.rb +163 -0
- data/lib/rubygems/indexer/abstract_index_builder.rb +80 -0
- data/lib/rubygems/indexer/marshal_index_builder.rb +17 -0
- data/lib/rubygems/indexer/master_index_builder.rb +53 -0
- data/lib/rubygems/indexer/quick_index_builder.rb +48 -0
- data/lib/rubygems/install_update_options.rb +87 -0
- data/lib/rubygems/installer.rb +316 -562
- data/lib/rubygems/local_remote_options.rb +106 -0
- data/lib/rubygems/old_format.rb +5 -13
- data/lib/rubygems/open-uri.rb +2 -0
- data/lib/rubygems/package.rb +28 -32
- data/lib/rubygems/platform.rb +187 -0
- data/lib/rubygems/remote_fetcher.rb +46 -29
- data/lib/rubygems/remote_installer.rb +11 -18
- data/lib/rubygems/requirement.rb +157 -0
- data/lib/rubygems/rubygems_version.rb +1 -1
- data/lib/rubygems/security.rb +715 -457
- data/lib/rubygems/server.rb +77 -59
- data/lib/rubygems/source_index.rb +154 -83
- data/lib/rubygems/source_info_cache.rb +73 -30
- data/lib/rubygems/source_info_cache_entry.rb +12 -3
- data/lib/rubygems/specification.rb +378 -145
- data/lib/rubygems/uninstaller.rb +183 -0
- data/lib/rubygems/user_interaction.rb +38 -9
- data/lib/rubygems/validator.rb +53 -24
- data/lib/rubygems/version.rb +126 -289
- data/lib/rubygems/version_option.rb +49 -0
- data/pkgs/sources/lib/sources.rb +1 -4
- data/pkgs/sources/sources.gemspec +3 -3
- data/scripts/gemdoc.rb +0 -1
- data/setup.rb +166 -1505
- data/test/bogussources.rb +0 -1
- data/test/data/gem-private_key.pem +27 -0
- data/test/data/gem-public_cert.pem +20 -0
- data/test/functional.rb +3 -105
- data/test/gemutilities.rb +145 -24
- data/test/insure_session.rb +0 -1
- data/test/{test_datadir.rb → test_config.rb} +7 -13
- data/test/test_gem.rb +360 -9
- data/test/test_gem_builder.rb +34 -0
- data/test/{test_command.rb → test_gem_command.rb} +119 -62
- data/test/{test_parse_commands.rb → test_gem_command_manager.rb} +64 -40
- data/test/test_gem_commands_build_command.rb +75 -0
- data/test/test_gem_commands_cert_command.rb +122 -0
- data/test/test_gem_commands_check_command.rb +25 -0
- data/test/test_gem_commands_contents_command.rb +92 -0
- data/test/test_gem_commands_dependency_command.rb +108 -0
- data/test/test_gem_commands_environment_command.rb +117 -0
- data/test/test_gem_commands_fetch_command.rb +34 -0
- data/test/test_gem_commands_generate_index_command.rb +32 -0
- data/test/test_gem_commands_install_command.rb +160 -0
- data/test/test_gem_commands_mirror_command.rb +56 -0
- data/test/test_gem_commands_pristine_command.rb +100 -0
- data/test/test_gem_commands_query_command.rb +82 -0
- data/test/test_gem_commands_sources_command.rb +147 -0
- data/test/test_gem_commands_specification_command.rb +93 -0
- data/test/test_gem_commands_unpack_command.rb +55 -0
- data/test/test_gem_config_file.rb +210 -0
- data/test/test_gem_dependency.rb +89 -0
- data/test/test_gem_dependency_installer.rb +542 -0
- data/test/test_gem_dependency_list.rb +212 -0
- data/test/test_gem_doc_manager.rb +32 -0
- data/test/test_gem_ext_configure_builder.rb +13 -17
- data/test/test_gem_ext_ext_conf_builder.rb +9 -9
- data/test/test_gem_ext_rake_builder.rb +23 -11
- data/test/test_gem_format.rb +69 -0
- data/test/test_gem_gem_path_searcher.rb +57 -0
- data/test/test_gem_gem_runner.rb +35 -0
- data/test/test_gem_indexer.rb +119 -0
- data/test/test_gem_install_update_options.rb +40 -0
- data/test/test_gem_installer.rb +796 -0
- data/test/test_gem_local_remote_options.rb +84 -0
- data/test/test_gem_outdated_command.rb +11 -9
- data/test/test_gem_platform.rb +240 -0
- data/test/{test_remote_fetcher.rb → test_gem_remote_fetcher.rb} +124 -55
- data/test/{test_remote_installer.rb → test_gem_remote_installer.rb} +3 -4
- data/test/test_gem_requirement.rb +223 -0
- data/test/test_gem_server.rb +71 -0
- data/test/test_gem_source_index.rb +429 -0
- data/test/test_gem_source_info_cache.rb +79 -17
- data/test/test_gem_source_info_cache_entry.rb +11 -9
- data/test/test_gem_specification.rb +738 -0
- data/test/test_gem_stream_ui.rb +117 -0
- data/test/test_gem_validator.rb +70 -0
- data/test/test_gem_version.rb +191 -0
- data/test/test_gem_version_option.rb +77 -0
- data/test/{test_require_gem.rb → test_kernel.rb} +19 -12
- data/test/test_open_uri.rb +1 -2
- data/test/test_package.rb +45 -34
- metadata +116 -141
- data/Releases +0 -127
- data/bin/gem_mirror +0 -73
- data/bin/gem_server +0 -6
- data/bin/gemlock +0 -127
- data/bin/gemri +0 -24
- data/bin/gemwhich +0 -89
- data/bin/index_gem_repository.rb +0 -302
- data/lib/gemconfigure.rb +0 -24
- data/lib/rubygems/gem_commands.rb +0 -273
- data/pkgs/sources/sources-0.0.1.gem +0 -0
- data/post-install.rb +0 -121
- data/test/brokenbuildgem.rb +0 -35
- data/test/data/PostMessage-0.0.1.gem +0 -0
- data/test/data/a-0.0.1.gem +0 -0
- data/test/data/a-0.0.2.gem +0 -0
- data/test/data/b-0.0.2.gem +0 -0
- data/test/data/broken-1.0.0.gem +0 -0
- data/test/data/broken_build/broken-build.gemspec +0 -20
- data/test/data/broken_build/ext/extconf.rb +0 -3
- data/test/data/broken_build/ext/foo.c +0 -1
- data/test/data/c-1.2.gem +0 -0
- data/test/data/gemhome/cache/a-0.0.1.gem +0 -0
- data/test/data/gemhome/cache/a-0.0.2.gem +0 -0
- data/test/data/gemhome/cache/b-0.0.2.gem +0 -0
- data/test/data/gemhome/cache/c-1.2.gem +0 -0
- data/test/data/gemhome/gems/a-0.0.1/lib/code.rb +0 -1
- data/test/data/gemhome/gems/a-0.0.2/lib/code.rb +0 -1
- data/test/data/gemhome/gems/b-0.0.2/lib/code.rb +0 -1
- data/test/data/gemhome/gems/c-1.2/lib/code.rb +0 -1
- data/test/data/gemhome/specifications/a-0.0.1.gemspec +0 -8
- data/test/data/gemhome/specifications/a-0.0.2.gemspec +0 -8
- data/test/data/gemhome/specifications/b-0.0.2.gemspec +0 -8
- data/test/data/gemhome/specifications/c-1.2.gemspec +0 -8
- data/test/data/legacy/keyedlist-0.4.0.ruby +0 -11
- data/test/data/legacy/keyedlist-0.4.0.yaml +0 -16
- data/test/data/lib/code.rb +0 -1
- data/test/data/one/README.one +0 -1
- data/test/data/one/lib/one.rb +0 -9
- data/test/data/one/one-0.0.1.gem +0 -0
- data/test/data/one/one.gemspec +0 -17
- data/test/data/one/one.yaml +0 -40
- data/test/data/post_install.gemspec +0 -19
- data/test/functional_extension_gems.rb +0 -48
- data/test/functional_generate_yaml_index.rb +0 -104
- data/test/gemenvironment.rb +0 -59
- data/test/io_capture.rb +0 -33
- data/test/mock/gems/gems/sources-0.0.1/lib/sources.rb +0 -11
- data/test/mock/gems/specifications/sources-0.0.1.gemspec +0 -8
- data/test/onegem.rb +0 -35
- data/test/test_builder.rb +0 -34
- data/test/test_check_command.rb +0 -34
- data/test/test_configfile.rb +0 -42
- data/test/test_dependency_list.rb +0 -169
- data/test/test_file_list.rb +0 -101
- data/test/test_format.rb +0 -49
- data/test/test_gem_sources_command.rb +0 -135
- data/test/test_gemloadpaths.rb +0 -51
- data/test/test_gempaths.rb +0 -170
- data/test/test_installer.rb +0 -369
- data/test/test_loadmanager.rb +0 -48
- data/test/test_process_commands.rb +0 -52
- data/test/test_source_index.rb +0 -231
- data/test/test_specific_extras.rb +0 -46
- data/test/test_specification.rb +0 -565
- data/test/test_user_interaction.rb +0 -48
- data/test/test_validator.rb +0 -59
- data/test/test_version_comparison.rb +0 -321
- data/test/testgem.rc +0 -7
- data/test/user_capture.rb +0 -7
- data/test/yaml_data.rb +0 -63
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems/indexer'
|
2
|
+
|
3
|
+
# Construct a quick index file and all of the individual specs to support
|
4
|
+
# incremental loading.
|
5
|
+
class Gem::Indexer::QuickIndexBuilder < Gem::Indexer::AbstractIndexBuilder
|
6
|
+
|
7
|
+
def initialize(filename, directory)
|
8
|
+
directory = File.join directory, 'quick'
|
9
|
+
|
10
|
+
super filename, directory
|
11
|
+
end
|
12
|
+
|
13
|
+
def cleanup
|
14
|
+
super
|
15
|
+
|
16
|
+
quick_index_file = File.join(@directory, @filename)
|
17
|
+
compress quick_index_file
|
18
|
+
|
19
|
+
# the complete quick index is in a directory, so move it as a whole
|
20
|
+
@files.delete quick_index_file
|
21
|
+
@files << @directory
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(spec)
|
25
|
+
@file.puts spec.original_name
|
26
|
+
add_yaml(spec)
|
27
|
+
add_marshal(spec)
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_yaml(spec)
|
31
|
+
fn = File.join @directory, "#{spec.original_name}.gemspec.rz"
|
32
|
+
zipped = zip spec.to_yaml
|
33
|
+
File.open fn, "wb" do |gsfile| gsfile.write zipped end
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_marshal(spec)
|
37
|
+
# HACK why does this not work in #initialize?
|
38
|
+
FileUtils.mkdir_p File.join(@directory, "Marshal.#{Gem.marshal_version}")
|
39
|
+
|
40
|
+
fn = File.join @directory, "Marshal.#{Gem.marshal_version}",
|
41
|
+
"#{spec.original_name}.gemspec.rz"
|
42
|
+
|
43
|
+
zipped = zip Marshal.dump(spec)
|
44
|
+
File.open fn, "wb" do |gsfile| gsfile.write zipped end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubygems/security'
|
9
|
+
|
10
|
+
##
|
11
|
+
# Mixin methods for install and update options for Gem::Commands
|
12
|
+
module Gem::InstallUpdateOptions
|
13
|
+
|
14
|
+
# Add the install/update options to the option parser.
|
15
|
+
def add_install_update_options
|
16
|
+
OptionParser.accept Gem::Security::Policy do |value|
|
17
|
+
value = Gem::Security::Policies[value]
|
18
|
+
raise OptionParser::InvalidArgument, value if value.nil?
|
19
|
+
value
|
20
|
+
end
|
21
|
+
|
22
|
+
add_option(:"Install/Update", '-i', '--install-dir DIR',
|
23
|
+
'Gem repository directory to get installed',
|
24
|
+
'gems') do |value, options|
|
25
|
+
options[:install_dir] = File.expand_path(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
add_option(:"Install/Update", '-d', '--[no-]rdoc',
|
29
|
+
'Generate RDoc documentation for the gem on',
|
30
|
+
'install') do |value, options|
|
31
|
+
options[:generate_rdoc] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
add_option(:"Install/Update", '--[no-]ri',
|
35
|
+
'Generate RI documentation for the gem on',
|
36
|
+
'install') do |value, options|
|
37
|
+
options[:generate_ri] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
add_option(:"Install/Update", '-E', '--env-shebang',
|
41
|
+
"Rewrite the shebang line on installed",
|
42
|
+
"scripts to use /usr/bin/env") do |value, options|
|
43
|
+
options[:env_shebang] = value
|
44
|
+
end
|
45
|
+
|
46
|
+
add_option(:"Install/Update", '-f', '--[no-]force',
|
47
|
+
'Force gem to install, bypassing dependency',
|
48
|
+
'checks') do |value, options|
|
49
|
+
options[:force] = value
|
50
|
+
end
|
51
|
+
|
52
|
+
add_option(:"Install/Update", '-t', '--[no-]test',
|
53
|
+
'Run unit tests prior to installation') do |value, options|
|
54
|
+
options[:test] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
add_option(:"Install/Update", '-w', '--[no-]wrappers',
|
58
|
+
'Use bin wrappers for executables',
|
59
|
+
'Not available on dosish platforms') do |value, options|
|
60
|
+
options[:wrappers] = value
|
61
|
+
end
|
62
|
+
|
63
|
+
add_option(:"Install/Update", '-P', '--trust-policy POLICY',
|
64
|
+
Gem::Security::Policy,
|
65
|
+
'Specify gem trust policy') do |value, options|
|
66
|
+
options[:security_policy] = value
|
67
|
+
end
|
68
|
+
|
69
|
+
add_option(:"Install/Update", '--ignore-dependencies',
|
70
|
+
'Do not install any required dependent gems') do |value, options|
|
71
|
+
options[:ignore_dependencies] = value
|
72
|
+
end
|
73
|
+
|
74
|
+
add_option(:"Install/Update", '-y', '--include-dependencies',
|
75
|
+
'Unconditionally install the required',
|
76
|
+
'dependent gems') do |value, options|
|
77
|
+
options[:include_dependencies] = value
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Default options for the gem install command.
|
82
|
+
def install_update_defaults_str
|
83
|
+
'--rdoc --no-force --no-test --wrappers'
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
data/lib/rubygems/installer.rb
CHANGED
@@ -7,661 +7,415 @@
|
|
7
7
|
require 'fileutils'
|
8
8
|
require 'pathname'
|
9
9
|
require 'rbconfig'
|
10
|
+
|
10
11
|
require 'rubygems/format'
|
11
|
-
require 'rubygems/
|
12
|
+
require 'rubygems/ext'
|
12
13
|
|
13
|
-
|
14
|
+
##
|
15
|
+
# The installer class processes RubyGem .gem files and installs the
|
16
|
+
# files contained in the .gem into the Gem.path.
|
17
|
+
#
|
18
|
+
# Gem::Installer does the work of putting files in all the right places on the
|
19
|
+
# filesystem including unpacking the gem into its gem dir, installing the
|
20
|
+
# gemspec in the specifications dir, storing the cached gem in the cache dir,
|
21
|
+
# and installing either wrappers or symlinks for executables.
|
22
|
+
class Gem::Installer
|
14
23
|
|
15
|
-
|
24
|
+
##
|
25
|
+
# Raised when there is an error while building extensions.
|
26
|
+
#
|
27
|
+
class ExtensionBuildError < Gem::InstallError; end
|
16
28
|
|
17
|
-
|
29
|
+
include Gem::UserInteraction
|
18
30
|
|
19
31
|
##
|
20
|
-
#
|
21
|
-
#
|
32
|
+
# Constructs an Installer instance that will install the gem located at
|
33
|
+
# +gem+. +options+ is a Hash with the following keys:
|
22
34
|
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# force:: [default = false] if false will fail if a required Gem is not
|
54
|
-
# installed, or if the Ruby version is too low for the gem
|
55
|
-
# install_dir:: [default = Gem.dir] directory that Gem is to be installed in
|
56
|
-
#
|
57
|
-
# return:: [Gem::Specification] The specification for the newly installed
|
58
|
-
# Gem.
|
59
|
-
#
|
60
|
-
def install(force=false, install_dir=Gem.dir, ignore_this_parameter=false)
|
61
|
-
# if we're forcing the install, then disable security, _unless_
|
62
|
-
# the security policy says that we only install singed gems
|
63
|
-
# (this includes Gem::Security::HighSecurity)
|
64
|
-
security_policy = @options[:security_policy]
|
65
|
-
security_policy = nil if force && security_policy && security_policy.only_signed != true
|
35
|
+
# :env_shebang:: Use /usr/bin/env in bin wrappers.
|
36
|
+
# :force:: Overrides all version checks and security policy checks, except
|
37
|
+
# for a signed-gems-only policy.
|
38
|
+
# :ignore_dependencies:: Don't raise if a dependency is missing.
|
39
|
+
# :install_dir:: The directory to install the gem into.
|
40
|
+
# :security_policy:: Use the specified security policy. See Gem::Security
|
41
|
+
# :wrappers:: Install wrappers if true, symlinks if false.
|
42
|
+
def initialize(gem, options={})
|
43
|
+
@gem = gem
|
44
|
+
|
45
|
+
options = { :force => false, :install_dir => Gem.dir }.merge options
|
46
|
+
|
47
|
+
@env_shebang = options[:env_shebang]
|
48
|
+
@force = options[:force]
|
49
|
+
gem_home = options[:install_dir]
|
50
|
+
@gem_home = Pathname.new(gem_home).expand_path
|
51
|
+
@ignore_dependencies = options[:ignore_dependencies]
|
52
|
+
@security_policy = options[:security_policy]
|
53
|
+
@wrappers = options[:wrappers]
|
54
|
+
|
55
|
+
begin
|
56
|
+
@format = Gem::Format.from_file_by_path @gem, @security_policy
|
57
|
+
rescue Gem::Package::FormatError
|
58
|
+
raise Gem::InstallError, "invalid gem format for #{@gem}"
|
59
|
+
end
|
60
|
+
|
61
|
+
@spec = @format.spec
|
62
|
+
|
63
|
+
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
|
64
|
+
end
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
##
|
67
|
+
# Installs the gem and returns a loaded Gem::Specification for the installed
|
68
|
+
# gem.
|
69
|
+
#
|
70
|
+
# The gem will be installed with the following structure:
|
71
|
+
#
|
72
|
+
# @gem_home/
|
73
|
+
# cache/<gem-version>.gem #=> a cached copy of the installed gem
|
74
|
+
# gems/<gem-version>/... #=> extracted files
|
75
|
+
# specifications/<gem-version>.gemspec #=> the Gem::Specification
|
76
|
+
def install
|
77
|
+
# If we're forcing the install then disable security unless the security
|
78
|
+
# policy says that we only install singed gems.
|
79
|
+
@security_policy = nil if @force and @security_policy and
|
80
|
+
not @security_policy.only_signed
|
81
|
+
|
82
|
+
unless @force then
|
83
|
+
if rrv = @spec.required_ruby_version then
|
84
|
+
unless rrv.satisfied_by? Gem::Version.new(RUBY_VERSION) then
|
85
|
+
raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}"
|
86
|
+
end
|
71
87
|
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}"
|
78
|
-
end
|
88
|
+
|
89
|
+
if rrgv = @spec.required_rubygems_version then
|
90
|
+
unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then
|
91
|
+
raise Gem::InstallError,
|
92
|
+
"#{@spec.name} requires RubyGems version #{rrgv}"
|
79
93
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
94
|
+
end
|
95
|
+
|
96
|
+
unless @ignore_dependencies then
|
97
|
+
@spec.dependencies.each do |dep_gem|
|
98
|
+
ensure_dependency @spec, dep_gem
|
84
99
|
end
|
85
100
|
end
|
101
|
+
end
|
86
102
|
|
87
|
-
|
103
|
+
FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
|
104
|
+
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
|
88
105
|
|
89
|
-
|
90
|
-
@directory = File.join(install_dir, "gems", format.spec.full_name).untaint
|
91
|
-
FileUtils.mkdir_p @directory
|
106
|
+
Gem.ensure_gem_subdirectories @gem_home
|
92
107
|
|
93
|
-
|
94
|
-
generate_bin(format.spec, install_dir)
|
95
|
-
build_extensions(@directory, format.spec)
|
108
|
+
FileUtils.mkdir_p @gem_dir
|
96
109
|
|
97
|
-
|
98
|
-
|
110
|
+
extract_files
|
111
|
+
generate_bin
|
112
|
+
build_extensions
|
113
|
+
write_spec
|
99
114
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
115
|
+
# HACK remove? Isn't this done in multiple places?
|
116
|
+
cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
|
117
|
+
unless File.exist? cached_gem then
|
118
|
+
FileUtils.cp @gem, File.join(@gem_home, "cache")
|
119
|
+
end
|
105
120
|
|
106
|
-
|
121
|
+
say @spec.post_install_message unless @spec.post_install_message.nil?
|
107
122
|
|
108
|
-
|
109
|
-
|
110
|
-
rescue Zlib::GzipFile::Error
|
111
|
-
raise InstallError, "gzip error installing #{@gem}"
|
112
|
-
end
|
123
|
+
@spec.loaded_from = File.join(@gem_home, 'specifications',
|
124
|
+
"#{@spec.full_name}.gemspec")
|
113
125
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
#
|
119
|
-
# spec :: Gem::Specification
|
120
|
-
# dependency :: Gem::Dependency
|
121
|
-
def ensure_dependency!(spec, dependency)
|
122
|
-
raise Gem::InstallError, "#{spec.name} requires #{dependency.name} #{dependency.version_requirements} " unless
|
123
|
-
installation_satisfies_dependency?(dependency)
|
124
|
-
end
|
126
|
+
return @spec
|
127
|
+
rescue Zlib::GzipFile::Error
|
128
|
+
raise Gem::InstallError, "gzip error installing #{@gem}"
|
129
|
+
end
|
125
130
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
131
|
+
##
|
132
|
+
# Ensure that the dependency is satisfied by the current installation of
|
133
|
+
# gem. If it is not an exception is raised.
|
134
|
+
#
|
135
|
+
# spec :: Gem::Specification
|
136
|
+
# dependency :: Gem::Dependency
|
137
|
+
def ensure_dependency(spec, dependency)
|
138
|
+
unless installation_satisfies_dependency? dependency then
|
139
|
+
raise Gem::InstallError, "#{spec.name} requires #{dependency}"
|
133
140
|
end
|
134
141
|
|
135
|
-
|
136
|
-
|
137
|
-
#
|
138
|
-
def unpack(directory)
|
139
|
-
format = Gem::Format.from_file_by_path(@gem, @options[:security_policy])
|
140
|
-
extract_files(directory, format)
|
141
|
-
end
|
142
|
+
true
|
143
|
+
end
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
FileUtils.mkdir_p File.join(install_dir, "cache")
|
152
|
-
end
|
153
|
-
unless File.exist? File.join(install_dir, "doc")
|
154
|
-
FileUtils.mkdir_p File.join(install_dir, "doc")
|
155
|
-
end
|
156
|
-
end
|
145
|
+
##
|
146
|
+
# True if the current installed gems satisfy the given dependency.
|
147
|
+
#
|
148
|
+
# dependency :: Gem::Dependency
|
149
|
+
def installation_satisfies_dependency?(dependency)
|
150
|
+
current_index = Gem::SourceIndex.from_installed_gems
|
151
|
+
current_index.find_name(dependency.name, dependency.version_requirements).size > 0
|
152
|
+
end
|
157
153
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
rubycode = spec.to_ruby
|
167
|
-
file_name = File.join(spec_path, spec.full_name+".gemspec").untaint
|
168
|
-
File.open(file_name, "w") do |file|
|
169
|
-
file.puts rubycode
|
170
|
-
end
|
171
|
-
end
|
154
|
+
##
|
155
|
+
# Unpacks the gem into the given directory.
|
156
|
+
#
|
157
|
+
def unpack(directory)
|
158
|
+
@gem_dir = directory
|
159
|
+
@format = Gem::Format.from_file_by_path @gem, @security_policy
|
160
|
+
extract_files
|
161
|
+
end
|
172
162
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
end
|
183
|
-
end
|
163
|
+
##
|
164
|
+
# Writes the .gemspec specification (in Ruby) to the supplied
|
165
|
+
# spec_path.
|
166
|
+
#
|
167
|
+
# spec:: [Gem::Specification] The Gem specification to output
|
168
|
+
# spec_path:: [String] The location (path) to write the gemspec to
|
169
|
+
#
|
170
|
+
def write_spec
|
171
|
+
rubycode = @spec.to_ruby
|
184
172
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
# new bin dir under the install_dir.
|
192
|
-
bindir = Gem.bindir(install_dir)
|
193
|
-
|
194
|
-
Dir.mkdir bindir unless File.exist? bindir
|
195
|
-
raise Gem::FilePermissionError.new(bindir) unless File.writable?(bindir)
|
196
|
-
|
197
|
-
spec.executables.each do |filename|
|
198
|
-
if @options[:wrappers] then
|
199
|
-
generate_bin_script spec, filename, bindir, install_dir
|
200
|
-
else
|
201
|
-
generate_bin_symlink spec, filename, bindir, install_dir
|
202
|
-
end
|
203
|
-
end
|
173
|
+
file_name = File.join @gem_home, 'specifications',
|
174
|
+
"#{@spec.full_name}.gemspec"
|
175
|
+
file_name.untaint
|
176
|
+
|
177
|
+
File.open(file_name, "w") do |file|
|
178
|
+
file.puts rubycode
|
204
179
|
end
|
180
|
+
end
|
205
181
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
182
|
+
##
|
183
|
+
# Creates windows .bat files for easy running of commands
|
184
|
+
#
|
185
|
+
def generate_windows_script(bindir, filename)
|
186
|
+
if Gem.win_platform? then
|
187
|
+
script_name = filename + ".bat"
|
188
|
+
File.open(File.join(bindir, File.basename(script_name)), "w") do |file|
|
189
|
+
file.puts windows_stub_script(bindir, filename)
|
212
190
|
end
|
213
|
-
generate_windows_script bindir, filename
|
214
191
|
end
|
192
|
+
end
|
215
193
|
|
216
|
-
|
217
|
-
|
218
|
-
# the symlink if the gem being installed has a newer version.
|
219
|
-
#
|
220
|
-
def generate_bin_symlink(spec, filename, bindir, install_dir)
|
221
|
-
if Config::CONFIG["arch"] =~ /dos|win32/i then
|
222
|
-
warn "Unable to use symlinks on win32, installing wrapper"
|
223
|
-
generate_bin_script spec, filename, bindir, install_dir
|
224
|
-
return
|
225
|
-
end
|
194
|
+
def generate_bin
|
195
|
+
return if @spec.executables.nil? or @spec.executables.empty?
|
226
196
|
|
227
|
-
|
228
|
-
|
197
|
+
# If the user has asked for the gem to be installed in a directory that is
|
198
|
+
# the system gem directory, then use the system bin directory, else create
|
199
|
+
# (or use) a new bin dir under the gem_home.
|
200
|
+
bindir = Gem.bindir @gem_home
|
229
201
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
202
|
+
Dir.mkdir bindir unless File.exist? bindir
|
203
|
+
raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
|
204
|
+
|
205
|
+
@spec.executables.each do |filename|
|
206
|
+
filename.untaint
|
207
|
+
bin_path = File.join @gem_dir, 'bin', filename
|
208
|
+
mode = File.stat(bin_path).mode | 0111
|
209
|
+
File.chmod mode, bin_path
|
210
|
+
|
211
|
+
if @wrappers then
|
212
|
+
generate_bin_script filename, bindir
|
213
|
+
else
|
214
|
+
generate_bin_symlink filename, bindir
|
237
215
|
end
|
216
|
+
end
|
217
|
+
end
|
238
218
|
|
239
|
-
|
219
|
+
##
|
220
|
+
# Creates the scripts to run the applications in the gem.
|
221
|
+
#--
|
222
|
+
# The Windows script is generated in addition to the regular one due to a
|
223
|
+
# bug or misfeature in the Windows shell's pipe. See
|
224
|
+
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/193379
|
225
|
+
#
|
226
|
+
def generate_bin_script(filename, bindir)
|
227
|
+
File.open(File.join(bindir, File.basename(filename)), "w", 0755) do |file|
|
228
|
+
file.print app_script_text(filename)
|
240
229
|
end
|
230
|
+
generate_windows_script bindir, filename
|
231
|
+
end
|
241
232
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
233
|
+
##
|
234
|
+
# Creates the symlinks to run the applications in the gem. Moves
|
235
|
+
# the symlink if the gem being installed has a newer version.
|
236
|
+
#
|
237
|
+
def generate_bin_symlink(filename, bindir)
|
238
|
+
if Config::CONFIG["arch"] =~ /dos|win32/i then
|
239
|
+
alert_warning "Unable to use symlinks on win32, installing wrapper"
|
240
|
+
generate_bin_script filename, bindir
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
src = File.join @gem_dir, 'bin', filename
|
245
|
+
dst = File.join bindir, File.basename(filename)
|
246
|
+
|
247
|
+
if File.exist? dst then
|
248
|
+
if File.symlink? dst then
|
249
|
+
link = File.readlink(dst).split File::SEPARATOR
|
250
|
+
cur_version = Gem::Version.create(link[-3].sub(/^.*-/, ''))
|
251
|
+
return if @spec.version < cur_version
|
247
252
|
end
|
253
|
+
File.unlink dst
|
248
254
|
end
|
249
255
|
|
250
|
-
|
251
|
-
|
256
|
+
File.symlink src, dst
|
257
|
+
end
|
258
|
+
|
259
|
+
##
|
260
|
+
# Generates a #! line for +bin_file_name+'s wrapper copying arguments if
|
261
|
+
# necessary.
|
262
|
+
def shebang(bin_file_name)
|
263
|
+
if @env_shebang then
|
264
|
+
"#!/usr/bin/env ruby"
|
265
|
+
else
|
266
|
+
path = File.join @gem_dir, @spec.bindir, bin_file_name
|
267
|
+
|
252
268
|
File.open(path, "rb") do |file|
|
253
|
-
first_line = file.
|
254
|
-
|
255
|
-
if first_line =~ /^#!/
|
269
|
+
first_line = file.gets
|
270
|
+
if first_line =~ /^#!/ then
|
256
271
|
# Preserve extra words on shebang line, like "-w". Thanks RPA.
|
257
|
-
shebang = first_line.sub(/\A
|
272
|
+
shebang = first_line.sub(/\A\#!.*?ruby\S*/, "#!#{Gem.ruby}")
|
258
273
|
else
|
259
274
|
# Create a plain shebang line.
|
260
|
-
shebang = "
|
275
|
+
shebang = "#!#{Gem.ruby}"
|
261
276
|
end
|
262
|
-
return shebang.strip # Avoid nasty ^M issues.
|
263
|
-
end
|
264
|
-
end
|
265
277
|
|
266
|
-
|
267
|
-
|
278
|
+
shebang.strip # Avoid nasty ^M issues.
|
279
|
+
end
|
268
280
|
end
|
281
|
+
end
|
269
282
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
#{shebang
|
283
|
+
# Return the text for an application file.
|
284
|
+
def app_script_text(bin_file_name)
|
285
|
+
<<-TEXT
|
286
|
+
#{shebang bin_file_name}
|
274
287
|
#
|
275
288
|
# This file was generated by RubyGems.
|
276
289
|
#
|
277
|
-
# The application '#{spec.name}' is installed as part of a gem, and
|
278
|
-
# this file is here to facilitate running it.
|
290
|
+
# The application '#{@spec.name}' is installed as part of a gem, and
|
291
|
+
# this file is here to facilitate running it.
|
279
292
|
#
|
280
293
|
|
281
294
|
require 'rubygems'
|
282
|
-
|
295
|
+
|
296
|
+
version = "#{Gem::Requirement.default}"
|
297
|
+
|
283
298
|
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
|
284
299
|
version = $1
|
285
300
|
ARGV.shift
|
286
301
|
end
|
287
|
-
|
288
|
-
|
302
|
+
|
303
|
+
gem '#{@spec.name}', version
|
304
|
+
load '#{bin_file_name}'
|
289
305
|
TEXT
|
290
|
-
|
291
|
-
end
|
306
|
+
end
|
292
307
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
case extension
|
305
|
-
when /extconf/ then
|
306
|
-
builder = ExtExtConfBuilder
|
307
|
-
when /configure/ then
|
308
|
-
builder = ExtConfigureBuilder
|
309
|
-
when /rakefile/i, /mkrf_conf/i then
|
310
|
-
builder = ExtRakeBuilder
|
311
|
-
ran_rake = true
|
312
|
-
else
|
313
|
-
builder = nil
|
314
|
-
results = ["No builder for extension '#{extension}'"]
|
315
|
-
end
|
308
|
+
# return the stub script text used to launch the true ruby script
|
309
|
+
def windows_stub_script(bindir, bin_file_name)
|
310
|
+
<<-TEXT
|
311
|
+
@ECHO OFF
|
312
|
+
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
313
|
+
@"#{Gem.ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
314
|
+
GOTO :EOF
|
315
|
+
:WinNT
|
316
|
+
"%~dp0ruby.exe" "%~dpn0" %*
|
317
|
+
TEXT
|
318
|
+
end
|
316
319
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
320
|
+
# Builds extensions. Valid types of extensions are extconf.rb files,
|
321
|
+
# configure scripts and rakefiles or mkrf_conf files.
|
322
|
+
def build_extensions
|
323
|
+
return if @spec.extensions.empty?
|
324
|
+
say "Building native extensions. This could take a while..."
|
325
|
+
start_dir = Dir.pwd
|
326
|
+
dest_path = File.join @gem_dir, @spec.require_paths.first
|
327
|
+
ran_rake = false # only run rake once
|
328
|
+
|
329
|
+
@spec.extensions.each do |extension|
|
330
|
+
break if ran_rake
|
331
|
+
results = []
|
332
|
+
|
333
|
+
builder = case extension
|
334
|
+
when /extconf/ then
|
335
|
+
Gem::Ext::ExtConfBuilder
|
336
|
+
when /configure/ then
|
337
|
+
Gem::Ext::ConfigureBuilder
|
338
|
+
when /rakefile/i, /mkrf_conf/i then
|
339
|
+
ran_rake = true
|
340
|
+
Gem::Ext::RakeBuilder
|
341
|
+
else
|
342
|
+
results = ["No builder for extension '#{extension}'"]
|
343
|
+
nil
|
344
|
+
end
|
322
345
|
|
323
|
-
|
346
|
+
begin
|
347
|
+
Dir.chdir File.join(@gem_dir, File.dirname(extension))
|
348
|
+
results = builder.build(extension, @gem_dir, dest_path, results)
|
349
|
+
rescue => ex
|
350
|
+
results = results.join "\n"
|
324
351
|
|
325
|
-
|
352
|
+
File.open('gem_make.out', 'wb') { |f| f.puts results }
|
353
|
+
|
354
|
+
message = <<-EOF
|
326
355
|
ERROR: Failed to build gem native extension.
|
327
356
|
|
328
357
|
#{results}
|
329
358
|
|
330
|
-
Gem files will remain installed in #{
|
359
|
+
Gem files will remain installed in #{@gem_dir} for inspection.
|
331
360
|
Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
|
332
|
-
|
361
|
+
EOF
|
333
362
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
##
|
342
|
-
# Reads the YAML file index and then extracts each file
|
343
|
-
# into the supplied directory, building directories for the
|
344
|
-
# extracted files as needed.
|
345
|
-
#
|
346
|
-
# directory:: [String] The root directory to extract files into
|
347
|
-
# file:: [IO] The IO that contains the file data
|
348
|
-
#
|
349
|
-
def extract_files(directory, format)
|
350
|
-
directory = expand_and_validate(directory)
|
351
|
-
raise ArgumentError, "format required to extract from" if format.nil?
|
352
|
-
|
353
|
-
format.file_entries.each do |entry, file_data|
|
354
|
-
path = entry['path'].untaint
|
355
|
-
if path =~ /\A\// then # for extra sanity
|
356
|
-
raise Gem::InstallError,
|
357
|
-
"attempt to install file into #{entry['path'].inspect}"
|
358
|
-
end
|
359
|
-
path = File.expand_path File.join(directory, path)
|
360
|
-
if path !~ /\A#{Regexp.escape directory}/ then
|
361
|
-
msg = "attempt to install file into %p under %p" %
|
362
|
-
[entry['path'], directory]
|
363
|
-
raise Gem::InstallError, msg
|
364
|
-
end
|
365
|
-
FileUtils.mkdir_p File.dirname(path)
|
366
|
-
File.open(path, "wb") do |out|
|
367
|
-
out.write file_data
|
368
|
-
end
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
private
|
373
|
-
def expand_and_validate(directory)
|
374
|
-
directory = Pathname.new(directory).expand_path
|
375
|
-
unless directory.absolute?
|
376
|
-
raise ArgumentError, "install directory %p not absolute" % directory
|
363
|
+
raise ExtensionBuildError, message
|
364
|
+
ensure
|
365
|
+
Dir.chdir start_dir
|
377
366
|
end
|
378
|
-
directory.to_str
|
379
367
|
end
|
380
|
-
end
|
368
|
+
end
|
381
369
|
|
382
370
|
##
|
383
|
-
#
|
371
|
+
# Reads the file index and extracts each file into the gem directory.
|
384
372
|
#
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
##
|
390
|
-
# Constructs an Uninstaller instance
|
391
|
-
#
|
392
|
-
# gem:: [String] The Gem name to uninstall
|
393
|
-
#
|
394
|
-
def initialize(gem, options)
|
395
|
-
@gem = gem
|
396
|
-
@version = options[:version] || "> 0"
|
397
|
-
@force_executables = options[:executables]
|
398
|
-
@force_all = options[:all]
|
399
|
-
@force_ignore = options[:ignore]
|
400
|
-
end
|
373
|
+
# Ensures that files can't be installed outside the gem directory.
|
374
|
+
def extract_files
|
375
|
+
expand_and_validate_gem_dir
|
401
376
|
|
402
|
-
|
403
|
-
# Performs the uninstall of the Gem. This removes the spec, the
|
404
|
-
# Gem directory, and the cached .gem file,
|
405
|
-
#
|
406
|
-
# Application stubs are (or should be) removed according to what
|
407
|
-
# is still installed.
|
408
|
-
#
|
409
|
-
# XXX: Application stubs refer to specific gem versions, which
|
410
|
-
# means things may get inconsistent after an uninstall
|
411
|
-
# (i.e. referring to a version that no longer exists).
|
412
|
-
#
|
413
|
-
def uninstall
|
414
|
-
list = Gem.source_index.search(/^#{@gem}$/, @version)
|
415
|
-
if list.empty?
|
416
|
-
raise Gem::InstallError, "Unknown gem #{@gem}-#{@version}"
|
417
|
-
elsif list.size > 1 && @force_all
|
418
|
-
remove_all(list.dup)
|
419
|
-
remove_executables(list.last)
|
420
|
-
elsif list.size > 1
|
421
|
-
say
|
422
|
-
gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
|
423
|
-
gem_name, index =
|
424
|
-
choose_from_list("Select gem to uninstall:", gem_names)
|
425
|
-
if index == list.size
|
426
|
-
remove_all(list.dup)
|
427
|
-
remove_executables(list.last)
|
428
|
-
elsif index >= 0 && index < list.size
|
429
|
-
to_remove = list[index]
|
430
|
-
remove(to_remove, list)
|
431
|
-
remove_executables(to_remove)
|
432
|
-
else
|
433
|
-
say "Error: must enter a number [1-#{list.size+1}]"
|
434
|
-
end
|
435
|
-
else
|
436
|
-
remove(list[0], list.dup)
|
437
|
-
remove_executables(list.last)
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
##
|
442
|
-
# Remove executables and batch files (windows only) for the gem as
|
443
|
-
# it is being installed
|
444
|
-
#
|
445
|
-
# gemspec::[Specification] the gem whose executables need to be removed.
|
446
|
-
#
|
447
|
-
def remove_executables(gemspec)
|
448
|
-
return if gemspec.nil?
|
449
|
-
if(gemspec.executables.size > 0)
|
450
|
-
raise Gem::FilePermissionError.new(Gem.bindir) unless
|
451
|
-
File.writable?(Gem.bindir)
|
452
|
-
list = Gem.source_index.search(gemspec.name).delete_if { |spec|
|
453
|
-
spec.version == gemspec.version
|
454
|
-
}
|
455
|
-
executables = gemspec.executables.clone
|
456
|
-
list.each do |spec|
|
457
|
-
spec.executables.each do |exe_name|
|
458
|
-
executables.delete(exe_name)
|
459
|
-
end
|
460
|
-
end
|
461
|
-
return if executables.size == 0
|
462
|
-
answer = @force_executables || ask_yes_no(
|
463
|
-
"Remove executables and scripts for\n" +
|
464
|
-
"'#{gemspec.executables.join(", ")}' in addition to the gem?",
|
465
|
-
true) # " # appease ruby-mode - don't ask
|
466
|
-
unless answer
|
467
|
-
say "Executables and scripts will remain installed."
|
468
|
-
return
|
469
|
-
else
|
470
|
-
gemspec.executables.each do |exe_name|
|
471
|
-
say "Removing #{exe_name}"
|
472
|
-
File.unlink File.join(Gem.bindir, exe_name) rescue nil
|
473
|
-
File.unlink File.join(Gem.bindir, exe_name + ".cmd") rescue nil
|
474
|
-
end
|
475
|
-
end
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
#
|
480
|
-
# list:: the list of all gems to remove
|
481
|
-
#
|
482
|
-
# Warning: this method modifies the +list+ parameter. Once it has
|
483
|
-
# uninstalled a gem, it is removed from that list.
|
484
|
-
#
|
485
|
-
def remove_all(list)
|
486
|
-
list.dup.each { |gem| remove(gem, list) }
|
487
|
-
end
|
377
|
+
raise ArgumentError, "format required to extract from" if @format.nil?
|
488
378
|
|
489
|
-
|
490
|
-
|
491
|
-
# list:: the list of all such gems
|
492
|
-
#
|
493
|
-
# Warning: this method modifies the +list+ parameter. Once it has
|
494
|
-
# uninstalled a gem, it is removed from that list.
|
495
|
-
#
|
496
|
-
def remove(spec, list)
|
497
|
-
if( ! ok_to_remove?(spec)) then
|
498
|
-
raise DependencyRemovalException.new(
|
499
|
-
"Uninstallation aborted due to dependent gem(s)")
|
500
|
-
end
|
501
|
-
raise Gem::FilePermissionError.new(spec.installation_path) unless
|
502
|
-
File.writable?(spec.installation_path)
|
503
|
-
FileUtils.rm_rf spec.full_gem_path
|
504
|
-
FileUtils.rm_rf File.join(
|
505
|
-
spec.installation_path,
|
506
|
-
'specifications',
|
507
|
-
"#{spec.full_name}.gemspec")
|
508
|
-
FileUtils.rm_rf File.join(
|
509
|
-
spec.installation_path,
|
510
|
-
'cache',
|
511
|
-
"#{spec.full_name}.gem")
|
512
|
-
DocManager.new(spec).uninstall_doc
|
513
|
-
#remove_stub_files(spec, list - [spec])
|
514
|
-
say "Successfully uninstalled #{spec.name} version #{spec.version}"
|
515
|
-
list.delete(spec)
|
516
|
-
end
|
517
|
-
|
518
|
-
def ok_to_remove?(spec)
|
519
|
-
return true if @force_ignore
|
520
|
-
srcindex= Gem::SourceIndex.from_installed_gems
|
521
|
-
deplist = Gem::DependencyList.from_source_index(srcindex)
|
522
|
-
deplist.ok_to_remove?(spec.full_name) ||
|
523
|
-
ask_if_ok(spec)
|
524
|
-
end
|
525
|
-
|
526
|
-
def ask_if_ok(spec)
|
527
|
-
msg = ['']
|
528
|
-
msg << 'You have requested to uninstall the gem:'
|
529
|
-
msg << "\t#{spec.full_name}"
|
530
|
-
spec.dependent_gems.each do |gem,dep,satlist|
|
531
|
-
msg <<
|
532
|
-
("#{gem.name}-#{gem.version} depends on " +
|
533
|
-
"[#{dep.name} (#{dep.version_requirements})]")
|
534
|
-
end
|
535
|
-
msg << 'If you remove this gems, one or more dependencies will not be met.'
|
536
|
-
msg << 'Continue with Uninstall?'
|
537
|
-
return ask_yes_no(msg.join("\n"), true)
|
538
|
-
end
|
539
|
-
|
540
|
-
private
|
541
|
-
|
542
|
-
##
|
543
|
-
# Remove application stub files. These are detected by the line
|
544
|
-
# # This file was generated by RubyGems.
|
545
|
-
#
|
546
|
-
# spec:: the spec of the gem that is being uninstalled
|
547
|
-
# other_specs:: any other installed specs for this gem
|
548
|
-
# (i.e. different versions)
|
549
|
-
#
|
550
|
-
# Both parameters are necessary to ensure that the correct files
|
551
|
-
# are uninstalled. It is assumed that +other_specs+ contains only
|
552
|
-
# *installed* gems, except the one that's about to be uninstalled.
|
553
|
-
#
|
554
|
-
def remove_stub_files(spec, other_specs)
|
555
|
-
remove_app_stubs(spec, other_specs)
|
556
|
-
end
|
379
|
+
@format.file_entries.each do |entry, file_data|
|
380
|
+
path = entry['path'].untaint
|
557
381
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
# what we delete isn't needed by any remaining versions of the
|
562
|
-
# gem.
|
563
|
-
#
|
564
|
-
# There's extra trickiness, too, because app stubs 'gem'
|
565
|
-
# a specific version of the gem. If we uninstall the latest
|
566
|
-
# gem, we should ensure that there is a sensible app stub(s)
|
567
|
-
# installed after the removal of the current one.
|
568
|
-
#
|
569
|
-
# Perhaps the best way to approach this is:
|
570
|
-
# * remove all application stubs for this gemspec
|
571
|
-
# * regenerate the app stubs for the latest remaining version
|
572
|
-
# (you always want to have the latest version of an app,
|
573
|
-
# don't you?)
|
574
|
-
#
|
575
|
-
# The Installer class doesn't really support this approach very
|
576
|
-
# well at the moment.
|
577
|
-
end
|
578
|
-
|
579
|
-
end # class Uninstaller
|
580
|
-
|
581
|
-
class ExtBuilder
|
582
|
-
|
583
|
-
def self.class_name
|
584
|
-
name =~ /Ext(.*)Builder/
|
585
|
-
$1.downcase
|
586
|
-
end
|
587
|
-
|
588
|
-
def self.make(dest_path, results)
|
589
|
-
unless File.exist? 'Makefile' then
|
590
|
-
raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
|
382
|
+
if path =~ /\A\// then # for extra sanity
|
383
|
+
raise Gem::InstallError,
|
384
|
+
"attempt to install file into #{entry['path'].inspect}"
|
591
385
|
end
|
592
386
|
|
593
|
-
|
594
|
-
mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}")
|
595
|
-
mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}")
|
596
|
-
|
597
|
-
File.open('Makefile', 'wb') {|f| f.print mf}
|
387
|
+
path = File.expand_path File.join(@gem_dir, path)
|
598
388
|
|
599
|
-
|
600
|
-
|
601
|
-
|
389
|
+
if path !~ /\A#{Regexp.escape @gem_dir}/ then
|
390
|
+
msg = "attempt to install file into %p under %p" %
|
391
|
+
[entry['path'], @gem_dir]
|
392
|
+
raise Gem::InstallError, msg
|
602
393
|
end
|
603
394
|
|
604
|
-
|
605
|
-
cmd = "#{make_program}#{target}"
|
606
|
-
results << cmd
|
607
|
-
results << `#{cmd} #{redirector}`
|
395
|
+
FileUtils.mkdir_p File.dirname(path)
|
608
396
|
|
609
|
-
|
610
|
-
|
397
|
+
File.open(path, "wb") do |out|
|
398
|
+
out.write file_data
|
611
399
|
end
|
612
400
|
end
|
613
|
-
|
614
|
-
def self.redirector
|
615
|
-
'2>&1'
|
616
|
-
end
|
617
|
-
|
618
|
-
def self.run(command, results)
|
619
|
-
results << command
|
620
|
-
results << `#{command} #{redirector}`
|
621
|
-
|
622
|
-
unless $?.exitstatus.zero? then
|
623
|
-
raise Gem::InstallError, "#{class_name} failed:\n\n#{results.join "\n"}"
|
624
|
-
end
|
625
|
-
end
|
626
|
-
|
627
401
|
end
|
628
402
|
|
629
|
-
|
630
|
-
def self.build(extension, directory, dest_path, results)
|
631
|
-
unless File.exist?('Makefile') then
|
632
|
-
cmd = "sh ./configure --prefix=#{dest_path}"
|
403
|
+
private
|
633
404
|
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
make dest_path, results
|
638
|
-
|
639
|
-
results
|
640
|
-
end
|
405
|
+
# HACK Pathname is broken on windows.
|
406
|
+
def absolute_path? pathname
|
407
|
+
pathname.absolute? or (Gem.win_platform? and pathname.to_s =~ /\A[a-z]:/i)
|
641
408
|
end
|
642
409
|
|
643
|
-
|
644
|
-
|
645
|
-
cmd = "#{Gem.ruby} #{File.basename extension}"
|
646
|
-
cmd << " #{ARGV.join " "}" unless ARGV.empty?
|
410
|
+
def expand_and_validate_gem_dir
|
411
|
+
@gem_dir = Pathname.new(@gem_dir).expand_path
|
647
412
|
|
648
|
-
|
649
|
-
|
650
|
-
make dest_path, results
|
651
|
-
|
652
|
-
results
|
413
|
+
unless absolute_path?(@gem_dir) then # HACK is this possible after #expand_path?
|
414
|
+
raise ArgumentError, "install directory %p not absolute" % @gem_dir
|
653
415
|
end
|
654
|
-
end
|
655
|
-
|
656
|
-
class ExtRakeBuilder < ExtBuilder
|
657
|
-
def ExtRakeBuilder.build(ext, directory, dest_path, results)
|
658
|
-
cmd = ENV['rake'] || 'rake'
|
659
|
-
cmd << " RUBYARCHDIR=#{dest_path} RUBYLIBDIR=#{dest_path} extension"
|
660
416
|
|
661
|
-
|
662
|
-
|
663
|
-
results
|
664
|
-
end
|
417
|
+
@gem_dir = @gem_dir.to_s
|
665
418
|
end
|
666
419
|
|
667
|
-
end
|
420
|
+
end
|
421
|
+
|