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,182 @@
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 'timeout'
8
+ require 'libgems/command'
9
+ require 'libgems/user_interaction'
10
+
11
+ ##
12
+ # The command manager registers and installs all the individual sub-commands
13
+ # supported by the gem command.
14
+ #
15
+ # Extra commands can be provided by writing a rubygems_plugin.rb
16
+ # file in an installed gem. You should register your command against the
17
+ # LibGems::CommandManager instance, like this:
18
+ #
19
+ # # file rubygems_plugin.rb
20
+ # require 'libgems/command_manager'
21
+ #
22
+ # class LibGems::Commands::EditCommand < LibGems::Command
23
+ # # ...
24
+ # end
25
+ #
26
+ # LibGems::CommandManager.instance.register_command :edit
27
+ #
28
+ # See LibGems::Command for instructions on writing gem commands.
29
+
30
+ class LibGems::CommandManager
31
+
32
+ include LibGems::UserInteraction
33
+
34
+ ##
35
+ # Return the authoritative instance of the command manager.
36
+
37
+ def self.instance
38
+ @command_manager ||= new
39
+ end
40
+
41
+ ##
42
+ # Register all the subcommands supported by the gem command.
43
+
44
+ def initialize
45
+ @commands = {}
46
+ register_command :build
47
+ register_command :cert
48
+ register_command :check
49
+ register_command :cleanup
50
+ register_command :contents
51
+ register_command :dependency
52
+ register_command :environment
53
+ register_command :fetch
54
+ register_command :generate_index
55
+ register_command :help
56
+ register_command :install
57
+ register_command :list
58
+ register_command :lock
59
+ register_command :mirror
60
+ register_command :outdated
61
+ register_command :owner
62
+ register_command :pristine
63
+ register_command :push
64
+ register_command :query
65
+ register_command :rdoc
66
+ register_command :search
67
+ register_command :server
68
+ register_command :sources
69
+ register_command :specification
70
+ register_command :stale
71
+ register_command :uninstall
72
+ register_command :unpack
73
+ register_command :update
74
+ register_command :which
75
+ end
76
+
77
+ ##
78
+ # Register the Symbol +command+ as a gem command.
79
+
80
+ def register_command(command)
81
+ @commands[command] = false
82
+ end
83
+
84
+ ##
85
+ # Return the registered command from the command name.
86
+
87
+ def [](command_name)
88
+ command_name = command_name.intern
89
+ return nil if @commands[command_name].nil?
90
+ @commands[command_name] ||= load_and_instantiate(command_name)
91
+ end
92
+
93
+ ##
94
+ # Return a sorted list of all command names (as strings).
95
+
96
+ def command_names
97
+ @commands.keys.collect {|key| key.to_s}.sort
98
+ end
99
+
100
+ ##
101
+ # Run the config specified by +args+.
102
+
103
+ def run(args)
104
+ process_args(args)
105
+ rescue StandardError, Timeout::Error => ex
106
+ alert_error "While executing gem ... (#{ex.class})\n #{ex.to_s}"
107
+ ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
108
+ LibGems.configuration.backtrace
109
+ terminate_interaction(1)
110
+ rescue Interrupt
111
+ alert_error "Interrupted"
112
+ terminate_interaction(1)
113
+ end
114
+
115
+ def process_args(args)
116
+ args = args.to_str.split(/\s+/) if args.respond_to?(:to_str)
117
+ if args.size == 0
118
+ say LibGems::Command::HELP
119
+ terminate_interaction(1)
120
+ end
121
+ case args[0]
122
+ when '-h', '--help'
123
+ say LibGems::Command::HELP
124
+ terminate_interaction(0)
125
+ when '-v', '--version'
126
+ say "#{LibGems::NAME} #{LibGems::VERSION} (RubyGems #{LibGems::GEM_VERSION})"
127
+ terminate_interaction(0)
128
+ when /^-/
129
+ alert_error "Invalid option: #{args[0]}. See 'gem --help'."
130
+ terminate_interaction(1)
131
+ else
132
+ cmd_name = args.shift.downcase
133
+ cmd = find_command(cmd_name)
134
+ cmd.invoke(*args)
135
+ end
136
+ end
137
+
138
+ def find_command(cmd_name)
139
+ possibilities = find_command_possibilities cmd_name
140
+ if possibilities.size > 1 then
141
+ raise "Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
142
+ elsif possibilities.size < 1 then
143
+ raise "Unknown command #{cmd_name}"
144
+ end
145
+
146
+ self[possibilities.first]
147
+ end
148
+
149
+ def find_command_possibilities(cmd_name)
150
+ len = cmd_name.length
151
+
152
+ command_names.select { |n| cmd_name == n[0, len] }
153
+ end
154
+
155
+ private
156
+
157
+ def load_and_instantiate(command_name)
158
+ command_name = command_name.to_s
159
+ const_name = command_name.capitalize.gsub(/_(.)/) { $1.upcase } << "Command"
160
+ commands = LibGems::Commands
161
+ retried = false
162
+
163
+ begin
164
+ commands.const_get const_name
165
+ rescue NameError
166
+ raise if retried
167
+
168
+ retried = true
169
+ begin
170
+ require "libgems/commands/#{command_name}_command"
171
+ rescue Exception => e
172
+ alert_error "Loading command: #{command_name} (#{e.class})\n #{e}"
173
+ ui.errs.puts "\t#{e.backtrace.join "\n\t"}" if
174
+ LibGems.configuration.backtrace
175
+ raise RuntimeError
176
+ end
177
+ retry
178
+ end.new
179
+ end
180
+
181
+ end
182
+
@@ -0,0 +1,53 @@
1
+ require 'libgems/command'
2
+ require 'libgems/builder'
3
+
4
+ class LibGems::Commands::BuildCommand < LibGems::Command
5
+
6
+ def initialize
7
+ super('build', 'Build a gem from a gemspec')
8
+ end
9
+
10
+ def arguments # :nodoc:
11
+ "GEMSPEC_FILE gemspec file name to build a gem for"
12
+ end
13
+
14
+ def usage # :nodoc:
15
+ "#{program_name} GEMSPEC_FILE"
16
+ end
17
+
18
+ def execute
19
+ gemspec = get_one_gem_name
20
+ if File.exist?(gemspec)
21
+ specs = load_gemspecs(gemspec)
22
+ specs.each do |spec|
23
+ LibGems::Builder.new(spec).build
24
+ end
25
+ else
26
+ alert_error "Gemspec file not found: #{gemspec}"
27
+ end
28
+ end
29
+
30
+ def load_gemspecs(filename)
31
+ if yaml?(filename)
32
+ result = []
33
+ open(filename) do |f|
34
+ begin
35
+ while not f.eof? and spec = LibGems::Specification.from_yaml(f)
36
+ result << spec
37
+ end
38
+ rescue LibGems::EndOfYAMLException
39
+ # OK
40
+ end
41
+ end
42
+ else
43
+ result = [LibGems::Specification.load(filename)]
44
+ end
45
+ result
46
+ end
47
+
48
+ def yaml?(filename)
49
+ line = open(filename) { |f| line = f.gets }
50
+ result = line =~ %r{!ruby/object:LibGems::Specification}
51
+ result
52
+ end
53
+ end
@@ -0,0 +1,86 @@
1
+ require 'libgems/command'
2
+ require 'libgems/security'
3
+
4
+ class LibGems::Commands::CertCommand < LibGems::Command
5
+
6
+ def initialize
7
+ super 'cert', "Manage #{LibGems::NAME} certificates and signing settings"
8
+
9
+ add_option('-a', '--add CERT',
10
+ 'Add a trusted certificate.') do |value, options|
11
+ cert = OpenSSL::X509::Certificate.new(File.read(value))
12
+ LibGems::Security.add_trusted_cert(cert)
13
+ say "Added '#{cert.subject.to_s}'"
14
+ end
15
+
16
+ add_option('-l', '--list',
17
+ 'List trusted certificates.') do |value, options|
18
+ glob_str = File::join(LibGems::Security::OPT[:trust_dir], '*.pem')
19
+ Dir::glob(glob_str) do |path|
20
+ begin
21
+ cert = OpenSSL::X509::Certificate.new(File.read(path))
22
+ # this could probably be formatted more gracefully
23
+ say cert.subject.to_s
24
+ rescue OpenSSL::X509::CertificateError
25
+ next
26
+ end
27
+ end
28
+ end
29
+
30
+ add_option('-r', '--remove STRING',
31
+ 'Remove trusted certificates containing',
32
+ 'STRING.') do |value, options|
33
+ trust_dir = LibGems::Security::OPT[:trust_dir]
34
+ glob_str = File::join(trust_dir, '*.pem')
35
+
36
+ Dir::glob(glob_str) do |path|
37
+ begin
38
+ cert = OpenSSL::X509::Certificate.new(File.read(path))
39
+ if cert.subject.to_s.downcase.index(value)
40
+ say "Removed '#{cert.subject.to_s}'"
41
+ File.unlink(path)
42
+ end
43
+ rescue OpenSSL::X509::CertificateError
44
+ next
45
+ end
46
+ end
47
+ end
48
+
49
+ add_option('-b', '--build EMAIL_ADDR',
50
+ 'Build private key and self-signed',
51
+ 'certificate for EMAIL_ADDR.') do |value, options|
52
+ vals = LibGems::Security.build_self_signed_cert(value)
53
+ File.chmod 0600, vals[:key_path]
54
+ say "Public Cert: #{vals[:cert_path]}"
55
+ say "Private Key: #{vals[:key_path]}"
56
+ say "Don't forget to move the key file to somewhere private..."
57
+ end
58
+
59
+ add_option('-C', '--certificate CERT',
60
+ 'Certificate for --sign command.') do |value, options|
61
+ cert = OpenSSL::X509::Certificate.new(File.read(value))
62
+ LibGems::Security::OPT[:issuer_cert] = cert
63
+ end
64
+
65
+ add_option('-K', '--private-key KEY',
66
+ 'Private key for --sign command.') do |value, options|
67
+ key = OpenSSL::PKey::RSA.new(File.read(value))
68
+ LibGems::Security::OPT[:issuer_key] = key
69
+ end
70
+
71
+ add_option('-s', '--sign NEWCERT',
72
+ 'Sign a certificate with my key and',
73
+ 'certificate.') do |value, options|
74
+ cert = OpenSSL::X509::Certificate.new(File.read(value))
75
+ my_cert = LibGems::Security::OPT[:issuer_cert]
76
+ my_key = LibGems::Security::OPT[:issuer_key]
77
+ cert = LibGems::Security.sign_cert(cert, my_key, my_cert)
78
+ File.open(value, 'wb') { |file| file.write(cert.to_pem) }
79
+ end
80
+ end
81
+
82
+ def execute
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,80 @@
1
+ require 'libgems/command'
2
+ require 'libgems/version_option'
3
+ require 'libgems/validator'
4
+
5
+ class LibGems::Commands::CheckCommand < LibGems::Command
6
+
7
+ include LibGems::VersionOption
8
+
9
+ def initialize
10
+ super 'check', 'Check installed gems',
11
+ :verify => false, :alien => false
12
+
13
+ add_option( '--verify FILE',
14
+ 'Verify gem file against its internal',
15
+ 'checksum') do |value, options|
16
+ options[:verify] = value
17
+ end
18
+
19
+ add_option('-a', '--alien', "Report 'unmanaged' or rogue files in the",
20
+ "gem repository") do |value, options|
21
+ options[:alien] = true
22
+ end
23
+
24
+ add_option('-v', '--verbose', "Spew more words") do |value, options|
25
+ options[:verbose] = true
26
+ end
27
+
28
+ add_option('-t', '--test', "Run unit tests for gem") do |value, options|
29
+ options[:test] = true
30
+ end
31
+
32
+ add_version_option 'run tests for'
33
+ end
34
+
35
+ def execute
36
+ if options[:test]
37
+ version = options[:version] || LibGems::Requirement.default
38
+ dep = LibGems::Dependency.new get_one_gem_name, version
39
+ gem_spec = LibGems::SourceIndex.from_installed_gems.search(dep).first
40
+ LibGems::Validator.new.unit_test(gem_spec)
41
+ end
42
+
43
+ if options[:alien]
44
+ say "Performing the 'alien' operation"
45
+ say
46
+ gems = get_all_gem_names rescue []
47
+ LibGems::Validator.new.alien(gems).sort.each do |key, val|
48
+ unless val.empty? then
49
+ say "#{key} has #{val.size} problems"
50
+ val.each do |error_entry|
51
+ say " #{error_entry.path}:"
52
+ say " #{error_entry.problem}"
53
+ end
54
+ else
55
+ say "#{key} is error-free" if options[:verbose]
56
+ end
57
+ say
58
+ end
59
+ end
60
+
61
+ if options[:verify]
62
+ gem_name = options[:verify]
63
+ unless gem_name
64
+ alert_error "Must specify a .gem file with --verify NAME"
65
+ return
66
+ end
67
+ unless File.exist?(gem_name)
68
+ alert_error "Unknown file: #{gem_name}."
69
+ return
70
+ end
71
+ say "Verifying gem: '#{gem_name}'"
72
+ begin
73
+ LibGems::Validator.new.verify_gem_file(gem_name)
74
+ rescue Exception
75
+ alert_error "#{gem_name} is invalid."
76
+ end
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,106 @@
1
+ require 'libgems/command'
2
+ require 'libgems/source_index'
3
+ require 'libgems/dependency_list'
4
+ require 'libgems/uninstaller'
5
+
6
+ class LibGems::Commands::CleanupCommand < LibGems::Command
7
+
8
+ def initialize
9
+ super 'cleanup',
10
+ 'Clean up old versions of installed gems in the local repository',
11
+ :force => false, :test => false, :install_dir => LibGems.dir
12
+
13
+ add_option('-d', '--dryrun', "") do |value, options|
14
+ options[:dryrun] = true
15
+ end
16
+ end
17
+
18
+ def arguments # :nodoc:
19
+ "GEMNAME name of gem to cleanup"
20
+ end
21
+
22
+ def defaults_str # :nodoc:
23
+ "--no-dryrun"
24
+ end
25
+
26
+ def description # :nodoc:
27
+ <<-EOF
28
+ The cleanup command removes old gems from GEM_HOME. If an older version is
29
+ installed elsewhere in GEM_PATH the cleanup command won't touch it.
30
+ EOF
31
+ end
32
+
33
+ def usage # :nodoc:
34
+ "#{program_name} [GEMNAME ...]"
35
+ end
36
+
37
+ def execute
38
+ say "Cleaning up installed gems..."
39
+ primary_gems = {}
40
+
41
+ LibGems.source_index.each do |name, spec|
42
+ if primary_gems[spec.name].nil? or
43
+ primary_gems[spec.name].version < spec.version then
44
+ primary_gems[spec.name] = spec
45
+ end
46
+ end
47
+
48
+ gems_to_cleanup = []
49
+
50
+ unless options[:args].empty? then
51
+ options[:args].each do |gem_name|
52
+ dep = LibGems::Dependency.new gem_name, LibGems::Requirement.default
53
+ specs = LibGems.source_index.search dep
54
+ specs.each do |spec|
55
+ gems_to_cleanup << spec
56
+ end
57
+ end
58
+ else
59
+ LibGems.source_index.each do |name, spec|
60
+ gems_to_cleanup << spec
61
+ end
62
+ end
63
+
64
+ gems_to_cleanup = gems_to_cleanup.select { |spec|
65
+ primary_gems[spec.name].version != spec.version
66
+ }
67
+
68
+ deplist = LibGems::DependencyList.new
69
+ gems_to_cleanup.uniq.each do |spec| deplist.add spec end
70
+
71
+ deps = deplist.strongly_connected_components.flatten.reverse
72
+
73
+ deps.each do |spec|
74
+ if options[:dryrun] then
75
+ say "Dry Run Mode: Would uninstall #{spec.full_name}"
76
+ else
77
+ say "Attempting to uninstall #{spec.full_name}"
78
+
79
+ options[:args] = [spec.name]
80
+
81
+ uninstall_options = {
82
+ :executables => false,
83
+ :version => "= #{spec.version}",
84
+ }
85
+
86
+ if LibGems.user_dir == spec.installation_path then
87
+ uninstall_options[:install_dir] = spec.installation_path
88
+ end
89
+
90
+ uninstaller = LibGems::Uninstaller.new spec.name, uninstall_options
91
+
92
+ begin
93
+ uninstaller.uninstall
94
+ rescue LibGems::DependencyRemovalException, LibGems::InstallError,
95
+ LibGems::GemNotInHomeException => e
96
+ say "Unable to uninstall #{spec.full_name}:"
97
+ say "\t#{e.class}: #{e.message}"
98
+ end
99
+ end
100
+ end
101
+
102
+ say "Clean Up Complete"
103
+ end
104
+
105
+ end
106
+