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,44 @@
|
|
|
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
|
+
module Kernel
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# The Kernel#require from before SlimGems was loaded.
|
|
11
|
+
|
|
12
|
+
alias libgems_original_require require
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# When SlimGems is required, Kernel#require is replaced with our own which
|
|
16
|
+
# is capable of loading gems on demand.
|
|
17
|
+
#
|
|
18
|
+
# When you call <tt>require 'x'</tt>, this is what happens:
|
|
19
|
+
# * If the file can be loaded from the existing Ruby loadpath, it
|
|
20
|
+
# is.
|
|
21
|
+
# * Otherwise, installed gems are searched for a file that matches.
|
|
22
|
+
# If it's found in gem 'y', that gem is activated (added to the
|
|
23
|
+
# loadpath).
|
|
24
|
+
#
|
|
25
|
+
# The normal <tt>require</tt> functionality of returning false if
|
|
26
|
+
# that file has already been loaded is preserved.
|
|
27
|
+
|
|
28
|
+
def require(path) # :doc:
|
|
29
|
+
libgems_original_require path
|
|
30
|
+
rescue LoadError => load_error
|
|
31
|
+
if load_error.message.end_with?(path)
|
|
32
|
+
if LibGems.try_activate(path)
|
|
33
|
+
return libgems_original_require(path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
raise load_error
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private :require
|
|
41
|
+
private :libgems_original_require
|
|
42
|
+
|
|
43
|
+
end unless Kernel.private_method_defined?(:libgems_original_require)
|
|
44
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module LibGems
|
|
2
|
+
|
|
3
|
+
@post_install_hooks ||= []
|
|
4
|
+
@post_uninstall_hooks ||= []
|
|
5
|
+
@pre_uninstall_hooks ||= []
|
|
6
|
+
@pre_install_hooks ||= []
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# An Array of the default sources that come with SlimGems
|
|
10
|
+
|
|
11
|
+
def self.default_sources
|
|
12
|
+
%w[http://rubygems.org/]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Default home directory path to be used if an alternate value is not
|
|
17
|
+
# specified in the environment
|
|
18
|
+
|
|
19
|
+
def self.default_dir
|
|
20
|
+
if defined? RUBY_FRAMEWORK_VERSION then
|
|
21
|
+
File.join File.dirname(ConfigMap[:sitedir]), 'Gems',
|
|
22
|
+
ConfigMap[:ruby_version]
|
|
23
|
+
elsif ConfigMap[:rubylibprefix] then
|
|
24
|
+
File.join(ConfigMap[:rubylibprefix], 'gems',
|
|
25
|
+
ConfigMap[:ruby_version])
|
|
26
|
+
else
|
|
27
|
+
File.join(ConfigMap[:libdir], ruby_engine, 'gems',
|
|
28
|
+
ConfigMap[:ruby_version])
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Path for gems in the user's home directory
|
|
34
|
+
|
|
35
|
+
def self.user_dir
|
|
36
|
+
File.join LibGems.user_home, '.gem', ruby_engine, ConfigMap[:ruby_version]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Default gem load path
|
|
41
|
+
|
|
42
|
+
def self.default_path
|
|
43
|
+
if File.exist? LibGems.user_home then
|
|
44
|
+
[user_dir, default_dir]
|
|
45
|
+
else
|
|
46
|
+
[default_dir]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Deduce Ruby's --program-prefix and --program-suffix from its install name
|
|
52
|
+
|
|
53
|
+
def self.default_exec_format
|
|
54
|
+
exec_format = ConfigMap[:ruby_install_name].sub('ruby', '%s') rescue '%s'
|
|
55
|
+
|
|
56
|
+
unless exec_format =~ /%s/ then
|
|
57
|
+
raise LibGems::Exception,
|
|
58
|
+
"[BUG] invalid exec_format #{exec_format.inspect}, no %s"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
exec_format
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##
|
|
65
|
+
# The default directory for binaries
|
|
66
|
+
|
|
67
|
+
def self.default_bindir
|
|
68
|
+
if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
|
|
69
|
+
'/usr/bin'
|
|
70
|
+
else # generic install
|
|
71
|
+
ConfigMap[:bindir]
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# The default system-wide source info cache directory
|
|
77
|
+
|
|
78
|
+
def self.default_system_source_cache_dir
|
|
79
|
+
File.join LibGems.dir, 'source_cache'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# The default user-specific source info cache directory
|
|
84
|
+
|
|
85
|
+
def self.default_user_source_cache_dir
|
|
86
|
+
File.join LibGems.user_home, '.gem', 'source_cache'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# A wrapper around RUBY_ENGINE const that may not be defined
|
|
91
|
+
|
|
92
|
+
def self.ruby_engine
|
|
93
|
+
if defined? RUBY_ENGINE then
|
|
94
|
+
RUBY_ENGINE
|
|
95
|
+
else
|
|
96
|
+
'ruby'
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
require "libgems/requirement"
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# The Dependency class holds a LibGems name and a LibGems::Requirement.
|
|
5
|
+
|
|
6
|
+
class LibGems::Dependency
|
|
7
|
+
|
|
8
|
+
# :stopdoc:
|
|
9
|
+
@warned_version_requirement = false
|
|
10
|
+
|
|
11
|
+
def self.warned_version_requirement
|
|
12
|
+
@warned_version_requirement
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.warned_version_requirement= value
|
|
16
|
+
@warned_version_requirement = value
|
|
17
|
+
end
|
|
18
|
+
# :startdoc:
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Valid dependency types.
|
|
22
|
+
#--
|
|
23
|
+
# When this list is updated, be sure to change
|
|
24
|
+
# LibGems::Specification::CURRENT_SPECIFICATION_VERSION as well.
|
|
25
|
+
|
|
26
|
+
TYPES = [
|
|
27
|
+
:development,
|
|
28
|
+
:runtime,
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Dependency name or regular expression.
|
|
33
|
+
|
|
34
|
+
attr_accessor :name
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Allows you to force this dependency to be a prerelease.
|
|
38
|
+
|
|
39
|
+
attr_writer :prerelease
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Dependency type.
|
|
43
|
+
|
|
44
|
+
attr_reader :type
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# Constructs a dependency with +name+ and +requirements+. The last
|
|
48
|
+
# argument can optionally be the dependency type, which defaults to
|
|
49
|
+
# <tt>:runtime</tt>.
|
|
50
|
+
|
|
51
|
+
def initialize name, *requirements
|
|
52
|
+
type = Symbol === requirements.last ? requirements.pop : :runtime
|
|
53
|
+
requirements = requirements.first if 1 == requirements.length # unpack
|
|
54
|
+
|
|
55
|
+
unless TYPES.include? type
|
|
56
|
+
raise ArgumentError, "Valid types are #{TYPES.inspect}, "
|
|
57
|
+
+ "not #{type.inspect}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
@name = name
|
|
61
|
+
@requirement = LibGems::Requirement.create requirements
|
|
62
|
+
@type = type
|
|
63
|
+
@prerelease = false
|
|
64
|
+
|
|
65
|
+
# This is for Marshal backwards compatability. See the comments in
|
|
66
|
+
# +requirement+ for the dirty details.
|
|
67
|
+
|
|
68
|
+
@version_requirements = @requirement
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# A dependency's hash is the XOR of the hashes of +name+, +type+,
|
|
73
|
+
# and +requirement+.
|
|
74
|
+
|
|
75
|
+
def hash # :nodoc:
|
|
76
|
+
name.hash ^ type.hash ^ requirement.hash
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def inspect # :nodoc:
|
|
80
|
+
"<%s type=%p name=%p requirements=%p>" %
|
|
81
|
+
[self.class, @type, @name, requirement.to_s]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# Does this dependency require a prerelease?
|
|
86
|
+
|
|
87
|
+
def prerelease?
|
|
88
|
+
@prerelease || requirement.prerelease?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def pretty_print(q) # :nodoc:
|
|
92
|
+
q.group 1, 'LibGems::Dependency.new(', ')' do
|
|
93
|
+
q.pp name
|
|
94
|
+
q.text ','
|
|
95
|
+
q.breakable
|
|
96
|
+
|
|
97
|
+
q.pp requirement
|
|
98
|
+
|
|
99
|
+
q.text ','
|
|
100
|
+
q.breakable
|
|
101
|
+
|
|
102
|
+
q.pp type
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# What does this dependency require?
|
|
108
|
+
|
|
109
|
+
def requirement
|
|
110
|
+
return @requirement if defined?(@requirement) and @requirement
|
|
111
|
+
|
|
112
|
+
# @version_requirements and @version_requirement are legacy ivar
|
|
113
|
+
# names, and supported here because older gems need to keep
|
|
114
|
+
# working and Dependency doesn't implement marshal_dump and
|
|
115
|
+
# marshal_load. In a happier world, this would be an
|
|
116
|
+
# attr_accessor. The horrifying instance_variable_get you see
|
|
117
|
+
# below is also the legacy of some old restructurings.
|
|
118
|
+
#
|
|
119
|
+
# Note also that because of backwards compatibility (loading new
|
|
120
|
+
# gems in an old SlimGems installation), we can't add explicit
|
|
121
|
+
# marshaling to this class until we want to make a big
|
|
122
|
+
# break. Maybe 2.0.
|
|
123
|
+
#
|
|
124
|
+
# Children, define explicit marshal and unmarshal behavior for
|
|
125
|
+
# public classes. Marshal formats are part of your public API.
|
|
126
|
+
|
|
127
|
+
if defined?(@version_requirement) && @version_requirement
|
|
128
|
+
version = @version_requirement.instance_variable_get :@version
|
|
129
|
+
@version_requirement = nil
|
|
130
|
+
@version_requirements = LibGems::Requirement.new version
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
@requirement = @version_requirements if defined?(@version_requirements)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Rails subclasses LibGems::Dependency and uses this method, so we'll hack
|
|
138
|
+
# around it.
|
|
139
|
+
|
|
140
|
+
alias __requirement requirement # :nodoc:
|
|
141
|
+
|
|
142
|
+
def requirements_list
|
|
143
|
+
requirement.as_list
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def to_s # :nodoc:
|
|
147
|
+
"#{name} (#{requirement}, #{type})"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def version_requirements # :nodoc:
|
|
151
|
+
unless LibGems::Dependency.warned_version_requirement then
|
|
152
|
+
warn "#{LibGems.location_of_caller.join ':'}:Warning: " \
|
|
153
|
+
"LibGems::Dependency#version_requirements is deprecated " \
|
|
154
|
+
"and will be removed on or after August 2010. " \
|
|
155
|
+
"Use #requirement"
|
|
156
|
+
|
|
157
|
+
LibGems::Dependency.warned_version_requirement = true
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
__requirement
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
alias version_requirement version_requirements # :nodoc:
|
|
164
|
+
|
|
165
|
+
def version_requirements= requirements # :nodoc:
|
|
166
|
+
warn "#{LibGems.location_of_caller.join ':'}:Warning: " \
|
|
167
|
+
"LibGems::Dependency#version_requirements= is deprecated " \
|
|
168
|
+
"and will be removed on or after August 2010. " \
|
|
169
|
+
"Use LibGems::Dependency.new."
|
|
170
|
+
|
|
171
|
+
@requirement = LibGems::Requirement.create requirements
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def == other # :nodoc:
|
|
175
|
+
LibGems::Dependency === other &&
|
|
176
|
+
self.name == other.name &&
|
|
177
|
+
self.type == other.type &&
|
|
178
|
+
self.requirement == other.requirement
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
##
|
|
182
|
+
# Dependencies are ordered by name.
|
|
183
|
+
|
|
184
|
+
def <=> other
|
|
185
|
+
@name <=> other.name
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
##
|
|
189
|
+
# Uses this dependency as a pattern to compare to +other+. This
|
|
190
|
+
# dependency will match if the name matches the other's name, and
|
|
191
|
+
# other has only an equal version requirement that satisfies this
|
|
192
|
+
# dependency.
|
|
193
|
+
|
|
194
|
+
def =~ other
|
|
195
|
+
unless LibGems::Dependency === other
|
|
196
|
+
return unless other.respond_to?(:name) && other.respond_to?(:version)
|
|
197
|
+
other = LibGems::Dependency.new other.name, other.version
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
return false unless name === other.name
|
|
201
|
+
|
|
202
|
+
reqs = other.requirement.requirements
|
|
203
|
+
|
|
204
|
+
return false unless reqs.length == 1
|
|
205
|
+
return false unless reqs.first.first == '='
|
|
206
|
+
|
|
207
|
+
version = reqs.first.last
|
|
208
|
+
|
|
209
|
+
requirement.satisfied_by? version
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def match?(spec_name, spec_version)
|
|
213
|
+
return false unless name === spec_name
|
|
214
|
+
return true if requirement.none?
|
|
215
|
+
|
|
216
|
+
requirement.satisfied_by? LibGems::Version.new(spec_version)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def matches_spec?(spec)
|
|
220
|
+
return false unless name === spec.name # name can be a Regexp, so use ===
|
|
221
|
+
return true if requirement.none?
|
|
222
|
+
|
|
223
|
+
requirement.satisfied_by?(spec.version)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
end
|
|
227
|
+
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
require 'libgems'
|
|
2
|
+
require 'libgems/dependency_list'
|
|
3
|
+
require 'libgems/installer'
|
|
4
|
+
require 'libgems/spec_fetcher'
|
|
5
|
+
require 'libgems/user_interaction'
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Installs a gem along with all its dependencies from local and remote gems.
|
|
9
|
+
|
|
10
|
+
class LibGems::DependencyInstaller
|
|
11
|
+
|
|
12
|
+
include LibGems::UserInteraction
|
|
13
|
+
|
|
14
|
+
attr_reader :gems_to_install
|
|
15
|
+
attr_reader :installed_gems
|
|
16
|
+
|
|
17
|
+
DEFAULT_OPTIONS = {
|
|
18
|
+
:env_shebang => false,
|
|
19
|
+
:domain => :both, # HACK dup
|
|
20
|
+
:force => false,
|
|
21
|
+
:format_executable => false, # HACK dup
|
|
22
|
+
:ignore_dependencies => false,
|
|
23
|
+
:prerelease => false,
|
|
24
|
+
:security_policy => nil, # HACK NoSecurity requires OpenSSL. AlmostNo? Low?
|
|
25
|
+
:wrappers => true,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Creates a new installer instance.
|
|
30
|
+
#
|
|
31
|
+
# Options are:
|
|
32
|
+
# :cache_dir:: Alternate repository path to store .gem files in.
|
|
33
|
+
# :domain:: :local, :remote, or :both. :local only searches gems in the
|
|
34
|
+
# current directory. :remote searches only gems in LibGems::sources.
|
|
35
|
+
# :both searches both.
|
|
36
|
+
# :env_shebang:: See LibGems::Installer::new.
|
|
37
|
+
# :force:: See LibGems::Installer#install.
|
|
38
|
+
# :format_executable:: See LibGems::Installer#initialize.
|
|
39
|
+
# :ignore_dependencies:: Don't install any dependencies.
|
|
40
|
+
# :install_dir:: See LibGems::Installer#install.
|
|
41
|
+
# :prerelease:: Allow prerelease versions. See #install.
|
|
42
|
+
# :security_policy:: See LibGems::Installer::new and LibGems::Security.
|
|
43
|
+
# :user_install:: See LibGems::Installer.new
|
|
44
|
+
# :wrappers:: See LibGems::Installer::new
|
|
45
|
+
|
|
46
|
+
def initialize(options = {})
|
|
47
|
+
if options[:install_dir] then
|
|
48
|
+
spec_dir = options[:install_dir], 'specifications'
|
|
49
|
+
@source_index = LibGems::SourceIndex.from_gems_in spec_dir
|
|
50
|
+
else
|
|
51
|
+
@source_index = LibGems.source_index
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
options = DEFAULT_OPTIONS.merge options
|
|
55
|
+
|
|
56
|
+
@bin_dir = options[:bin_dir]
|
|
57
|
+
@development = options[:development]
|
|
58
|
+
@domain = options[:domain]
|
|
59
|
+
@env_shebang = options[:env_shebang]
|
|
60
|
+
@force = options[:force]
|
|
61
|
+
@format_executable = options[:format_executable]
|
|
62
|
+
@ignore_dependencies = options[:ignore_dependencies]
|
|
63
|
+
@prerelease = options[:prerelease]
|
|
64
|
+
@security_policy = options[:security_policy]
|
|
65
|
+
@user_install = options[:user_install]
|
|
66
|
+
@wrappers = options[:wrappers]
|
|
67
|
+
|
|
68
|
+
@installed_gems = []
|
|
69
|
+
|
|
70
|
+
@install_dir = options[:install_dir] || LibGems.dir
|
|
71
|
+
@cache_dir = options[:cache_dir] || @install_dir
|
|
72
|
+
|
|
73
|
+
# Set with any errors that SpecFetcher finds while search through
|
|
74
|
+
# gemspecs for a dep
|
|
75
|
+
@errors = nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Returns a list of pairs of gemspecs and source_uris that match
|
|
80
|
+
# LibGems::Dependency +dep+ from both local (Dir.pwd) and remote (LibGems.sources)
|
|
81
|
+
# sources. Gems are sorted with newer gems prefered over older gems, and
|
|
82
|
+
# local gems preferred over remote gems.
|
|
83
|
+
|
|
84
|
+
def find_gems_with_sources(dep)
|
|
85
|
+
# Reset the errors
|
|
86
|
+
@errors = nil
|
|
87
|
+
gems_and_sources = []
|
|
88
|
+
|
|
89
|
+
if @domain == :both or @domain == :local then
|
|
90
|
+
Dir[File.join(Dir.pwd, "#{dep.name}-[0-9]*.gem")].each do |gem_file|
|
|
91
|
+
spec = LibGems::Format.from_file_by_path(gem_file).spec
|
|
92
|
+
gems_and_sources << [spec, gem_file] if spec.name == dep.name
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
if @domain == :both or @domain == :remote then
|
|
97
|
+
begin
|
|
98
|
+
requirements = dep.requirement.requirements.map do |req, ver|
|
|
99
|
+
req
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
all = !dep.prerelease? &&
|
|
103
|
+
# we only need latest if there's one requirement and it is
|
|
104
|
+
# guaranteed to match the newest specs
|
|
105
|
+
(requirements.length > 1 or
|
|
106
|
+
(requirements.first != ">=" and requirements.first != ">"))
|
|
107
|
+
|
|
108
|
+
found, @errors = LibGems::SpecFetcher.fetcher.fetch_with_errors dep, all, true, dep.prerelease?
|
|
109
|
+
|
|
110
|
+
gems_and_sources.push(*found)
|
|
111
|
+
|
|
112
|
+
rescue LibGems::RemoteFetcher::FetchError => e
|
|
113
|
+
if LibGems.configuration.really_verbose then
|
|
114
|
+
say "Error fetching remote data:\t\t#{e.message}"
|
|
115
|
+
say "Falling back to local-only install"
|
|
116
|
+
end
|
|
117
|
+
@domain = :local
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
gems_and_sources.sort_by do |gem, source|
|
|
122
|
+
[gem, source =~ /^http:\/\// ? 0 : 1] # local gems win
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
##
|
|
127
|
+
# Gathers all dependencies necessary for the installation from local and
|
|
128
|
+
# remote sources unless the ignore_dependencies was given.
|
|
129
|
+
|
|
130
|
+
def gather_dependencies
|
|
131
|
+
specs = @specs_and_sources.map { |spec,_| spec }
|
|
132
|
+
|
|
133
|
+
dependency_list = LibGems::DependencyList.new @development
|
|
134
|
+
dependency_list.add(*specs)
|
|
135
|
+
|
|
136
|
+
unless @ignore_dependencies then
|
|
137
|
+
to_do = specs.dup
|
|
138
|
+
seen = {}
|
|
139
|
+
|
|
140
|
+
until to_do.empty? do
|
|
141
|
+
spec = to_do.shift
|
|
142
|
+
next if spec.nil? or seen[spec.name]
|
|
143
|
+
seen[spec.name] = true
|
|
144
|
+
|
|
145
|
+
deps = spec.runtime_dependencies
|
|
146
|
+
deps |= spec.development_dependencies if @development
|
|
147
|
+
|
|
148
|
+
deps.each do |dep|
|
|
149
|
+
results = find_gems_with_sources(dep).reverse
|
|
150
|
+
|
|
151
|
+
results.reject! do |dep_spec,|
|
|
152
|
+
to_do.push dep_spec
|
|
153
|
+
|
|
154
|
+
@source_index.any? do |_, installed_spec|
|
|
155
|
+
dep.name == installed_spec.name and
|
|
156
|
+
dep.requirement.satisfied_by? installed_spec.version
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
results.each do |dep_spec, source_uri|
|
|
161
|
+
next if seen[dep_spec.name]
|
|
162
|
+
@specs_and_sources << [dep_spec, source_uri]
|
|
163
|
+
dependency_list.add dep_spec
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
@gems_to_install = dependency_list.dependency_order.reverse
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
##
|
|
173
|
+
# Finds a spec and the source_uri it came from for gem +gem_name+ and
|
|
174
|
+
# +version+. Returns an Array of specs and sources required for
|
|
175
|
+
# installation of the gem.
|
|
176
|
+
|
|
177
|
+
def find_spec_by_name_and_version(gem_name,
|
|
178
|
+
version = LibGems::Requirement.default,
|
|
179
|
+
prerelease = false)
|
|
180
|
+
spec_and_source = nil
|
|
181
|
+
|
|
182
|
+
glob = if File::ALT_SEPARATOR then
|
|
183
|
+
gem_name.gsub File::ALT_SEPARATOR, File::SEPARATOR
|
|
184
|
+
else
|
|
185
|
+
gem_name
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
local_gems = Dir["#{glob}*"].sort.reverse
|
|
189
|
+
|
|
190
|
+
unless local_gems.empty? then
|
|
191
|
+
local_gems.each do |gem_file|
|
|
192
|
+
next unless gem_file =~ /gem$/
|
|
193
|
+
begin
|
|
194
|
+
spec = LibGems::Format.from_file_by_path(gem_file).spec
|
|
195
|
+
spec_and_source = [spec, gem_file]
|
|
196
|
+
break
|
|
197
|
+
rescue SystemCallError, LibGems::Package::FormatError
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
if spec_and_source.nil? then
|
|
203
|
+
dep = LibGems::Dependency.new gem_name, version
|
|
204
|
+
dep.prerelease = true if prerelease
|
|
205
|
+
spec_and_sources = find_gems_with_sources(dep).reverse
|
|
206
|
+
|
|
207
|
+
spec_and_source = spec_and_sources.find { |spec, source|
|
|
208
|
+
LibGems::Platform.match spec.platform
|
|
209
|
+
}
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
if spec_and_source.nil? then
|
|
213
|
+
raise LibGems::GemNotFoundException.new(
|
|
214
|
+
"Could not find a valid gem '#{gem_name}' (#{version}) locally or in a repository",
|
|
215
|
+
gem_name, version, @errors)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
@specs_and_sources = [spec_and_source]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
##
|
|
222
|
+
# Installs the gem +dep_or_name+ and all its dependencies. Returns an Array
|
|
223
|
+
# of installed gem specifications.
|
|
224
|
+
#
|
|
225
|
+
# If the +:prerelease+ option is set and there is a prerelease for
|
|
226
|
+
# +dep_or_name+ the prerelease version will be installed.
|
|
227
|
+
#
|
|
228
|
+
# Unless explicitly specified as a prerelease dependency, prerelease gems
|
|
229
|
+
# that +dep_or_name+ depend on will not be installed.
|
|
230
|
+
#
|
|
231
|
+
# If c-1.a depends on b-1 and a-1.a and there is a gem b-1.a available then
|
|
232
|
+
# c-1.a, b-1 and a-1.a will be installed. b-1.a will need to be installed
|
|
233
|
+
# separately.
|
|
234
|
+
|
|
235
|
+
def install dep_or_name, version = LibGems::Requirement.default
|
|
236
|
+
if String === dep_or_name then
|
|
237
|
+
find_spec_by_name_and_version dep_or_name, version, @prerelease
|
|
238
|
+
else
|
|
239
|
+
dep_or_name.prerelease = @prerelease
|
|
240
|
+
@specs_and_sources = [find_gems_with_sources(dep_or_name).last]
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
@installed_gems = []
|
|
244
|
+
|
|
245
|
+
gather_dependencies
|
|
246
|
+
|
|
247
|
+
@gems_to_install.each do |spec|
|
|
248
|
+
last = spec == @gems_to_install.last
|
|
249
|
+
# HACK is this test for full_name acceptable?
|
|
250
|
+
next if @source_index.any? { |n,_| n == spec.full_name } and not last
|
|
251
|
+
|
|
252
|
+
# TODO: make this sorta_verbose so other users can benefit from it
|
|
253
|
+
say "Installing gem #{spec.full_name}" if LibGems.configuration.really_verbose
|
|
254
|
+
|
|
255
|
+
_, source_uri = @specs_and_sources.assoc spec
|
|
256
|
+
begin
|
|
257
|
+
local_gem_path = LibGems::RemoteFetcher.fetcher.download spec, source_uri,
|
|
258
|
+
@cache_dir
|
|
259
|
+
rescue LibGems::RemoteFetcher::FetchError
|
|
260
|
+
next if @force
|
|
261
|
+
raise
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
inst = LibGems::Installer.new local_gem_path,
|
|
265
|
+
:bin_dir => @bin_dir,
|
|
266
|
+
:development => @development,
|
|
267
|
+
:env_shebang => @env_shebang,
|
|
268
|
+
:force => @force,
|
|
269
|
+
:format_executable => @format_executable,
|
|
270
|
+
:ignore_dependencies => @ignore_dependencies,
|
|
271
|
+
:install_dir => @install_dir,
|
|
272
|
+
:security_policy => @security_policy,
|
|
273
|
+
:source_index => @source_index,
|
|
274
|
+
:user_install => @user_install,
|
|
275
|
+
:wrappers => @wrappers
|
|
276
|
+
|
|
277
|
+
spec = inst.install
|
|
278
|
+
|
|
279
|
+
@installed_gems << spec
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
@installed_gems
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
end
|
|
286
|
+
|