rider-server 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.build.yml +23 -0
- data/.ruby-version +1 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +44 -0
- data/Rakefile +12 -0
- data/exe/rider-server +11 -0
- data/lib/rider_server/core_ext/array.rb +32 -0
- data/lib/rider_server/core_ext/hash.rb +14 -0
- data/lib/rider_server/core_ext/object.rb +18 -0
- data/lib/rider_server/core_ext/string.rb +18 -0
- data/lib/rider_server/core_ext/symbol.rb +14 -0
- data/lib/rider_server/errors.rb +16 -0
- data/lib/rider_server/exception_extension.rb +34 -0
- data/lib/rider_server/inspect.rb +148 -0
- data/lib/rider_server/logger.rb +13 -0
- data/lib/rider_server/operation.rb +69 -0
- data/lib/rider_server/operations.rb +136 -0
- data/lib/rider_server/ops/clone.rb +32 -0
- data/lib/rider_server/ops/close.rb +25 -0
- data/lib/rider_server/ops/completions.rb +100 -0
- data/lib/rider_server/ops/eval.rb +62 -0
- data/lib/rider_server/ops/inspect.rb +121 -0
- data/lib/rider_server/ops/inspect_exception.rb +47 -0
- data/lib/rider_server/ops/interrupt.rb +30 -0
- data/lib/rider_server/ops/load_path.rb +20 -0
- data/lib/rider_server/ops/lookup.rb +83 -0
- data/lib/rider_server/ops/ls_exceptions.rb +29 -0
- data/lib/rider_server/ops/ls_services.rb +19 -0
- data/lib/rider_server/ops/ls_sessions.rb +52 -0
- data/lib/rider_server/ops/service.rb +43 -0
- data/lib/rider_server/ops/set_namespace.rb +79 -0
- data/lib/rider_server/ops/set_namespace_variable.rb +80 -0
- data/lib/rider_server/ops/stdin.rb +20 -0
- data/lib/rider_server/ops/toggle_catch_all_exceptions.rb +27 -0
- data/lib/rider_server/response.rb +69 -0
- data/lib/rider_server/server.rb +104 -0
- data/lib/rider_server/service.rb +20 -0
- data/lib/rider_server/services/capture_exceptions.rb +62 -0
- data/lib/rider_server/services/capture_io.rb +302 -0
- data/lib/rider_server/services/rails.rb +129 -0
- data/lib/rider_server/session.rb +190 -0
- data/lib/rider_server/transports/bencode.rb +0 -0
- data/lib/rider_server/utils.rb +63 -0
- data/lib/rider_server/version.rb +12 -0
- data/lib/rider_server/workspace.rb +111 -0
- data/lib/rider_server.rb +5 -0
- metadata +122 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class Close < Operation
|
7
|
+
documentation "Close a specific session."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :session, :string, "The session to close", required: true
|
11
|
+
|
12
|
+
# Handle the close operation, session will be nil
|
13
|
+
def handle(session, operation)
|
14
|
+
response = Response.new(operation)
|
15
|
+
|
16
|
+
session_id = operation["session"]
|
17
|
+
|
18
|
+
controller.delete_session(session_id)
|
19
|
+
|
20
|
+
response.status("done")
|
21
|
+
response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
require "rider_server/inspect"
|
4
|
+
|
5
|
+
module RiderServer
|
6
|
+
module Ops
|
7
|
+
class Completions < Operation
|
8
|
+
documentation "Get completions for a given prefix"
|
9
|
+
|
10
|
+
argument :id, :string, "The request id", required: true
|
11
|
+
argument :prefix, :string, "The prefix to complete", required: true
|
12
|
+
argument :ns, :string, "The namespace to search for completions"
|
13
|
+
|
14
|
+
def initialize(*args)
|
15
|
+
@workspace = Workspace.new
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle(session, operation)
|
20
|
+
response = Response.new(operation)
|
21
|
+
|
22
|
+
prefix = operation["prefix"]
|
23
|
+
log.info "prefix: #{prefix}"
|
24
|
+
ns = operation["ns"]
|
25
|
+
# options = operation["options"]
|
26
|
+
|
27
|
+
log.info "prefix: #{prefix}"
|
28
|
+
ns_object = @workspace.lookup_module(ns)
|
29
|
+
log.info "ns_object: #{ns_object}"
|
30
|
+
|
31
|
+
response.set("completions", lookup_module(prefix, ns_object))
|
32
|
+
log.info "completions: #{response["completions"]}"
|
33
|
+
|
34
|
+
response.status("done")
|
35
|
+
response
|
36
|
+
rescue ScriptError, StandardError => e
|
37
|
+
log.error "Error in completions: #{e}"
|
38
|
+
log.error e.backtrace.join("\n")
|
39
|
+
raise e
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def lookup_module(module_name, klass = ::Object)
|
45
|
+
node = parse_string(module_name)
|
46
|
+
case node.type
|
47
|
+
when :const
|
48
|
+
ns = lookup_module_ast(node.children.first, klass)
|
49
|
+
prefix = node.children.last
|
50
|
+
all_constants(ns, prefix) + all_methods(ns, prefix)
|
51
|
+
when :send
|
52
|
+
ns = lookup_module_ast(node.children.first, klass)
|
53
|
+
prefix = node.children.last
|
54
|
+
all_methods(ns, prefix)
|
55
|
+
else
|
56
|
+
[]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_string(string)
|
61
|
+
buffer = Parser::Source::Buffer.new("(string)")
|
62
|
+
buffer.source = string
|
63
|
+
Parser::CurrentRuby.new.parse(buffer)
|
64
|
+
end
|
65
|
+
|
66
|
+
def lookup_module_ast(node, klass = ::Object)
|
67
|
+
case node.type
|
68
|
+
when :cbase
|
69
|
+
::Object
|
70
|
+
when :const
|
71
|
+
if node.children.first.nil?
|
72
|
+
klass.const_get(node.children.last)
|
73
|
+
else
|
74
|
+
lookup_module_ast(node.children.first, klass).const_get(node.children.last)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
raise ModuleLookupError, "Unknown node type #{node.type}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def all_constants(ns_object, prefix)
|
82
|
+
ns_object.constants.grep(/^#{prefix}/).map do |constant|
|
83
|
+
{
|
84
|
+
"candidate" => constant.to_s,
|
85
|
+
"type" => "constant"
|
86
|
+
}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def all_methods(ns_object, prefix)
|
91
|
+
ns_object.methods.grep(/^#{prefix}/).map do |method|
|
92
|
+
{
|
93
|
+
"candidate" => method.to_s,
|
94
|
+
"type" => "method"
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
require "rider_server/utils"
|
4
|
+
|
5
|
+
module RiderServer
|
6
|
+
module Ops
|
7
|
+
class Eval < Operation
|
8
|
+
documentation "Evaluate a string of code"
|
9
|
+
|
10
|
+
argument :id, :string, "The request id", required: true
|
11
|
+
argument :code, :string, "The code to evaluate"
|
12
|
+
argument :ns, :string, "The namespace to evaluate the code in"
|
13
|
+
argument :file, :string, "The file the code is from"
|
14
|
+
argument :line, :integer, "The line number the code is from"
|
15
|
+
|
16
|
+
def handle(session, operation)
|
17
|
+
# TODO should do something if the session is nil
|
18
|
+
|
19
|
+
response = Response.new(operation)
|
20
|
+
|
21
|
+
# Abort if there is an evaluation with the same id
|
22
|
+
if session.running_evaluation?(operation["id"])
|
23
|
+
msg = "Evaluation already in progress for #{operation["id"]}"
|
24
|
+
log.warn(msg)
|
25
|
+
response.set("value", msg)
|
26
|
+
response.status("eval-error", "done")
|
27
|
+
send_response(response)
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
session.push_history(operation)
|
32
|
+
code = operation["code"]
|
33
|
+
ns = operation["ns"]
|
34
|
+
file = operation["file"] || ""
|
35
|
+
line = operation["line"] || 0
|
36
|
+
|
37
|
+
eval_thread = Thread.new do
|
38
|
+
begin
|
39
|
+
value = session.workspace.evaluate(code, ns, file, line)
|
40
|
+
response.set("value", Utils.rider_inspect(value))
|
41
|
+
response.set("ns", session.workspace.evaluate("inspect"))
|
42
|
+
response.status("done")
|
43
|
+
session.add_result(operation["id"], value)
|
44
|
+
send_response(response)
|
45
|
+
rescue EvalInterrupt, ScriptError, StandardError => e
|
46
|
+
response.set("ex", e.inspect)
|
47
|
+
response.set("ns", session.workspace.evaluate("inspect"))
|
48
|
+
response.status("eval-error", "done")
|
49
|
+
exception_id = session.add_exception(operation["id"], e)
|
50
|
+
response.set("rider/exception-id", exception_id)
|
51
|
+
send_response(response)
|
52
|
+
end
|
53
|
+
|
54
|
+
session.remove_evaluation(operation["id"])
|
55
|
+
end
|
56
|
+
|
57
|
+
session.add_evaluation(operation["id"], eval_thread)
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require "rider_server/inspect"
|
2
|
+
require "rider_server/operation"
|
3
|
+
require "rider_server/response"
|
4
|
+
require "rider_server/utils"
|
5
|
+
|
6
|
+
module RiderServer
|
7
|
+
module Ops
|
8
|
+
class Inspect < Operation
|
9
|
+
documentation "Inspect an object"
|
10
|
+
|
11
|
+
argument :id, :string, "The request id", required: true
|
12
|
+
argument :location, :array, "The location of the object to inspect"
|
13
|
+
|
14
|
+
def handle(session, operation)
|
15
|
+
response = Response.new(operation)
|
16
|
+
location = operation["location"]
|
17
|
+
raise "Location is required" if location.nil? || location.empty?
|
18
|
+
|
19
|
+
value = traverse_location(location, nil, session)
|
20
|
+
response.set("name", Utils.rider_inspect(value))
|
21
|
+
|
22
|
+
if value.is_a?(Array)
|
23
|
+
value = value.map.with_index do |item, index|
|
24
|
+
{
|
25
|
+
"name" => item.to_s,
|
26
|
+
"value" => Utils.rider_inspect(item),
|
27
|
+
"inspect-location" => "rider_array_item:#{index}"
|
28
|
+
}
|
29
|
+
end
|
30
|
+
response.set("value-array", value)
|
31
|
+
elsif value.is_a?(Hash)
|
32
|
+
value = value.map do |key, value|
|
33
|
+
[
|
34
|
+
{
|
35
|
+
"name" => key.to_s,
|
36
|
+
"value" => Utils.rider_inspect(key),
|
37
|
+
"inspect-location" => "rider_hash_key:#{key.hash}"
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"name" => value.to_s,
|
41
|
+
"value" => Utils.rider_inspect(value),
|
42
|
+
"inspect-location" => "rider_hash_value:#{key.hash}"
|
43
|
+
}
|
44
|
+
]
|
45
|
+
end
|
46
|
+
response.set("value-hash", value)
|
47
|
+
elsif value.is_a?(String)
|
48
|
+
response.set("value", value.inspect)
|
49
|
+
elsif value.is_a?(Numeric)
|
50
|
+
response.set("value", value.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
response.set("inspect-location", location)
|
54
|
+
|
55
|
+
response.set("class", RiderServer::Inspect.class(value))
|
56
|
+
response.set("ancestors", RiderServer::Inspect.ancestors(value))
|
57
|
+
response.set("constants", RiderServer::Inspect.constants(value))
|
58
|
+
response.set("methods", RiderServer::Inspect.methods(value))
|
59
|
+
response.set("instance-variables", RiderServer::Inspect.instance_variables(value))
|
60
|
+
response.set("instance-methods", RiderServer::Inspect.instance_methods(value))
|
61
|
+
response.set("class-variables", RiderServer::Inspect.class_variables(value))
|
62
|
+
response.status("done")
|
63
|
+
response
|
64
|
+
end
|
65
|
+
|
66
|
+
def traverse_location(location, ctx, session)
|
67
|
+
loc = location.first
|
68
|
+
locs = location.drop(1)
|
69
|
+
|
70
|
+
if locs.empty?
|
71
|
+
lookup_object(loc, ctx, session)
|
72
|
+
else
|
73
|
+
traverse_location(locs, lookup_object(loc, ctx, session), session)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def lookup_object(loc, ctx, session)
|
78
|
+
lookup, identifier = loc.split(":", 2)
|
79
|
+
|
80
|
+
case lookup
|
81
|
+
when "rider_main"
|
82
|
+
"main"
|
83
|
+
when "rider_history"
|
84
|
+
rider_history(identifier, nil, session)
|
85
|
+
when "rider_exception"
|
86
|
+
rider_exception(identifier, nil, session)
|
87
|
+
when "rider_stackframe_variable"
|
88
|
+
frame_id, local_var = identifier.split(":", 2)
|
89
|
+
ctx.__rider_bindings_stack[frame_id.to_i].local_variable_get(local_var)
|
90
|
+
when "rider_array_item"
|
91
|
+
ctx[identifier.to_i]
|
92
|
+
when "rider_hash_key"
|
93
|
+
hash = identifier.to_i
|
94
|
+
ctx.keys.find { |key| key.hash == hash }
|
95
|
+
when "rider_hash_value"
|
96
|
+
hash = identifier.to_i
|
97
|
+
key = ctx.keys.find { |key| key.hash == hash }
|
98
|
+
ctx.fetch(key)
|
99
|
+
when "toplevel_const_get"
|
100
|
+
Object.const_get(identifier)
|
101
|
+
when "instance_variable_get"
|
102
|
+
ctx.instance_variable_get(identifier)
|
103
|
+
when "const_get"
|
104
|
+
ctx.const_get(identifier)
|
105
|
+
when "ancestor_find"
|
106
|
+
ctx.class.ancestors.find { |item| item.to_s == identifier }
|
107
|
+
else
|
108
|
+
raise "Unknown inspect function: #{lookup}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def rider_history(id, ctx, session)
|
113
|
+
session.get_result(id)
|
114
|
+
end
|
115
|
+
|
116
|
+
def rider_exception(id, ctx, session)
|
117
|
+
session.get_exception(id)["exception"]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class InspectException < Operation
|
7
|
+
documentation "Inspect an exception."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :"exception-id", :string, "The exception id"
|
11
|
+
|
12
|
+
def handle(session, operation)
|
13
|
+
response = Response.new(operation)
|
14
|
+
exception_id = operation["exception-id"]
|
15
|
+
|
16
|
+
value = session.get_exception(exception_id)
|
17
|
+
response.set("inspect-location", value["id"])
|
18
|
+
response.set("exception-id", value["id"])
|
19
|
+
response.set("source-operation-id", value["operation_id"])
|
20
|
+
response.set("created-at", value["created_at"].to_s)
|
21
|
+
|
22
|
+
exception = value["exception"]
|
23
|
+
response.set("value", exception.inspect)
|
24
|
+
response.set("stacktrace", encode_stacktrace(exception, exception_id))
|
25
|
+
|
26
|
+
response.status("done")
|
27
|
+
response
|
28
|
+
end
|
29
|
+
|
30
|
+
def encode_stacktrace(exception, exception_id)
|
31
|
+
exception.backtrace.zip(exception.__rider_bindings_stack).map.with_index do |(line, frame), frame_id|
|
32
|
+
{
|
33
|
+
"line" => line,
|
34
|
+
"inspect-location" => ["rider_exception:#{exception_id}", "rider_stackframe:#{frame_id}"],
|
35
|
+
"frame" => (frame&.local_variables || []).map do |var|
|
36
|
+
{
|
37
|
+
"name" => var.to_s,
|
38
|
+
"value" => Utils.rider_inspect(frame.local_variable_get(var)),
|
39
|
+
"inspect-location" => ["rider_exception:#{exception_id}", "rider_stackframe_variable:#{frame_id}:#{var}"]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class Interrupt < Operation
|
7
|
+
documentation "Interrupts the evaluation of a session."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :"interrupt-id", :string, "The ID of the evaluation to interrupt.", required: true
|
11
|
+
|
12
|
+
def handle(session, operation)
|
13
|
+
# TODO should do something if the session is nil
|
14
|
+
|
15
|
+
if operation["interrupt-id"].nil? || operation["interrupt-id"].empty?
|
16
|
+
if session.evaluations.empty?
|
17
|
+
raise ArgumentError, "No evaluations to interrupt"
|
18
|
+
end
|
19
|
+
session.interrupt_evaluation(session.evaluations.keys.max)
|
20
|
+
else
|
21
|
+
session.interrupt_evaluation(operation["interrupt-id"])
|
22
|
+
end
|
23
|
+
|
24
|
+
response = Response.new(operation)
|
25
|
+
response.status("interrupted", "done")
|
26
|
+
response
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class LoadPath < Operation
|
7
|
+
documentation "Return the current load path."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
|
11
|
+
def handle(session, operation)
|
12
|
+
response = Response.new(operation)
|
13
|
+
load_path = session.workspace.evaluate("$LOAD_PATH", "main")
|
14
|
+
response.set("load-path", load_path)
|
15
|
+
response.status("done")
|
16
|
+
response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
require "rider_server/inspect"
|
4
|
+
|
5
|
+
module RiderServer
|
6
|
+
module Ops
|
7
|
+
class Lookup < Operation
|
8
|
+
documentation "Get completions for a given string"
|
9
|
+
|
10
|
+
argument :id, :string, "The request id", required: true
|
11
|
+
argument :sym, :string, "The symbol to lookup", required: true
|
12
|
+
argument :ns, :string, "The namespace to search for completions"
|
13
|
+
|
14
|
+
def initialize(*args)
|
15
|
+
@workspace = Workspace.new
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle(session, operation)
|
20
|
+
response = Response.new(operation)
|
21
|
+
ns = operation["ns"]
|
22
|
+
sym = operation["sym"]
|
23
|
+
|
24
|
+
ns_object = @workspace.lookup_module(ns)
|
25
|
+
|
26
|
+
method_type = nil
|
27
|
+
if sym.include?("#")
|
28
|
+
sym, method = sym.split("#")
|
29
|
+
method_type = :instance
|
30
|
+
method = method.to_sym
|
31
|
+
elsif sym.start_with?("self.class")
|
32
|
+
method = sym.split(".").last
|
33
|
+
method_type = :class
|
34
|
+
method = method.to_sym
|
35
|
+
elsif sym.include?(".")
|
36
|
+
sym, method = sym.split(".")
|
37
|
+
method_type = :class
|
38
|
+
method = method.to_sym
|
39
|
+
end
|
40
|
+
|
41
|
+
if sym.include?("::")
|
42
|
+
ns_object = lookup_ns(sym.split("::"), ns_object)
|
43
|
+
end
|
44
|
+
constant = ns_object
|
45
|
+
|
46
|
+
info = if sym.start_with?("@")
|
47
|
+
constant = ns_object.instance_variable_get(sym)
|
48
|
+
elsif method_type == :instance
|
49
|
+
RiderServer::Inspect.describe_method(constant.instance_method(method))
|
50
|
+
elsif method_type == :class
|
51
|
+
RiderServer::Inspect.describe_method(constant.method(method))
|
52
|
+
elsif constant.respond_to?(:instance_methods) && constant.instance_methods.include?(sym.to_sym)
|
53
|
+
RiderServer::Inspect.describe_method(constant.instance_method(sym))
|
54
|
+
elsif constant.respond_to?(:methods) && constant.methods.include?(sym.to_sym)
|
55
|
+
RiderServer::Inspect.describe_method(constant.method(sym))
|
56
|
+
else
|
57
|
+
{}
|
58
|
+
end
|
59
|
+
|
60
|
+
response.set("info", info)
|
61
|
+
response.status("done")
|
62
|
+
response
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def lookup_ns(module_name, klass = Object)
|
68
|
+
if module_name.start_with?("::")
|
69
|
+
klass = Module
|
70
|
+
module_name = module_name.delete_prefix("::")
|
71
|
+
end
|
72
|
+
|
73
|
+
path = module_name.split("::")
|
74
|
+
|
75
|
+
path.inject(klass) do |acc, elem|
|
76
|
+
acc.const_get(elem)
|
77
|
+
end
|
78
|
+
rescue NameError
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class LsExceptions < Operation
|
7
|
+
documentation "List all exceptions that have occurred in the session."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
|
11
|
+
def handle(session, operation)
|
12
|
+
response = Response.new(operation)
|
13
|
+
|
14
|
+
exceptions = session.exceptions.map do |item|
|
15
|
+
{
|
16
|
+
"id" => item["id"],
|
17
|
+
"operation-id" => item["operation_id"],
|
18
|
+
"created-at" => item["created_at"].iso8601,
|
19
|
+
"exception" => item["exception"].inspect
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
response.set("exceptions", exceptions)
|
24
|
+
response.status("done")
|
25
|
+
response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class LsServices < Operation
|
7
|
+
documentation "List all services."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
|
11
|
+
def handle(session, operation)
|
12
|
+
response = Response.new(operation)
|
13
|
+
response.set("services", session.list_services)
|
14
|
+
response.status("done")
|
15
|
+
response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class LsSessions < Operation
|
7
|
+
documentation "List all sessions"
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
|
11
|
+
def handle(session, operation)
|
12
|
+
response = Response.new(operation)
|
13
|
+
response.set("sessions", controller.sessions.map { |k, v| k })
|
14
|
+
response.set("rider/session-headings",
|
15
|
+
[
|
16
|
+
{
|
17
|
+
"id" => "id",
|
18
|
+
"name" => "ID",
|
19
|
+
"length" => 36
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"id" => "namespace_name",
|
23
|
+
"name" => "Namespace",
|
24
|
+
"length" => 25
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"id" => "history_items",
|
28
|
+
"name" => "History Items",
|
29
|
+
"length" => 5
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"id" => "exceptions",
|
33
|
+
"name" => "Exceptions",
|
34
|
+
"length" => 5
|
35
|
+
}
|
36
|
+
])
|
37
|
+
response.set("rider/sessions", controller.sessions.map { |k, v| session_summary(v) })
|
38
|
+
response.status("done")
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
42
|
+
def session_summary(session)
|
43
|
+
{
|
44
|
+
"id" => session.id,
|
45
|
+
"namespace_name" => session.workspace.namespace_name,
|
46
|
+
"history_items" => session.history.length.to_s,
|
47
|
+
"exceptions" => session.exceptions.length.to_s
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
module Ops
|
6
|
+
class Service < Operation
|
7
|
+
documentation "Control a Ruby service integration"
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :service, :string, "The name of the Ruby service to control", required: true
|
11
|
+
argument :state, :string, "The desired state of the service", required: true
|
12
|
+
|
13
|
+
def handle(session, operation)
|
14
|
+
response = Response.new(operation)
|
15
|
+
|
16
|
+
service = operation["service"]
|
17
|
+
state = operation["state"]
|
18
|
+
|
19
|
+
current_state = session.service_state(service)
|
20
|
+
|
21
|
+
case state
|
22
|
+
when "start"
|
23
|
+
raise "Service already running" if current_state == "running"
|
24
|
+
session.start_service(service, response.id)
|
25
|
+
response.set("rider/stream", "true")
|
26
|
+
when "stop"
|
27
|
+
raise "Can't stop service #{service}. It's not running." if current_state == "stopped"
|
28
|
+
session.stop_service(service)
|
29
|
+
response.status("done")
|
30
|
+
else
|
31
|
+
# TODO: throwing this exception will caues a "done" response
|
32
|
+
# to be sent, which will implicitly close the stream. It
|
33
|
+
# might make sense to handle this more gracefully here.
|
34
|
+
raise "Unknown state #{state}"
|
35
|
+
end
|
36
|
+
|
37
|
+
response.set("service", service)
|
38
|
+
response.set("state", session.service_state(service).to_s)
|
39
|
+
response
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|