capsaicin 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -3
- data/VERSION.yml +1 -1
- data/capsaicin.gemspec +7 -5
- data/lib/capistrano/recipes/deploy/strategy/local_copy.rb +0 -3
- data/lib/capsaicin/files/remote.rb +29 -33
- data/lib/capsaicin/invocation.rb +56 -18
- data/lib/capsaicin/service/command.rb +5 -5
- data/test/capsaicin/invocation_test.rb +112 -0
- data/test/helper.rb +22 -0
- metadata +7 -5
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ begin
|
|
15
15
|
s.email = "joe@ankhcraft.com"
|
16
16
|
s.rubyforge_project = "capsaicin"
|
17
17
|
|
18
|
-
s.add_dependency 'capistrano', ['>= 2.
|
18
|
+
s.add_dependency 'capistrano', ['>= 2.5']
|
19
19
|
s.add_dependency 'archive-tar-minitar', ['>= 0.5']
|
20
20
|
end
|
21
21
|
rescue LoadError
|
@@ -26,7 +26,6 @@ require 'rake/testtask'
|
|
26
26
|
Rake::TestTask.new(:test) do |test|
|
27
27
|
test.libs << 'test'
|
28
28
|
test.pattern = 'test/**/*_test.rb'
|
29
|
-
test.verbose = true
|
30
29
|
end
|
31
30
|
|
32
31
|
begin
|
@@ -34,7 +33,6 @@ begin
|
|
34
33
|
Rcov::RcovTask.new do |test|
|
35
34
|
test.libs << 'test'
|
36
35
|
test.pattern = 'test/**/*_test.rb'
|
37
|
-
test.verbose = true
|
38
36
|
end
|
39
37
|
rescue LoadError
|
40
38
|
task :rcov do
|
data/VERSION.yml
CHANGED
data/capsaicin.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{capsaicin}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.10"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Joe Khoobyar"]
|
12
|
-
s.date = %q{2010-06-
|
12
|
+
s.date = %q{2010-06-16}
|
13
13
|
s.description = %q{Spicy capistrano extensions for various needs}
|
14
14
|
s.email = %q{joe@ankhcraft.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
"lib/capsaicin/sys.rb",
|
40
40
|
"lib/capsaicin/ui.rb",
|
41
41
|
"test/capsaicin/files/local_test.rb",
|
42
|
+
"test/capsaicin/invocation_test.rb",
|
42
43
|
"test/helper.rb"
|
43
44
|
]
|
44
45
|
s.homepage = %q{http://github.com/joekhoobyar/capsaicin}
|
@@ -49,6 +50,7 @@ Gem::Specification.new do |s|
|
|
49
50
|
s.summary = %q{Joe Khoobyar's spicy capistrano extensions}
|
50
51
|
s.test_files = [
|
51
52
|
"test/capsaicin/files/local_test.rb",
|
53
|
+
"test/capsaicin/invocation_test.rb",
|
52
54
|
"test/helper.rb"
|
53
55
|
]
|
54
56
|
|
@@ -57,14 +59,14 @@ Gem::Specification.new do |s|
|
|
57
59
|
s.specification_version = 3
|
58
60
|
|
59
61
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
-
s.add_runtime_dependency(%q<capistrano>, [">= 2.
|
62
|
+
s.add_runtime_dependency(%q<capistrano>, [">= 2.5"])
|
61
63
|
s.add_runtime_dependency(%q<archive-tar-minitar>, [">= 0.5"])
|
62
64
|
else
|
63
|
-
s.add_dependency(%q<capistrano>, [">= 2.
|
65
|
+
s.add_dependency(%q<capistrano>, [">= 2.5"])
|
64
66
|
s.add_dependency(%q<archive-tar-minitar>, [">= 0.5"])
|
65
67
|
end
|
66
68
|
else
|
67
|
-
s.add_dependency(%q<capistrano>, [">= 2.
|
69
|
+
s.add_dependency(%q<capistrano>, [">= 2.5"])
|
68
70
|
s.add_dependency(%q<archive-tar-minitar>, [">= 0.5"])
|
69
71
|
end
|
70
72
|
end
|
@@ -17,6 +17,14 @@ module Capsaicin
|
|
17
17
|
end
|
18
18
|
end
|
19
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
|
+
|
20
28
|
def chmod(mode, list, options={})
|
21
29
|
_r 'chmod', Array(list).unshift(mode.to_s(8))
|
22
30
|
end
|
@@ -36,14 +44,6 @@ module Capsaicin
|
|
36
44
|
_r 'install', src.push(dest)
|
37
45
|
end
|
38
46
|
|
39
|
-
FILE_TESTS.each do |m,t|
|
40
|
-
class_eval <<-EODEF
|
41
|
-
def #{m}(a, options={})
|
42
|
-
_t "test #{t}", a
|
43
|
-
end
|
44
|
-
EODEF
|
45
|
-
end
|
46
|
-
|
47
47
|
def tail_f(file, n=10)
|
48
48
|
cmd = "tail -n #{n} -f #{_q file}"
|
49
49
|
case v = _via
|
@@ -56,6 +56,15 @@ module Capsaicin
|
|
56
56
|
logger.trace "interrupted (Ctrl-C)" if logger
|
57
57
|
end
|
58
58
|
|
59
|
+
def put(data, path, options={})
|
60
|
+
case _via
|
61
|
+
when :system, :local_run
|
62
|
+
FileUtils::Verbose.copy_stream StringIO.new(from), to
|
63
|
+
else
|
64
|
+
upload StringIO.new(data), path, options
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
59
68
|
def upload(from, to, options={}, &block)
|
60
69
|
case _via
|
61
70
|
when :system, :local_run
|
@@ -70,11 +79,20 @@ module Capsaicin
|
|
70
79
|
to2, to = to, "/tmp/#{tof}-#{Time.now.utc.to_i}"
|
71
80
|
end
|
72
81
|
end
|
82
|
+
options = options.dup
|
83
|
+
mode = options.delete(:mode)
|
73
84
|
@config.upload(from, to, options, &block)
|
74
85
|
if to2
|
75
|
-
|
76
|
-
|
77
|
-
|
86
|
+
begin
|
87
|
+
run "chmod 0644 #{to}", :via=>:run
|
88
|
+
cp to, to2
|
89
|
+
if mode
|
90
|
+
mode = mode.is_a?(Numeric) ? '0'+mode.to_s(8) : mode.to_s
|
91
|
+
run "chmod #{mode} #{to2}"
|
92
|
+
end
|
93
|
+
ensure
|
94
|
+
run "rm -f #{to}", :via=>:run
|
95
|
+
end
|
78
96
|
end
|
79
97
|
end
|
80
98
|
end
|
@@ -88,28 +106,6 @@ module Capsaicin
|
|
88
106
|
end
|
89
107
|
end
|
90
108
|
|
91
|
-
def put(data, path, options={})
|
92
|
-
case _via
|
93
|
-
when :system, :local_run
|
94
|
-
FileUtils::Verbose.copy_stream StringIO.new(from), to
|
95
|
-
else
|
96
|
-
if _via.to_s[0,4] == 'sudo'
|
97
|
-
if path[-1]==?/ || path[-1]==?\\ || directory?(path)
|
98
|
-
abort "Target path is a directory!"
|
99
|
-
else
|
100
|
-
pathf = File.basename path
|
101
|
-
path2, path = path, "/tmp/#{pathf}-#{Time.now.utc.to_i}"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
@config.put(data, path, options)
|
105
|
-
if path2
|
106
|
-
run "chmod 0644 #{path}"
|
107
|
-
cp path, path2
|
108
|
-
run "rm -f #{path}"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
109
|
def cd(dir, options={})
|
114
110
|
if block_given?
|
115
111
|
dir, dir2 = pwd, dir
|
data/lib/capsaicin/invocation.rb
CHANGED
@@ -1,28 +1,62 @@
|
|
1
1
|
module Capsaicin
|
2
2
|
|
3
3
|
module Invocation
|
4
|
-
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
[:run, :sudo].each do |k|
|
7
|
+
base.send :alias_method, :"#{k}_without_override", k
|
8
|
+
base.send :alias_method, k, :"#{k}_with_override"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Allows overriding the default behavior of +run+ by setting
|
13
|
+
# :override_run_method and (optionally) :override_runner
|
14
|
+
def run_with_override(cmd, options={}, &block)
|
15
|
+
via = options[:via] || fetch(:override_run_method, :run)
|
16
|
+
if cmd.include?(sudo) or :run == via
|
17
|
+
run_without_override cmd, options, &block
|
18
|
+
else
|
19
|
+
options = options.dup
|
20
|
+
as = fetch(:override_runner, nil) and options[:as] ||= as
|
21
|
+
send via, cmd, options, &block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Allows overriding the default behavior of +sudo+ by setting
|
26
|
+
# :override_sudo_method and (optionally) :override_sudo_runner
|
27
|
+
def sudo_with_override(*args, &block)
|
28
|
+
options = Hash===args.last ? args.pop.dup : {}
|
29
|
+
as = fetch(:override_sudo_runner, nil) and options[:as] ||= as
|
30
|
+
args << options unless options.empty?
|
31
|
+
if :sudo == (via = fetch(:override_sudo_method, :sudo))
|
32
|
+
options[:via] = :run
|
33
|
+
sudo_without_override *args, &block
|
34
|
+
else
|
35
|
+
send via, *args, &block
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
5
39
|
# Automatically uses the :run_method variable to run things.
|
6
40
|
# Equivalent to +invoke_command *args, :via=>fetch(:run_method, :run)+
|
7
41
|
def vrun(*args, &block)
|
8
|
-
options = Hash===args.last ? args.pop.dup :
|
9
|
-
options[:via]
|
42
|
+
options = Hash===args.last ? args.pop.dup : {}
|
43
|
+
options[:via] ||= fetch(:run_method, :run)
|
10
44
|
invoke_command *args.push(options), &block
|
11
45
|
end
|
12
46
|
|
13
47
|
# Automatically uses the :run_method variable to run things.
|
14
48
|
# Equivalent to +capture *args, :via=>fetch(:run_method, :run)+
|
15
49
|
def vcapture(*args, &block)
|
16
|
-
options = Hash===args.last ? args.pop.dup :
|
17
|
-
options[:via]
|
50
|
+
options = Hash===args.last ? args.pop.dup : {}
|
51
|
+
options[:via] ||= fetch(:run_method, :run)
|
18
52
|
capture *args.push(options), &block
|
19
53
|
end
|
20
54
|
|
21
55
|
# Automatically uses the :run_method variable to run things.
|
22
56
|
# Equivalent to +stream *args, :via=>fetch(:run_method, :run)+
|
23
57
|
def vstream(*args, &block)
|
24
|
-
options = Hash===args.last ? args.pop.dup :
|
25
|
-
options[:via]
|
58
|
+
options = Hash===args.last ? args.pop.dup : {}
|
59
|
+
options[:via] ||= fetch(:run_method, :run)
|
26
60
|
stream *args.push(options), &block
|
27
61
|
end
|
28
62
|
|
@@ -46,25 +80,29 @@ module Capsaicin
|
|
46
80
|
# Always uses :runner to sudo as someone.
|
47
81
|
# Equivalent to: sudo "command", :as => fetch(:runner,nil)
|
48
82
|
def sudo_as(*args, &block)
|
49
|
-
options = Hash===args.last ? args.pop.dup :
|
50
|
-
options[:as]
|
51
|
-
|
83
|
+
options = Hash===args.last ? args.pop.dup : {}
|
84
|
+
options[:as] ||= fetch(:runner, nil)
|
85
|
+
sudo_without_override *args.push(options), &block
|
52
86
|
end
|
53
87
|
|
54
|
-
# Extremely helpful if you only have permission to: sudo su SOMEUSER -c
|
88
|
+
# Extremely helpful if you only have permission to: sudo su SOMEUSER -c 'command'
|
55
89
|
def sudo_su(*args, &block)
|
56
|
-
options = Hash===args.last ? args.pop.dup :
|
57
|
-
|
58
|
-
|
90
|
+
options = Hash===args.last ? args.pop.dup : {}
|
91
|
+
options[:as] ||= fetch(:runner, nil)
|
92
|
+
return sudo_as(options, &block) if args.empty? # compatibility with capistrano's +sudo+
|
93
|
+
args[0] = "su #{options.delete(:as)} -c '#{args[0].gsub("'","'\"'\"'")}'"
|
94
|
+
sudo_without_override *args.push(options), &block
|
59
95
|
end
|
60
96
|
|
61
97
|
# Extremely helpful if you only have permission to: sudo su - SOMEUSER
|
62
98
|
def sudo_su_to(*args, &block)
|
63
|
-
options = Hash===args.last ? args.pop.dup :
|
99
|
+
options = Hash===args.last ? args.pop.dup : {}
|
100
|
+
options[:as] ||= fetch(:runner, nil)
|
101
|
+
return sudo_as(options, &block) if args.empty? # compatibility with capistrano's +sudo+
|
64
102
|
options[:shell] = false
|
65
|
-
cmd
|
66
|
-
args[0] = "echo \"#{cmd}\" | #{
|
67
|
-
|
103
|
+
cmd = args[0].gsub(/[$\\`"]/) { |m| "\\#{m}" }
|
104
|
+
args[0] = "echo \"#{cmd}\" | #{sudo_without_override} su - #{options.delete(:as)}"
|
105
|
+
run_without_override *args.push(options), &block
|
68
106
|
end
|
69
107
|
end
|
70
108
|
end
|
@@ -2,12 +2,12 @@ module Capsaicin
|
|
2
2
|
module Service
|
3
3
|
module Command
|
4
4
|
|
5
|
-
# Check for the existance of a
|
5
|
+
# Check for the existance of a command-based service.
|
6
6
|
def command?(start, stop)
|
7
7
|
files.executable? start and files.executable? stop
|
8
8
|
end
|
9
9
|
|
10
|
-
# Defines a recipe to control a
|
10
|
+
# Defines a recipe to control a command-based service.
|
11
11
|
#
|
12
12
|
def command(id,start,stop,*args)
|
13
13
|
options = Hash===args.last ? args.pop : {}
|
@@ -21,12 +21,12 @@ module Capsaicin
|
|
21
21
|
|
22
22
|
desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:start]}" if svc_desc
|
23
23
|
task :start, options do
|
24
|
-
send(via || fetch(:run_method, :
|
24
|
+
send(via || fetch(:run_method, :run), start)
|
25
25
|
end
|
26
26
|
|
27
27
|
desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[:stop]}" if svc_desc
|
28
28
|
task :stop, options do
|
29
|
-
send(via || fetch(:run_method, :
|
29
|
+
send(via || fetch(:run_method, :run), stop)
|
30
30
|
end
|
31
31
|
|
32
32
|
unless extras.key? :restart
|
@@ -40,7 +40,7 @@ module Capsaicin
|
|
40
40
|
extras.each do |k,cmd|
|
41
41
|
desc "#{svc_desc}: #{SVC_ACTION_CAPTIONS[k]}" if svc_desc
|
42
42
|
task k, options do
|
43
|
-
send(via || fetch(:run_method, :
|
43
|
+
send(via || fetch(:run_method, :run), cmd)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'capsaicin/invocation'
|
4
|
+
|
5
|
+
class Capsaicin::InvocationTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@ext = CapistranoMock.new
|
9
|
+
class << @ext
|
10
|
+
include Capsaicin::Invocation
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_vrun
|
18
|
+
check_run_methods :vrun, :invoke_command
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_vcapture
|
22
|
+
check_run_methods :vcapture, :capture
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_vstream
|
26
|
+
check_run_methods :vstream, :stream
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_sudo_as
|
30
|
+
check_as_methods :sudo_as, :sudo
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_sudo_su
|
34
|
+
check_as_methods(:sudo_su, :sudo) {|c,as| ["su #{as} -c '#{c}'", {}] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_sudo_su_escapes_single_quotes
|
38
|
+
check_as_methods(:sudo_su, :sudo,"echo 'abc'") do |c,as|
|
39
|
+
["su #{as} -c 'echo '\"'\"'abc'\"'\"''", {}]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_sudo_su_to
|
44
|
+
check_as_methods(:sudo_su_to, :run) do |c,as|
|
45
|
+
["echo \"uptime\" | sudo su - #{as}", {:shell=>false}]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_run_without_override
|
50
|
+
@ext.run 'uptime'
|
51
|
+
assert_equal [%w(uptime) << {}], @ext.invocations[:run].last
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_run_with_override
|
55
|
+
@ext.set :override_run_method, :sudo
|
56
|
+
@ext.set :override_runnner, :admin
|
57
|
+
@ext.run 'uptime'
|
58
|
+
assert_equal [%w(uptime)], @ext.invocations[:sudo].last
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_sudo_without_override
|
62
|
+
@ext.sudo 'uptime'
|
63
|
+
assert_equal [%w(uptime)], @ext.invocations[:sudo].last
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_sudo_with_override
|
67
|
+
@ext.set :override_sudo_method, :sudo_as
|
68
|
+
@ext.set :override_sudo_runner, :admin
|
69
|
+
@ext.sudo 'uptime'
|
70
|
+
assert_equal [%w(uptime) << {:as=>:admin}], @ext.invocations[:sudo].last
|
71
|
+
@ext.set :override_sudo_method, :sudo_su_to
|
72
|
+
@ext.sudo 'uptime'
|
73
|
+
assert_equal [["echo \"uptime\" | sudo su - admin", {:shell=>false}]], @ext.invocations[:run].last
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def check_run_methods(method,key)
|
79
|
+
[:run, :sudo].each do |via|
|
80
|
+
@ext.send method, 'uptime'
|
81
|
+
assert_equal [%w(uptime) << {:via=>via}], @ext.invocations[key].last
|
82
|
+
@ext.set :run_method, :sudo
|
83
|
+
end
|
84
|
+
[:sudo, :run].each do |via|
|
85
|
+
@ext.send method, 'uptime', &block=Proc.new{}
|
86
|
+
assert_equal [%w(uptime) << {:via=>via}, block], @ext.invocations[key].last
|
87
|
+
@ext.unset :run_method
|
88
|
+
end
|
89
|
+
@ext.send method, 'uptime', :via=>:sudo
|
90
|
+
assert_equal [%w(uptime) << {:via=>:sudo}], @ext.invocations[key].last
|
91
|
+
end
|
92
|
+
|
93
|
+
def check_as_methods(method,key,cmd='uptime',&p)
|
94
|
+
p ||= lambda{|c,as| [c, {:as=>as}] }
|
95
|
+
[nil, :admin].each do |as|
|
96
|
+
@ext.send method,cmd
|
97
|
+
assert_equal [p[cmd,as]], @ext.invocations[key].last
|
98
|
+
@ext.set :runner, :admin
|
99
|
+
end
|
100
|
+
@ext.send method, cmd, :as=>:busybody
|
101
|
+
assert_equal [p[cmd,:busybody]], @ext.invocations[key].last
|
102
|
+
[:admin, nil].each do |as|
|
103
|
+
@ext.send method, cmd, &block=Proc.new{}
|
104
|
+
assert_equal [p[cmd,as], block], @ext.invocations[key].last
|
105
|
+
@ext.unset :runner
|
106
|
+
end
|
107
|
+
@ext.send method, cmd, :as=>:busybody
|
108
|
+
assert_equal [p[cmd,:busybody]], @ext.invocations[key].last
|
109
|
+
@ext.send method, :as=>:busybody
|
110
|
+
assert_equal [[{:as=>:busybody}]], @ext.invocations[:sudo].last
|
111
|
+
end
|
112
|
+
end
|
data/test/helper.rb
CHANGED
@@ -2,9 +2,14 @@ require 'stringio'
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'rubygems'
|
4
4
|
require 'capistrano/logger'
|
5
|
+
require 'capistrano/configuration/variables'
|
5
6
|
|
6
7
|
class CapistranoMock
|
7
8
|
|
9
|
+
include Capistrano::Configuration::Variables
|
10
|
+
|
11
|
+
attr_reader :invocations
|
12
|
+
|
8
13
|
def logbuf
|
9
14
|
@logbuf ||= StringIO.new
|
10
15
|
end
|
@@ -17,4 +22,21 @@ class CapistranoMock
|
|
17
22
|
@logger
|
18
23
|
end
|
19
24
|
|
25
|
+
%w(invoke_command capture stream run).each do |k|
|
26
|
+
class_eval %Q{
|
27
|
+
def #{k}(*args, &block)
|
28
|
+
args = [args]
|
29
|
+
args << block if block
|
30
|
+
((@invocations ||= {})[:#{k}] ||= []) << args
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def sudo(*args, &block)
|
36
|
+
return 'sudo' if args.empty?
|
37
|
+
args = [args]
|
38
|
+
args << block if block
|
39
|
+
((@invocations ||= {})[:sudo] ||= []) << args
|
40
|
+
end
|
41
|
+
|
20
42
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 10
|
9
|
+
version: 0.1.10
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joe Khoobyar
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-16 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,8 +26,8 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
segments:
|
28
28
|
- 2
|
29
|
-
-
|
30
|
-
version: "2.
|
29
|
+
- 5
|
30
|
+
version: "2.5"
|
31
31
|
type: :runtime
|
32
32
|
version_requirements: *id001
|
33
33
|
- !ruby/object:Gem::Dependency
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/capsaicin/sys.rb
|
76
76
|
- lib/capsaicin/ui.rb
|
77
77
|
- test/capsaicin/files/local_test.rb
|
78
|
+
- test/capsaicin/invocation_test.rb
|
78
79
|
- test/helper.rb
|
79
80
|
has_rdoc: true
|
80
81
|
homepage: http://github.com/joekhoobyar/capsaicin
|
@@ -108,4 +109,5 @@ specification_version: 3
|
|
108
109
|
summary: Joe Khoobyar's spicy capistrano extensions
|
109
110
|
test_files:
|
110
111
|
- test/capsaicin/files/local_test.rb
|
112
|
+
- test/capsaicin/invocation_test.rb
|
111
113
|
- test/helper.rb
|