ruboty-exec_command 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/README.md +16 -0
- data/commands/example/hello +3 -1
- data/commands/example/sleep +8 -0
- data/lib/ruboty/exec_command/actions/command.rb +47 -2
- data/lib/ruboty/exec_command/command.rb +77 -10
- data/lib/ruboty/exec_command/command_slot.rb +70 -0
- data/lib/ruboty/exec_command/version.rb +1 -1
- data/lib/ruboty/exec_command.rb +1 -0
- data/lib/ruboty/handlers/command.rb +17 -2
- data/ruboty-exec_command.gemspec +0 -1
- data/spec/lib/ruboty/exec_command/command_slot_spec.rb +50 -0
- data/spec/lib/ruboty/{exec-command → exec_command}/command_spec.rb +10 -3
- data/spec/lib/ruboty/handlers/command_spec.rb +96 -11
- metadata +8 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f31fbeb824f00f5843ea7a7168363a33539b82f
|
4
|
+
data.tar.gz: d7fabdad9e511f00165e8096e828e83f1af70023
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45bc5f831cdc072533200b0ce52c2a4dadc83cb9808c7620c407de2fbf4e64a30b7de6660c5c5b651b0c03693d32c9abab394577d1967b53891b30a3a186b3ce
|
7
|
+
data.tar.gz: 6c91c79b5694c3017427aeea2f804395f662ff8bc949aa51a72fc1bf99436faa9fb43f3495162eeba4fc76cd174211d57466420764a83f6de57584360ea0cc6a
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -12,6 +12,16 @@ if RUBOTY_ROOT is defined.
|
|
12
12
|
For your convinience, please implement -h option into the
|
13
13
|
command. The usage will be used for help message of ruboty.
|
14
14
|
|
15
|
+
## Command Controll
|
16
|
+
|
17
|
+
List running commands:
|
18
|
+
|
19
|
+
> ruboty command list
|
20
|
+
|
21
|
+
Kill running command, you can specify command index in the result of ```command list``` or PID
|
22
|
+
|
23
|
+
> ruboty command kill <index|PID>
|
24
|
+
|
15
25
|
## Installation
|
16
26
|
|
17
27
|
Add this line to your application's Gemfile:
|
@@ -28,6 +38,12 @@ Or install it yourself as:
|
|
28
38
|
|
29
39
|
$ gem install ruboty-exec_command
|
30
40
|
|
41
|
+
## History
|
42
|
+
|
43
|
+
- 0.0.4:
|
44
|
+
- command runs as a back ground thread
|
45
|
+
- command accepts option arguments
|
46
|
+
|
31
47
|
## Contributing
|
32
48
|
|
33
49
|
1. Fork it ( https://github.com/[my-github-username]/ruboty-exec_command/fork )
|
data/commands/example/hello
CHANGED
@@ -4,8 +4,53 @@ module Ruboty
|
|
4
4
|
class Command < Ruboty::Actions::Base
|
5
5
|
def call
|
6
6
|
# TODO: add timeout
|
7
|
-
|
8
|
-
|
7
|
+
c = Ruboty::ExecCommand::Command.new(command_args: command_body)
|
8
|
+
run_and_monitor(c)
|
9
|
+
end
|
10
|
+
|
11
|
+
def command_slot
|
12
|
+
message.robot.brain.data[:command_slot] ||= Ruboty::ExecCommand::CommandSlot.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def list_commands
|
16
|
+
message.reply(command_slot.list_commands)
|
17
|
+
end
|
18
|
+
|
19
|
+
def kill_command
|
20
|
+
# TODO: command list lock
|
21
|
+
# kill running process, command is "kill command <index>"
|
22
|
+
killed = command_slot.kill(message.body.split.last.to_i)
|
23
|
+
|
24
|
+
if killed.nil?
|
25
|
+
message.reply("Command [#{message.body.split.last}] not found.")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_and_monitor(comm)
|
30
|
+
pid = command_slot.run(comm)
|
31
|
+
message.reply("[#{comm.command_name}] invoked.")
|
32
|
+
|
33
|
+
# Waiter thread
|
34
|
+
thread = Thread.new do
|
35
|
+
ignore_pid, status = Process.wait2(pid)
|
36
|
+
command_slot.forget(pid)
|
37
|
+
|
38
|
+
if status.exitstatus == 0
|
39
|
+
message.reply("[#{comm.command_name}] completed successfully.")
|
40
|
+
message.reply(comm.stdout_log.chomp)
|
41
|
+
elsif status.signaled?
|
42
|
+
message.reply("[#{comm.command_name}] killed by signal #{status.termsig}")
|
43
|
+
else
|
44
|
+
message.reply("[#{comm.command_name}] exit status with #{status}\n" +
|
45
|
+
comm.stdout_log +
|
46
|
+
"stderr: " + comm.stderr_log.chomp
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if ENV['RUBOTY_ENV'] == 'blocked_test'
|
52
|
+
thread.join
|
53
|
+
end
|
9
54
|
end
|
10
55
|
|
11
56
|
def robot_prefix_pattern
|
@@ -3,8 +3,16 @@ module Ruboty
|
|
3
3
|
class Command
|
4
4
|
|
5
5
|
class << self
|
6
|
+
def ruboty_root
|
7
|
+
"#{ENV['RUBOTY_ROOT'] || Dir.pwd}"
|
8
|
+
end
|
9
|
+
|
6
10
|
def command_root
|
7
|
-
"#{
|
11
|
+
"#{ruboty_root}/commands"
|
12
|
+
end
|
13
|
+
|
14
|
+
def log_root
|
15
|
+
"#{ruboty_root}/logs/exec_command"
|
8
16
|
end
|
9
17
|
|
10
18
|
def command?(path)
|
@@ -27,34 +35,93 @@ module Ruboty
|
|
27
35
|
def initialize(args={})
|
28
36
|
args = { absolute_path: nil, command_args: nil }.merge(args)
|
29
37
|
@absolute_path = args[:absolute_path]
|
30
|
-
@command_args = args[:command_args]
|
38
|
+
@command_args = args[:command_args].split if not args[:command_args].nil?
|
39
|
+
@pid = nil
|
40
|
+
@start_at = nil
|
31
41
|
end
|
32
42
|
|
43
|
+
attr_reader :pid
|
44
|
+
attr_reader :start_at
|
45
|
+
|
33
46
|
def absolute_path
|
34
|
-
@absolute_path ||= command2path
|
47
|
+
@absolute_path ||= command2path[0]
|
35
48
|
end
|
36
49
|
|
37
50
|
def relative_path
|
38
51
|
@relative_path ||= absolute_path.sub(/^#{self.class.command_root}\//,"")
|
39
52
|
end
|
40
53
|
|
41
|
-
def
|
42
|
-
@
|
54
|
+
def command_name
|
55
|
+
@command_name ||= relative_path.gsub('/', ' ')
|
56
|
+
end
|
57
|
+
|
58
|
+
def __command2path(path, args)
|
59
|
+
if self.class.command?(path)
|
60
|
+
[path, args]
|
61
|
+
else
|
62
|
+
if args == []
|
63
|
+
# command not found
|
64
|
+
return ["", ""]
|
65
|
+
else
|
66
|
+
__command2path("#{path}/#{args[0]}", args.slice(1, args.length))
|
67
|
+
end
|
68
|
+
end
|
43
69
|
end
|
44
70
|
|
45
71
|
def command2path
|
46
72
|
path = self.class.command_root
|
47
|
-
@command_args
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
73
|
+
__command2path "#{path}/#{@command_args[0]}",
|
74
|
+
@command_args.slice(1, @command_args.length)
|
75
|
+
end
|
76
|
+
|
77
|
+
def opt_args
|
78
|
+
@opt_args ||= command2path[1]
|
79
|
+
end
|
80
|
+
|
81
|
+
def this_month
|
82
|
+
Time.now.strftime "%Y-%m"
|
83
|
+
end
|
84
|
+
|
85
|
+
def this_time
|
86
|
+
Time.now.strftime "%Y-%m-%d_%H:%M:%S"
|
87
|
+
end
|
88
|
+
|
89
|
+
def log_dir
|
90
|
+
d = "#{self.class.log_root}/#{this_month}"
|
91
|
+
FileUtils.mkdir_p(d) if not Dir.exists?(d)
|
92
|
+
d
|
93
|
+
end
|
94
|
+
|
95
|
+
def output_file_name
|
96
|
+
%Q(#{log_dir}/#{command_name.gsub(" ", "_")}-#{this_time})
|
97
|
+
end
|
98
|
+
|
99
|
+
def output_files
|
100
|
+
# return temporary output file IO objects [stdout, stderr]
|
101
|
+
["#{output_file_name}.out", "#{output_file_name}.err"]
|
102
|
+
end
|
103
|
+
|
104
|
+
def stdout_log
|
105
|
+
# return contents of stdout
|
106
|
+
File.open(output_files[0]).read
|
107
|
+
end
|
108
|
+
|
109
|
+
def stderr_log
|
110
|
+
# return contents of stderr
|
111
|
+
File.open(output_files[1]).read
|
52
112
|
end
|
53
113
|
|
54
114
|
def run(args=[])
|
55
115
|
`#{absolute_path} #{args.join(" ")}`
|
56
116
|
end
|
57
117
|
|
118
|
+
def run_bg(args=[])
|
119
|
+
stdout, stderr = output_files
|
120
|
+
@start_at = this_time
|
121
|
+
@pid = Process.spawn(%Q(#{absolute_path} #{args.join(" ")}),
|
122
|
+
pgroup: true, out: stdout, err: stderr)
|
123
|
+
end
|
124
|
+
|
58
125
|
def help
|
59
126
|
run(args=['-h']).chomp
|
60
127
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Ruboty
|
2
|
+
module ExecCommand
|
3
|
+
class CommandSlot
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@commands = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def running_commands
|
10
|
+
@commands
|
11
|
+
end
|
12
|
+
|
13
|
+
def remember(comm)
|
14
|
+
# remember
|
15
|
+
# comm: command object
|
16
|
+
# TODO: add owner info
|
17
|
+
@commands << comm
|
18
|
+
end
|
19
|
+
|
20
|
+
def forget(pid)
|
21
|
+
# remove thread object
|
22
|
+
@commands.delete_if do |c|
|
23
|
+
c.pid == pid
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def command_in_list(idx_or_pid)
|
28
|
+
found = @commands.index { |c| c.pid == idx_or_pid }
|
29
|
+
|
30
|
+
if found.nil?
|
31
|
+
i = idx_or_pid.to_i
|
32
|
+
num_commands = @commands.size
|
33
|
+
if i <= 0 or i > num_commands
|
34
|
+
nil
|
35
|
+
else
|
36
|
+
@commands[i-1]
|
37
|
+
end
|
38
|
+
else
|
39
|
+
@commands[found]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def run(command)
|
44
|
+
remember(command)
|
45
|
+
command.run_bg(command.opt_args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def list_commands
|
49
|
+
if @commands.size == 0
|
50
|
+
"No command running."
|
51
|
+
else
|
52
|
+
number = 0
|
53
|
+
@commands.map do |c|
|
54
|
+
number += 1
|
55
|
+
"#{number}: #{c.command_name} (PID[#{c.pid}], started at #{c.start_at})\n"
|
56
|
+
end.join.chomp
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def kill(idx_or_pid)
|
61
|
+
command = command_in_list(idx_or_pid)
|
62
|
+
unless command.nil?
|
63
|
+
Process.kill(-9, command.pid) # kill process group
|
64
|
+
forget(command.pid)
|
65
|
+
end
|
66
|
+
command
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/ruboty/exec_command.rb
CHANGED
@@ -3,20 +3,35 @@ require "ruboty/exec_command/actions/command"
|
|
3
3
|
module Ruboty
|
4
4
|
module Handlers
|
5
5
|
class Command < Base
|
6
|
+
|
7
|
+
on(/command list/i, name: "list_commands",
|
8
|
+
description: "List running commands in background")
|
9
|
+
|
10
|
+
on(/command kill/i, name: "kill_command",
|
11
|
+
description: "command kill <index|PID> ")
|
12
|
+
|
6
13
|
# Registering commands. Each command is located
|
7
14
|
# under "commands" directory. The path name to the
|
8
15
|
# executable command is gonna be a command name.
|
9
|
-
# i.e. commands/server/monitor =>
|
16
|
+
# i.e. commands/server/monitor => /server monitor/
|
10
17
|
# The command should return a usage with -h option
|
11
18
|
def self.register_commands
|
12
19
|
Ruboty::ExecCommand::Command.all.each do |e|
|
13
|
-
on /#{e.
|
20
|
+
on /#{e.command_name}/i, name: "command_handler", description: e.help
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
17
24
|
def command_handler(message)
|
18
25
|
Ruboty::ExecCommand::Actions::Command.new(message).call
|
19
26
|
end
|
27
|
+
|
28
|
+
def list_commands(message)
|
29
|
+
Ruboty::ExecCommand::Actions::Command.new(message).list_commands
|
30
|
+
end
|
31
|
+
|
32
|
+
def kill_command(message)
|
33
|
+
Ruboty::ExecCommand::Actions::Command.new(message).kill_command
|
34
|
+
end
|
20
35
|
end
|
21
36
|
end
|
22
37
|
end
|
data/ruboty-exec_command.gemspec
CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "ruboty"
|
22
|
-
spec.add_runtime_dependency "systemu"
|
23
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
24
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
24
|
spec.add_development_dependency "rspec", "2.14.1"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Ruboty::ExecCommand::CommandSlot do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@slot = Ruboty::ExecCommand::CommandSlot.new
|
7
|
+
@command = Ruboty::ExecCommand::Command.new(command_args: "example sleep")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#run" do
|
11
|
+
it "should count up number of commands" do
|
12
|
+
expect { @slot.run(@command) }.to change {
|
13
|
+
@slot.running_commands.count
|
14
|
+
}.from(0).to(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return pid" do
|
18
|
+
expect(@slot.run(@command)).to be > 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe Ruboty::ExecCommand::CommandSlot do
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@slot = Ruboty::ExecCommand::CommandSlot.new
|
28
|
+
@command = Ruboty::ExecCommand::Command.new(command_args: "example sleep")
|
29
|
+
@slot.remember(@command)
|
30
|
+
@command.run_bg(["1"])
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#forget" do
|
34
|
+
it "should count down number of commnads" do
|
35
|
+
expect { @command.pid }.not_to be_nil
|
36
|
+
expect { @slot.forget(@command.pid) }.to change {@slot.running_commands.count}.from(1).to(0)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#command_in_list" do
|
41
|
+
it "should return command with pid" do
|
42
|
+
expect(@slot.command_in_list(@command.pid).pid).to eq(@command.pid)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return command with index" do
|
46
|
+
expect(@slot.command_in_list(1).pid).to eq(@command.pid)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -34,15 +34,16 @@ describe Ruboty::ExecCommand::Command do
|
|
34
34
|
|
35
35
|
describe "#command" do
|
36
36
|
it "should return command name" do
|
37
|
-
expect(@e.
|
37
|
+
expect(@e.command_name).to eq("a b")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
# convert command args -> absolute path, so this is a test for ruboty action
|
42
43
|
describe Ruboty::ExecCommand::Command do
|
43
|
-
before do
|
44
|
+
before(:each) do
|
44
45
|
ENV['RUBOTY_ROOT'] = Dir.pwd
|
45
|
-
@c = Ruboty::ExecCommand::Command.new(command_args: "example hello hoge")
|
46
|
+
@c = Ruboty::ExecCommand::Command.new(command_args: "example hello hoge -l fuga")
|
46
47
|
end
|
47
48
|
|
48
49
|
describe "#absolute_path" do
|
@@ -50,4 +51,10 @@ describe Ruboty::ExecCommand::Command do
|
|
50
51
|
expect(@c.absolute_path).to eq("#{ENV['RUBOTY_ROOT']}/commands/example/hello")
|
51
52
|
end
|
52
53
|
end
|
54
|
+
|
55
|
+
describe "#opt_args" do
|
56
|
+
it "should return only command options" do
|
57
|
+
expect(@c.opt_args).to eq(["hoge", "-l", "fuga"])
|
58
|
+
end
|
59
|
+
end
|
53
60
|
end
|
@@ -15,32 +15,117 @@ describe Ruboty::Handlers::Command do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:said) do
|
18
|
-
"@ruboty example hello"
|
18
|
+
"@ruboty example hello world"
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:said_to_sleep) do
|
22
|
+
"@ruboty example sleep 1"
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:said_to_kill) do
|
26
|
+
"@ruboty command kill 1"
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:said_to_list) do
|
30
|
+
"@ruboty command list"
|
19
31
|
end
|
20
32
|
|
21
33
|
let(:replied) do
|
22
|
-
"hello
|
34
|
+
"[example hello] invoked."
|
23
35
|
end
|
24
36
|
|
25
|
-
|
26
|
-
|
37
|
+
let(:replied_sleep) do
|
38
|
+
"[example sleep] invoked."
|
27
39
|
end
|
28
40
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
41
|
+
let(:replied_success) do
|
42
|
+
"[example hello] completed successfully."
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:replied_stdout) do
|
46
|
+
"hello world!"
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:replied_after_kill) do
|
50
|
+
"[example sleep] killed by signal 9"
|
51
|
+
end
|
52
|
+
|
53
|
+
def reply_data(body, original_body)
|
54
|
+
{
|
55
|
+
body: body,
|
33
56
|
from: to,
|
34
57
|
to: from,
|
35
58
|
original: {
|
36
|
-
body:
|
59
|
+
body: original_body,
|
37
60
|
from: from,
|
38
61
|
robot: robot,
|
39
62
|
to: to,
|
40
|
-
}
|
41
|
-
|
63
|
+
}
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
before do
|
68
|
+
ENV['RUBOTY_ROOT'] = Dir.pwd
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#command_handler" do
|
72
|
+
before do
|
73
|
+
# block waiter thread in Ruboty::ExecCommand::Actions::Command.run_and_monitor
|
74
|
+
ENV['RUBOTY_ENV'] = "blocked_test"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "run example command" do
|
78
|
+
robot.should_receive(:say).with(reply_data(replied, said))
|
79
|
+
robot.should_receive(:say).with(reply_data(replied_success, said))
|
80
|
+
robot.should_receive(:say).with(reply_data(replied_stdout, said))
|
42
81
|
robot.receive(body: said, from: from, to: to)
|
43
82
|
end
|
83
|
+
|
84
|
+
after do
|
85
|
+
ENV['RUBOTY_ENV'] = "test"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#kill_command" do
|
90
|
+
it "run kill command" do
|
91
|
+
thread = Thread.new do
|
92
|
+
ENV['RUBOTY_ENV'] = "blocked_test"
|
93
|
+
robot.should_receive(:say).with(reply_data(replied_sleep, said_to_sleep))
|
94
|
+
robot.should_receive(:say).with(reply_data(replied_after_kill, said_to_sleep))
|
95
|
+
robot.receive(body: said_to_sleep, from: from, to: to)
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# Test command invoked
|
100
|
+
expect { robot.receive(body: said_to_kill, from: from, to: to) }.to change {
|
101
|
+
robot.brain.data[:command_slot].running_commands.count}.from(1).to(0)
|
102
|
+
|
103
|
+
# Wait killed message
|
104
|
+
thread.join
|
105
|
+
end
|
106
|
+
|
107
|
+
after do
|
108
|
+
ENV['RUBOTY_ENV'] = "test"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#list_command" do
|
113
|
+
it "list running commands" do
|
114
|
+
robot.receive(body: said_to_sleep, from: from, to: to)
|
115
|
+
robot.receive(body: said_to_sleep, from: from, to: to)
|
116
|
+
|
117
|
+
comm1 = robot.brain.data[:command_slot].running_commands[0]
|
118
|
+
comm2 = robot.brain.data[:command_slot].running_commands[1]
|
119
|
+
body1="1: example sleep (PID[#{comm1.pid}], started at #{comm1.start_at})\n"
|
120
|
+
body2="2: example sleep (PID[#{comm2.pid}], started at #{comm2.start_at})"
|
121
|
+
|
122
|
+
robot.should_receive(:say).with(reply_data(body1+body2, said_to_list))
|
123
|
+
robot.receive(body: said_to_list, from: from, to: to)
|
124
|
+
end
|
125
|
+
|
126
|
+
after do
|
127
|
+
ENV['RUBOTY_ENV'] = "test"
|
128
|
+
end
|
44
129
|
end
|
45
130
|
|
46
131
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruboty-exec_command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nakai Tooru
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruboty
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: systemu
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,13 +122,16 @@ files:
|
|
136
122
|
- README.md
|
137
123
|
- Rakefile
|
138
124
|
- commands/example/hello
|
125
|
+
- commands/example/sleep
|
139
126
|
- lib/ruboty/exec_command.rb
|
140
127
|
- lib/ruboty/exec_command/actions/command.rb
|
141
128
|
- lib/ruboty/exec_command/command.rb
|
129
|
+
- lib/ruboty/exec_command/command_slot.rb
|
142
130
|
- lib/ruboty/exec_command/version.rb
|
143
131
|
- lib/ruboty/handlers/command.rb
|
144
132
|
- ruboty-exec_command.gemspec
|
145
|
-
- spec/lib/ruboty/
|
133
|
+
- spec/lib/ruboty/exec_command/command_slot_spec.rb
|
134
|
+
- spec/lib/ruboty/exec_command/command_spec.rb
|
146
135
|
- spec/lib/ruboty/handlers/command_spec.rb
|
147
136
|
- spec/spec_helper.rb
|
148
137
|
homepage: ''
|
@@ -170,6 +159,7 @@ signing_key:
|
|
170
159
|
specification_version: 4
|
171
160
|
summary: Add command to ruboty as a handler
|
172
161
|
test_files:
|
173
|
-
- spec/lib/ruboty/
|
162
|
+
- spec/lib/ruboty/exec_command/command_slot_spec.rb
|
163
|
+
- spec/lib/ruboty/exec_command/command_spec.rb
|
174
164
|
- spec/lib/ruboty/handlers/command_spec.rb
|
175
165
|
- spec/spec_helper.rb
|