rutty 2.3.2 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -3
- data/Gemfile.lock +22 -11
- data/README.md +62 -5
- data/Rakefile +33 -27
- data/VERSION +1 -1
- data/bin/rutty +8 -8
- data/lib/rutty/actions.rb +171 -98
- data/lib/rutty/helpers.rb +33 -3
- data/lib/rutty/node.rb +13 -1
- data/lib/rutty/thread_pool/pool.rb +80 -0
- data/lib/rutty/thread_pool/worker.rb +103 -0
- data/lib/rutty/version.rb +2 -2
- data/rutty.gemspec +105 -54
- data/test/helper.rb +20 -4
- data/test/test_action_add_node.rb +2 -5
- data/test/test_action_dsh.rb +20 -19
- data/test/test_action_init.rb +4 -8
- data/test/test_action_list_nodes.rb +1 -4
- data/test/test_action_scp.rb +50 -0
- data/test/test_node.rb +13 -0
- data/test/test_nodes.rb +10 -1
- metadata +303 -50
- data/.gitignore +0 -24
data/lib/rutty/helpers.rb
CHANGED
@@ -2,7 +2,7 @@ require 'rutty/errors'
|
|
2
2
|
require 'rutty/version'
|
3
3
|
|
4
4
|
module Rutty
|
5
|
-
|
5
|
+
|
6
6
|
##
|
7
7
|
# Simple mixin module for miscellaneous methods that don't fit in elsewhere.
|
8
8
|
#
|
@@ -17,10 +17,10 @@ module Rutty
|
|
17
17
|
def check_installed!
|
18
18
|
unless File.exists? self.config_dir
|
19
19
|
raise Rutty::NotInstalledError.new %Q(Can't find conf directory at #{self.config_dir}.
|
20
|
-
|
20
|
+
Run `rutty init' first. (Or rutty --help for usage))
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
##
|
25
25
|
# Returns the version string contained in {Rutty::Version::STRING}. Used by the rutty bin.
|
26
26
|
#
|
@@ -29,5 +29,35 @@ module Rutty
|
|
29
29
|
def self.get_version
|
30
30
|
Rutty::Version::STRING
|
31
31
|
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Returns a string formatted to a more human-readable representation of a time difference in seconds.
|
35
|
+
#
|
36
|
+
# @since 2.4.0
|
37
|
+
#
|
38
|
+
# @param [Float] seconds_total The number of seconds to convert
|
39
|
+
# @return [String] The formatted string
|
40
|
+
def seconds_in_words seconds_total
|
41
|
+
hours = seconds_total / 3600
|
42
|
+
minutes = (seconds_total - (3600 * hours)) / 60
|
43
|
+
seconds = (seconds_total % (hours >= 1 ? (3600 * hours) : 60)) % 60
|
44
|
+
|
45
|
+
out = ''
|
46
|
+
|
47
|
+
unless hours < 1
|
48
|
+
out << hours.to_s
|
49
|
+
out << ((hours > 1) ? " hours " : " hour ")
|
50
|
+
end
|
51
|
+
|
52
|
+
unless minutes < 1
|
53
|
+
out << minutes.to_s
|
54
|
+
out << ((minutes > 1) ? " minutes " : " minute ")
|
55
|
+
end
|
56
|
+
|
57
|
+
out << seconds.to_s
|
58
|
+
out << ((seconds > 1) ? " seconds" : " second")
|
59
|
+
|
60
|
+
out.strip
|
61
|
+
end
|
32
62
|
end
|
33
63
|
end
|
data/lib/rutty/node.rb
CHANGED
@@ -9,6 +9,18 @@ module Rutty
|
|
9
9
|
# @author Josh Lindsey
|
10
10
|
# @since 2.0.0
|
11
11
|
class Node < Config
|
12
|
+
class << self
|
13
|
+
##
|
14
|
+
# Override the inherited {Rutty::Config.load_config} method, raising an exception
|
15
|
+
# to indicate improper usage.
|
16
|
+
#
|
17
|
+
# @since 2.3.3
|
18
|
+
# @raise [RuntimeError] On call, as this class has no use for this method
|
19
|
+
def load_config dir
|
20
|
+
raise "Unable to call load_config on Node objects."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
##
|
13
25
|
# Initialize a new {Rutty::Node} instance by merging the user-provided data with
|
14
26
|
# the configured defaults.
|
@@ -54,4 +66,4 @@ module Rutty
|
|
54
66
|
self.tags == other.tags
|
55
67
|
end
|
56
68
|
end
|
57
|
-
end
|
69
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'fastthread'
|
3
|
+
require 'rutty/thread_pool/worker'
|
4
|
+
|
5
|
+
module Rutty
|
6
|
+
|
7
|
+
##
|
8
|
+
# A thread pool implementation using the work queue pattern. Shamelessly stolen from a StackOverflow question.
|
9
|
+
#
|
10
|
+
# @see http://stackoverflow.com/questions/81788/deadlock-in-threadpool/82777#82777
|
11
|
+
# @since 2.4.0
|
12
|
+
class ThreadPool
|
13
|
+
## @return [Integer] The maximum number of concurrent {Worker} threads
|
14
|
+
attr_accessor :max_size
|
15
|
+
|
16
|
+
##
|
17
|
+
# Creates a new {ThreadPool} instance with a maximum number of {Worker} threads.
|
18
|
+
def initialize max_size = 10
|
19
|
+
Thread.abort_on_exception = true
|
20
|
+
|
21
|
+
@max_size = max_size
|
22
|
+
@queue = Queue.new
|
23
|
+
@workers = []
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# The current size of the <tt>@workers</tt> array.
|
28
|
+
#
|
29
|
+
# @return [Integer] The current number of {Worker} threads
|
30
|
+
def current_size
|
31
|
+
@workers.size
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Whether any {Worker} threads are currently executing, determined by
|
36
|
+
# comparing the sizes of the <tt>@workers</tt> array and the <tt>@queue</tt>.
|
37
|
+
#
|
38
|
+
# @return [Boolean] Any currently executing workers?
|
39
|
+
def busy?
|
40
|
+
@queue.size < current_size
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Loops over every {Worker} and calls {Worker#stop}, then clears the <tt>@workers</tt> array.
|
45
|
+
def shutdown
|
46
|
+
@workers.each { |w| w.stop }
|
47
|
+
@workers = []
|
48
|
+
end
|
49
|
+
|
50
|
+
alias :join :shutdown
|
51
|
+
|
52
|
+
##
|
53
|
+
# Gets a free worker and passes it the specified closure.
|
54
|
+
#
|
55
|
+
# @see #get_worker
|
56
|
+
# @param [Proc, Lambda, #call] block An instance of any class that responds to <tt>#call</tt>
|
57
|
+
def process block = nil, &blk
|
58
|
+
block = blk if block_given?
|
59
|
+
get_worker.set_block block
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
##
|
65
|
+
# Gets a free {Worker}. If the {#max_size} has been reached and the <tt>@queue</tt> isn't empty,
|
66
|
+
# pops an existing {Worker} from there. Otherwise spins up a new {Worker} and adds it to the <tt>@workers</tt>
|
67
|
+
# array.
|
68
|
+
#
|
69
|
+
# @return [Rutty::Worker] A {Worker} ready for a new job
|
70
|
+
def get_worker
|
71
|
+
if !@queue.empty? or current_size == @max_size
|
72
|
+
return @queue.pop
|
73
|
+
else
|
74
|
+
worker = Rutty::Worker.new @queue
|
75
|
+
@workers << worker
|
76
|
+
worker
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'fastthread'
|
3
|
+
|
4
|
+
module Rutty
|
5
|
+
|
6
|
+
##
|
7
|
+
# The {ThreadPool} Thread wrapper, representing a single thread of execution in the pool.
|
8
|
+
#
|
9
|
+
# @since 2.4.0
|
10
|
+
class Worker
|
11
|
+
|
12
|
+
##
|
13
|
+
# Initialize a new {Worker}. Sets up the initial state of this instance, then spins out its thread. The thread will
|
14
|
+
# wait until it's signaled (by being passed a new closure to execute, or being told to die, etc.), then resume execution
|
15
|
+
# of its task. The Thread is wrapped in a <tt>while @running</tt> loop, allowing for easy termination from {#shutdown}.
|
16
|
+
#
|
17
|
+
# @param [Queue] thread_queue The thread queue from the {ThreadPool} instance to add this worker to
|
18
|
+
# @return [Worker] The new, available Worker object.
|
19
|
+
def initialize thread_queue
|
20
|
+
@mutex = Mutex.new
|
21
|
+
@cv = ConditionVariable.new
|
22
|
+
@queue = thread_queue
|
23
|
+
@running = true
|
24
|
+
|
25
|
+
@thread = Thread.new do
|
26
|
+
@mutex.synchronize do
|
27
|
+
while @running
|
28
|
+
@cv.wait @mutex
|
29
|
+
block = get_block
|
30
|
+
|
31
|
+
if block
|
32
|
+
@mutex.unlock
|
33
|
+
block.call
|
34
|
+
@mutex.lock
|
35
|
+
reset_block
|
36
|
+
end
|
37
|
+
|
38
|
+
@queue << self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns the evaluation of <tt>@thread.inspect</tt>.
|
46
|
+
#
|
47
|
+
# @return [String] This thread's name
|
48
|
+
def name
|
49
|
+
@thread.inspect
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Returns the value of <tt>@block</tt>.
|
54
|
+
#
|
55
|
+
# @return [Proc, Lambda, #call] The <tt>@block</tt> object previously passed.
|
56
|
+
def get_block
|
57
|
+
@block
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Sets a new closure as the task for this worker. Signals the Thread to wakeup after assignment.
|
62
|
+
#
|
63
|
+
# @param (see Rutty::ThreadPool#process)
|
64
|
+
# @raise [RuntimeError] If the thread is currently busy when called.
|
65
|
+
def set_block block
|
66
|
+
@mutex.synchronize do
|
67
|
+
raise RuntimeError, "Thread already busy." if @block
|
68
|
+
@block = block
|
69
|
+
# Signal the thread in this class, that there's a job to be done
|
70
|
+
@cv.signal
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Sets the <tt>@block</tt> to <tt>nil</tt>. Called after the Thread has finished execution of a task to
|
76
|
+
# ready itself for the next one.
|
77
|
+
def reset_block
|
78
|
+
@block = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Whether or not this Thread is currently executing. Determined by whether <tt>@block</tt> is <tt>nil</tt>.
|
83
|
+
#
|
84
|
+
# @return [Boolean] Is this Thread executing?
|
85
|
+
def busy?
|
86
|
+
@mutex.synchronize { !@block.nil? }
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Sets <tt>@running</tt> to <tt>false</tt>, causing the Thread to finish after the current loop. Signals
|
91
|
+
# the Thread to wake and resume, then calls <tt>#join</tt>.
|
92
|
+
#
|
93
|
+
# @see #initialize
|
94
|
+
def stop
|
95
|
+
@mutex.synchronize do
|
96
|
+
@running = false
|
97
|
+
@cv.signal
|
98
|
+
end
|
99
|
+
|
100
|
+
@thread.join
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/rutty/version.rb
CHANGED
data/rutty.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rutty}
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Josh Lindsey"]
|
12
|
-
s.date = %q{2010-11-
|
12
|
+
s.date = %q{2010-11-24}
|
13
13
|
s.default_executable = %q{rutty}
|
14
14
|
s.description = %q{
|
15
15
|
RuTTY is a DSH (distributed / dancer's shell) written in Ruby. It's used to run commands
|
@@ -20,63 +20,66 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.executables = ["rutty"]
|
21
21
|
s.extra_rdoc_files = [
|
22
22
|
"LICENSE",
|
23
|
-
|
23
|
+
"README.md"
|
24
24
|
]
|
25
25
|
s.files = [
|
26
|
-
".
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
26
|
+
".yardopts",
|
27
|
+
"Gemfile",
|
28
|
+
"Gemfile.lock",
|
29
|
+
"LICENSE",
|
30
|
+
"README.md",
|
31
|
+
"Rakefile",
|
32
|
+
"VERSION",
|
33
|
+
"bin/rutty",
|
34
|
+
"lib/rutty.rb",
|
35
|
+
"lib/rutty/actions.rb",
|
36
|
+
"lib/rutty/config.rb",
|
37
|
+
"lib/rutty/consts.rb",
|
38
|
+
"lib/rutty/errors.rb",
|
39
|
+
"lib/rutty/helpers.rb",
|
40
|
+
"lib/rutty/node.rb",
|
41
|
+
"lib/rutty/nodes.rb",
|
42
|
+
"lib/rutty/proc_classes.rb",
|
43
|
+
"lib/rutty/thread_pool/pool.rb",
|
44
|
+
"lib/rutty/thread_pool/worker.rb",
|
45
|
+
"lib/rutty/treetop/syntax_nodes.rb",
|
46
|
+
"lib/rutty/treetop/tag_query.rb",
|
47
|
+
"lib/rutty/treetop/tag_query.treetop",
|
48
|
+
"lib/rutty/version.rb",
|
49
|
+
"rutty.gemspec",
|
50
|
+
"test/helper.rb",
|
51
|
+
"test/test_action_add_node.rb",
|
52
|
+
"test/test_action_dsh.rb",
|
53
|
+
"test/test_action_init.rb",
|
54
|
+
"test/test_action_list_nodes.rb",
|
55
|
+
"test/test_action_scp.rb",
|
56
|
+
"test/test_actions.rb",
|
57
|
+
"test/test_config.rb",
|
58
|
+
"test/test_consts.rb",
|
59
|
+
"test/test_helpers.rb",
|
60
|
+
"test/test_node.rb",
|
61
|
+
"test/test_nodes.rb",
|
62
|
+
"test/test_runner.rb"
|
61
63
|
]
|
62
64
|
s.homepage = %q{http://github.com/jlindsey/rutty}
|
63
|
-
s.
|
65
|
+
s.licenses = ["MIT"]
|
64
66
|
s.require_paths = ["lib"]
|
65
67
|
s.rubygems_version = %q{1.3.7}
|
66
68
|
s.summary = %q{A DSH implementation in Ruby}
|
67
69
|
s.test_files = [
|
68
70
|
"test/helper.rb",
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
71
|
+
"test/test_action_add_node.rb",
|
72
|
+
"test/test_action_dsh.rb",
|
73
|
+
"test/test_action_init.rb",
|
74
|
+
"test/test_action_list_nodes.rb",
|
75
|
+
"test/test_action_scp.rb",
|
76
|
+
"test/test_actions.rb",
|
77
|
+
"test/test_config.rb",
|
78
|
+
"test/test_consts.rb",
|
79
|
+
"test/test_helpers.rb",
|
80
|
+
"test/test_node.rb",
|
81
|
+
"test/test_nodes.rb",
|
82
|
+
"test/test_runner.rb"
|
80
83
|
]
|
81
84
|
|
82
85
|
if s.respond_to? :specification_version then
|
@@ -84,39 +87,87 @@ Gem::Specification.new do |s|
|
|
84
87
|
s.specification_version = 3
|
85
88
|
|
86
89
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
90
|
+
s.add_runtime_dependency(%q<commander>, ["~> 4.0.3"])
|
91
|
+
s.add_runtime_dependency(%q<terminal-table>, ["~> 1.4.2"])
|
92
|
+
s.add_runtime_dependency(%q<json>, ["~> 1.4.6"])
|
93
|
+
s.add_runtime_dependency(%q<net-ssh>, ["~> 2.0.23"])
|
94
|
+
s.add_runtime_dependency(%q<net-scp>, ["~> 1.0.4"])
|
95
|
+
s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
|
96
|
+
s.add_runtime_dependency(%q<treetop>, ["~> 1.4.8"])
|
97
|
+
s.add_runtime_dependency(%q<fastthread>, ["~> 1.0.7"])
|
98
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
99
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
100
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
101
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
102
|
+
s.add_development_dependency(%q<xml-simple>, ["~> 1.0.12"])
|
103
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
87
104
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
88
|
-
s.add_development_dependency(%q<jeweler>, [">= 1.
|
105
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.5.1"])
|
89
106
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
90
107
|
s.add_development_dependency(%q<xml-simple>, [">= 1.0.12"])
|
91
108
|
s.add_runtime_dependency(%q<commander>, [">= 4.0.3"])
|
92
109
|
s.add_runtime_dependency(%q<terminal-table>, [">= 1.4.2"])
|
110
|
+
s.add_runtime_dependency(%q<json>, [">= 1.4.6"])
|
93
111
|
s.add_runtime_dependency(%q<net-ssh>, [">= 2.0.23"])
|
94
112
|
s.add_runtime_dependency(%q<net-scp>, [">= 1.0.4"])
|
95
113
|
s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
|
96
114
|
s.add_runtime_dependency(%q<treetop>, [">= 1.4.8"])
|
115
|
+
s.add_runtime_dependency(%q<fastthread>, [">= 1.0.7"])
|
97
116
|
else
|
117
|
+
s.add_dependency(%q<commander>, ["~> 4.0.3"])
|
118
|
+
s.add_dependency(%q<terminal-table>, ["~> 1.4.2"])
|
119
|
+
s.add_dependency(%q<json>, ["~> 1.4.6"])
|
120
|
+
s.add_dependency(%q<net-ssh>, ["~> 2.0.23"])
|
121
|
+
s.add_dependency(%q<net-scp>, ["~> 1.0.4"])
|
122
|
+
s.add_dependency(%q<builder>, ["~> 2.1.2"])
|
123
|
+
s.add_dependency(%q<treetop>, ["~> 1.4.8"])
|
124
|
+
s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
|
125
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
126
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
127
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
128
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
129
|
+
s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
|
130
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
98
131
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
99
|
-
s.add_dependency(%q<jeweler>, [">= 1.
|
132
|
+
s.add_dependency(%q<jeweler>, [">= 1.5.1"])
|
100
133
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
101
134
|
s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
|
102
135
|
s.add_dependency(%q<commander>, [">= 4.0.3"])
|
103
136
|
s.add_dependency(%q<terminal-table>, [">= 1.4.2"])
|
137
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
104
138
|
s.add_dependency(%q<net-ssh>, [">= 2.0.23"])
|
105
139
|
s.add_dependency(%q<net-scp>, [">= 1.0.4"])
|
106
140
|
s.add_dependency(%q<builder>, [">= 2.1.2"])
|
107
141
|
s.add_dependency(%q<treetop>, [">= 1.4.8"])
|
142
|
+
s.add_dependency(%q<fastthread>, [">= 1.0.7"])
|
108
143
|
end
|
109
144
|
else
|
145
|
+
s.add_dependency(%q<commander>, ["~> 4.0.3"])
|
146
|
+
s.add_dependency(%q<terminal-table>, ["~> 1.4.2"])
|
147
|
+
s.add_dependency(%q<json>, ["~> 1.4.6"])
|
148
|
+
s.add_dependency(%q<net-ssh>, ["~> 2.0.23"])
|
149
|
+
s.add_dependency(%q<net-scp>, ["~> 1.0.4"])
|
150
|
+
s.add_dependency(%q<builder>, ["~> 2.1.2"])
|
151
|
+
s.add_dependency(%q<treetop>, ["~> 1.4.8"])
|
152
|
+
s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
|
153
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
154
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
155
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
156
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
157
|
+
s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
|
158
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
110
159
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
111
|
-
s.add_dependency(%q<jeweler>, [">= 1.
|
160
|
+
s.add_dependency(%q<jeweler>, [">= 1.5.1"])
|
112
161
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
113
162
|
s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
|
114
163
|
s.add_dependency(%q<commander>, [">= 4.0.3"])
|
115
164
|
s.add_dependency(%q<terminal-table>, [">= 1.4.2"])
|
165
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
116
166
|
s.add_dependency(%q<net-ssh>, [">= 2.0.23"])
|
117
167
|
s.add_dependency(%q<net-scp>, [">= 1.0.4"])
|
118
168
|
s.add_dependency(%q<builder>, [">= 2.1.2"])
|
119
169
|
s.add_dependency(%q<treetop>, [">= 1.4.8"])
|
170
|
+
s.add_dependency(%q<fastthread>, [">= 1.0.7"])
|
120
171
|
end
|
121
172
|
end
|
122
173
|
|