libgems 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +5811 -0
- data/History.txt +887 -0
- data/LICENSE.txt +51 -0
- data/README.md +87 -0
- data/Rakefile +113 -0
- data/lib/gauntlet_libgems.rb +50 -0
- data/lib/libgems.rb +1246 -0
- data/lib/libgems/builder.rb +102 -0
- data/lib/libgems/command.rb +534 -0
- data/lib/libgems/command_manager.rb +182 -0
- data/lib/libgems/commands/build_command.rb +53 -0
- data/lib/libgems/commands/cert_command.rb +86 -0
- data/lib/libgems/commands/check_command.rb +80 -0
- data/lib/libgems/commands/cleanup_command.rb +106 -0
- data/lib/libgems/commands/contents_command.rb +98 -0
- data/lib/libgems/commands/dependency_command.rb +195 -0
- data/lib/libgems/commands/environment_command.rb +133 -0
- data/lib/libgems/commands/fetch_command.rb +67 -0
- data/lib/libgems/commands/generate_index_command.rb +133 -0
- data/lib/libgems/commands/help_command.rb +172 -0
- data/lib/libgems/commands/install_command.rb +178 -0
- data/lib/libgems/commands/list_command.rb +35 -0
- data/lib/libgems/commands/lock_command.rb +110 -0
- data/lib/libgems/commands/mirror_command.rb +111 -0
- data/lib/libgems/commands/outdated_command.rb +33 -0
- data/lib/libgems/commands/owner_command.rb +75 -0
- data/lib/libgems/commands/pristine_command.rb +93 -0
- data/lib/libgems/commands/push_command.rb +56 -0
- data/lib/libgems/commands/query_command.rb +280 -0
- data/lib/libgems/commands/rdoc_command.rb +91 -0
- data/lib/libgems/commands/search_command.rb +31 -0
- data/lib/libgems/commands/server_command.rb +86 -0
- data/lib/libgems/commands/sources_command.rb +157 -0
- data/lib/libgems/commands/specification_command.rb +125 -0
- data/lib/libgems/commands/stale_command.rb +27 -0
- data/lib/libgems/commands/uninstall_command.rb +83 -0
- data/lib/libgems/commands/unpack_command.rb +121 -0
- data/lib/libgems/commands/update_command.rb +160 -0
- data/lib/libgems/commands/which_command.rb +86 -0
- data/lib/libgems/config_file.rb +345 -0
- data/lib/libgems/custom_require.rb +44 -0
- data/lib/libgems/defaults.rb +101 -0
- data/lib/libgems/dependency.rb +227 -0
- data/lib/libgems/dependency_installer.rb +286 -0
- data/lib/libgems/dependency_list.rb +208 -0
- data/lib/libgems/doc_manager.rb +242 -0
- data/lib/libgems/errors.rb +35 -0
- data/lib/libgems/exceptions.rb +91 -0
- data/lib/libgems/ext.rb +18 -0
- data/lib/libgems/ext/builder.rb +56 -0
- data/lib/libgems/ext/configure_builder.rb +25 -0
- data/lib/libgems/ext/ext_conf_builder.rb +24 -0
- data/lib/libgems/ext/rake_builder.rb +39 -0
- data/lib/libgems/format.rb +81 -0
- data/lib/libgems/gem_openssl.rb +92 -0
- data/lib/libgems/gem_path_searcher.rb +100 -0
- data/lib/libgems/gem_runner.rb +79 -0
- data/lib/libgems/gemcutter_utilities.rb +49 -0
- data/lib/libgems/indexer.rb +720 -0
- data/lib/libgems/install_update_options.rb +125 -0
- data/lib/libgems/installer.rb +604 -0
- data/lib/libgems/local_remote_options.rb +135 -0
- data/lib/libgems/old_format.rb +153 -0
- data/lib/libgems/package.rb +97 -0
- data/lib/libgems/package/f_sync_dir.rb +23 -0
- data/lib/libgems/package/tar_header.rb +266 -0
- data/lib/libgems/package/tar_input.rb +222 -0
- data/lib/libgems/package/tar_output.rb +144 -0
- data/lib/libgems/package/tar_reader.rb +106 -0
- data/lib/libgems/package/tar_reader/entry.rb +141 -0
- data/lib/libgems/package/tar_writer.rb +241 -0
- data/lib/libgems/package_task.rb +126 -0
- data/lib/libgems/platform.rb +183 -0
- data/lib/libgems/remote_fetcher.rb +414 -0
- data/lib/libgems/require_paths_builder.rb +18 -0
- data/lib/libgems/requirement.rb +153 -0
- data/lib/libgems/security.rb +814 -0
- data/lib/libgems/server.rb +872 -0
- data/lib/libgems/source_index.rb +597 -0
- data/lib/libgems/source_info_cache.rb +395 -0
- data/lib/libgems/source_info_cache_entry.rb +56 -0
- data/lib/libgems/spec_fetcher.rb +337 -0
- data/lib/libgems/specification.rb +1487 -0
- data/lib/libgems/test_utilities.rb +147 -0
- data/lib/libgems/text.rb +65 -0
- data/lib/libgems/uninstaller.rb +278 -0
- data/lib/libgems/user_interaction.rb +527 -0
- data/lib/libgems/validator.rb +240 -0
- data/lib/libgems/version.rb +316 -0
- data/lib/libgems/version_option.rb +65 -0
- data/lib/rbconfig/datadir.rb +20 -0
- data/test/bogussources.rb +8 -0
- data/test/data/gem-private_key.pem +27 -0
- data/test/data/gem-public_cert.pem +20 -0
- data/test/fake_certlib/openssl.rb +7 -0
- data/test/foo/discover.rb +0 -0
- data/test/gem_installer_test_case.rb +97 -0
- data/test/gem_package_tar_test_case.rb +132 -0
- data/test/gemutilities.rb +605 -0
- data/test/insure_session.rb +43 -0
- data/test/mockgemui.rb +56 -0
- data/test/plugin/exception/libgems_plugin.rb +2 -0
- data/test/plugin/load/libgems_plugin.rb +1 -0
- data/test/plugin/standarderror/libgems_plugin.rb +2 -0
- data/test/private_key.pem +27 -0
- data/test/public_cert.pem +20 -0
- data/test/rubygems_plugin.rb +21 -0
- data/test/simple_gem.rb +66 -0
- data/test/test_config.rb +12 -0
- data/test/test_gem.rb +780 -0
- data/test/test_gem_builder.rb +27 -0
- data/test/test_gem_command.rb +178 -0
- data/test/test_gem_command_manager.rb +207 -0
- data/test/test_gem_commands_build_command.rb +74 -0
- data/test/test_gem_commands_cert_command.rb +124 -0
- data/test/test_gem_commands_check_command.rb +18 -0
- data/test/test_gem_commands_contents_command.rb +156 -0
- data/test/test_gem_commands_dependency_command.rb +216 -0
- data/test/test_gem_commands_environment_command.rb +144 -0
- data/test/test_gem_commands_fetch_command.rb +76 -0
- data/test/test_gem_commands_generate_index_command.rb +135 -0
- data/test/test_gem_commands_install_command.rb +315 -0
- data/test/test_gem_commands_list_command.rb +36 -0
- data/test/test_gem_commands_lock_command.rb +68 -0
- data/test/test_gem_commands_mirror_command.rb +60 -0
- data/test/test_gem_commands_outdated_command.rb +40 -0
- data/test/test_gem_commands_owner_command.rb +105 -0
- data/test/test_gem_commands_pristine_command.rb +108 -0
- data/test/test_gem_commands_push_command.rb +81 -0
- data/test/test_gem_commands_query_command.rb +426 -0
- data/test/test_gem_commands_server_command.rb +59 -0
- data/test/test_gem_commands_sources_command.rb +209 -0
- data/test/test_gem_commands_specification_command.rb +139 -0
- data/test/test_gem_commands_stale_command.rb +38 -0
- data/test/test_gem_commands_uninstall_command.rb +83 -0
- data/test/test_gem_commands_unpack_command.rb +199 -0
- data/test/test_gem_commands_update_command.rb +207 -0
- data/test/test_gem_commands_which_command.rb +66 -0
- data/test/test_gem_config_file.rb +287 -0
- data/test/test_gem_dependency.rb +149 -0
- data/test/test_gem_dependency_installer.rb +661 -0
- data/test/test_gem_dependency_list.rb +230 -0
- data/test/test_gem_doc_manager.rb +31 -0
- data/test/test_gem_ext_configure_builder.rb +84 -0
- data/test/test_gem_ext_ext_conf_builder.rb +173 -0
- data/test/test_gem_ext_rake_builder.rb +81 -0
- data/test/test_gem_format.rb +70 -0
- data/test/test_gem_gem_path_searcher.rb +78 -0
- data/test/test_gem_gem_runner.rb +45 -0
- data/test/test_gem_gemcutter_utilities.rb +103 -0
- data/test/test_gem_indexer.rb +673 -0
- data/test/test_gem_install_update_options.rb +68 -0
- data/test/test_gem_installer.rb +857 -0
- data/test/test_gem_local_remote_options.rb +97 -0
- data/test/test_gem_package_tar_header.rb +130 -0
- data/test/test_gem_package_tar_input.rb +112 -0
- data/test/test_gem_package_tar_output.rb +97 -0
- data/test/test_gem_package_tar_reader.rb +46 -0
- data/test/test_gem_package_tar_reader_entry.rb +109 -0
- data/test/test_gem_package_tar_writer.rb +144 -0
- data/test/test_gem_package_task.rb +59 -0
- data/test/test_gem_platform.rb +264 -0
- data/test/test_gem_remote_fetcher.rb +740 -0
- data/test/test_gem_requirement.rb +292 -0
- data/test/test_gem_server.rb +356 -0
- data/test/test_gem_silent_ui.rb +113 -0
- data/test/test_gem_source_index.rb +461 -0
- data/test/test_gem_spec_fetcher.rb +410 -0
- data/test/test_gem_specification.rb +1334 -0
- data/test/test_gem_stream_ui.rb +218 -0
- data/test/test_gem_text.rb +43 -0
- data/test/test_gem_uninstaller.rb +146 -0
- data/test/test_gem_validator.rb +63 -0
- data/test/test_gem_version.rb +181 -0
- data/test/test_gem_version_option.rb +89 -0
- data/test/test_kernel.rb +59 -0
- metadata +402 -0
|
@@ -0,0 +1,125 @@
|
|
|
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 'libgems'
|
|
8
|
+
require 'libgems/security'
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
# Mixin methods for install and update options for LibGems::Commands
|
|
12
|
+
|
|
13
|
+
module LibGems::InstallUpdateOptions
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Add the install/update options to the option parser.
|
|
17
|
+
|
|
18
|
+
def add_install_update_options
|
|
19
|
+
OptionParser.accept LibGems::Security::Policy do |value|
|
|
20
|
+
value = LibGems::Security::Policies[value]
|
|
21
|
+
valid = LibGems::Security::Policies.keys.sort
|
|
22
|
+
message = "#{value} (#{valid.join ', '} are valid)"
|
|
23
|
+
raise OptionParser::InvalidArgument, message if value.nil?
|
|
24
|
+
value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
add_option(:"Install/Update", '-i', '--install-dir DIR',
|
|
28
|
+
'Gem repository directory to get installed',
|
|
29
|
+
'gems') do |value, options|
|
|
30
|
+
options[:install_dir] = File.expand_path(value)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
add_option(:"Install/Update", '-n', '--bindir DIR',
|
|
34
|
+
'Directory where binary files are',
|
|
35
|
+
'located') do |value, options|
|
|
36
|
+
options[:bin_dir] = File.expand_path(value)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
add_option(:"Install/Update", '-d', '--[no-]rdoc',
|
|
40
|
+
'Generate RDoc documentation for the gem on',
|
|
41
|
+
'install') do |value, options|
|
|
42
|
+
options[:generate_rdoc] = value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
add_option(:"Install/Update", '--[no-]ri',
|
|
46
|
+
'Generate RI documentation for the gem on',
|
|
47
|
+
'install') do |value, options|
|
|
48
|
+
options[:generate_ri] = value
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
add_option(:"Install/Update", '-E', '--[no-]env-shebang',
|
|
52
|
+
"Rewrite the shebang line on installed",
|
|
53
|
+
"scripts to use /usr/bin/env") do |value, options|
|
|
54
|
+
options[:env_shebang] = value
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
add_option(:"Install/Update", '-f', '--[no-]force',
|
|
58
|
+
'Force gem to install, bypassing dependency',
|
|
59
|
+
'checks') do |value, options|
|
|
60
|
+
options[:force] = value
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
add_option(:"Install/Update", '-t', '--[no-]test',
|
|
64
|
+
'Run unit tests prior to installation') do |value, options|
|
|
65
|
+
options[:test] = value
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
add_option(:"Install/Update", '-w', '--[no-]wrappers',
|
|
69
|
+
'Use bin wrappers for executables',
|
|
70
|
+
'Not available on dosish platforms') do |value, options|
|
|
71
|
+
options[:wrappers] = value
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
add_option(:"Install/Update", '-P', '--trust-policy POLICY',
|
|
75
|
+
LibGems::Security::Policy,
|
|
76
|
+
'Specify gem trust policy') do |value, options|
|
|
77
|
+
options[:security_policy] = value
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
add_option(:"Install/Update", '--ignore-dependencies',
|
|
81
|
+
'Do not install any required dependent gems') do |value, options|
|
|
82
|
+
options[:ignore_dependencies] = value
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
add_option(:"Install/Update", '-y', '--include-dependencies',
|
|
86
|
+
'Unconditionally install the required',
|
|
87
|
+
'dependent gems') do |value, options|
|
|
88
|
+
options[:include_dependencies] = value
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
add_option(:"Install/Update", '--[no-]format-executable',
|
|
92
|
+
'Make installed executable names match ruby.',
|
|
93
|
+
'If ruby is ruby18, foo_exec will be',
|
|
94
|
+
'foo_exec18') do |value, options|
|
|
95
|
+
options[:format_executable] = value
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
add_option(:"Install/Update", '--[no-]user-install',
|
|
99
|
+
'Install in user\'s home directory instead',
|
|
100
|
+
'of GEM_HOME.') do |value, options|
|
|
101
|
+
options[:user_install] = value
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
add_option(:"Install/Update", "--development",
|
|
105
|
+
"Install any additional development",
|
|
106
|
+
"dependencies") do |value, options|
|
|
107
|
+
options[:development] = true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
add_option(:"Install/Update", "--conservative",
|
|
111
|
+
"Don't attempt to upgrade gems already",
|
|
112
|
+
"meeting version requirement") do |value, options|
|
|
113
|
+
options[:conservative] = true
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# Default options for the gem install command.
|
|
119
|
+
|
|
120
|
+
def install_update_defaults_str
|
|
121
|
+
'--rdoc --no-force --no-test --wrappers'
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
@@ -0,0 +1,604 @@
|
|
|
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 'fileutils'
|
|
8
|
+
require 'rbconfig'
|
|
9
|
+
|
|
10
|
+
require 'libgems/format'
|
|
11
|
+
require 'libgems/ext'
|
|
12
|
+
require 'libgems/require_paths_builder'
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# The installer class processes RubyGem .gem files and installs the files
|
|
16
|
+
# contained in the .gem into the LibGems.path.
|
|
17
|
+
#
|
|
18
|
+
# LibGems::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
|
+
#
|
|
23
|
+
# The installer fires pre and post install hooks. Hooks can be added either
|
|
24
|
+
# through a rubygems_plugin.rb file in an installed gem or via a
|
|
25
|
+
# rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb
|
|
26
|
+
# file. See LibGems.pre_install and LibGems.post_install for details.
|
|
27
|
+
|
|
28
|
+
class LibGems::Installer
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# Paths where env(1) might live. Some systems are broken and have it in
|
|
32
|
+
# /bin
|
|
33
|
+
|
|
34
|
+
ENV_PATHS = %w[/usr/bin/env /bin/env]
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Raised when there is an error while building extensions.
|
|
38
|
+
#
|
|
39
|
+
class ExtensionBuildError < LibGems::InstallError; end
|
|
40
|
+
|
|
41
|
+
include LibGems::UserInteraction
|
|
42
|
+
|
|
43
|
+
include LibGems::RequirePathsBuilder
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# The directory a gem's executables will be installed into
|
|
47
|
+
|
|
48
|
+
attr_reader :bin_dir
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# The gem repository the gem will be installed into
|
|
52
|
+
|
|
53
|
+
attr_reader :gem_home
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# The LibGems::Specification for the gem being installed
|
|
57
|
+
|
|
58
|
+
attr_reader :spec
|
|
59
|
+
|
|
60
|
+
##
|
|
61
|
+
# The options passed when the LibGems::Installer was instantiated.
|
|
62
|
+
|
|
63
|
+
attr_accessor :options
|
|
64
|
+
|
|
65
|
+
@path_warning = false
|
|
66
|
+
|
|
67
|
+
class << self
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# True if we've warned about PATH not including LibGems.bindir
|
|
71
|
+
|
|
72
|
+
attr_accessor :path_warning
|
|
73
|
+
|
|
74
|
+
attr_writer :exec_format
|
|
75
|
+
|
|
76
|
+
# Defaults to use Ruby's program prefix and suffix.
|
|
77
|
+
def exec_format
|
|
78
|
+
@exec_format ||= LibGems.default_exec_format
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Constructs an Installer instance that will install the gem located at
|
|
85
|
+
# +gem+. +options+ is a Hash with the following keys:
|
|
86
|
+
#
|
|
87
|
+
# :env_shebang:: Use /usr/bin/env in bin wrappers.
|
|
88
|
+
# :force:: Overrides all version checks and security policy checks, except
|
|
89
|
+
# for a signed-gems-only policy.
|
|
90
|
+
# :ignore_dependencies:: Don't raise if a dependency is missing.
|
|
91
|
+
# :install_dir:: The directory to install the gem into.
|
|
92
|
+
# :format_executable:: Format the executable the same as the ruby executable.
|
|
93
|
+
# If your ruby is ruby18, foo_exec will be installed as
|
|
94
|
+
# foo_exec18.
|
|
95
|
+
# :security_policy:: Use the specified security policy. See LibGems::Security
|
|
96
|
+
# :wrappers:: Install wrappers if true, symlinks if false.
|
|
97
|
+
|
|
98
|
+
def initialize(gem, options={})
|
|
99
|
+
@gem = gem
|
|
100
|
+
@options = options
|
|
101
|
+
process_options
|
|
102
|
+
load_gem_file
|
|
103
|
+
|
|
104
|
+
if options[:user_install] and not options[:unpack] then
|
|
105
|
+
@gem_home = LibGems.user_dir
|
|
106
|
+
check_that_user_bin_dir_is_in_path
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
verify_gem_home(options[:unpack])
|
|
110
|
+
|
|
111
|
+
@spec = @format.spec
|
|
112
|
+
|
|
113
|
+
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
##
|
|
117
|
+
# Installs the gem and returns a loaded LibGems::Specification for the installed
|
|
118
|
+
# gem.
|
|
119
|
+
#
|
|
120
|
+
# The gem will be installed with the following structure:
|
|
121
|
+
#
|
|
122
|
+
# @gem_home/
|
|
123
|
+
# cache/<gem-version>.gem #=> a cached copy of the installed gem
|
|
124
|
+
# gems/<gem-version>/... #=> extracted files
|
|
125
|
+
# specifications/<gem-version>.gemspec #=> the LibGems::Specification
|
|
126
|
+
|
|
127
|
+
def install
|
|
128
|
+
# If we're forcing the install then disable security unless the security
|
|
129
|
+
# policy says that we only install singed gems.
|
|
130
|
+
@security_policy = nil if @force and @security_policy and
|
|
131
|
+
not @security_policy.only_signed
|
|
132
|
+
|
|
133
|
+
unless @force
|
|
134
|
+
ensure_required_ruby_version_met
|
|
135
|
+
ensure_required_rubygems_version_met
|
|
136
|
+
ensure_dependencies_met unless @ignore_dependencies
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
LibGems.pre_install_hooks.each do |hook|
|
|
140
|
+
result = hook.call self
|
|
141
|
+
|
|
142
|
+
if result == false then
|
|
143
|
+
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
|
|
144
|
+
|
|
145
|
+
message = "pre-install hook#{location} failed for #{spec.full_name}"
|
|
146
|
+
raise LibGems::InstallError, message
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
LibGems.ensure_gem_subdirectories @gem_home
|
|
151
|
+
|
|
152
|
+
FileUtils.mkdir_p @gem_dir
|
|
153
|
+
|
|
154
|
+
extract_files
|
|
155
|
+
build_extensions
|
|
156
|
+
|
|
157
|
+
LibGems.post_build_hooks.each do |hook|
|
|
158
|
+
result = hook.call self
|
|
159
|
+
|
|
160
|
+
if result == false then
|
|
161
|
+
FileUtils.rm_rf @gem_dir
|
|
162
|
+
|
|
163
|
+
location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
|
|
164
|
+
|
|
165
|
+
message = "post-build hook#{location} failed for #{spec.full_name}"
|
|
166
|
+
raise LibGems::InstallError, message
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
generate_bin
|
|
171
|
+
write_spec
|
|
172
|
+
|
|
173
|
+
write_require_paths_file_if_needed
|
|
174
|
+
|
|
175
|
+
# HACK remove? Isn't this done in multiple places?
|
|
176
|
+
cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
|
|
177
|
+
unless File.exist? cached_gem then
|
|
178
|
+
FileUtils.cp @gem, File.join(@gem_home, "cache")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
unless @spec.post_install_message.nil?
|
|
182
|
+
# Only for SlimGems
|
|
183
|
+
if @spec.name == LibGems::GEM_NAME
|
|
184
|
+
lines = @spec.post_install_message.split("\n")
|
|
185
|
+
lines.shift if lines.first.include?("Upgraded from #{LibGems::NAME}")
|
|
186
|
+
say lines.join("\n")
|
|
187
|
+
else
|
|
188
|
+
say @spec.post_install_message
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
@spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name)
|
|
193
|
+
|
|
194
|
+
@source_index.add_spec @spec
|
|
195
|
+
|
|
196
|
+
LibGems.post_install_hooks.each do |hook|
|
|
197
|
+
hook.call self
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
return @spec
|
|
201
|
+
rescue Zlib::GzipFile::Error
|
|
202
|
+
raise LibGems::InstallError, "gzip error installing #{@gem}"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
##
|
|
206
|
+
# Ensure that the dependency is satisfied by the current installation of
|
|
207
|
+
# gem. If it is not an exception is raised.
|
|
208
|
+
#
|
|
209
|
+
# spec :: LibGems::Specification
|
|
210
|
+
# dependency :: LibGems::Dependency
|
|
211
|
+
|
|
212
|
+
def ensure_dependency(spec, dependency)
|
|
213
|
+
unless installation_satisfies_dependency? dependency then
|
|
214
|
+
raise LibGems::InstallError, "#{spec.name} requires #{dependency}"
|
|
215
|
+
end
|
|
216
|
+
true
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
##
|
|
220
|
+
# True if the gems in the source_index satisfy +dependency+.
|
|
221
|
+
|
|
222
|
+
def installation_satisfies_dependency?(dependency)
|
|
223
|
+
@source_index.find_name(dependency.name, dependency.requirement).size > 0
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
##
|
|
227
|
+
# Unpacks the gem into the given directory.
|
|
228
|
+
|
|
229
|
+
def unpack(directory)
|
|
230
|
+
@gem_dir = directory
|
|
231
|
+
@format = LibGems::Format.from_file_by_path @gem, @security_policy
|
|
232
|
+
extract_files
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
##
|
|
236
|
+
# Writes the .gemspec specification (in Ruby) to the gem home's
|
|
237
|
+
# specifications directory.
|
|
238
|
+
|
|
239
|
+
def write_spec
|
|
240
|
+
rubycode = @spec.to_ruby
|
|
241
|
+
|
|
242
|
+
file_name = File.join @gem_home, 'specifications', @spec.spec_name
|
|
243
|
+
|
|
244
|
+
file_name.untaint
|
|
245
|
+
|
|
246
|
+
File.open(file_name, "w") do |file|
|
|
247
|
+
file.puts rubycode
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
##
|
|
252
|
+
# Creates windows .bat files for easy running of commands
|
|
253
|
+
|
|
254
|
+
def generate_windows_script(filename, bindir)
|
|
255
|
+
if LibGems.win_platform? then
|
|
256
|
+
script_name = filename + ".bat"
|
|
257
|
+
script_path = File.join bindir, File.basename(script_name)
|
|
258
|
+
File.open script_path, 'w' do |file|
|
|
259
|
+
file.puts windows_stub_script(bindir, filename)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
say script_path if LibGems.configuration.really_verbose
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def generate_bin
|
|
267
|
+
return if @spec.executables.nil? or @spec.executables.empty?
|
|
268
|
+
|
|
269
|
+
# If the user has asked for the gem to be installed in a directory that is
|
|
270
|
+
# the system gem directory, then use the system bin directory, else create
|
|
271
|
+
# (or use) a new bin dir under the gem_home.
|
|
272
|
+
bindir = @bin_dir ? @bin_dir : LibGems.bindir(@gem_home)
|
|
273
|
+
|
|
274
|
+
Dir.mkdir bindir unless File.exist? bindir
|
|
275
|
+
raise LibGems::FilePermissionError.new(bindir) unless File.writable? bindir
|
|
276
|
+
|
|
277
|
+
@spec.executables.each do |filename|
|
|
278
|
+
filename.untaint
|
|
279
|
+
bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir
|
|
280
|
+
mode = File.stat(bin_path).mode | 0111
|
|
281
|
+
File.chmod mode, bin_path
|
|
282
|
+
|
|
283
|
+
if @wrappers then
|
|
284
|
+
generate_bin_script filename, bindir
|
|
285
|
+
else
|
|
286
|
+
generate_bin_symlink filename, bindir
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
##
|
|
292
|
+
# Creates the scripts to run the applications in the gem.
|
|
293
|
+
#--
|
|
294
|
+
# The Windows script is generated in addition to the regular one due to a
|
|
295
|
+
# bug or misfeature in the Windows shell's pipe. See
|
|
296
|
+
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/193379
|
|
297
|
+
|
|
298
|
+
def generate_bin_script(filename, bindir)
|
|
299
|
+
bin_script_path = File.join bindir, formatted_program_filename(filename)
|
|
300
|
+
|
|
301
|
+
File.join @gem_dir, @spec.bindir, filename
|
|
302
|
+
|
|
303
|
+
# HACK some gems don't have #! in their executables, restore 2008/06
|
|
304
|
+
#if File.read(exec_path, 2) == '#!' then
|
|
305
|
+
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
|
|
306
|
+
|
|
307
|
+
File.open bin_script_path, 'w', 0755 do |file|
|
|
308
|
+
file.print app_script_text(filename)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
say bin_script_path if LibGems.configuration.really_verbose
|
|
312
|
+
|
|
313
|
+
generate_windows_script filename, bindir
|
|
314
|
+
#else
|
|
315
|
+
# FileUtils.rm_f bin_script_path
|
|
316
|
+
# FileUtils.cp exec_path, bin_script_path,
|
|
317
|
+
# :verbose => LibGems.configuration.really_verbose
|
|
318
|
+
#end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
##
|
|
322
|
+
# Creates the symlinks to run the applications in the gem. Moves
|
|
323
|
+
# the symlink if the gem being installed has a newer version.
|
|
324
|
+
|
|
325
|
+
def generate_bin_symlink(filename, bindir)
|
|
326
|
+
if LibGems.win_platform? then
|
|
327
|
+
alert_warning "Unable to use symlinks on Windows, installing wrapper"
|
|
328
|
+
generate_bin_script filename, bindir
|
|
329
|
+
return
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
src = File.join @gem_dir, 'bin', filename
|
|
333
|
+
dst = File.join bindir, formatted_program_filename(filename)
|
|
334
|
+
|
|
335
|
+
if File.exist? dst then
|
|
336
|
+
if File.symlink? dst then
|
|
337
|
+
link = File.readlink(dst).split File::SEPARATOR
|
|
338
|
+
cur_version = LibGems::Version.create(link[-3].sub(/^.*-/, ''))
|
|
339
|
+
return if @spec.version < cur_version
|
|
340
|
+
end
|
|
341
|
+
File.unlink dst
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
FileUtils.symlink src, dst, :verbose => LibGems.configuration.really_verbose
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
##
|
|
348
|
+
# Generates a #! line for +bin_file_name+'s wrapper copying arguments if
|
|
349
|
+
# necessary.
|
|
350
|
+
|
|
351
|
+
def shebang(bin_file_name)
|
|
352
|
+
ruby_name = LibGems::ConfigMap[:ruby_install_name] if @env_shebang
|
|
353
|
+
path = File.join @gem_dir, @spec.bindir, bin_file_name
|
|
354
|
+
first_line = File.open(path, "rb") {|file| file.gets}
|
|
355
|
+
|
|
356
|
+
if /\A#!/ =~ first_line then
|
|
357
|
+
# Preserve extra words on shebang line, like "-w". Thanks RPA.
|
|
358
|
+
shebang = first_line.sub(/\A\#!.*?ruby\S*(?=(\s+\S+))/, "#!#{LibGems.ruby}")
|
|
359
|
+
opts = $1
|
|
360
|
+
shebang.strip! # Avoid nasty ^M issues.
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
if not ruby_name then
|
|
364
|
+
"#!#{LibGems.ruby}#{opts}"
|
|
365
|
+
elsif opts then
|
|
366
|
+
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
|
|
367
|
+
else
|
|
368
|
+
# Create a plain shebang line.
|
|
369
|
+
@env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
|
|
370
|
+
"#!#{@env_path} #{ruby_name}"
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def ensure_required_ruby_version_met
|
|
375
|
+
if rrv = @spec.required_ruby_version then
|
|
376
|
+
unless rrv.satisfied_by? LibGems.ruby_version then
|
|
377
|
+
raise LibGems::InstallError, "#{@spec.name} requires Ruby version #{rrv}."
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def ensure_required_rubygems_version_met
|
|
383
|
+
if rrgv = @spec.required_rubygems_version then
|
|
384
|
+
unless rrgv.satisfied_by? LibGems::Version.new(LibGems::GEM_VERSION) then
|
|
385
|
+
raise LibGems::InstallError,
|
|
386
|
+
"#{@spec.name} requires #{LibGems::NAME} version #{rrgv}. " +
|
|
387
|
+
"Try 'gem update --system' to update #{LibGems::NAME} itself."
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def ensure_dependencies_met
|
|
393
|
+
deps = @spec.runtime_dependencies
|
|
394
|
+
deps |= @spec.development_dependencies if @development
|
|
395
|
+
|
|
396
|
+
deps.each do |dep_gem|
|
|
397
|
+
ensure_dependency @spec, dep_gem
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def process_options
|
|
402
|
+
self.options = {
|
|
403
|
+
:bin_dir => nil,
|
|
404
|
+
:env_shebang => false,
|
|
405
|
+
:exec_format => false,
|
|
406
|
+
:force => false,
|
|
407
|
+
:install_dir => LibGems.dir,
|
|
408
|
+
:source_index => LibGems.source_index,
|
|
409
|
+
}.merge options
|
|
410
|
+
|
|
411
|
+
@env_shebang = options[:env_shebang]
|
|
412
|
+
@force = options[:force]
|
|
413
|
+
gem_home = options[:install_dir]
|
|
414
|
+
@gem_home = File.expand_path(gem_home)
|
|
415
|
+
@ignore_dependencies = options[:ignore_dependencies]
|
|
416
|
+
@format_executable = options[:format_executable]
|
|
417
|
+
@security_policy = options[:security_policy]
|
|
418
|
+
@wrappers = options[:wrappers]
|
|
419
|
+
@bin_dir = options[:bin_dir]
|
|
420
|
+
@development = options[:development]
|
|
421
|
+
@source_index = options[:source_index]
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def load_gem_file
|
|
425
|
+
begin
|
|
426
|
+
@format = LibGems::Format.from_file_by_path @gem, @security_policy
|
|
427
|
+
rescue LibGems::Package::FormatError
|
|
428
|
+
raise LibGems::InstallError, "invalid gem format for #{@gem}"
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def check_that_user_bin_dir_is_in_path
|
|
433
|
+
user_bin_dir = File.join(@gem_home, 'bin')
|
|
434
|
+
unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
|
|
435
|
+
unless self.class.path_warning then
|
|
436
|
+
alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
|
|
437
|
+
self.class.path_warning = true
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def verify_gem_home(unpack = false)
|
|
443
|
+
FileUtils.mkdir_p @gem_home
|
|
444
|
+
raise LibGems::FilePermissionError, @gem_home unless
|
|
445
|
+
unpack or File.writable? @gem_home
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
##
|
|
449
|
+
# Return the text for an application file.
|
|
450
|
+
|
|
451
|
+
def app_script_text(bin_file_name)
|
|
452
|
+
<<-TEXT
|
|
453
|
+
#{shebang bin_file_name}
|
|
454
|
+
#
|
|
455
|
+
# This file was generated by LibGems.
|
|
456
|
+
#
|
|
457
|
+
# The application '#{@spec.name}' is installed as part of a gem, and
|
|
458
|
+
# this file is here to facilitate running it.
|
|
459
|
+
#
|
|
460
|
+
|
|
461
|
+
require 'libgems'
|
|
462
|
+
|
|
463
|
+
version = "#{LibGems::Requirement.default}"
|
|
464
|
+
|
|
465
|
+
if ARGV.first =~ /^_(.*)_$/ and LibGems::Version.correct? $1 then
|
|
466
|
+
version = $1
|
|
467
|
+
ARGV.shift
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
gem '#{@spec.name}', version
|
|
471
|
+
load LibGems.bin_path('#{@spec.name}', '#{bin_file_name}', version)
|
|
472
|
+
TEXT
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
##
|
|
476
|
+
# return the stub script text used to launch the true ruby script
|
|
477
|
+
|
|
478
|
+
def windows_stub_script(bindir, bin_file_name)
|
|
479
|
+
<<-TEXT
|
|
480
|
+
@ECHO OFF
|
|
481
|
+
IF NOT "%~f0" == "~f0" GOTO :WinNT
|
|
482
|
+
@"#{File.basename(LibGems.ruby).chomp('"')}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
|
|
483
|
+
GOTO :EOF
|
|
484
|
+
:WinNT
|
|
485
|
+
@"#{File.basename(LibGems.ruby).chomp('"')}" "%~dpn0" %*
|
|
486
|
+
TEXT
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
##
|
|
490
|
+
# Builds extensions. Valid types of extensions are extconf.rb files,
|
|
491
|
+
# configure scripts and rakefiles or mkrf_conf files.
|
|
492
|
+
|
|
493
|
+
def build_extensions
|
|
494
|
+
return if @spec.extensions.empty?
|
|
495
|
+
unless @spec.name == LibGems::GEM_NAME
|
|
496
|
+
say "Building native extensions. This could take a while..."
|
|
497
|
+
end
|
|
498
|
+
start_dir = Dir.pwd
|
|
499
|
+
dest_path = File.join @gem_dir, @spec.require_paths.first
|
|
500
|
+
ran_rake = false # only run rake once
|
|
501
|
+
|
|
502
|
+
@spec.extensions.each do |extension|
|
|
503
|
+
break if ran_rake
|
|
504
|
+
results = []
|
|
505
|
+
|
|
506
|
+
builder = case extension
|
|
507
|
+
when /extconf/ then
|
|
508
|
+
LibGems::Ext::ExtConfBuilder
|
|
509
|
+
when /configure/ then
|
|
510
|
+
LibGems::Ext::ConfigureBuilder
|
|
511
|
+
when /rakefile/i, /mkrf_conf/i then
|
|
512
|
+
ran_rake = true
|
|
513
|
+
LibGems::Ext::RakeBuilder
|
|
514
|
+
else
|
|
515
|
+
results = ["No builder for extension '#{extension}'"]
|
|
516
|
+
nil
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
begin
|
|
520
|
+
Dir.chdir File.join(@gem_dir, File.dirname(extension))
|
|
521
|
+
results = builder.build(extension, @gem_dir, dest_path, results)
|
|
522
|
+
|
|
523
|
+
say results.join("\n") if LibGems.configuration.really_verbose
|
|
524
|
+
|
|
525
|
+
rescue
|
|
526
|
+
results = results.join "\n"
|
|
527
|
+
|
|
528
|
+
File.open('gem_make.out', 'wb') { |f| f.puts results }
|
|
529
|
+
|
|
530
|
+
message = <<-EOF
|
|
531
|
+
ERROR: Failed to build gem native extension.
|
|
532
|
+
|
|
533
|
+
#{results}
|
|
534
|
+
|
|
535
|
+
Gem files will remain installed in #{@gem_dir} for inspection.
|
|
536
|
+
Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
|
|
537
|
+
EOF
|
|
538
|
+
|
|
539
|
+
raise ExtensionBuildError, message
|
|
540
|
+
ensure
|
|
541
|
+
Dir.chdir start_dir
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
##
|
|
547
|
+
# Reads the file index and extracts each file into the gem directory.
|
|
548
|
+
#
|
|
549
|
+
# Ensures that files can't be installed outside the gem directory.
|
|
550
|
+
|
|
551
|
+
def extract_files
|
|
552
|
+
@gem_dir = File.expand_path @gem_dir
|
|
553
|
+
|
|
554
|
+
raise ArgumentError, "format required to extract from" if @format.nil?
|
|
555
|
+
|
|
556
|
+
dirs = []
|
|
557
|
+
|
|
558
|
+
@format.file_entries.each do |entry, file_data|
|
|
559
|
+
path = entry['path'].untaint
|
|
560
|
+
|
|
561
|
+
if path =~ /\A\// then # for extra sanity
|
|
562
|
+
raise LibGems::InstallError,
|
|
563
|
+
"attempt to install file into #{entry['path'].inspect}"
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
path = File.expand_path File.join(@gem_dir, path)
|
|
567
|
+
|
|
568
|
+
if path !~ /\A#{Regexp.escape @gem_dir}/ then
|
|
569
|
+
msg = "attempt to install file into %p under %p" %
|
|
570
|
+
[entry['path'], @gem_dir]
|
|
571
|
+
raise LibGems::InstallError, msg
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
FileUtils.rm_rf(path) if File.exists?(path)
|
|
575
|
+
|
|
576
|
+
dir = File.dirname(path)
|
|
577
|
+
if !dirs.include?(dir)
|
|
578
|
+
dirs << dir
|
|
579
|
+
FileUtils.mkdir_p dir
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
File.open(path, "wb") do |out|
|
|
583
|
+
out.write file_data
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
FileUtils.chmod entry['mode'], path
|
|
587
|
+
|
|
588
|
+
say path if LibGems.configuration.really_verbose
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
##
|
|
593
|
+
# Prefix and suffix the program filename the same as ruby.
|
|
594
|
+
|
|
595
|
+
def formatted_program_filename(filename)
|
|
596
|
+
if @format_executable then
|
|
597
|
+
self.class.exec_format % File.basename(filename)
|
|
598
|
+
else
|
|
599
|
+
filename
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
end
|
|
604
|
+
|