ruboty-exec_command 0.0.2 → 0.1.0
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.
- 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
|