rapt 0.1.0

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.
@@ -0,0 +1,4 @@
1
+
2
+ = 0.1.0
3
+
4
+ * Converted from original Rails plugin code
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006 Geoffrey Grosenbach boss@topfunky.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,4 @@
1
+ Rapt
2
+ ====
3
+
4
+ A plugin manager for Ruby on Rails.
@@ -0,0 +1,74 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ $:.unshift(File.dirname(__FILE__) + "/lib/commands")
10
+ require 'plugin'
11
+
12
+ PKG_NAME = 'rapt'
13
+ PKG_VERSION = '0.1.0'
14
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
15
+
16
+ RELEASE_NAME = "REL #{PKG_VERSION}"
17
+
18
+ RUBY_FORGE_PROJECT = PKG_NAME
19
+ RUBY_FORGE_USER = "topfunky"
20
+
21
+ desc "Default Task"
22
+ task :default => :test
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.pattern = 'test/**/*_test.rb'
27
+ t.verbose = true
28
+ end
29
+
30
+ # Genereate the RDoc documentation
31
+ Rake::RDocTask.new { |rdoc|
32
+ rdoc.rdoc_dir = 'doc'
33
+ rdoc.title = "Rapt -- Rails plugin manager"
34
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
35
+ rdoc.rdoc_files.include('README', 'CHANGELOG')
36
+ rdoc.rdoc_files.include('lib/plugin.rb')
37
+ rdoc.rdoc_files.include('lib/plugin/*.rb')
38
+ }
39
+
40
+ # Create compressed packages
41
+ spec = Gem::Specification.new do |s|
42
+ s.platform = Gem::Platform::RUBY
43
+ s.name = PKG_NAME
44
+ s.summary = "Rails plugin manager."
45
+ s.description = %q{Install, remove, and discover new plugins for your Ruby on Rails app.}
46
+ s.version = PKG_VERSION
47
+
48
+ s.authors = ["Ryan Tomayko", "Geoffrey Grosenbach"]
49
+ s.email = "boss@topfunky.com"
50
+ s.rubyforge_project = RUBY_FORGE_PROJECT
51
+ s.homepage = "http://nubyonrails.com/pages/rapt"
52
+
53
+ s.has_rdoc = false
54
+ s.requirements << 'none'
55
+ s.require_path = 'lib'
56
+
57
+ s.files = [ "Rakefile", "README", "CHANGELOG", "MIT-LICENSE" ]
58
+ %w(bin lib test).each do |dir|
59
+ s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
60
+ end
61
+ s.executables = ["rapt"]
62
+ end
63
+
64
+ Rake::GemPackageTask.new(spec) do |p|
65
+ p.gem_spec = spec
66
+ p.need_tar = true
67
+ p.need_zip = true
68
+ end
69
+
70
+ # desc "Publish the API documentation"
71
+ # task :pgem => [:package] do
72
+ # Rake::SshFilePublisher.new("boss@topfunky.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
73
+ # end
74
+
@@ -0,0 +1,6 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require "commands/plugin"
4
+
5
+ Commands::Plugin.parse!
6
+
@@ -0,0 +1,65 @@
1
+ # Rails Plugin Manager.
2
+ #
3
+ # Listing available plugins:
4
+ #
5
+ # $ ./script/plugin list
6
+ # continuous_builder http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder
7
+ # asset_timestamping http://svn.aviditybytes.com/rails/plugins/asset_timestamping
8
+ # enumerations_mixin http://svn.protocool.com/rails/plugins/enumerations_mixin/trunk
9
+ # calculations http://techno-weenie.net/svn/projects/calculations/
10
+ # ...
11
+ #
12
+ # Installing plugins:
13
+ #
14
+ # $ ./script/plugin install continuous_builder asset_timestamping
15
+ #
16
+ # Finding Repositories:
17
+ #
18
+ # $ ./script/plugin discover
19
+ #
20
+ # Adding Repositories:
21
+ #
22
+ # $ ./script/plugin source http://svn.protocool.com/rails/plugins/
23
+ #
24
+ # How it works:
25
+ #
26
+ # * Maintains a list of subversion repositories that are assumed to have
27
+ # a plugin directory structure. Manage them with the (source, unsource,
28
+ # and sources commands)
29
+ #
30
+ # * The discover command scrapes the following page for things that
31
+ # look like subversion repositories with plugins:
32
+ # http://wiki.rubyonrails.org/rails/pages/Plugins
33
+ #
34
+ # * Unless you specify that you want to use svn, script/plugin uses plain old
35
+ # HTTP for downloads. The following bullets are true if you specify
36
+ # that you want to use svn.
37
+ #
38
+ # * If `vendor/plugins` is under subversion control, the script will
39
+ # modify the svn:externals property and perform an update. You can
40
+ # use normal subversion commands to keep the plugins up to date.
41
+ #
42
+ # * Or, if `vendor/plugins` is not under subversion control, the
43
+ # plugin is pulled via `svn checkout` or `svn export` but looks
44
+ # exactly the same.
45
+ #
46
+ # This is Free Software, copyright 2005 by Ryan Tomayko (rtomayko@gmail.com)
47
+ # and is licensed MIT: (http://www.opensource.org/licenses/mit-license.php)
48
+
49
+ $verbose = false
50
+
51
+ require 'open-uri'
52
+ require 'fileutils'
53
+ require 'tempfile'
54
+
55
+ include FileUtils
56
+
57
+ require File.dirname(__FILE__) + '/plugin/rails_environment'
58
+ require File.dirname(__FILE__) + '/plugin/plugin'
59
+ require File.dirname(__FILE__) + '/plugin/repositories'
60
+ require File.dirname(__FILE__) + '/plugin/repository'
61
+ require File.dirname(__FILE__) + '/plugin/commands'
62
+ require File.dirname(__FILE__) + '/plugin/recursive_http_fetcher'
63
+
64
+
65
+
@@ -0,0 +1,486 @@
1
+
2
+ # Load default environment and parse arguments
3
+ require 'optparse'
4
+ module Commands
5
+
6
+ class Plugin
7
+ attr_reader :environment, :script_name, :sources
8
+ def initialize
9
+ @environment = RailsEnvironment.default
10
+ @rails_root = RailsEnvironment.default.root
11
+ @script_name = File.basename($0)
12
+ @sources = []
13
+ end
14
+
15
+ def environment=(value)
16
+ @environment = value
17
+ RailsEnvironment.default = value
18
+ end
19
+
20
+ def options
21
+ OptionParser.new do |o|
22
+ o.set_summary_indent(' ')
23
+ o.banner = "Usage: #{@script_name} [OPTIONS] command"
24
+ o.define_head "Rails plugin manager."
25
+
26
+ o.separator ""
27
+ o.separator "GENERAL OPTIONS"
28
+
29
+ o.on("-r", "--root=DIR", String,
30
+ "Set an explicit rails app directory.",
31
+ "Default: #{@rails_root}") { |@rails_root| self.environment = RailsEnvironment.new(@rails_root) }
32
+ o.on("-s", "--source=URL1,URL2", Array,
33
+ "Use the specified plugin repositories instead of the defaults.") { |@sources|}
34
+
35
+ o.on("-v", "--verbose", "Turn on verbose output.") { |$verbose| }
36
+ o.on("-h", "--help", "Show this help message.") { puts o; exit }
37
+
38
+ o.separator ""
39
+ o.separator "COMMANDS"
40
+
41
+ o.separator " discover Discover plugin repositories."
42
+ o.separator " list List available plugins."
43
+ o.separator " about Show basic info about a plugin."
44
+ o.separator " install Install plugin(s) from known repositories or URLs."
45
+ o.separator " update Update installed plugins."
46
+ o.separator " remove Uninstall plugins."
47
+ o.separator " source Add a plugin source repository."
48
+ o.separator " unsource Remove a plugin repository."
49
+ o.separator " sources List currently configured plugin repositories."
50
+
51
+ o.separator ""
52
+ o.separator "EXAMPLES"
53
+ o.separator " Install a plugin:"
54
+ o.separator " #{@script_name} install continuous_builder\n"
55
+ o.separator " Install a plugin from a subversion URL:"
56
+ o.separator " #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
57
+ o.separator " Install a plugin and add a svn:externals entry to vendor/plugins"
58
+ o.separator " #{@script_name} install -x continuous_builder\n"
59
+ o.separator " Show information about the acts_as_chunky_bacon plugin:"
60
+ o.separator " #{@script_name} about acts_as_chunky_bacon\n"
61
+ o.separator " List all available plugins:"
62
+ o.separator " #{@script_name} list\n"
63
+ o.separator " List plugins in the specified repository:"
64
+ o.separator " #{@script_name} list --source=http://dev.rubyonrails.com/svn/rails/plugins/\n"
65
+ o.separator " Discover and prompt to add new repositories:"
66
+ o.separator " #{@script_name} discover\n"
67
+ o.separator " Discover new repositories but just list them, don't add anything:"
68
+ o.separator " #{@script_name} discover -l\n"
69
+ o.separator " Add a new repository to the source list:"
70
+ o.separator " #{@script_name} source http://dev.rubyonrails.com/svn/rails/plugins/\n"
71
+ o.separator " Remove a repository from the source list:"
72
+ o.separator " #{@script_name} unsource http://dev.rubyonrails.com/svn/rails/plugins/\n"
73
+ o.separator " Show currently configured repositories:"
74
+ o.separator " #{@script_name} sources\n"
75
+ o.separator " Show the options for the list command:"
76
+ o.separator " #{@script_name} list -h\n"
77
+ end
78
+ end
79
+
80
+ def parse!(args=ARGV)
81
+ general, sub = split_args(args)
82
+ options.parse!(general)
83
+
84
+ command = general.shift
85
+ if command =~ /^(list|discover|install|source|unsource|sources|remove|update|about)$/
86
+ command = Commands.const_get(command.capitalize).new(self)
87
+ command.parse!(sub)
88
+ else
89
+ puts "Unknown command: #{command}"
90
+ puts options
91
+ exit 1
92
+ end
93
+ end
94
+
95
+ def split_args(args)
96
+ left = []
97
+ left << args.shift while args[0] and args[0] =~ /^-/
98
+ left << args.shift if args[0]
99
+ return [left, args]
100
+ end
101
+
102
+ def self.parse!(args=ARGV)
103
+ Plugin.new.parse!(args)
104
+ end
105
+ end
106
+
107
+
108
+ class List
109
+ def initialize(base_command)
110
+ @base_command = base_command
111
+ @sources = []
112
+ @local = false
113
+ @remote = false
114
+ @cached = true
115
+ end
116
+
117
+ def options
118
+ OptionParser.new do |o|
119
+ o.set_summary_indent(' ')
120
+ o.banner = "Usage: #{@base_command.script_name} list [OPTIONS] [PATTERN]"
121
+ o.define_head "List available plugins."
122
+ o.separator ""
123
+ o.separator "Options:"
124
+ o.separator ""
125
+ o.on( "-s", "--source=URL1,URL2", Array,
126
+ "Use the specified plugin repositories.") {|@sources| @remote = true; @cached = false }
127
+ o.on( "--local",
128
+ "List locally installed plugins.") {|@local| @cached = false }
129
+ o.on( "--cached",
130
+ "List the known plugins in the local sources cache. This is the default behavior.") {|@cached|}
131
+ o.on( "--remote",
132
+ "List remotely available plugins.",
133
+ "unless --local is provided.") {|@remote| @cached = false }
134
+ end
135
+ end
136
+
137
+ def parse!(args)
138
+ options.order!(args)
139
+ unless @sources.empty?
140
+ @sources.map!{ |uri| Repository.new(uri) }
141
+ else
142
+ @sources = Repositories.instance.all
143
+ end
144
+ if @remote
145
+ @sources.map{|r| r.plugins}.flatten.each do |plugin|
146
+ if @local or !plugin.installed?
147
+ puts plugin.to_s
148
+ end
149
+ end
150
+ elsif @cached
151
+ Repositories.instance.cached_plugins.each { |plugin| puts plugin.to_s }
152
+ puts "\nThere are #{Repositories.instance.plugin_count} plugins in the source cache.\n\n"
153
+ else
154
+ cd "#{@base_command.environment.root}/vendor/plugins"
155
+ Dir["*"].select{|p| File.directory?(p)}.each do |name|
156
+ puts name
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ class Sources
164
+ def initialize(base_command)
165
+ @base_command = base_command
166
+ end
167
+
168
+ def options
169
+ OptionParser.new do |o|
170
+ o.set_summary_indent(' ')
171
+ o.banner = "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]"
172
+ o.define_head "List configured plugin repositories."
173
+ o.separator ""
174
+ o.separator "Options:"
175
+ o.separator ""
176
+ o.on( "-c", "--check",
177
+ "Report status of repository.") { |@sources| } # TODO Implement
178
+ o.on( "-r", "--refresh",
179
+ "Refresh the source cache with the list of plugins available in each repository.") { refresh }
180
+ end
181
+ end
182
+
183
+ def parse!(args)
184
+ options.parse!(args)
185
+ Repositories.each do |repo|
186
+ puts repo.uri
187
+ end
188
+ end
189
+
190
+ def refresh
191
+ puts "Refreshing source cache (may take a few minutes)..."
192
+ repositories = Repositories.instance
193
+ repositories.refresh!
194
+ repositories.save
195
+ end
196
+ end
197
+
198
+
199
+ class Source
200
+ def initialize(base_command)
201
+ @base_command = base_command
202
+ end
203
+
204
+ def options
205
+ OptionParser.new do |o|
206
+ o.set_summary_indent(' ')
207
+ o.banner = "Usage: #{@base_command.script_name} source REPOSITORY"
208
+ o.define_head "Add a new repository."
209
+ end
210
+ end
211
+
212
+ def parse!(args)
213
+ options.parse!(args)
214
+ count = 0
215
+ args.each do |uri|
216
+ if Repositories.instance.add(uri)
217
+ puts "added: #{uri.ljust(50)}" if $verbose
218
+ count += 1
219
+ else
220
+ puts "failed: #{uri.ljust(50)}"
221
+ end
222
+ end
223
+ Repositories.instance.save
224
+ puts "Added #{count} repositories."
225
+ end
226
+ end
227
+
228
+
229
+ class Unsource
230
+ def initialize(base_command)
231
+ @base_command = base_command
232
+ end
233
+
234
+ def options
235
+ OptionParser.new do |o|
236
+ o.set_summary_indent(' ')
237
+ o.banner = "Usage: #{@base_command.script_name} source URI [URI [URI]...]"
238
+ o.define_head "Remove repositories from the default search list."
239
+ o.separator ""
240
+ o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
241
+ end
242
+ end
243
+
244
+ def parse!(args)
245
+ options.parse!(args)
246
+ count = 0
247
+ args.each do |uri|
248
+ if Repositories.instance.remove(uri)
249
+ count += 1
250
+ puts "removed: #{uri.ljust(50)}"
251
+ else
252
+ puts "failed: #{uri.ljust(50)}"
253
+ end
254
+ end
255
+ Repositories.instance.save
256
+ puts "Removed #{count} repositories."
257
+ end
258
+ end
259
+
260
+
261
+ class Discover
262
+ def initialize(base_command)
263
+ @base_command = base_command
264
+ @list = false
265
+ @prompt = true
266
+ end
267
+
268
+ def options
269
+ OptionParser.new do |o|
270
+ o.set_summary_indent(' ')
271
+ o.banner = "Usage: #{@base_command.script_name} discover URI [URI [URI]...]"
272
+ o.define_head "Discover repositories referenced on a page."
273
+ o.separator ""
274
+ o.separator "Options:"
275
+ o.separator ""
276
+ o.on( "-l", "--list",
277
+ "List but don't prompt or add discovered repositories.") { |@list| @prompt = !@list }
278
+ o.on( "-n", "--no-prompt",
279
+ "Add all new repositories without prompting.") { |v| @prompt = false }
280
+ end
281
+ end
282
+
283
+ def parse!(args)
284
+ options.parse!(args)
285
+ args = ['http://wiki.rubyonrails.org/rails/pages/Plugins', 'http://agilewebdevelopment.com/plugins/scrape'] if args.empty?
286
+ args.each do |uri|
287
+ scrape(uri) do |repo_uri|
288
+ catch(:next_uri) do
289
+ if @prompt
290
+ begin
291
+ $stdout.print "Add #{repo_uri}? [Y/n] "
292
+ throw :next_uri if $stdin.gets !~ /^y?$/i
293
+ rescue Interrupt
294
+ $stdout.puts
295
+ exit 1
296
+ end
297
+ elsif @list
298
+ puts repo_uri
299
+ throw :next_uri
300
+ end
301
+ Repositories.instance.add(repo_uri)
302
+ puts "discovered: #{repo_uri}" if $verbose or !@prompt
303
+ end
304
+ end
305
+ end
306
+ Repositories.instance.save
307
+ end
308
+
309
+ def scrape(uri)
310
+ require 'open-uri'
311
+ puts "Scraping #{uri}" if $verbose
312
+ dupes = []
313
+ content = open(uri).each do |line|
314
+ begin
315
+ if line =~ /<a[^>]*href=['"]([^'"]*)['"]/ || line =~ /(svn:\/\/[^<|\n]*)/
316
+ uri = $1
317
+ if uri =~ /^\w+:\/\// && uri =~ /\/plugins\// && uri !~ /\/browser\// && uri !~ /^http:\/\/wiki\.rubyonrails/ && uri !~ /http:\/\/instiki/
318
+ uri = extract_repository_uri(uri)
319
+ yield uri unless dupes.include?(uri) || Repositories.instance.exist?(uri)
320
+ dupes << uri
321
+ end
322
+ end
323
+ rescue
324
+ puts "Problems scraping '#{uri}': #{$!.to_s}"
325
+ end
326
+ end
327
+ end
328
+
329
+ def extract_repository_uri(uri)
330
+ uri.match(/(svn|https?):.*\/plugins\//i)[0]
331
+ end
332
+ end
333
+
334
+ class Install
335
+ def initialize(base_command)
336
+ @base_command = base_command
337
+ @method = :http
338
+ @options = { :quiet => false, :revision => nil, :force => false }
339
+ end
340
+
341
+ def options
342
+ OptionParser.new do |o|
343
+ o.set_summary_indent(' ')
344
+ o.banner = "Usage: #{@base_command.script_name} install PLUGIN [PLUGIN [PLUGIN] ...]"
345
+ o.define_head "Install one or more plugins."
346
+ o.separator ""
347
+ o.separator "Options:"
348
+ o.on( "-x", "--externals",
349
+ "Use svn:externals to grab the plugin.",
350
+ "Enables plugin updates and plugin versioning.") { |v| @method = :externals }
351
+ o.on( "-o", "--checkout",
352
+ "Use svn checkout to grab the plugin.",
353
+ "Enables updating but does not add a svn:externals entry.") { |v| @method = :checkout }
354
+ o.on( "-q", "--quiet",
355
+ "Suppresses the output from installation.",
356
+ "Ignored if -v is passed (./script/plugin -v install ...)") { |v| @options[:quiet] = true }
357
+ o.on( "-r REVISION", "--revision REVISION",
358
+ "Checks out the given revision from subversion.",
359
+ "Ignored if subversion is not used.") { |v| @options[:revision] = v }
360
+ o.on( "-f", "--force",
361
+ "Reinstalls a plugin if it's already installed.") { |v| @options[:force] = true }
362
+ o.separator ""
363
+ o.separator "You can specify plugin names as given in 'plugin list' output or absolute URLs to "
364
+ o.separator "a plugin repository."
365
+ end
366
+ end
367
+
368
+ def determine_install_method
369
+ best = @base_command.environment.best_install_method?
370
+ @method = :http if best == :http and @method == :export
371
+ case
372
+ when (best == :http and @method != :http)
373
+ msg = "Cannot install using subversion because `svn' cannot be found in your PATH"
374
+ when (best == :export and (@method != :export and @method != :http))
375
+ msg = "Cannot install using #{@method} because this project is not under subversion."
376
+ when (best != :externals and @method == :externals)
377
+ msg = "Cannot install using externals because vendor/plugins is not under subversion."
378
+ end
379
+ if msg
380
+ puts msg
381
+ exit 1
382
+ end
383
+ @method
384
+ end
385
+
386
+ def parse!(args)
387
+ options.parse!(args)
388
+ environment = @base_command.environment
389
+ install_method = determine_install_method
390
+ puts "Plugins will be installed using #{install_method}" if $verbose
391
+ args.each do |name|
392
+ ::Plugin.find(name).install(install_method, @options)
393
+ end
394
+ rescue
395
+ puts "Plugin not found: #{args.inspect}"
396
+ exit 1
397
+ end
398
+ end
399
+
400
+ class Update
401
+ def initialize(base_command)
402
+ @base_command = base_command
403
+ end
404
+
405
+ def options
406
+ OptionParser.new do |o|
407
+ o.set_summary_indent(' ')
408
+ o.banner = "Usage: #{@base_command.script_name} update [name [name]...]"
409
+ o.on( "-r REVISION", "--revision REVISION",
410
+ "Checks out the given revision from subversion.",
411
+ "Ignored if subversion is not used.") { |v| @revision = v }
412
+ o.define_head "Update plugins."
413
+ end
414
+ end
415
+
416
+ def parse!(args)
417
+ options.parse!(args)
418
+ root = @base_command.environment.root
419
+ cd root
420
+ args = Dir["vendor/plugins/*"].map do |f|
421
+ File.directory?("#{f}/.svn") ? File.basename(f) : nil
422
+ end.compact if args.empty?
423
+ cd "vendor/plugins"
424
+ args.each do |name|
425
+ if File.directory?(name)
426
+ puts "Updating plugin: #{name}"
427
+ system("svn #{$verbose ? '' : '-q'} up \"#{name}\" #{@revision ? "-r #{@revision}" : ''}")
428
+ else
429
+ puts "Plugin doesn't exist: #{name}"
430
+ end
431
+ end
432
+ end
433
+ end
434
+
435
+ class Remove
436
+ def initialize(base_command)
437
+ @base_command = base_command
438
+ end
439
+
440
+ def options
441
+ OptionParser.new do |o|
442
+ o.set_summary_indent(' ')
443
+ o.banner = "Usage: #{@base_command.script_name} remove name [name]..."
444
+ o.define_head "Remove plugins."
445
+ end
446
+ end
447
+
448
+ def parse!(args)
449
+ options.parse!(args)
450
+ root = @base_command.environment.root
451
+ args.each do |name|
452
+ ::Plugin.new(name).uninstall
453
+ end
454
+ end
455
+ end
456
+
457
+ class About
458
+ def initialize(base_command)
459
+ @base_command = base_command
460
+ end
461
+
462
+ def options
463
+ OptionParser.new do |o|
464
+ o.set_summary_indent(' ')
465
+ o.banner = "Usage: #{@base_command.script_name} about name [name]..."
466
+ o.define_head "Shows plugin info at {url}/about.yml."
467
+ end
468
+ end
469
+
470
+ def parse!(args)
471
+ options.parse!(args)
472
+ args.each do |name|
473
+ if plugin = ::Plugin.find(name)
474
+ if about_hash = plugin.about
475
+ puts about_hash.to_yaml + "\n"
476
+ next
477
+ end
478
+ end
479
+
480
+ puts "Plugin #{name} could not be found in the known repositories."
481
+ puts
482
+ end
483
+ end
484
+ end
485
+ end
486
+