scout_agent 3.0.1 → 3.0.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.
Files changed (36) hide show
  1. data/CHANGELOG +12 -2
  2. data/Rakefile +4 -3
  3. data/bin/scout_agent +3 -2
  4. data/lib/scout_agent.rb +7 -6
  5. data/lib/scout_agent/agent.rb +1 -0
  6. data/lib/scout_agent/agent/communication_agent.rb +13 -2
  7. data/lib/scout_agent/agent/master_agent.rb +1 -0
  8. data/lib/scout_agent/api.rb +18 -3
  9. data/lib/scout_agent/assignment.rb +1 -0
  10. data/lib/scout_agent/assignment/configuration.rb +1 -0
  11. data/lib/scout_agent/assignment/identify.rb +1 -0
  12. data/lib/scout_agent/assignment/queue.rb +1 -0
  13. data/lib/scout_agent/assignment/reset.rb +1 -0
  14. data/lib/scout_agent/assignment/snapshot.rb +4 -3
  15. data/lib/scout_agent/assignment/start.rb +6 -3
  16. data/lib/scout_agent/assignment/status.rb +1 -0
  17. data/lib/scout_agent/assignment/stop.rb +1 -0
  18. data/lib/scout_agent/assignment/upload_log.rb +1 -0
  19. data/lib/scout_agent/core_extensions.rb +41 -4
  20. data/lib/scout_agent/database.rb +2 -1
  21. data/lib/scout_agent/database/mission_log.rb +1 -0
  22. data/lib/scout_agent/database/queue.rb +1 -0
  23. data/lib/scout_agent/database/snapshots.rb +1 -0
  24. data/lib/scout_agent/database/statuses.rb +1 -0
  25. data/lib/scout_agent/dispatcher.rb +3 -1
  26. data/lib/scout_agent/id_card.rb +1 -0
  27. data/lib/scout_agent/lifeline.rb +7 -2
  28. data/lib/scout_agent/mission.rb +1 -0
  29. data/lib/scout_agent/order.rb +1 -0
  30. data/lib/scout_agent/order/check_in_order.rb +1 -0
  31. data/lib/scout_agent/order/snapshot_order.rb +1 -0
  32. data/lib/scout_agent/plan.rb +3 -2
  33. data/lib/scout_agent/server.rb +7 -16
  34. data/lib/scout_agent/tracked.rb +1 -0
  35. data/lib/scout_agent/wire_tap.rb +2 -0
  36. metadata +14 -4
data/CHANGELOG CHANGED
@@ -1,8 +1,18 @@
1
+ == 3.0.2
2
+
3
+ * Added xmpp4r gem dependency
4
+ * Locked gem version numbers at load time
5
+ * Upgraded to Amalgalite 0.9.0 for Ruby 1.9 compatibility
6
+ * Upgraded to RestClient 0.9.2 to remove a couple of bug workarounds
7
+ * Changed the API to always shell out to the same version of Ruby it is running
8
+ under
9
+ * Made a first pass at Ruby 1.9 support
10
+
1
11
  == 3.0.1
2
12
 
3
13
  * Added more error protection to the server wrapper so thinks like
4
- OpenSSL::SSL::SSLError and SocketError don't kill the agent.
5
- * Switched to the beta URL.
14
+ OpenSSL::SSL::SSLError and SocketError don't kill the agent
15
+ * Switched to the beta URL
6
16
 
7
17
  == 3.0.0
8
18
 
data/Rakefile CHANGED
@@ -34,10 +34,11 @@ SA_SPEC = Gem::Specification.new do |spec|
34
34
 
35
35
  spec.require_path = "lib"
36
36
 
37
- spec.add_dependency("arrayfields", "=4.7.2")
38
- spec.add_dependency("amalgalite", "=0.7.7")
39
- spec.add_dependency("rest-client", "=0.9")
37
+ spec.add_dependency("arrayfields", "=4.7.2") # fix Amalgalite's results
38
+ spec.add_dependency("amalgalite", "=0.9.0")
39
+ spec.add_dependency("rest-client", "=0.9.2")
40
40
  spec.add_dependency("json", "=1.1.3")
41
+ spec.add_dependency("xmpp4r", "=0.4")
41
42
  spec.add_dependency("elif", "=0.1.0") # used by some plugins
42
43
 
43
44
  spec.authors = [ "James Edward Gray II",
data/bin/scout_agent CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # encoding: UTF-8
2
3
 
3
- $VERBOSE = true # -w
4
- $KCODE = "u" # -Ku
4
+ $VERBOSE = true # -w
5
+ $KCODE = "u" if RUBY_VERSION < "1.9" # -Ku
5
6
 
6
7
  # load the agent
7
8
  $LOAD_PATH << File.join(File.expand_path(File.dirname(__FILE__)), *%w[.. lib])
data/lib/scout_agent.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  # require standard libraries
4
5
  require "etc"
@@ -25,11 +26,11 @@ require "scout_agent/lifeline"
25
26
  require "scout_agent/dispatcher"
26
27
 
27
28
  # require gems
28
- require_lib_or_gem "json"
29
- require_lib_or_gem "amalgalite"
30
- require_lib_or_gem "rest_client"
31
- require_lib_or_gem "xmpp4r"
32
- require_lib_or_gem "xmpp4r/roster"
29
+ require_lib_or_gem "json", "=1.1.3"
30
+ require_lib_or_gem "amalgalite", "=0.9.0"
31
+ require_lib_or_gem "rest_client", "=0.9.2"
32
+ require_lib_or_gem "xmpp4r", "=0.4"
33
+ require_lib_or_gem "xmpp4r/roster" # loads from xmpp4r's version
33
34
 
34
35
  # The namespace for all agent software.
35
36
  module ScoutAgent
@@ -64,7 +65,7 @@ module ScoutAgent
64
65
  end
65
66
 
66
67
  # The version of this agent.
67
- VERSION = "3.0.1".freeze
68
+ VERSION = "3.0.2".freeze
68
69
  # A Pathname reference to the agent code directory, used in dynamic loading.
69
70
  LIB_DIR = Pathname.new(File.dirname(__FILE__)) + agent_name
70
71
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Agent
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  # load agent extensions
4
5
  require "scout_agent/api"
@@ -44,10 +45,10 @@ module ScoutAgent
44
45
 
45
46
  def login
46
47
  Thread.abort_on_exception = true # make XMPP4R fail fast
47
- @agent_jid = Jabber::JID.new("#{Plan.agent_key}@jabber.org/agent")
48
+ @agent_jid = Jabber::JID.new("#{agent_key}@#{jabber_server}/agent")
48
49
  @jabber = Jabber::Client.new(@agent_jid)
49
50
  no_warnings { @jabber.connect }
50
- @jabber.auth(Plan.agent_key)
51
+ @jabber.auth(agent_key)
51
52
  end
52
53
 
53
54
  def update_status(message, status = nil)
@@ -80,6 +81,16 @@ module ScoutAgent
80
81
  Thread.stop
81
82
  @jabber.close
82
83
  end
84
+
85
+ def agent_key
86
+ @agent_key ||= Plan.test_mode? ?
87
+ "a7349498-bec3-4ddf-963c-149a666433a4" :
88
+ Plan.agent_key
89
+ end
90
+
91
+ def jabber_server
92
+ @jabber_server ||= Plan.test_mode? ? "jabber.org" : "FIXME"
93
+ end
83
94
  end
84
95
  end
85
96
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  # load agent extensions
4
5
  require "scout_agent/mission"
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
4
+ require "rbconfig" # used to find the Ruby we are running under
3
5
  require "pathname" # all paths are Pathname objects
4
6
 
5
7
  begin
@@ -69,7 +71,8 @@ module ScoutAgent
69
71
  private
70
72
 
71
73
  def run
72
- command = [API.path_to_agent, @name, *Array(@args)].
74
+ command = [ API.path_to_ruby, API.path_to_agent,
75
+ @name, *Array(@args) ].
73
76
  map { |s| "'#{API.shell_escape(s)}'" }.join(" ")
74
77
  begin
75
78
  response = open("| #{command} 2>&1", "r+") do |agent|
@@ -136,14 +139,26 @@ module ScoutAgent
136
139
  sub(/^$/, "''")
137
140
  end
138
141
 
142
+ #
143
+ # This method returns the path to the Ruby executable used to load this code
144
+ # as a Pathname object. The API uses this path to make sure another version
145
+ # of Ruby isn't invoked when shelling out.
146
+ #
147
+ def path_to_ruby
148
+ @path_to_ruby ||= Pathname.new(
149
+ File.join(Config::CONFIG.values_at(*%w[bindir ruby_install_name])) +
150
+ Config::CONFIG["EXEEXT"]
151
+ )
152
+ end
153
+
139
154
  #
140
155
  # This method returns the path to the agent executable as a Pathname object.
141
156
  # This is convience for those who wish to manually communicate with the
142
157
  # agent and not needed if you stick to the higher level interface.
143
158
  #
144
159
  def path_to_agent
145
- Pathname.new( File.join( File.dirname(__FILE__),
146
- *%w[.. .. bin scout_agent] ) )
160
+ @path_to_agent ||= Pathname.new( File.join( File.dirname(__FILE__),
161
+ *%w[.. .. bin scout_agent] ) )
147
162
  end
148
163
 
149
164
  #
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  # require standard libraries
4
5
  require "io/wait"
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -68,9 +69,9 @@ module ScoutAgent
68
69
 
69
70
  # Escape +str+ to make it useable in a shell as one "word".
70
71
  def shell_escape(str)
71
- str.to_s.gsub( /(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/, '\\' ).
72
- gsub( /\n/, "'\n'" ).
73
- sub( /^$/, "''" )
72
+ str.to_s.gsub( /(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/n, '\\' ).
73
+ gsub( /\n/, "'\n'" ).
74
+ sub( /^$/, "''" )
74
75
  end
75
76
 
76
77
  def abort_with_missing_db
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -47,9 +48,11 @@ module ScoutAgent
47
48
  Lifeline.new(agent, log)
48
49
  }
49
50
  %w[TERM INT].each do |signal|
50
- trap(signal) do
51
- lifelines.each { |line| line.terminate }
52
- Process.waitall
51
+ trap(signal) do
52
+ Thread.new do
53
+ lifelines.each { |line| line.terminate }
54
+ Process.waitall
55
+ end
53
56
  end
54
57
  end
55
58
  lifelines.each { |line| line.launch_and_monitor }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Assignment
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  # require standard libraries
4
5
  require "tempfile"
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -55,21 +56,56 @@ module ScoutAgent
55
56
  # RubyGems and tries the require again. If that too fails, this process
56
57
  # will exit with a message about the missing library.
57
58
  #
58
- def require_lib_or_gem(name)
59
- require name
59
+ # Setting +version+ will cause this method to try to lock the gem with
60
+ # that version, if loading via RubyGems. This helps prevent gem upgrades
61
+ # from causing issues with the agent, but it's still possible to load
62
+ # directly from installed libraries if you need to bypass RubyGems for any
63
+ # reason.
64
+ #
65
+ def require_lib_or_gem(name, version = nil)
66
+ # special case JSON, which became a standard library in Ruby 1.9
67
+ if name == "json" and RUBY_VERSION >= "1.9"
68
+ no_warnings { return require(name) }
69
+ end
70
+
71
+ lock_gem_version(name, version) if version
72
+ if %w[amalgalite rest_client].include?(name) and RUBY_VERSION >= "1.9"
73
+ no_warnings { require name }
74
+ else
75
+ require name
76
+ end
60
77
  rescue LoadError # library not found
61
78
  begin
62
79
  require "rubygems"
63
- require name
80
+ lock_gem_version(name, version) if version
81
+ if %w[amalgalite rest_client].include?(name) and RUBY_VERSION >= "1.9"
82
+ no_warnings { require name }
83
+ else
84
+ require name
85
+ end
64
86
  rescue LoadError # library not found
87
+ v_str = version.to_s[/\d\.\d(?:\.\d)?/]
88
+ v_str = "-v #{v_str}" if v_str
65
89
  abort <<-END_LOAD_ERROR.trim
66
90
  Unable to load the required '#{name}' library. Try:
67
91
 
68
- sudo gem install #{name.tr('_', '-')}
92
+ sudo gem install #{name.tr('_', '-')} #{v_str}
69
93
 
70
94
  END_LOAD_ERROR
71
95
  end
72
96
  end
97
+
98
+ #
99
+ # Locks the +library+ at +version+, if gem() is available (a recent
100
+ # version of RubyGems is loaded).
101
+ #
102
+ def lock_gem_version(library, version)
103
+ begin
104
+ gem(library.tr("_", "-"), version)
105
+ rescue NoMethodError # gem() not available
106
+ # do nothing: RubyGems not loaded
107
+ end
108
+ end
73
109
 
74
110
  #
75
111
  # This is a helper for those libraries that aren't well enough behaved not
@@ -253,6 +289,7 @@ end
253
289
 
254
290
  # load all core extensions
255
291
  ScoutAgent::CoreExtensions.constants.each do |name|
292
+ name = name.to_s # needed for Ruby 1.9 compatibility
256
293
  extension = ScoutAgent::CoreExtensions.const_get(name)
257
294
  mixer = name.sub!(/([a-z])(?:Module|Class)\z/, "\\1") ? :extend : :include
258
295
  core = Object.const_get(name)
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -49,7 +50,7 @@ module ScoutAgent
49
50
  #
50
51
  def initialize(log = WireTap.new(nil))
51
52
  @log = log
52
- @sqlite = Amalgalite::Database.new(path)
53
+ @sqlite = Amalgalite::Database.new(path.to_s)
53
54
  @read_locked = false
54
55
  @write_locked = false
55
56
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Database
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Database
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Database
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Database
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  module Dispatcher
@@ -117,7 +118,8 @@ module ScoutAgent
117
118
 
118
119
  def load_assignment(assignment)
119
120
  dir = LIB_DIR + "assignment"
120
- matches = dir.entries.grep(/#{Regexp.escape(assignment)}\w*\.rb\z/)
121
+ matches = dir.entries.map { |path| path.to_s }.
122
+ grep(/#{Regexp.escape(assignment)}\w*\.rb\z/)
121
123
  if matches.size > 1
122
124
  abort_with_ambiguous_assignment(assignment, matches)
123
125
  elsif matches.first and (code = dir + matches.first).exist?
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Lifeline
@@ -228,7 +229,9 @@ module ScoutAgent
228
229
  close_writer
229
230
 
230
231
  if @code
231
- @code.finish
232
+ Thread.new do
233
+ @code.finish
234
+ end
232
235
  else
233
236
  exit
234
237
  end
@@ -236,7 +239,9 @@ module ScoutAgent
236
239
 
237
240
  def alert_code
238
241
  if @code
239
- @code.notice_changes
242
+ Thread.new do
243
+ @code.notice_changes
244
+ end
240
245
  end
241
246
  end
242
247
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Mission
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Order
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Order
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  class Order
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -211,7 +212,7 @@ module ScoutAgent
211
212
  #
212
213
  %w[os_config_path os_db_path os_pid_path os_log_path].each do |path|
213
214
  define_method(path) do
214
- prefix_path + super
215
+ prefix_path + super()
215
216
  end
216
217
  end
217
218
 
@@ -230,7 +231,7 @@ module ScoutAgent
230
231
  #
231
232
  %w[db pid log].each do |path|
232
233
  define_method("#{path}_dir") do
233
- send("os_#{path}_path") + (super || ScoutAgent.agent_name)
234
+ send("os_#{path}_path") + (super() || ScoutAgent.agent_name)
234
235
  end
235
236
  end
236
237
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -80,14 +81,9 @@ module ScoutAgent
80
81
  log.error("Check-in could not be zipped.")
81
82
  false
82
83
  rescue RestClient::RequestFailed => error # RestClient bug workaround
83
- # all success codes are OK, but other codes are not
84
- if error.http_code.between? 200, 299
85
- true
86
- else
87
- log.warn( "Check-in was returned as a failure code: " +
88
- "#{error.http_code}." )
89
- false
90
- end
84
+ log.warn( "Check-in was returned as a failure code: " +
85
+ "#{error.http_code}." )
86
+ false
91
87
  rescue Exception => error # networking problem
92
88
  log.warn("Check-in could not be sent: #{error.class}.")
93
89
  false # we failed to send and will retry later
@@ -107,14 +103,9 @@ module ScoutAgent
107
103
  end
108
104
  true
109
105
  rescue RestClient::RequestFailed => error # RestClient bug workaround
110
- # all success codes are OK, but other codes are not
111
- if error.http_code.between? 200, 299
112
- true
113
- else
114
- log.warn( "Log upload was returned as a failure code: " +
115
- "#{error.http_code}." )
116
- false
117
- end
106
+ log.warn( "Log upload was returned as a failure code: " +
107
+ "#{error.http_code}." )
108
+ false
118
109
  rescue Errno::ECONNREFUSED, RestClient::Exception # networking problem
119
110
  log.warn("Log could not be sent: #{error.class}.")
120
111
  false # could not send log
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby -wKU
2
+ # encoding: UTF-8
2
3
 
3
4
  module ScoutAgent
4
5
  #
@@ -479,6 +480,7 @@ module ScoutAgent
479
480
  # Builds a Hash of all levels used.
480
481
  def levels
481
482
  @levels ||= Hash[ *Severity.constants.
483
+ map { |name| name.to_s }. # for Ruby 1.9
482
484
  map { |name| [name, level_by_name(name)] }.
483
485
  flatten ]
484
486
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edward Gray II
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2009-04-01 00:00:00 -05:00
15
+ date: 2009-04-06 00:00:00 -05:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -33,7 +33,7 @@ dependencies:
33
33
  requirements:
34
34
  - - "="
35
35
  - !ruby/object:Gem::Version
36
- version: 0.7.7
36
+ version: 0.9.0
37
37
  version:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: rest-client
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - "="
45
45
  - !ruby/object:Gem::Version
46
- version: "0.9"
46
+ version: 0.9.2
47
47
  version:
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: json
@@ -55,6 +55,16 @@ dependencies:
55
55
  - !ruby/object:Gem::Version
56
56
  version: 1.1.3
57
57
  version:
58
+ - !ruby/object:Gem::Dependency
59
+ name: xmpp4r
60
+ type: :runtime
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "="
65
+ - !ruby/object:Gem::Version
66
+ version: "0.4"
67
+ version:
58
68
  - !ruby/object:Gem::Dependency
59
69
  name: elif
60
70
  type: :runtime