rutty 2.4.2 → 2.5.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/.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