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.
Files changed (177) hide show
  1. data/ChangeLog +5811 -0
  2. data/History.txt +887 -0
  3. data/LICENSE.txt +51 -0
  4. data/README.md +87 -0
  5. data/Rakefile +113 -0
  6. data/lib/gauntlet_libgems.rb +50 -0
  7. data/lib/libgems.rb +1246 -0
  8. data/lib/libgems/builder.rb +102 -0
  9. data/lib/libgems/command.rb +534 -0
  10. data/lib/libgems/command_manager.rb +182 -0
  11. data/lib/libgems/commands/build_command.rb +53 -0
  12. data/lib/libgems/commands/cert_command.rb +86 -0
  13. data/lib/libgems/commands/check_command.rb +80 -0
  14. data/lib/libgems/commands/cleanup_command.rb +106 -0
  15. data/lib/libgems/commands/contents_command.rb +98 -0
  16. data/lib/libgems/commands/dependency_command.rb +195 -0
  17. data/lib/libgems/commands/environment_command.rb +133 -0
  18. data/lib/libgems/commands/fetch_command.rb +67 -0
  19. data/lib/libgems/commands/generate_index_command.rb +133 -0
  20. data/lib/libgems/commands/help_command.rb +172 -0
  21. data/lib/libgems/commands/install_command.rb +178 -0
  22. data/lib/libgems/commands/list_command.rb +35 -0
  23. data/lib/libgems/commands/lock_command.rb +110 -0
  24. data/lib/libgems/commands/mirror_command.rb +111 -0
  25. data/lib/libgems/commands/outdated_command.rb +33 -0
  26. data/lib/libgems/commands/owner_command.rb +75 -0
  27. data/lib/libgems/commands/pristine_command.rb +93 -0
  28. data/lib/libgems/commands/push_command.rb +56 -0
  29. data/lib/libgems/commands/query_command.rb +280 -0
  30. data/lib/libgems/commands/rdoc_command.rb +91 -0
  31. data/lib/libgems/commands/search_command.rb +31 -0
  32. data/lib/libgems/commands/server_command.rb +86 -0
  33. data/lib/libgems/commands/sources_command.rb +157 -0
  34. data/lib/libgems/commands/specification_command.rb +125 -0
  35. data/lib/libgems/commands/stale_command.rb +27 -0
  36. data/lib/libgems/commands/uninstall_command.rb +83 -0
  37. data/lib/libgems/commands/unpack_command.rb +121 -0
  38. data/lib/libgems/commands/update_command.rb +160 -0
  39. data/lib/libgems/commands/which_command.rb +86 -0
  40. data/lib/libgems/config_file.rb +345 -0
  41. data/lib/libgems/custom_require.rb +44 -0
  42. data/lib/libgems/defaults.rb +101 -0
  43. data/lib/libgems/dependency.rb +227 -0
  44. data/lib/libgems/dependency_installer.rb +286 -0
  45. data/lib/libgems/dependency_list.rb +208 -0
  46. data/lib/libgems/doc_manager.rb +242 -0
  47. data/lib/libgems/errors.rb +35 -0
  48. data/lib/libgems/exceptions.rb +91 -0
  49. data/lib/libgems/ext.rb +18 -0
  50. data/lib/libgems/ext/builder.rb +56 -0
  51. data/lib/libgems/ext/configure_builder.rb +25 -0
  52. data/lib/libgems/ext/ext_conf_builder.rb +24 -0
  53. data/lib/libgems/ext/rake_builder.rb +39 -0
  54. data/lib/libgems/format.rb +81 -0
  55. data/lib/libgems/gem_openssl.rb +92 -0
  56. data/lib/libgems/gem_path_searcher.rb +100 -0
  57. data/lib/libgems/gem_runner.rb +79 -0
  58. data/lib/libgems/gemcutter_utilities.rb +49 -0
  59. data/lib/libgems/indexer.rb +720 -0
  60. data/lib/libgems/install_update_options.rb +125 -0
  61. data/lib/libgems/installer.rb +604 -0
  62. data/lib/libgems/local_remote_options.rb +135 -0
  63. data/lib/libgems/old_format.rb +153 -0
  64. data/lib/libgems/package.rb +97 -0
  65. data/lib/libgems/package/f_sync_dir.rb +23 -0
  66. data/lib/libgems/package/tar_header.rb +266 -0
  67. data/lib/libgems/package/tar_input.rb +222 -0
  68. data/lib/libgems/package/tar_output.rb +144 -0
  69. data/lib/libgems/package/tar_reader.rb +106 -0
  70. data/lib/libgems/package/tar_reader/entry.rb +141 -0
  71. data/lib/libgems/package/tar_writer.rb +241 -0
  72. data/lib/libgems/package_task.rb +126 -0
  73. data/lib/libgems/platform.rb +183 -0
  74. data/lib/libgems/remote_fetcher.rb +414 -0
  75. data/lib/libgems/require_paths_builder.rb +18 -0
  76. data/lib/libgems/requirement.rb +153 -0
  77. data/lib/libgems/security.rb +814 -0
  78. data/lib/libgems/server.rb +872 -0
  79. data/lib/libgems/source_index.rb +597 -0
  80. data/lib/libgems/source_info_cache.rb +395 -0
  81. data/lib/libgems/source_info_cache_entry.rb +56 -0
  82. data/lib/libgems/spec_fetcher.rb +337 -0
  83. data/lib/libgems/specification.rb +1487 -0
  84. data/lib/libgems/test_utilities.rb +147 -0
  85. data/lib/libgems/text.rb +65 -0
  86. data/lib/libgems/uninstaller.rb +278 -0
  87. data/lib/libgems/user_interaction.rb +527 -0
  88. data/lib/libgems/validator.rb +240 -0
  89. data/lib/libgems/version.rb +316 -0
  90. data/lib/libgems/version_option.rb +65 -0
  91. data/lib/rbconfig/datadir.rb +20 -0
  92. data/test/bogussources.rb +8 -0
  93. data/test/data/gem-private_key.pem +27 -0
  94. data/test/data/gem-public_cert.pem +20 -0
  95. data/test/fake_certlib/openssl.rb +7 -0
  96. data/test/foo/discover.rb +0 -0
  97. data/test/gem_installer_test_case.rb +97 -0
  98. data/test/gem_package_tar_test_case.rb +132 -0
  99. data/test/gemutilities.rb +605 -0
  100. data/test/insure_session.rb +43 -0
  101. data/test/mockgemui.rb +56 -0
  102. data/test/plugin/exception/libgems_plugin.rb +2 -0
  103. data/test/plugin/load/libgems_plugin.rb +1 -0
  104. data/test/plugin/standarderror/libgems_plugin.rb +2 -0
  105. data/test/private_key.pem +27 -0
  106. data/test/public_cert.pem +20 -0
  107. data/test/rubygems_plugin.rb +21 -0
  108. data/test/simple_gem.rb +66 -0
  109. data/test/test_config.rb +12 -0
  110. data/test/test_gem.rb +780 -0
  111. data/test/test_gem_builder.rb +27 -0
  112. data/test/test_gem_command.rb +178 -0
  113. data/test/test_gem_command_manager.rb +207 -0
  114. data/test/test_gem_commands_build_command.rb +74 -0
  115. data/test/test_gem_commands_cert_command.rb +124 -0
  116. data/test/test_gem_commands_check_command.rb +18 -0
  117. data/test/test_gem_commands_contents_command.rb +156 -0
  118. data/test/test_gem_commands_dependency_command.rb +216 -0
  119. data/test/test_gem_commands_environment_command.rb +144 -0
  120. data/test/test_gem_commands_fetch_command.rb +76 -0
  121. data/test/test_gem_commands_generate_index_command.rb +135 -0
  122. data/test/test_gem_commands_install_command.rb +315 -0
  123. data/test/test_gem_commands_list_command.rb +36 -0
  124. data/test/test_gem_commands_lock_command.rb +68 -0
  125. data/test/test_gem_commands_mirror_command.rb +60 -0
  126. data/test/test_gem_commands_outdated_command.rb +40 -0
  127. data/test/test_gem_commands_owner_command.rb +105 -0
  128. data/test/test_gem_commands_pristine_command.rb +108 -0
  129. data/test/test_gem_commands_push_command.rb +81 -0
  130. data/test/test_gem_commands_query_command.rb +426 -0
  131. data/test/test_gem_commands_server_command.rb +59 -0
  132. data/test/test_gem_commands_sources_command.rb +209 -0
  133. data/test/test_gem_commands_specification_command.rb +139 -0
  134. data/test/test_gem_commands_stale_command.rb +38 -0
  135. data/test/test_gem_commands_uninstall_command.rb +83 -0
  136. data/test/test_gem_commands_unpack_command.rb +199 -0
  137. data/test/test_gem_commands_update_command.rb +207 -0
  138. data/test/test_gem_commands_which_command.rb +66 -0
  139. data/test/test_gem_config_file.rb +287 -0
  140. data/test/test_gem_dependency.rb +149 -0
  141. data/test/test_gem_dependency_installer.rb +661 -0
  142. data/test/test_gem_dependency_list.rb +230 -0
  143. data/test/test_gem_doc_manager.rb +31 -0
  144. data/test/test_gem_ext_configure_builder.rb +84 -0
  145. data/test/test_gem_ext_ext_conf_builder.rb +173 -0
  146. data/test/test_gem_ext_rake_builder.rb +81 -0
  147. data/test/test_gem_format.rb +70 -0
  148. data/test/test_gem_gem_path_searcher.rb +78 -0
  149. data/test/test_gem_gem_runner.rb +45 -0
  150. data/test/test_gem_gemcutter_utilities.rb +103 -0
  151. data/test/test_gem_indexer.rb +673 -0
  152. data/test/test_gem_install_update_options.rb +68 -0
  153. data/test/test_gem_installer.rb +857 -0
  154. data/test/test_gem_local_remote_options.rb +97 -0
  155. data/test/test_gem_package_tar_header.rb +130 -0
  156. data/test/test_gem_package_tar_input.rb +112 -0
  157. data/test/test_gem_package_tar_output.rb +97 -0
  158. data/test/test_gem_package_tar_reader.rb +46 -0
  159. data/test/test_gem_package_tar_reader_entry.rb +109 -0
  160. data/test/test_gem_package_tar_writer.rb +144 -0
  161. data/test/test_gem_package_task.rb +59 -0
  162. data/test/test_gem_platform.rb +264 -0
  163. data/test/test_gem_remote_fetcher.rb +740 -0
  164. data/test/test_gem_requirement.rb +292 -0
  165. data/test/test_gem_server.rb +356 -0
  166. data/test/test_gem_silent_ui.rb +113 -0
  167. data/test/test_gem_source_index.rb +461 -0
  168. data/test/test_gem_spec_fetcher.rb +410 -0
  169. data/test/test_gem_specification.rb +1334 -0
  170. data/test/test_gem_stream_ui.rb +218 -0
  171. data/test/test_gem_text.rb +43 -0
  172. data/test/test_gem_uninstaller.rb +146 -0
  173. data/test/test_gem_validator.rb +63 -0
  174. data/test/test_gem_version.rb +181 -0
  175. data/test/test_gem_version_option.rb +89 -0
  176. data/test/test_kernel.rb +59 -0
  177. metadata +402 -0
@@ -0,0 +1,147 @@
1
+ require 'tempfile'
2
+ require 'libgems'
3
+ require 'libgems/remote_fetcher'
4
+
5
+ ##
6
+ # A fake LibGems::RemoteFetcher for use in tests or to avoid real live HTTP
7
+ # requests when testing code that uses SlimGems.
8
+ #
9
+ # Example:
10
+ #
11
+ # @fetcher = LibGems::FakeFetcher.new
12
+ # @fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml
13
+ # LibGems::RemoteFetcher.fetcher = @fetcher
14
+ #
15
+ # # invoke SlimGems code
16
+ #
17
+ # paths = @fetcher.paths
18
+ # assert_equal 'http://gems.example.com/yaml', paths.shift
19
+ # assert paths.empty?, paths.join(', ')
20
+ #
21
+ # See SlimGems' tests for more examples of FakeFetcher.
22
+
23
+ class LibGems::FakeFetcher
24
+
25
+ attr_reader :data
26
+ attr_reader :last_request
27
+ attr_accessor :paths
28
+
29
+ def initialize
30
+ @data = {}
31
+ @paths = []
32
+ end
33
+
34
+ def find_data(path)
35
+ path = path.to_s
36
+ @paths << path
37
+ raise ArgumentError, 'need full URI' unless path =~ %r'^https?://'
38
+
39
+ unless @data.key? path then
40
+ raise LibGems::RemoteFetcher::FetchError.new("no data for #{path}", path)
41
+ end
42
+
43
+ @data[path]
44
+ end
45
+
46
+ def fetch_path path, mtime = nil
47
+ data = find_data(path)
48
+
49
+ if data.respond_to?(:call) then
50
+ data.call
51
+ else
52
+ if path.to_s =~ /gz$/ and not data.nil? and not data.empty? then
53
+ data = LibGems.gunzip data
54
+ end
55
+
56
+ data
57
+ end
58
+ end
59
+
60
+ # Thanks, FakeWeb!
61
+ def open_uri_or_path(path)
62
+ data = find_data(path)
63
+ body, code, msg = data
64
+
65
+ response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
66
+ response.instance_variable_set(:@body, body)
67
+ response.instance_variable_set(:@read, true)
68
+ response
69
+ end
70
+
71
+ def request(uri, request_class, last_modified = nil)
72
+ data = find_data(uri)
73
+ body, code, msg = data
74
+
75
+ @last_request = request_class.new uri.request_uri
76
+ yield @last_request if block_given?
77
+
78
+ response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
79
+ response.instance_variable_set(:@body, body)
80
+ response.instance_variable_set(:@read, true)
81
+ response
82
+ end
83
+
84
+ def fetch_size(path)
85
+ path = path.to_s
86
+ @paths << path
87
+
88
+ raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
89
+
90
+ unless @data.key? path then
91
+ raise LibGems::RemoteFetcher::FetchError.new("no data for #{path}", path)
92
+ end
93
+
94
+ data = @data[path]
95
+
96
+ data.respond_to?(:call) ? data.call : data.length
97
+ end
98
+
99
+ def download spec, source_uri, install_dir = LibGems.dir
100
+ name = spec.file_name
101
+ path = File.join(install_dir, 'cache', name)
102
+
103
+ LibGems.ensure_gem_subdirectories install_dir
104
+
105
+ if source_uri =~ /^http/ then
106
+ File.open(path, "wb") do |f|
107
+ f.write fetch_path(File.join(source_uri, "gems", name))
108
+ end
109
+ else
110
+ FileUtils.cp source_uri, path
111
+ end
112
+
113
+ path
114
+ end
115
+
116
+ end
117
+
118
+ # :stopdoc:
119
+ class LibGems::RemoteFetcher
120
+
121
+ def self.fetcher=(fetcher)
122
+ @fetcher = fetcher
123
+ end
124
+
125
+ end
126
+ # :startdoc:
127
+
128
+ ##
129
+ # A StringIO duck-typed class that uses Tempfile instead of String as the
130
+ # backing store.
131
+ #--
132
+ # This class was added to flush out problems in Rubinius' IO implementation.
133
+
134
+ class TempIO < Tempfile
135
+ def initialize(string = '')
136
+ super "TempIO"
137
+ binmode
138
+ write string
139
+ rewind
140
+ end
141
+
142
+ def string
143
+ flush
144
+ LibGems.read_binary path
145
+ end
146
+ end
147
+
@@ -0,0 +1,65 @@
1
+ require 'libgems'
2
+
3
+ ##
4
+ # A collection of text-wrangling methods
5
+
6
+ module LibGems::Text
7
+
8
+ ##
9
+ # Wraps +text+ to +wrap+ characters and optionally indents by +indent+
10
+ # characters
11
+
12
+ def format_text(text, wrap, indent=0)
13
+ result = []
14
+ work = text.dup
15
+
16
+ while work.length > wrap do
17
+ if work =~ /^(.{0,#{wrap}})[ \n]/ then
18
+ result << $1
19
+ work.slice!(0, $&.length)
20
+ else
21
+ result << work.slice!(0, wrap)
22
+ end
23
+ end
24
+
25
+ result << work if work.length.nonzero?
26
+ result.join("\n").gsub(/^/, " " * indent)
27
+ end
28
+
29
+ # This code is based directly on the Text gem implementation
30
+ # Returns a value representing the "cost" of transforming str1 into str2
31
+ def levenshtein_distance str1, str2
32
+ s = str1
33
+ t = str2
34
+ n = s.length
35
+ m = t.length
36
+ max = n/2
37
+
38
+ return m if (0 == n)
39
+ return n if (0 == m)
40
+ return n if (n - m).abs > max
41
+
42
+ d = (0..m).to_a
43
+ x = nil
44
+
45
+ n.times do |i|
46
+ e = i+1
47
+
48
+ m.times do |j|
49
+ cost = (s[i] == t[j]) ? 0 : 1
50
+ x = [
51
+ d[j+1] + 1, # insertion
52
+ e + 1, # deletion
53
+ d[j] + cost # substitution
54
+ ].min
55
+ d[j] = e
56
+ e = x
57
+ end
58
+
59
+ d[m] = x
60
+ end
61
+
62
+ return x
63
+ end
64
+ end
65
+
@@ -0,0 +1,278 @@
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 'libgems'
9
+ require 'libgems/dependency_list'
10
+ require 'libgems/doc_manager'
11
+ require 'libgems/user_interaction'
12
+
13
+ # Restores RubyGems
14
+ LibGems.post_uninstall do |uninstaller|
15
+ site_lib = File.expand_path(File.join(File.dirname(__FILE__), '..'))
16
+ old_lib = File.join(site_lib, 'rubygems-backup')
17
+ if File.directory?(old_lib)
18
+ uninstaller.say "Restoring RubyGems"
19
+ Dir.glob(File.join(old_lib, '*')).each do |file|
20
+ fname = File.basename(file)
21
+ old_file = File.join(site_lib, fname)
22
+ FileUtils.rm_rf(old_file) if File.exist?(old_file)
23
+ FileUtils.mv(file, File.join(site_lib, fname))
24
+ end
25
+ FileUtils.rm_rf(old_lib)
26
+ end
27
+ end
28
+
29
+ ##
30
+ # An Uninstaller.
31
+ #
32
+ # The uninstaller fires pre and post uninstall hooks. Hooks can be added
33
+ # either through a rubygems_plugin.rb file in an installed gem or via a
34
+ # rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb
35
+ # file. See LibGems.pre_uninstall and LibGems.post_uninstall for details.
36
+
37
+ class LibGems::Uninstaller
38
+
39
+ include LibGems::UserInteraction
40
+
41
+ ##
42
+ # The directory a gem's executables will be installed into
43
+
44
+ attr_reader :bin_dir
45
+
46
+ ##
47
+ # The gem repository the gem will be installed into
48
+
49
+ attr_reader :gem_home
50
+
51
+ ##
52
+ # The LibGems::Specification for the gem being uninstalled, only set during
53
+ # #uninstall_gem
54
+
55
+ attr_reader :spec
56
+
57
+ ##
58
+ # Constructs an uninstaller that will uninstall +gem+
59
+
60
+ def initialize(gem, options = {})
61
+ @gem = gem
62
+ @version = options[:version] || LibGems::Requirement.default
63
+ gem_home = options[:install_dir] || LibGems.dir
64
+ @gem_home = File.expand_path gem_home
65
+ @force_executables = options[:executables]
66
+ @force_all = options[:all]
67
+ @force_ignore = options[:ignore]
68
+ @bin_dir = options[:bin_dir]
69
+
70
+ # only add user directory if install_dir is not set
71
+ @user_install = false
72
+ @user_install = options[:user_install] unless options[:install_dir]
73
+
74
+ spec_dir = File.join @gem_home, 'specifications'
75
+ @source_index = LibGems::SourceIndex.from_gems_in spec_dir
76
+
77
+ if @user_install then
78
+ user_dir = File.join LibGems.user_dir, 'specifications'
79
+ @user_index = LibGems::SourceIndex.from_gems_in user_dir
80
+ end
81
+ end
82
+
83
+ ##
84
+ # Performs the uninstall of the gem. This removes the spec, the LibGems
85
+ # directory, and the cached .gem file.
86
+
87
+ def uninstall
88
+ list = @source_index.find_name @gem, @version
89
+ list += @user_index.find_name @gem, @version if @user_install
90
+
91
+ if list.empty? then
92
+ raise LibGems::InstallError, "cannot uninstall, check `gem list -d #{@gem}`"
93
+
94
+ elsif list.size > 1 and @force_all then
95
+ remove_all list.dup
96
+
97
+ elsif list.size > 1 then
98
+ gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
99
+
100
+ say
101
+ _, index = choose_from_list "Select gem to uninstall:", gem_names
102
+
103
+ if index == list.size then
104
+ remove_all list.dup
105
+ elsif index >= 0 && index < list.size then
106
+ uninstall_gem list[index], list.dup
107
+ else
108
+ say "Error: must enter a number [1-#{list.size+1}]"
109
+ end
110
+ else
111
+ uninstall_gem list.first, list.dup
112
+ end
113
+ end
114
+
115
+ ##
116
+ # Uninstalls gem +spec+
117
+
118
+ def uninstall_gem(spec, specs)
119
+ @spec = spec
120
+
121
+ LibGems.pre_uninstall_hooks.each do |hook|
122
+ hook.call self
123
+ end
124
+
125
+ remove_executables @spec
126
+ remove @spec, specs
127
+
128
+ LibGems.post_uninstall_hooks.each do |hook|
129
+ hook.call self
130
+ end
131
+
132
+ @spec = nil
133
+ end
134
+
135
+ ##
136
+ # Removes installed executables and batch files (windows only) for
137
+ # +gemspec+.
138
+
139
+ def remove_executables(spec)
140
+ return if spec.nil?
141
+
142
+ unless spec.executables.empty? then
143
+ bindir = @bin_dir ? @bin_dir : LibGems.bindir(spec.installation_path)
144
+
145
+ list = @source_index.find_name(spec.name).delete_if { |s|
146
+ s.version == spec.version
147
+ }
148
+
149
+ executables = spec.executables.clone
150
+
151
+ list.each do |s|
152
+ s.executables.each do |exe_name|
153
+ executables.delete exe_name
154
+ end
155
+ end
156
+
157
+ return if executables.empty?
158
+
159
+ answer = if @force_executables.nil? then
160
+ ask_yes_no("Remove executables:\n" \
161
+ "\t#{spec.executables.join(", ")}\n\nin addition to the gem?",
162
+ true) # " # appease ruby-mode - don't ask
163
+ else
164
+ @force_executables
165
+ end
166
+
167
+ unless answer then
168
+ say "Executables and scripts will remain installed."
169
+ else
170
+ raise LibGems::FilePermissionError, bindir unless File.writable? bindir
171
+
172
+ spec.executables.each do |exe_name|
173
+ say "Removing #{exe_name}"
174
+ FileUtils.rm_f File.join(bindir, exe_name)
175
+ FileUtils.rm_f File.join(bindir, "#{exe_name}.bat")
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ ##
182
+ # Removes all gems in +list+.
183
+ #
184
+ # NOTE: removes uninstalled gems from +list+.
185
+
186
+ def remove_all(list)
187
+ list.dup.each { |spec| uninstall_gem spec, list }
188
+ end
189
+
190
+ ##
191
+ # spec:: the spec of the gem to be uninstalled
192
+ # list:: the list of all such gems
193
+ #
194
+ # Warning: this method modifies the +list+ parameter. Once it has
195
+ # uninstalled a gem, it is removed from that list.
196
+
197
+ def remove(spec, list)
198
+ unless dependencies_ok? spec then
199
+ raise LibGems::DependencyRemovalException,
200
+ "Uninstallation aborted due to dependent gem(s)"
201
+ end
202
+
203
+ unless path_ok?(@gem_home, spec) or
204
+ (@user_install and path_ok?(LibGems.user_dir, spec)) then
205
+ e = LibGems::GemNotInHomeException.new \
206
+ "Gem is not installed in directory #{@gem_home}"
207
+ e.spec = spec
208
+
209
+ raise e
210
+ end
211
+
212
+ raise LibGems::FilePermissionError, spec.installation_path unless
213
+ File.writable?(spec.installation_path)
214
+
215
+ FileUtils.rm_rf spec.full_gem_path
216
+
217
+ original_platform_name = [
218
+ spec.name, spec.version, spec.original_platform].join '-'
219
+
220
+ spec_dir = File.join spec.installation_path, 'specifications'
221
+ gemspec = File.join spec_dir, spec.spec_name
222
+
223
+ unless File.exist? gemspec then
224
+ gemspec = File.join spec_dir, "#{original_platform_name}.gemspec"
225
+ end
226
+
227
+ FileUtils.rm_rf gemspec
228
+
229
+ cache_dir = File.join spec.installation_path, 'cache'
230
+ gem = File.join cache_dir, spec.file_name
231
+
232
+ unless File.exist? gem then
233
+ gem = File.join cache_dir, "#{original_platform_name}.gem"
234
+ end
235
+
236
+ FileUtils.rm_rf gem
237
+
238
+ LibGems::DocManager.new(spec).uninstall_doc
239
+
240
+ say "Successfully uninstalled #{spec.full_name}"
241
+
242
+ list.delete spec
243
+ end
244
+
245
+ ##
246
+ # Is +spec+ in +gem_dir+?
247
+
248
+ def path_ok?(gem_dir, spec)
249
+ full_path = File.join gem_dir, 'gems', spec.full_name
250
+ original_path = File.join gem_dir, 'gems', spec.original_name
251
+
252
+ full_path == spec.full_gem_path || original_path == spec.full_gem_path
253
+ end
254
+
255
+ def dependencies_ok?(spec)
256
+ return true if @force_ignore
257
+
258
+ deplist = LibGems::DependencyList.from_source_index @source_index
259
+ deplist.add(*@user_index.gems.values) if @user_install
260
+ deplist.ok_to_remove?(spec.full_name) || ask_if_ok(spec)
261
+ end
262
+
263
+ def ask_if_ok(spec)
264
+ msg = ['']
265
+ msg << 'You have requested to uninstall the gem:'
266
+ msg << "\t#{spec.full_name}"
267
+ spec.dependent_gems.each do |gem,dep,satlist|
268
+ msg <<
269
+ ("#{gem.name}-#{gem.version} depends on " +
270
+ "[#{dep.name} (#{dep.requirement})]")
271
+ end
272
+ msg << 'If you remove this gems, one or more dependencies will not be met.'
273
+ msg << 'Continue with Uninstall?'
274
+ return ask_yes_no(msg.join("\n"), true)
275
+ end
276
+
277
+ end
278
+