rider-server 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 +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
|