capsaicin 0.1.2

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Joe Khoobyar
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.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = capsaicin
2
+
3
+ Joe Khoobyar's spicy capistrano extensions.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Joe Khoobyar. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rake/rdoctask'
5
+ require 'rake/testtask'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |s|
10
+ s.name = "capsaicin"
11
+ s.homepage = "http://github.com/joekhoobyar/capsaicin"
12
+ s.summary = "Joe Khoobyar's spicy capistrano extensions"
13
+ s.description = %Q{Spicy capistrano extensions for various needs}
14
+
15
+ s.authors = ["Joe Khoobyar"]
16
+ s.email = "joe@ankhcraft.com"
17
+
18
+ s.add_dependency 'capistrano', ['>= 2.0']
19
+ s.add_dependency 'archive-tar-minitar', ['>= 0.5']
20
+ end
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
23
+ end
24
+
25
+ # --------- RDoc Documentation ---------
26
+ desc "Generate RDoc documentation"
27
+ Rake::RDocTask.new(:rdoc) do |rdoc|
28
+ rdoc.options << '--line-numbers' << '--inline-source' <<
29
+ '--main' << 'README' <<
30
+ '--title' << "Capsaicin" <<
31
+ '--charset' << 'utf-8'
32
+ rdoc.rdoc_dir = "doc"
33
+ rdoc.rdoc_files.include 'README*'
34
+ rdoc.rdoc_files.include('lib/**/*.rb')
35
+ end
36
+
37
+ Rake::TestTask.new do |t|
38
+ t.libs << "test"
39
+ t.libs << "lib"
40
+ end
41
+
42
+ task :default => :build
43
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 2
3
+ :major: 0
4
+ :minor: 1
data/lib/capsaicin.rb ADDED
@@ -0,0 +1,10 @@
1
+ unless Capistrano::Configuration.respond_to?(:instance)
2
+ abort "capsaicin requires capistrano 2.0 or later"
3
+ end
4
+ require 'capistrano'
5
+
6
+ require File.join(File.dirname(__FILE__), %w(capsaicin sys))
7
+ require File.join(File.dirname(__FILE__), %w(capsaicin invocation))
8
+ require File.join(File.dirname(__FILE__), %w(capsaicin files))
9
+ require File.join(File.dirname(__FILE__), %w(capsaicin service))
10
+ require File.join(File.dirname(__FILE__), %w(capsaicin ui))
@@ -0,0 +1,7 @@
1
+ module Capsaicin
2
+ module Bundle
3
+
4
+ end
5
+
6
+ Capistrano.plugin :bundle
7
+ end
@@ -0,0 +1,47 @@
1
+ module Capsaicin
2
+ module Files
3
+
4
+ COMMANDS = [ %w(mkdir mkdir_p rmdir cp cp_r rm rm_f rm_r rm_rf
5
+ chmod chmod_R chown chown_R touch),
6
+ %w(ln ln_s ln_sf mv install) ]
7
+
8
+ FILE_TESTS = [
9
+ %w(blockdev? -b),
10
+ %w(chardev? -c),
11
+ %w(directory? -d),
12
+ %w(exists? -e),
13
+ %w(file? -f),
14
+ %w(grpowned? -G),
15
+ %w(owned? -O),
16
+ %w(pipe? -p),
17
+ %w(readable? -r),
18
+ %w(setgid? -g),
19
+ %w(setuid? -u),
20
+ %w(size? -s),
21
+ %w(socket? -S),
22
+ %w(sticky? -k),
23
+ %w(symlink? -h),
24
+ %w(writable? -w),
25
+ %w(executable? -x)
26
+ ]
27
+
28
+ LOCAL_RUN_METHODS = [:system, :local_run]
29
+
30
+ require File.join(File.dirname(__FILE__), %w(files local.rb))
31
+ require File.join(File.dirname(__FILE__), %w(files remote.rb))
32
+
33
+ class_eval(Local.public_instance_methods(false).map do |m|
34
+ "def #{m}(*args, &block)\n send(_via.to_s + '_files').#{m}(*args, &block)\nend"
35
+ end.join("\n"), __FILE__, __LINE__)
36
+
37
+ def _via
38
+ if LOCAL_RUN_METHODS.include? @config.fetch(:run_method, nil)
39
+ :local
40
+ else
41
+ :remote
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ Capistrano.plugin :files, Capsaicin::Files
@@ -0,0 +1,49 @@
1
+ require 'fileutils'
2
+
3
+ module Capsaicin
4
+ module Files
5
+ module Local
6
+
7
+ include FileUtils::Verbose
8
+
9
+ public *COMMANDS.flatten
10
+ public :pwd
11
+
12
+ FILE_TESTS.each do |m,t|
13
+ class_eval <<-EODEF, __FILE__, __LINE__
14
+ def #{m}(a, options={})
15
+ logger.trace "test #{t} \#{a.gsub ' ', '\\ '}" if logger
16
+ File.#{m} a
17
+ end
18
+ EODEF
19
+ end
20
+
21
+ def tail_f(file, n=10)
22
+ unless defined? File::Tail::Logfile then gem 'file-tail'; require 'file/tail' end
23
+ File::Tail::Logfile.tail(file, :backward=>n) do |line| puts line end
24
+ rescue Interrupt
25
+ logger.trace "interrupted (Ctrl-C)" if logger
26
+ end
27
+
28
+ def upload(from, to)
29
+ cp from, to
30
+ end
31
+
32
+ def download(from, to)
33
+ cp from, to
34
+ end
35
+
36
+ def cd(dir, options={})
37
+ if block_given?
38
+ dir, dir2 = pwd, dir
39
+ cd dir2
40
+ yield
41
+ end
42
+ cd dir
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+
49
+ Capistrano.plugin :local_files, Capsaicin::Files::Local
@@ -0,0 +1,117 @@
1
+ require 'fileutils'
2
+
3
+ module Capsaicin
4
+ module Files
5
+ module Remote
6
+
7
+ COMMANDS.each_with_index do |l,n|
8
+ l.each do |m|
9
+ k, f = m.split('_')
10
+ f = ' -' + f if f
11
+ class_eval <<-EODEF, __FILE__, __LINE__
12
+ def #{m}(*args)
13
+ options = args.pop if Hash === args.last
14
+ _r '#{k}#{f}', args#{', ' + (n+1).to_s if n > 0}
15
+ end
16
+ EODEF
17
+ end
18
+ end
19
+
20
+ FILE_TESTS.each do |m,t|
21
+ class_eval <<-EODEF
22
+ def #{m}(a, options={})
23
+ _t "test #{t}", a
24
+ end
25
+ EODEF
26
+ end
27
+
28
+ def tail_f(file, n=10)
29
+ cmd = "tail -n #{n} -f #{_q file}"
30
+ case v = _via
31
+ when :system, :local_run
32
+ send v, cmd
33
+ else
34
+ stream cmd, :via => v
35
+ end
36
+ rescue Interrupt
37
+ logger.trace "interrupted (Ctrl-C)" if logger
38
+ end
39
+
40
+ def upload(*args)
41
+ case _via
42
+ when :system, :local_run
43
+ cp(*args)
44
+ else
45
+ @config.upload(*args)
46
+ end
47
+ end
48
+
49
+ def download(*args)
50
+ case _via
51
+ when :system, :local_run
52
+ cp(*args)
53
+ else
54
+ @config.download(*args)
55
+ end
56
+ end
57
+
58
+ def cd(dir, options={})
59
+ if block_given?
60
+ dir, dir2 = pwd, dir
61
+ _r 'cd', dir2
62
+ yield
63
+ end
64
+ _r 'cd', dir
65
+ end
66
+
67
+ def pwd
68
+ capture 'pwd', :via => _via
69
+ end
70
+
71
+ private
72
+
73
+ def _t(cmd, args=nil, min=nil)
74
+ cmd = _a cmd, args, min
75
+ if _via == :system then
76
+ local_run(cmd)
77
+ else
78
+ capture("#{cmd}; echo $?", :via => _via).strip == '0'
79
+ end
80
+ end
81
+
82
+ def _r(cmd, args=nil, min=nil)
83
+ cmd = _a cmd, args, min
84
+ if _via != :system then
85
+ invoke_command cmd, :via => _via
86
+ else
87
+ local_run cmd
88
+ end
89
+ end
90
+
91
+ def _a(cmd, args=nil, min=nil)
92
+ case args
93
+ when NilClass
94
+ raise ArgumentError unless min.nil? or min.zero?
95
+ when Array
96
+ args = args.flatten
97
+ raise ArgumentError if (min || 1) > args.length
98
+ cmd = "#{cmd} #{_q(*args)}" if args.any?
99
+ else
100
+ raise ArgumentError if min and min < 1
101
+ cmd = "#{cmd} #{_q args}"
102
+ end
103
+ end
104
+
105
+ def _q(*list)
106
+ list.map { |l| "'#{l.gsub("'", "\\'")}'" }.join ' '
107
+ end
108
+
109
+ def _via
110
+ @config.fetch(:run_method, nil)
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+
117
+ Capistrano.plugin :remote_files, Capsaicin::Files::Remote
@@ -0,0 +1,48 @@
1
+ module Capsaicin
2
+
3
+ module Invocation
4
+
5
+ # Capistrano's system() override is only available from the base deployment strategy.
6
+ # Also, we could do with a few more windows checks.
7
+ def local_run(*args, &block)
8
+ args.pop if Hash===args.last
9
+ cmd = args.join(' ')
10
+ if RUBY_PLATFORM =~ /win32|mingw|mswin/
11
+ cmd.gsub!('/','\\') # Replace / with \\
12
+ cmd.gsub!(/^cd /,'cd /D ') # Replace cd with cd /D
13
+ cmd.gsub!(/&& cd /,'&& cd /D ') # Replace cd with cd /D
14
+ logger.trace "executing locally: #{cmd}"
15
+ Kernel.system cmd
16
+ else
17
+ logger.trace "executing locally: #{cmd}"
18
+ Kernel.system cmd
19
+ end
20
+ end
21
+
22
+ # Always uses :runner to sudo as someone.
23
+ # Equivalent to: sudo "command", :as => fetch(:runner,nil)
24
+ def sudo_as(*args, &block)
25
+ options = Hash===args.last ? args.pop.dup : {}
26
+ options[:as] = fetch(:runner, nil)
27
+ sudo *args.push(options), &block
28
+ end
29
+
30
+ # Extremely helpful if you only have permission to: sudo su SOMEUSER -c "command"
31
+ def sudo_su(*args, &block)
32
+ options = Hash===args.last ? args.pop.dup : {}
33
+ args[0] = "su #{fetch(:runner, nil)} -c '#{args[0]}'"
34
+ sudo *args.push(options), &block
35
+ end
36
+
37
+ # Extremely helpful if you only have permission to: sudo su - SOMEUSER
38
+ def sudo_su_to(*args, &block)
39
+ options = Hash===args.last ? args.pop.dup : {}
40
+ options[:shell] = false
41
+ cmd = args[0].gsub(/[$\\`"]/) { |m| "\\#{m}" }
42
+ args[0] = "echo \"#{cmd}\" | #{sudo} su - #{fetch(:runner, nil)}"
43
+ run *args.push(options), &block
44
+ end
45
+ end
46
+
47
+ Capistrano::Configuration.send :include, Invocation
48
+ end
@@ -0,0 +1,21 @@
1
+ module Capsaicin
2
+
3
+ module Service
4
+
5
+ SVC_ACTION_CAPTIONS = Hash.new do |h,k|
6
+ h[k] = "#{k.to_s.capitalize} Service"
7
+ end.update :status => 'Check Status',
8
+ :check => 'Check Config',
9
+ :summary => 'Status Summary'
10
+
11
+ %w(lsb crm windows command).each do |k|
12
+ require File.join(File.dirname(__FILE__), 'service', k+'.rb')
13
+ end
14
+
15
+ include LSB, CRM, Windows, Command
16
+
17
+ end
18
+
19
+ end
20
+
21
+ Capistrano.plugin :service, Capsaicin::Service
@@ -0,0 +1,44 @@
1
+ module Capsaicin
2
+ module Service
3
+ module Command
4
+
5
+ # Check for the existance of a generic Windows NT service.
6
+ def command?(start, stop)
7
+ files.executable? start and files.executable? stop
8
+ end
9
+
10
+ # Defines a recipe to control a generic Windows NT service.
11
+ #
12
+ def command(id,start,stop,*args)
13
+ options = Hash===args.last ? args.pop : {}
14
+
15
+ svc_name = id.to_s
16
+ svc_desc = next_description(:reset) || (svc_name.capitalize unless options.delete(:hide))
17
+ extras = args.pop if Array === args.last
18
+ via = options.delete(:via)
19
+
20
+ namespace id do
21
+
22
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:start]}" if svc_desc
23
+ task :start, options do
24
+ send(via || fetch(:run_method, :local_run), start)
25
+ end
26
+
27
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:stop]}" if svc_desc
28
+ task :stop, options do
29
+ send(via || fetch(:run_method, :local_run), stop)
30
+ end
31
+
32
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:restart]}" if svc_desc
33
+ task :restart, options do
34
+ stop
35
+ start
36
+ end
37
+
38
+ instance_eval { yield } if block_given?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,84 @@
1
+ module Capsaicin
2
+ module Service
3
+ module CRM
4
+
5
+ DEFAULT_ACTIONS = [ [ :status, '-W' ],
6
+ [ :summary, "-x | awk '/^raw xml:/ { exit }; { print }'" ],
7
+ [ :start, "--meta -d 'target_role'" ],
8
+ [ :stop, "--meta -p 'target_role' -v 'stopped'" ] ]
9
+
10
+ OCF_DEFAULT_ACTIONS = [ [ :validate, '-c -C' ],
11
+ [ :monitor, '-c -m' ] ]
12
+
13
+ # Defines a recipe to control a cluster-managed service, using heartbeat or pacemaker.
14
+ #
15
+ def crm(id,*args)
16
+ options = Hash===args.last ? args.pop : {}
17
+
18
+ svc_name = id.to_s
19
+ svc_desc = next_description(:reset) || (svc_name.capitalize unless options.delete(:hide))
20
+ svc_actions = DEFAULT_ACTIONS
21
+ svc_actions += args.pop if Array === args.last
22
+
23
+ namespace id do
24
+
25
+ case args.first
26
+ when String; id = args.shift.intern
27
+ when Symbol; id = args.shift
28
+ end
29
+ svc_cmd = "/usr/sbin/crm_resource -r #{id.to_s.split(':').last}"
30
+
31
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:status]}" if svc_desc
32
+ task :default, options do
33
+ sudo "#{svc_cmd} -W"
34
+ end
35
+
36
+ svc_actions.each do |svc_action,svc_args|
37
+ svc_action = svc_action.intern unless Symbol===svc_action
38
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[svc_action]}" if svc_desc
39
+ task svc_action, options do
40
+ sudo "#{svc_cmd} #{svc_args}"
41
+ end
42
+ end
43
+
44
+ instance_eval { yield } if block_given?
45
+ end
46
+ end
47
+
48
+ # Defines a recipe providing additional controls for a cluster-managed service,
49
+ # using the ocf_resource tool which interoperates with heartbeat or pacemaker.
50
+ #
51
+ # For more information about ocf_resource and other add-ons for heartbeat/pacemaker,
52
+ # see http://github.com/joekhoobyar/ha-tools
53
+ #
54
+ def crm_ocf(id,*args)
55
+ options = Hash===args.last ? args.pop : {}
56
+
57
+ svc_name = id.to_s
58
+ svc_desc = next_description(:reset) || (svc_name.capitalize unless options.delete(:hide))
59
+ svc_actions = DEFAULT_ACTIONS
60
+ svc_actions += args.pop if Array === args.last
61
+
62
+ namespace id do
63
+
64
+ case args.first
65
+ when String; id = args.shift.intern
66
+ when Symbol; id = args.shift
67
+ end
68
+ svc_cmd = "ocf_resource -g #{id.to_s.split(':').last}"
69
+
70
+ svc_actions.each do |svc_action,svc_args|
71
+ svc_action = svc_action.intern if String === svc_action
72
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[svc_action]}" if svc_desc
73
+ task svc_action, options do
74
+ sudo "#{svc_cmd} #{svc_args}"
75
+ end
76
+ end
77
+
78
+ instance_eval { yield } if block_given?
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,48 @@
1
+ module Capsaicin
2
+ module Service
3
+ module LSB
4
+
5
+ DEFAULT_ACTIONS = %w(status start stop restart)
6
+
7
+ # Check for the existance of a generic LSB initscript.
8
+ def lsb?(id, basedir="/etc/init.d")
9
+ files.exists? "#{basedir}/#{id.to_s.split(':').last}"
10
+ end
11
+
12
+ # Defines a recipe to control a generic LSB service.
13
+ #
14
+ def lsb(id,*args)
15
+ options = Hash===args.last ? args.pop : {}
16
+
17
+ basedir = options.delete(:basedir)
18
+ svc_name = id.to_s
19
+ svc_desc = next_description(:reset) || (svc_name.capitalize unless options.delete(:hide))
20
+ svc_actions = DEFAULT_ACTIONS
21
+ svc_actions += args.pop if Array === args.last
22
+
23
+ namespace id do
24
+ case args.first
25
+ when String; id = args.shift.intern
26
+ when Symbol; id = args.shift
27
+ end
28
+ svc_cmd = "#{basedir || '/etc/init.d'}/#{id.to_s.split(':').last}"
29
+
30
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:status]}" if svc_desc
31
+ task :default, options do
32
+ send(basedir ? run_method : :sudo, "#{svc_cmd} status")
33
+ end
34
+
35
+ svc_actions.each do |svc_action|
36
+ svc_action = svc_action.intern if String === svc_action
37
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[svc_action]}" if svc_desc
38
+ task svc_action, options do
39
+ send(basedir ? run_method : :sudo, "#{svc_cmd} #{svc_action}")
40
+ end
41
+ end
42
+
43
+ instance_eval { yield } if block_given?
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,62 @@
1
+ module Capsaicin
2
+ module Service
3
+ module Windows
4
+
5
+ DEFAULT_ACTIONS = [:start, :stop]
6
+
7
+ # Check for the existance of a generic Windows NT service.
8
+ def windows?(id, verbose=false)
9
+ logger.trace "executing locally: sc query \"#{id}\"" if logger and verbose
10
+ $1.to_i if `sc query "#{id}"` =~ /STATE +: +([0-9])+ +([^ ]+)/
11
+ ensure
12
+ logger.trace " service status => #{$2} (#{$1})" if logger and verbose
13
+ end
14
+
15
+ # Defines a recipe to control a generic Windows NT service.
16
+ #
17
+ def windows(id,*args)
18
+ options = Hash===args.last ? args.pop : {}
19
+
20
+ svc_name = id.to_s
21
+ svc_desc = next_description(:reset) || (svc_name.capitalize unless options.delete(:hide))
22
+ svc_actions = DEFAULT_ACTIONS
23
+ svc_actions += args.pop if Array === args.last
24
+
25
+ namespace id do
26
+ case args.first
27
+ when String; id = args.shift.intern
28
+ when Symbol; id = args.shift
29
+ end
30
+
31
+ [:default, :status].each do |k|
32
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:status]}" if svc_desc
33
+ task k, options do
34
+ service.windows? id, true or
35
+ abort "Failed to get service status for #{svc_name}"
36
+ end
37
+ end
38
+
39
+ DEFAULT_ACTIONS.each do |svc_action|
40
+ svc_action = svc_action.intern if String === svc_action
41
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[svc_action]}" if svc_desc
42
+ task svc_action, options do
43
+ local_run "net #{svc_action} \"#{id}\""
44
+ end
45
+ end
46
+
47
+ desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:restart]}" if svc_desc
48
+ task :restart, options do
49
+ case service.windows?(id)
50
+ when 4, 2; stop
51
+ when NilClass; abort "Failed to get service status for #{svc_name}"
52
+ end
53
+ start
54
+ end
55
+
56
+ instance_eval { yield } if block_given?
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,11 @@
1
+ module Capsaicin
2
+ module LocalSys
3
+
4
+ def windows?
5
+ @windows ||= !! (RUBY_PLATFORM =~ /cygwin|mingw|win32|mswin|windows/)
6
+ end
7
+
8
+ end
9
+
10
+ Capistrano.plugin :local_sys, LocalSys
11
+ end
@@ -0,0 +1,20 @@
1
+ module Capsaicin
2
+ module UI
3
+ module AskPass
4
+ def password_prompt(prompt='Password: ')
5
+ if cap_askpass = ENV['CAP_ASKPASS']
6
+ `#{cap_askpass} "#{prompt}"`.strip
7
+ else
8
+ password_prompt_console
9
+ end
10
+ end
11
+ end
12
+
13
+ (class << Capistrano::CLI; self; end).class_eval do
14
+ alias :password_prompt_console :password_prompt
15
+ include AskPass
16
+ alias :password_prompt_askpass :password_prompt
17
+ end
18
+ end
19
+ end
20
+
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capsaicin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Joe Khoobyar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-07 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: capistrano
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "2.0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: archive-tar-minitar
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0.5"
34
+ version:
35
+ description: Spicy capistrano extensions for various needs
36
+ email: joe@ankhcraft.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - LICENSE
46
+ - README.rdoc
47
+ - Rakefile
48
+ - VERSION.yml
49
+ - lib/capsaicin.rb
50
+ - lib/capsaicin/bundle.rb
51
+ - lib/capsaicin/files.rb
52
+ - lib/capsaicin/files/local.rb
53
+ - lib/capsaicin/files/remote.rb
54
+ - lib/capsaicin/invocation.rb
55
+ - lib/capsaicin/service.rb
56
+ - lib/capsaicin/service/command.rb
57
+ - lib/capsaicin/service/crm.rb
58
+ - lib/capsaicin/service/lsb.rb
59
+ - lib/capsaicin/service/windows.rb
60
+ - lib/capsaicin/sys.rb
61
+ - lib/capsaicin/ui.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/joekhoobyar/capsaicin
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.2
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Joe Khoobyar's spicy capistrano extensions
90
+ test_files: []
91
+