rutty 2.4.2 → 2.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.8.7@rutty --create
data/Gemfile CHANGED
@@ -8,12 +8,13 @@ gem "net-scp", '~> 1.0.4'
8
8
  gem "builder", '~> 2.1.2'
9
9
  gem "treetop", '~> 1.4.8'
10
10
  gem "fastthread", '~> 1.0.7'
11
+ gem "work_queue", '~> 1.0.0'
11
12
 
12
13
  group :development do
13
- gem "jeweler", '~> 1.5.1'
14
+ gem "jeweler", '~> 1.6.2'
14
15
  gem "bundler", '~> 1.0.0'
15
16
  gem "shoulda", ">= 0"
16
- gem "rcov", ">= 0"
17
17
  gem "xml-simple", '~> 1.0.12'
18
18
  gem "ruby-debug", ">= 0"
19
+ gem "rake", "~> 0.9.2"
19
20
  end
@@ -2,14 +2,14 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  builder (2.1.2)
5
- columnize (0.3.1)
5
+ columnize (0.3.2)
6
6
  commander (4.0.3)
7
7
  highline (>= 1.5.0)
8
8
  fastthread (1.0.7)
9
9
  git (1.2.5)
10
10
  highline (1.6.1)
11
- jeweler (1.5.1)
12
- bundler (~> 1.0.0)
11
+ jeweler (1.6.2)
12
+ bundler (~> 1.0)
13
13
  git (>= 1.2.5)
14
14
  rake
15
15
  json (1.4.6)
@@ -18,17 +18,17 @@ GEM
18
18
  net-ssh (>= 1.99.1)
19
19
  net-ssh (2.0.23)
20
20
  polyglot (0.3.1)
21
- rake (0.8.7)
22
- rcov (0.9.9)
23
- ruby-debug (0.10.3)
21
+ rake (0.9.2)
22
+ ruby-debug (0.10.4)
24
23
  columnize (>= 0.1)
25
- ruby-debug-base (~> 0.10.3.0)
26
- ruby-debug-base (0.10.3)
24
+ ruby-debug-base (~> 0.10.4.0)
25
+ ruby-debug-base (0.10.4)
27
26
  linecache (>= 0.3)
28
27
  shoulda (2.11.3)
29
28
  terminal-table (1.4.2)
30
- treetop (1.4.8)
29
+ treetop (1.4.9)
31
30
  polyglot (>= 0.3.1)
31
+ work_queue (1.0.0)
32
32
  xml-simple (1.0.12)
33
33
 
34
34
  PLATFORMS
@@ -39,13 +39,14 @@ DEPENDENCIES
39
39
  bundler (~> 1.0.0)
40
40
  commander (~> 4.0.3)
41
41
  fastthread (~> 1.0.7)
42
- jeweler (~> 1.5.1)
42
+ jeweler (~> 1.6.2)
43
43
  json (~> 1.4.6)
44
44
  net-scp (~> 1.0.4)
45
45
  net-ssh (~> 2.0.23)
46
- rcov
46
+ rake (~> 0.9.2)
47
47
  ruby-debug
48
48
  shoulda
49
49
  terminal-table (~> 1.4.2)
50
50
  treetop (~> 1.4.8)
51
+ work_queue (~> 1.0.0)
51
52
  xml-simple (~> 1.0.12)
data/README.md CHANGED
@@ -111,21 +111,23 @@ will run the `uptime` command on any nodes that are tagged with "foo" **OR** "ba
111
111
  The pseudo-SQL tag query mode provides the most control over your tags. This allows you to pass in a string that looks
112
112
  a bit like SQL, letting you specify complex rules for your tag lookup. For example:
113
113
 
114
- $ rutty dsh -g "'foo' AND 'bar'" uptime
114
+ $ rutty dsh -g "foo AND bar" uptime
115
115
 
116
116
  will run `uptime` on any node that has **BOTH** "foo" and "bar" tags. The command
117
117
 
118
- $ rutty dsh -g "'foo' OR ('baz' AND 'bar')" uptime
118
+ $ rutty dsh -g "foo OR (baz AND bar)" uptime
119
119
 
120
120
  will run `uptime` on any node that has a "foo" tag **OR** any node that has **BOTH** "baz" and "bar" tags.
121
121
 
122
122
  TODO
123
123
  ----
124
124
 
125
+ * Add negation to tag query (eg something like "'foo' AND !'bar'" or "'foo' AND NOT 'bar'")
125
126
  * Refactor defaults config YAML to allow for a broader range of
126
127
  configuration options (max number of threads, default output format, etc)
127
128
  * Implement `rutty upgrade` action, which will upgrade your config files to the latest version
128
129
  * Make a GitHub page
130
+ * Add multi_progress_bar to scp command
129
131
 
130
132
  Note on Patches/Pull Requests
131
133
  -----------------------------
data/Rakefile CHANGED
@@ -22,6 +22,9 @@ Jeweler::Tasks.new do |gem|
22
22
  gem.homepage = "http://github.com/jlindsey/rutty"
23
23
  gem.license = "MIT"
24
24
  gem.authors = ["Josh Lindsey"]
25
+
26
+ require './lib/rutty/version.rb'
27
+ gem.version = Rutty::Version::STRING
25
28
  end
26
29
  Jeweler::RubygemsDotOrgTasks.new
27
30
 
@@ -32,18 +35,12 @@ Rake::TestTask.new(:test) do |test|
32
35
  test.verbose = false
33
36
  end
34
37
 
35
- begin
36
- require 'rcov/rcovtask'
37
- Rcov::RcovTask.new do |test|
38
- test.libs << 'test'
39
- test.pattern = 'test/**/test_*.rb'
40
- test.verbose = true
41
- end
42
- rescue LoadError
43
- task :rcov do
44
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ task :default => :test
39
+
40
+ namespace :treetop do
41
+ desc "Recompile the Treetop Ruby parser file"
42
+ task :regen do
43
+ puts %x(cd #{File.dirname __FILE__}/lib/rutty/treetop && tt tag_query.treetop 2>&1)
45
44
  end
46
45
  end
47
46
 
48
- task :default => :test
49
-
@@ -37,7 +37,8 @@ module Rutty
37
37
  defaults_hash = {
38
38
  :user => 'root',
39
39
  :keypath => File.join(ENV['HOME'], '.ssh', 'id_rsa'),
40
- :port => 22
40
+ :port => 22,
41
+ :tags => []
41
42
  }
42
43
 
43
44
  File.open(general_file, 'w') do |f|
@@ -245,32 +246,33 @@ module Rutty
245
246
  # @see #scp
246
247
  #
247
248
  # @param [Nodes] nodes The {Node} objects to connect to
249
+ # @param [Bool] debug (false) Whether to output debugging info for each connection
248
250
  # @return [Array<Net:SSH::Connection>] The array of live connections
249
251
  def connect_to_nodes nodes, debug = false
250
252
  require 'logger'
251
253
  require 'net/ssh'
252
254
  require 'net/scp'
253
255
  require 'fastthread'
254
- require 'rutty/thread_pool/pool'
256
+ require 'work_queue'
255
257
 
256
258
  connections = []
257
259
  cons_lock = Mutex.new
258
260
  returns_lock = Mutex.new
259
261
 
260
- pool = Rutty::ThreadPool.new 10
262
+ pool = WorkQueue.new 10
261
263
 
262
264
  nodes.each do |node|
263
- pool.process do
265
+ pool.enqueue_b do
264
266
  returns_lock.synchronize {
265
267
  @returns[node.host] = { :exit => 0, :out => '' }
266
268
  }
267
269
  begin
268
- cons_lock.synchronize {
269
- connections << Net::SSH.start(node.host, node.user, :port => node.port, :paranoid => false,
270
- :user_known_hosts_file => '/dev/null', :keys => [node.keypath], :timeout => 5,
271
- :logger => Logger.new(debug ? $stderr : $stdout),
272
- :verbose => (debug ? Logger::FATAL : Logger::DEBUG))
273
- }
270
+ conn = Net::SSH.start(node.host, node.user, :port => node.port, :paranoid => false,
271
+ :user_known_hosts_file => '/dev/null', :keys => [node.keypath], :timeout => 5,
272
+ :logger => Logger.new(debug ? $stderr : $stdout),
273
+ :verbose => (debug ? Logger::FATAL : Logger::DEBUG))
274
+
275
+ cons_lock.synchronize { connections << conn }
274
276
  rescue Errno::ECONNREFUSED
275
277
  returns_lock.synchronize {
276
278
  @returns[node.host][:out] = "ERROR: Connection refused"
@@ -308,7 +310,7 @@ module Rutty
308
310
  sleep 0.2
309
311
  end
310
312
 
311
- pool.shutdown
313
+ pool.stop
312
314
  connections.compact
313
315
  end
314
316
 
@@ -337,7 +339,7 @@ module Rutty
337
339
 
338
340
  if hash[:exit] >= 10000
339
341
  padded_host = "<%= color('#{padded_host}', :critical) %>"
340
- hash[:out] = "<%= color('#{hash[:out]}', :red) %>"
342
+ hash[:out] = "<%= color('#{hash[:out]}', :red) %>\n"
341
343
  elsif hash[:exit] > 0
342
344
  padded_host = "<%= color('#{padded_host}', :error) %>"
343
345
  else
@@ -11,7 +11,7 @@ module Rutty
11
11
  DEFAULT_OUTPUT_FORMAT = 'human-readable'
12
12
 
13
13
  ## Name of the general (defaults) config file
14
- GENERAL_CONF_FILE = 'defaults.yaml'
14
+ GENERAL_CONF_FILE = 'config.yaml'
15
15
  ## Name of the datastore file for user-defined nodes
16
16
  NODES_CONF_FILE = 'nodes.yaml'
17
17
 
@@ -38,6 +38,7 @@ module Rutty
38
38
  #
39
39
  # @param [String] tag The tag string to check for
40
40
  def has_tag? tag
41
+ return false if self.tags.nil?
41
42
  self.tags.include? tag
42
43
  end
43
44
 
@@ -112,7 +112,7 @@ module Rutty
112
112
 
113
113
  parsed_syntax_tree = parser.parse(query_str)
114
114
 
115
- raise InvalidTagQueryString.new "error: Unable to parse tag query string" if parsed_syntax_tree.nil?
115
+ raise InvalidTagQueryString.new "Unable to parse tag query string" if parsed_syntax_tree.nil?
116
116
 
117
117
  proc_str = recursive_build_query_proc_string parsed_syntax_tree.elements
118
118
  proc_str = proc_str.rstrip << ') }'
@@ -145,7 +145,7 @@ module Rutty
145
145
 
146
146
  case elem.class.to_s
147
147
  when 'TagQueryGrammar::Tag'
148
- str << "n.has_tag?(#{elem.text_value}) "
148
+ str << "n.has_tag?('#{elem.text_value}') "
149
149
  when 'TagQueryGrammar::AndLiteral'
150
150
  str << "&& "
151
151
  when 'TagQueryGrammar::OrLiteral'
@@ -167,4 +167,4 @@ module Rutty
167
167
  recursive_build_query_proc_string elems, str
168
168
  end
169
169
  end
170
- end
170
+ end
@@ -109,44 +109,69 @@ module TagQueryGrammar
109
109
  end
110
110
 
111
111
  i0, s0 = index, []
112
- if has_terminal?('\G["|\']', true, index)
113
- r1 = true
114
- @index += 1
112
+ i1 = index
113
+ i2 = index
114
+ r3 = _nt_quote
115
+ if r3
116
+ r2 = r3
115
117
  else
118
+ r4 = _nt_group
119
+ if r4
120
+ r2 = r4
121
+ else
122
+ r5 = _nt_boolean
123
+ if r5
124
+ r2 = r5
125
+ else
126
+ r6 = _nt_space
127
+ if r6
128
+ r2 = r6
129
+ else
130
+ r7 = _nt_group_start
131
+ if r7
132
+ r2 = r7
133
+ else
134
+ r8 = _nt_group_end
135
+ if r8
136
+ r2 = r8
137
+ else
138
+ @index = i2
139
+ r2 = nil
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ if r2
116
147
  r1 = nil
148
+ else
149
+ @index = i1
150
+ r1 = instantiate_node(SyntaxNode,input, index...index)
117
151
  end
118
152
  s0 << r1
119
153
  if r1
120
- s2, i2 = [], index
154
+ s9, i9 = [], index
121
155
  loop do
122
156
  if has_terminal?('\G[\\w-]', true, index)
123
- r3 = true
157
+ r10 = true
124
158
  @index += 1
125
159
  else
126
- r3 = nil
160
+ r10 = nil
127
161
  end
128
- if r3
129
- s2 << r3
162
+ if r10
163
+ s9 << r10
130
164
  else
131
165
  break
132
166
  end
133
167
  end
134
- if s2.empty?
135
- @index = i2
136
- r2 = nil
168
+ if s9.empty?
169
+ @index = i9
170
+ r9 = nil
137
171
  else
138
- r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
139
- end
140
- s0 << r2
141
- if r2
142
- if has_terminal?('\G["|\']', true, index)
143
- r4 = true
144
- @index += 1
145
- else
146
- r4 = nil
147
- end
148
- s0 << r4
172
+ r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
149
173
  end
174
+ s0 << r9
150
175
  end
151
176
  if s0.last
152
177
  r0 = instantiate_node(Tag,input, i0...index, s0)
@@ -161,6 +186,48 @@ module TagQueryGrammar
161
186
  r0
162
187
  end
163
188
 
189
+ def _nt_quote
190
+ start_index = index
191
+ if node_cache[:quote].has_key?(index)
192
+ cached = node_cache[:quote][index]
193
+ if cached
194
+ cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
195
+ @index = cached.interval.end
196
+ end
197
+ return cached
198
+ end
199
+
200
+ i0 = index
201
+ if has_terminal?('"', false, index)
202
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
203
+ @index += 1
204
+ else
205
+ terminal_parse_failure('"')
206
+ r1 = nil
207
+ end
208
+ if r1
209
+ r0 = r1
210
+ else
211
+ if has_terminal?("'", false, index)
212
+ r2 = instantiate_node(SyntaxNode,input, index...(index + 1))
213
+ @index += 1
214
+ else
215
+ terminal_parse_failure("'")
216
+ r2 = nil
217
+ end
218
+ if r2
219
+ r0 = r2
220
+ else
221
+ @index = i0
222
+ r0 = nil
223
+ end
224
+ end
225
+
226
+ node_cache[:quote][start_index] = r0
227
+
228
+ r0
229
+ end
230
+
164
231
  module Group0
165
232
  def group_start
166
233
  elements[0]
@@ -4,7 +4,11 @@ grammar TagQueryGrammar
4
4
  end
5
5
 
6
6
  rule tag
7
- ["|'] [\w-]+ ["|'] <Tag>
7
+ !(quote / group / boolean / space / group_start / group_end) [\w-]+ <Tag>
8
+ end
9
+
10
+ rule quote
11
+ '"' / "'"
8
12
  end
9
13
 
10
14
  rule group
@@ -8,7 +8,7 @@ module Rutty
8
8
  # @see http://semver.org
9
9
  module Version
10
10
  MAJOR = 2
11
- MINOR = 4
11
+ MINOR = 5
12
12
  PATCH = 2
13
13
  BUILD = nil
14
14
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rutty}
8
- s.version = "2.4.2"
8
+ s.version = "2.5.2"
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-27}
12
+ s.date = %q{2011-06-20}
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
@@ -23,13 +23,13 @@ Gem::Specification.new do |s|
23
23
  "README.md"
24
24
  ]
25
25
  s.files = [
26
+ ".rvmrc",
26
27
  ".yardopts",
27
28
  "Gemfile",
28
29
  "Gemfile.lock",
29
30
  "LICENSE",
30
31
  "README.md",
31
32
  "Rakefile",
32
- "VERSION",
33
33
  "bin/rutty",
34
34
  "lib/rutty.rb",
35
35
  "lib/rutty/actions.rb",
@@ -40,8 +40,6 @@ Gem::Specification.new do |s|
40
40
  "lib/rutty/node.rb",
41
41
  "lib/rutty/nodes.rb",
42
42
  "lib/rutty/proc_classes.rb",
43
- "lib/rutty/thread_pool/pool.rb",
44
- "lib/rutty/thread_pool/worker.rb",
45
43
  "lib/rutty/treetop/syntax_nodes.rb",
46
44
  "lib/rutty/treetop/tag_query.rb",
47
45
  "lib/rutty/treetop/tag_query.treetop",
@@ -64,26 +62,10 @@ Gem::Specification.new do |s|
64
62
  s.homepage = %q{http://github.com/jlindsey/rutty}
65
63
  s.licenses = ["MIT"]
66
64
  s.require_paths = ["lib"]
67
- s.rubygems_version = %q{1.3.7}
65
+ s.rubygems_version = %q{1.6.2}
68
66
  s.summary = %q{A DSH implementation in Ruby}
69
- s.test_files = [
70
- "test/helper.rb",
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"
83
- ]
84
67
 
85
68
  if s.respond_to? :specification_version then
86
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
87
69
  s.specification_version = 3
88
70
 
89
71
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -95,12 +77,13 @@ Gem::Specification.new do |s|
95
77
  s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
96
78
  s.add_runtime_dependency(%q<treetop>, ["~> 1.4.8"])
97
79
  s.add_runtime_dependency(%q<fastthread>, ["~> 1.0.7"])
98
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
80
+ s.add_runtime_dependency(%q<work_queue>, ["~> 1.0.0"])
81
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
99
82
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
100
83
  s.add_development_dependency(%q<shoulda>, [">= 0"])
101
- s.add_development_dependency(%q<rcov>, [">= 0"])
102
84
  s.add_development_dependency(%q<xml-simple>, ["~> 1.0.12"])
103
85
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
86
+ s.add_development_dependency(%q<rake>, ["~> 0.9.2"])
104
87
  else
105
88
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
106
89
  s.add_dependency(%q<terminal-table>, ["~> 1.4.2"])
@@ -110,12 +93,13 @@ Gem::Specification.new do |s|
110
93
  s.add_dependency(%q<builder>, ["~> 2.1.2"])
111
94
  s.add_dependency(%q<treetop>, ["~> 1.4.8"])
112
95
  s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
113
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
96
+ s.add_dependency(%q<work_queue>, ["~> 1.0.0"])
97
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
114
98
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
115
99
  s.add_dependency(%q<shoulda>, [">= 0"])
116
- s.add_dependency(%q<rcov>, [">= 0"])
117
100
  s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
118
101
  s.add_dependency(%q<ruby-debug>, [">= 0"])
102
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
119
103
  end
120
104
  else
121
105
  s.add_dependency(%q<commander>, ["~> 4.0.3"])
@@ -126,12 +110,13 @@ Gem::Specification.new do |s|
126
110
  s.add_dependency(%q<builder>, ["~> 2.1.2"])
127
111
  s.add_dependency(%q<treetop>, ["~> 1.4.8"])
128
112
  s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
129
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
113
+ s.add_dependency(%q<work_queue>, ["~> 1.0.0"])
114
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
130
115
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
131
116
  s.add_dependency(%q<shoulda>, [">= 0"])
132
- s.add_dependency(%q<rcov>, [">= 0"])
133
117
  s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
134
118
  s.add_dependency(%q<ruby-debug>, [">= 0"])
119
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
135
120
  end
136
121
  end
137
122
 
@@ -23,8 +23,8 @@ class Test::Unit::TestCase
23
23
 
24
24
  TMP_DIR = File.join(File.dirname(__FILE__), '..', 'tmp')
25
25
  TEST_CONF_DIR = File.join(TMP_DIR, 'config')
26
- TEST_GENERAL_CONF = File.join(TEST_CONF_DIR, 'defaults.yaml')
27
- TEST_NODES_CONF = File.join(TEST_CONF_DIR, 'nodes.yaml')
26
+ TEST_GENERAL_CONF = File.join(TEST_CONF_DIR, Rutty::Consts::GENERAL_CONF_FILE)
27
+ TEST_NODES_CONF = File.join(TEST_CONF_DIR, Rutty::Consts::NODES_CONF_FILE)
28
28
 
29
29
  RUTTY_BIN = File.join File.dirname(__FILE__), '..', 'bin', 'rutty'
30
30
 
@@ -3,18 +3,11 @@ require 'helper'
3
3
  class TestConsts < Test::Unit::TestCase
4
4
  context "The Rutty::Consts module" do
5
5
  should "have all the constants set" do
6
+ assert_not_nil Rutty::Consts::GENERAL_CONF_FILE
7
+ assert_not_nil Rutty::Consts::NODES_CONF_FILE
6
8
  assert_not_nil Rutty::Consts::CONF_DIR
7
9
  assert_not_nil Rutty::Consts::GENERAL_CONF
8
10
  assert_not_nil Rutty::Consts::NODES_CONF
9
11
  end
10
-
11
- should "have the constants be the proper values" do
12
- assert_equal Rutty::Consts::GENERAL_CONF_FILE, 'defaults.yaml'
13
- assert_equal Rutty::Consts::NODES_CONF_FILE, 'nodes.yaml'
14
-
15
- assert_equal Rutty::Consts::CONF_DIR, File.join(ENV['HOME'], '.rutty')
16
- assert_equal Rutty::Consts::GENERAL_CONF, File.join(Rutty::Consts::CONF_DIR, 'defaults.yaml')
17
- assert_equal Rutty::Consts::NODES_CONF, File.join(Rutty::Consts::CONF_DIR, 'nodes.yaml')
18
- end
19
12
  end
20
13
  end
@@ -59,7 +59,7 @@ class TestNodes < Test::Unit::TestCase
59
59
  Rutty::Nodes.publicize_methods do
60
60
  assert_instance_of Rutty::Procs::SingleTagQuery, @nodes.get_tag_query_filter('foo')
61
61
  assert_instance_of Rutty::Procs::MultipleTagQuery, @nodes.get_tag_query_filter('foo,bar')
62
- assert_instance_of Rutty::Procs::SqlLikeTagQuery, @nodes.get_tag_query_filter("'foo' AND 'bar' OR 'baz'")
62
+ assert_instance_of Rutty::Procs::SqlLikeTagQuery, @nodes.get_tag_query_filter("foo AND bar OR baz")
63
63
  end
64
64
  end
65
65
 
@@ -71,12 +71,12 @@ class TestNodes < Test::Unit::TestCase
71
71
 
72
72
  parser = TagQueryGrammarParser.new
73
73
 
74
- proc_str = @nodes.recursive_build_query_proc_string parser.parse("'foo' AND 'bar' OR 'baz'").elements
74
+ proc_str = @nodes.recursive_build_query_proc_string parser.parse("foo AND bar OR baz").elements
75
75
  proc_str = proc_str.rstrip << ') }'
76
76
 
77
77
  assert_equal "Procs::SqlLikeTagQuery.new { |n| !(n.has_tag?('foo') && n.has_tag?('bar') || n.has_tag?('baz')) }", proc_str
78
78
 
79
- proc_str = @nodes.recursive_build_query_proc_string parser.parse("'test' OR ('example' AND 'foo')").elements
79
+ proc_str = @nodes.recursive_build_query_proc_string parser.parse("test OR (example AND foo)").elements
80
80
  proc_str = proc_str.rstrip << ') }'
81
81
 
82
82
  assert_equal "Procs::SqlLikeTagQuery.new { |n| !(n.has_tag?('test') || (n.has_tag?('example') && n.has_tag?('foo'))) }", proc_str
@@ -85,7 +85,7 @@ class TestNodes < Test::Unit::TestCase
85
85
 
86
86
  should "raise an exception on malformed tag query strings" do
87
87
  Rutty::Nodes.publicize_methods do
88
- ["'foo' ARND 'bar'", "'fail", "'failure' AND )'foo'"].each do |str|
88
+ ["foo ARND bar", "'fail", "failure AND )foo"].each do |str|
89
89
  assert_raises Rutty::InvalidTagQueryString do
90
90
  @nodes.get_tag_query_filter str
91
91
  end
@@ -128,15 +128,15 @@ class TestNodes < Test::Unit::TestCase
128
128
  end
129
129
 
130
130
  should "correctly filter on a SQL-like tag query and return the correct node(s)" do
131
- filtered = @nodes.filter(OpenStruct.new :tags => "'test' AND 'localhost'")
131
+ filtered = @nodes.filter(OpenStruct.new :tags => "test AND localhost")
132
132
  assert_equal 1, filtered.length
133
133
  assert_equal [@node1], filtered
134
134
 
135
- filtered = @nodes.filter(OpenStruct.new :tags => "'example' OR 'localhost'")
135
+ filtered = @nodes.filter(OpenStruct.new :tags => "example OR localhost")
136
136
  assert_equal 2, filtered.length
137
137
  assert_equal [@node1, @node3], filtered
138
138
 
139
- filtered = @nodes.filter(OpenStruct.new :tags => "'localhost' AND 'test' OR ('google')")
139
+ filtered = @nodes.filter(OpenStruct.new :tags => "localhost AND test OR (google)")
140
140
  assert_equal 2, filtered.length
141
141
  assert_equal [@node1, @node2], filtered
142
142
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rutty
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
4
+ hash: 31
5
+ prerelease:
6
6
  segments:
7
7
  - 2
8
- - 4
8
+ - 5
9
9
  - 2
10
- version: 2.4.2
10
+ version: 2.5.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Lindsey
@@ -15,10 +15,12 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-27 00:00:00 -05:00
18
+ date: 2011-06-20 00:00:00 -04:00
19
19
  default_executable: rutty
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
22
24
  requirement: &id001 !ruby/object:Gem::Requirement
23
25
  none: false
24
26
  requirements:
@@ -30,11 +32,11 @@ dependencies:
30
32
  - 0
31
33
  - 3
32
34
  version: 4.0.3
33
- type: :runtime
34
35
  name: commander
35
- prerelease: false
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ type: :runtime
38
40
  requirement: &id002 !ruby/object:Gem::Requirement
39
41
  none: false
40
42
  requirements:
@@ -46,11 +48,11 @@ dependencies:
46
48
  - 4
47
49
  - 2
48
50
  version: 1.4.2
49
- type: :runtime
50
51
  name: terminal-table
51
- prerelease: false
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ type: :runtime
54
56
  requirement: &id003 !ruby/object:Gem::Requirement
55
57
  none: false
56
58
  requirements:
@@ -62,11 +64,11 @@ dependencies:
62
64
  - 4
63
65
  - 6
64
66
  version: 1.4.6
65
- type: :runtime
66
67
  name: json
67
- prerelease: false
68
68
  version_requirements: *id003
69
69
  - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ type: :runtime
70
72
  requirement: &id004 !ruby/object:Gem::Requirement
71
73
  none: false
72
74
  requirements:
@@ -78,11 +80,11 @@ dependencies:
78
80
  - 0
79
81
  - 23
80
82
  version: 2.0.23
81
- type: :runtime
82
83
  name: net-ssh
83
- prerelease: false
84
84
  version_requirements: *id004
85
85
  - !ruby/object:Gem::Dependency
86
+ prerelease: false
87
+ type: :runtime
86
88
  requirement: &id005 !ruby/object:Gem::Requirement
87
89
  none: false
88
90
  requirements:
@@ -94,11 +96,11 @@ dependencies:
94
96
  - 0
95
97
  - 4
96
98
  version: 1.0.4
97
- type: :runtime
98
99
  name: net-scp
99
- prerelease: false
100
100
  version_requirements: *id005
101
101
  - !ruby/object:Gem::Dependency
102
+ prerelease: false
103
+ type: :runtime
102
104
  requirement: &id006 !ruby/object:Gem::Requirement
103
105
  none: false
104
106
  requirements:
@@ -110,11 +112,11 @@ dependencies:
110
112
  - 1
111
113
  - 2
112
114
  version: 2.1.2
113
- type: :runtime
114
115
  name: builder
115
- prerelease: false
116
116
  version_requirements: *id006
117
117
  - !ruby/object:Gem::Dependency
118
+ prerelease: false
119
+ type: :runtime
118
120
  requirement: &id007 !ruby/object:Gem::Requirement
119
121
  none: false
120
122
  requirements:
@@ -126,11 +128,11 @@ dependencies:
126
128
  - 4
127
129
  - 8
128
130
  version: 1.4.8
129
- type: :runtime
130
131
  name: treetop
131
- prerelease: false
132
132
  version_requirements: *id007
133
133
  - !ruby/object:Gem::Dependency
134
+ prerelease: false
135
+ type: :runtime
134
136
  requirement: &id008 !ruby/object:Gem::Requirement
135
137
  none: false
136
138
  requirements:
@@ -142,57 +144,59 @@ dependencies:
142
144
  - 0
143
145
  - 7
144
146
  version: 1.0.7
145
- type: :runtime
146
147
  name: fastthread
147
- prerelease: false
148
148
  version_requirements: *id008
149
149
  - !ruby/object:Gem::Dependency
150
+ prerelease: false
151
+ type: :runtime
150
152
  requirement: &id009 !ruby/object:Gem::Requirement
151
153
  none: false
152
154
  requirements:
153
155
  - - ~>
154
156
  - !ruby/object:Gem::Version
155
- hash: 1
157
+ hash: 23
156
158
  segments:
157
159
  - 1
158
- - 5
159
- - 1
160
- version: 1.5.1
161
- type: :development
162
- name: jeweler
163
- prerelease: false
160
+ - 0
161
+ - 0
162
+ version: 1.0.0
163
+ name: work_queue
164
164
  version_requirements: *id009
165
165
  - !ruby/object:Gem::Dependency
166
+ prerelease: false
167
+ type: :development
166
168
  requirement: &id010 !ruby/object:Gem::Requirement
167
169
  none: false
168
170
  requirements:
169
171
  - - ~>
170
172
  - !ruby/object:Gem::Version
171
- hash: 23
173
+ hash: 11
172
174
  segments:
173
175
  - 1
174
- - 0
175
- - 0
176
- version: 1.0.0
177
- type: :development
178
- name: bundler
179
- prerelease: false
176
+ - 6
177
+ - 2
178
+ version: 1.6.2
179
+ name: jeweler
180
180
  version_requirements: *id010
181
181
  - !ruby/object:Gem::Dependency
182
+ prerelease: false
183
+ type: :development
182
184
  requirement: &id011 !ruby/object:Gem::Requirement
183
185
  none: false
184
186
  requirements:
185
- - - ">="
187
+ - - ~>
186
188
  - !ruby/object:Gem::Version
187
- hash: 3
189
+ hash: 23
188
190
  segments:
191
+ - 1
189
192
  - 0
190
- version: "0"
191
- type: :development
192
- name: shoulda
193
- prerelease: false
193
+ - 0
194
+ version: 1.0.0
195
+ name: bundler
194
196
  version_requirements: *id011
195
197
  - !ruby/object:Gem::Dependency
198
+ prerelease: false
199
+ type: :development
196
200
  requirement: &id012 !ruby/object:Gem::Requirement
197
201
  none: false
198
202
  requirements:
@@ -202,11 +206,11 @@ dependencies:
202
206
  segments:
203
207
  - 0
204
208
  version: "0"
205
- type: :development
206
- name: rcov
207
- prerelease: false
209
+ name: shoulda
208
210
  version_requirements: *id012
209
211
  - !ruby/object:Gem::Dependency
212
+ prerelease: false
213
+ type: :development
210
214
  requirement: &id013 !ruby/object:Gem::Requirement
211
215
  none: false
212
216
  requirements:
@@ -218,11 +222,11 @@ dependencies:
218
222
  - 0
219
223
  - 12
220
224
  version: 1.0.12
221
- type: :development
222
225
  name: xml-simple
223
- prerelease: false
224
226
  version_requirements: *id013
225
227
  - !ruby/object:Gem::Dependency
228
+ prerelease: false
229
+ type: :development
226
230
  requirement: &id014 !ruby/object:Gem::Requirement
227
231
  none: false
228
232
  requirements:
@@ -232,10 +236,24 @@ dependencies:
232
236
  segments:
233
237
  - 0
234
238
  version: "0"
235
- type: :development
236
239
  name: ruby-debug
237
- prerelease: false
238
240
  version_requirements: *id014
241
+ - !ruby/object:Gem::Dependency
242
+ prerelease: false
243
+ type: :development
244
+ requirement: &id015 !ruby/object:Gem::Requirement
245
+ none: false
246
+ requirements:
247
+ - - ~>
248
+ - !ruby/object:Gem::Version
249
+ hash: 63
250
+ segments:
251
+ - 0
252
+ - 9
253
+ - 2
254
+ version: 0.9.2
255
+ name: rake
256
+ version_requirements: *id015
239
257
  description: "\n RuTTY is a DSH (distributed / dancer's shell) written in Ruby. It's used to run commands \n on multiple remote servers at once, based on a tagging system. Also allows for multiple\n SCP-style uploads.\n "
240
258
  email: josh@cloudspace.com
241
259
  executables:
@@ -246,13 +264,13 @@ extra_rdoc_files:
246
264
  - LICENSE
247
265
  - README.md
248
266
  files:
267
+ - .rvmrc
249
268
  - .yardopts
250
269
  - Gemfile
251
270
  - Gemfile.lock
252
271
  - LICENSE
253
272
  - README.md
254
273
  - Rakefile
255
- - VERSION
256
274
  - bin/rutty
257
275
  - lib/rutty.rb
258
276
  - lib/rutty/actions.rb
@@ -263,8 +281,6 @@ files:
263
281
  - lib/rutty/node.rb
264
282
  - lib/rutty/nodes.rb
265
283
  - lib/rutty/proc_classes.rb
266
- - lib/rutty/thread_pool/pool.rb
267
- - lib/rutty/thread_pool/worker.rb
268
284
  - lib/rutty/treetop/syntax_nodes.rb
269
285
  - lib/rutty/treetop/tag_query.rb
270
286
  - lib/rutty/treetop/tag_query.treetop
@@ -313,21 +329,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
313
329
  requirements: []
314
330
 
315
331
  rubyforge_project:
316
- rubygems_version: 1.3.7
332
+ rubygems_version: 1.6.2
317
333
  signing_key:
318
334
  specification_version: 3
319
335
  summary: A DSH implementation in Ruby
320
- test_files:
321
- - test/helper.rb
322
- - test/test_action_add_node.rb
323
- - test/test_action_dsh.rb
324
- - test/test_action_init.rb
325
- - test/test_action_list_nodes.rb
326
- - test/test_action_scp.rb
327
- - test/test_actions.rb
328
- - test/test_config.rb
329
- - test/test_consts.rb
330
- - test/test_helpers.rb
331
- - test/test_node.rb
332
- - test/test_nodes.rb
333
- - test/test_runner.rb
336
+ test_files: []
337
+
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 2.4.2
@@ -1,80 +0,0 @@
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
@@ -1,103 +0,0 @@
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