rider-server 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.build.yml +3 -3
  3. data/CHANGELOG.md +17 -1
  4. data/README.rdoc +39 -0
  5. data/Rakefile +5 -0
  6. data/exe/rider-server +3 -3
  7. data/lib/rider_server/config.rb +76 -0
  8. data/lib/rider_server/core_ext/array.rb +3 -1
  9. data/lib/rider_server/core_ext/class.rb +5 -0
  10. data/lib/rider_server/core_ext/env.rb +14 -0
  11. data/lib/rider_server/core_ext/hash.rb +3 -1
  12. data/lib/rider_server/core_ext/kernel.rb +5 -0
  13. data/lib/rider_server/core_ext/module.rb +18 -0
  14. data/lib/rider_server/core_ext/object.rb +7 -1
  15. data/lib/rider_server/core_ext/string.rb +3 -1
  16. data/lib/rider_server/core_ext/symbol.rb +3 -1
  17. data/lib/rider_server/exception_extension.rb +2 -0
  18. data/lib/rider_server/inspect.rb +108 -32
  19. data/lib/rider_server/logger.rb +11 -4
  20. data/lib/rider_server/operation.rb +39 -20
  21. data/lib/rider_server/{ops → operations}/clone.rb +3 -2
  22. data/lib/rider_server/{ops → operations}/close.rb +3 -2
  23. data/lib/rider_server/operations/completions.rb +146 -0
  24. data/lib/rider_server/operations/lookup.rb +102 -0
  25. data/lib/rider_server/operations/ls_sessions.rb +51 -0
  26. data/lib/rider_server/operations/toggle_catch_all_exceptions.rb +24 -0
  27. data/lib/rider_server/operations.rb +42 -68
  28. data/lib/rider_server/request.rb +61 -0
  29. data/lib/rider_server/response.rb +10 -2
  30. data/lib/rider_server/server.rb +28 -16
  31. data/lib/rider_server/services/capture_exceptions.rb +1 -1
  32. data/lib/rider_server/services/rails.rb +1 -1
  33. data/lib/rider_server/session.rb +75 -44
  34. data/lib/rider_server/session_operation.rb +17 -0
  35. data/lib/rider_server/session_operations/eval.rb +61 -0
  36. data/lib/rider_server/session_operations/inspect.rb +123 -0
  37. data/lib/rider_server/session_operations/inspect_exception.rb +46 -0
  38. data/lib/rider_server/session_operations/interrupt.rb +29 -0
  39. data/lib/rider_server/session_operations/load_path.rb +19 -0
  40. data/lib/rider_server/session_operations/ls_exceptions.rb +28 -0
  41. data/lib/rider_server/session_operations/ls_services.rb +18 -0
  42. data/lib/rider_server/session_operations/service.rb +42 -0
  43. data/lib/rider_server/session_operations/set_namespace.rb +82 -0
  44. data/lib/rider_server/session_operations/set_namespace_variable.rb +81 -0
  45. data/lib/rider_server/session_operations/stdin.rb +19 -0
  46. data/lib/rider_server/utils.rb +7 -7
  47. data/lib/rider_server/validate/array.rb +32 -0
  48. data/lib/rider_server/validate/base.rb +28 -0
  49. data/lib/rider_server/validate/boolean.rb +47 -0
  50. data/lib/rider_server/validate/hash.rb +32 -0
  51. data/lib/rider_server/validate/integer.rb +56 -0
  52. data/lib/rider_server/validate/predicates.rb +30 -0
  53. data/lib/rider_server/validate/string.rb +60 -0
  54. data/lib/rider_server/validate/symbol.rb +90 -0
  55. data/lib/rider_server/validate.rb +15 -0
  56. data/lib/rider_server/version.rb +1 -1
  57. data/lib/rider_server/workspace.rb +1 -1
  58. data/lib/rider_server.rb +3 -1
  59. metadata +54 -24
  60. data/README.md +0 -46
  61. data/lib/rider_server/ops/completions.rb +0 -145
  62. data/lib/rider_server/ops/eval.rb +0 -62
  63. data/lib/rider_server/ops/inspect.rb +0 -121
  64. data/lib/rider_server/ops/inspect_exception.rb +0 -47
  65. data/lib/rider_server/ops/interrupt.rb +0 -30
  66. data/lib/rider_server/ops/load_path.rb +0 -20
  67. data/lib/rider_server/ops/lookup.rb +0 -104
  68. data/lib/rider_server/ops/ls_exceptions.rb +0 -29
  69. data/lib/rider_server/ops/ls_services.rb +0 -19
  70. data/lib/rider_server/ops/ls_sessions.rb +0 -52
  71. data/lib/rider_server/ops/service.rb +0 -43
  72. data/lib/rider_server/ops/set_namespace.rb +0 -79
  73. data/lib/rider_server/ops/set_namespace_variable.rb +0 -80
  74. data/lib/rider_server/ops/stdin.rb +0 -20
  75. data/lib/rider_server/ops/toggle_catch_all_exceptions.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acb6833a29ab9facb82c72d8f2e012ab0dd7a44dbd1ad93dfe69f8d1bff2a765
4
- data.tar.gz: 62834c0a615baa860e1e7650f14353180b874cf877833cc94b6f9804edd32efa
3
+ metadata.gz: 42460de42badb3c5e588c8f606d395f91b8c91f419f119983e18d9ee7833b6c6
4
+ data.tar.gz: 3a1b5c4b92bb2bfe630a01736aa75dfa7eb23cd058686faaa748589d62f95e96
5
5
  SHA512:
6
- metadata.gz: bec9b6906b7e47954bdf9a85fcb3a47ca89d86f63f68023b90d0c8ac83028f6aa7681ad0a4042934cd4a663a0f86f344d8ee11374816efe5616d5eaeaa2a8b75
7
- data.tar.gz: a0d1b287bfeeaf68bbd82c9d72d7bb9405a9873286993e6171cd5f754c545c56cdcde1f186e8c9edb755a1e883a627ce6b33eeea2b21a047220ced97e3e973e5
6
+ metadata.gz: f42e2bb3d67f2922b0fe7a06c027b17a5737361521aa73f41a9b2376d53217f2f81f54066b82ba168ec3f5046dc8b2b238d0c7e2d6d0d8f8db5a6ac1bd279654
7
+ data.tar.gz: 5518b9ca7125186c9c248606b219819b271aa35514518ee90384614c8ccb9e7f0d8e1d1bc22014129d11dda586d849fd31854a7b8309083a0c3f8ac35e4e0acc
data/.build.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  image: debian/stable
2
2
  sources:
3
- - https://git.sr.ht/~rsl/rider
3
+ - https://git.sr.ht/~rsl/rider-server
4
4
  packages:
5
5
  - bundler
6
6
  - curl
@@ -10,11 +10,11 @@ packages:
10
10
  - zlib1g-dev
11
11
  tasks:
12
12
  - lint: |
13
- cd rider
13
+ cd rider-server
14
14
  bundle install --path="../.gems"
15
15
  bundle exec rake standard
16
16
  - test: |
17
- cd rider
17
+ cd rider-server
18
18
  bundle install --path="../.gems"
19
19
  bundle exec rake test
20
20
  triggers:
data/CHANGELOG.md CHANGED
@@ -1,4 +1,20 @@
1
- ## [Unreleased]
1
+ ## [0.1.2] - 2024-08-14
2
+
3
+ - update to latest bencode and remove ruby version limitation
4
+ - request argument validation
5
+ - add a global configuration object and a mechanism to load
6
+ configuration at startup.
7
+ - support setting the caputured exception buffer size.
8
+ - allow setting of the log level
9
+ - enable setting of the current namespace to an element of an array
10
+ - add a separate inspect mechanism for the singleton class
11
+ - fill in missing parameter details in ruby. This is a port of the
12
+ elisp code, and simplifies the Emacs implementation.
13
+ - ENV object printing, previously the env object would print the
14
+ entire env value which is of an unknown size.
15
+ - printing of constant names along with values in inspect view.
16
+ Module constants have a name as a value, but this isn't true for
17
+ other constants.
2
18
 
3
19
  ## [0.1.1] - 2024-07-31
4
20
 
data/README.rdoc ADDED
@@ -0,0 +1,39 @@
1
+ = RIDER -- RIDER Interactive Development Environment for Ruby
2
+
3
+ RIDER Server is the server component of the RIDER development
4
+ environment.
5
+
6
+ == Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ $ bundle add rider-server
11
+
12
+ If bundler is not being used to manage dependencies, install the gem by executing:
13
+
14
+ $ gem install rider-server
15
+
16
+ == Usage
17
+
18
+ TODO: Write usage instructions here
19
+
20
+ == Development
21
+
22
+ After checking out the repo, run <tt>bin/setup</tt> to install
23
+ dependencies. Then, run <tt>rake test</tt> to run the tests. You can also run
24
+ <tt>bin/console</tt> for an interactive prompt that will allow you to
25
+ experiment.
26
+
27
+ To install this gem onto your local machine, run <tt>bundle exec rake
28
+ install</tt>.
29
+
30
+ To release a new version run <tt>rake bump:patch</tt> and then run <tt>bundle
31
+ exec rake release</tt>, which will create a git tag for the version, push
32
+ git commits and the created tag, and push the <tt>.gem</tt> file to
33
+ http://rubygems.org.
34
+
35
+ == Contributing
36
+
37
+ Bug reports http://todo.sr.ht/~rsl/rider
38
+
39
+ Support or discussion http://lists.sr.ht/~rsl/rider-devel
data/Rakefile CHANGED
@@ -3,9 +3,14 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "minitest/test_task"
5
5
  require "bump/tasks"
6
+ require "rdoc/task"
6
7
 
7
8
  Bump.tag_by_default = true
8
9
  Minitest::TestTask.create
10
+ RDoc::Task.new do |rdoc|
11
+ rdoc.main = "README.rdoc"
12
+ rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
13
+ end
9
14
 
10
15
  require "standard/rake"
11
16
 
data/exe/rider-server CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
7
7
 
8
- require "rider_server/server"
9
-
10
- server = RiderServer::Server.new
8
+ require "rider_server"
9
+ config = RiderServer::Config.new
10
+ server = RiderServer::Server.new(config)
11
11
  server.run
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # config.rb -- A config class for global config
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate"
11
+
12
+ module RiderServer
13
+ class Config
14
+ DEFAULTS = {
15
+ host: "localhost",
16
+ port: 7888,
17
+
18
+ # Whether to capture RIDER exceptions and send them to the
19
+ # client.
20
+ capture_exceptions: false,
21
+
22
+ # The number of exceptions to keep in the history.
23
+ exception_history_size: 10,
24
+
25
+ # The log level
26
+ log_level: :INFO
27
+ }
28
+
29
+ def self.configure(&block)
30
+ instance = new
31
+ instance.instance_eval(&block)
32
+ instance
33
+ end
34
+
35
+ # Define a configuration option, +option_name+ is a symbol
36
+ # representing the name of the configuration option, and
37
+ # +validator+ is a Validate object that will be used to validate
38
+ # the value of the option.
39
+ def self.def_option(option_name, validator)
40
+ define_method :"#{option_name}" do |value = nil|
41
+ if value
42
+ @options[option_name] = validator.validate(value)
43
+ else
44
+ unless @options.key?(option_name)
45
+ raise ArgumentError, "Option #{option_name} not set"
46
+ end
47
+
48
+ @options[option_name]
49
+ end
50
+ end
51
+ end
52
+
53
+ def_option :host, Validate.string.not_empty
54
+ def_option :port, Validate.integer.greater_than(0)
55
+ def_option :capture_exceptions, Validate.bool
56
+ def_option :exception_history_size, Validate.integer.greater_than(0)
57
+
58
+ def_option :log_level, Validate.symbol.upcase.one_of(:DEBUG, :INFO, :WARN, :ERROR, :FATAL)
59
+
60
+ attr_reader :options
61
+
62
+ def initialize(config_file: "rider.rb")
63
+ @options = DEFAULTS.dup
64
+
65
+ if File.file?(config_file)
66
+ config.load_from(config_file)
67
+ end
68
+ end
69
+
70
+ # Load configuration from file +path+. The contents of the file
71
+ # will be evaluated within the context of this class instance.
72
+ def load_from(path)
73
+ instance_eval(File.read(path), path, 1)
74
+ end
75
+ end
76
+ end
@@ -8,7 +8,9 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  class Array
11
- def rider_inspect
11
+ # Return a +string+ representation of the object in a consistent
12
+ # manner that will not be excessivly long.
13
+ def rider_display
12
14
  max_length = 50
13
15
  sample = +""
14
16
 
@@ -0,0 +1,5 @@
1
+ class Class
2
+ def rider_descendants
3
+ ObjectSpace.each_object(::Class).select { |klass| klass < self }
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # env.rb -- ENV extensions
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ # Return a +string+ representation of the object in a consistent
11
+ # manner that will not be excessivly long.
12
+ def ENV.rider_display
13
+ "#<ENV #{keys[..3].join(", ")}, ...>"
14
+ end
@@ -8,7 +8,9 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  class Hash
11
- def rider_inspect
11
+ # Return a +string+ representation of the object in a consistent
12
+ # manner that will not be excessivly long.
13
+ def rider_display
12
14
  "#<#{self.class}: #{length} items}>"
13
15
  end
14
16
  end
@@ -0,0 +1,5 @@
1
+ module Kernel
2
+ def rider_methods
3
+ Kernel.instance_method(:methods).bind_call(self)
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # module.rb -- Module extensions
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ class Module
11
+ def rider_inspect
12
+ Module.instance_method(:inspect).bind_call(self)
13
+ end
14
+
15
+ def rider_instance_methods
16
+ Module.instance_method(:instance_methods).bind_call(self)
17
+ end
18
+ end
@@ -8,11 +8,17 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  class Object
11
- def rider_inspect
11
+ # Return a +string+ representation of the object in a consistent
12
+ # manner that will not be excessivly long.
13
+ def rider_display
12
14
  if defined?(inspect) && method(:inspect).owner != Object && method(:inspect).owner != Kernel
13
15
  inspect
14
16
  else
15
17
  "#<#{self.class} #{object_id}>"
16
18
  end
17
19
  end
20
+
21
+ def rider_inspect
22
+ Object.instance_method(:inspect).bind_call(self)
23
+ end
18
24
  end
@@ -8,7 +8,9 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  class String
11
- def rider_inspect
11
+ # Return a +string+ representation of the object in a consistent
12
+ # manner that will not be excessivly long.
13
+ def rider_display
12
14
  if length <= 50
13
15
  "#<String #{inspect}>"
14
16
  else
@@ -8,7 +8,9 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  class Symbol
11
- def rider_inspect
11
+ # Return a +string+ representation of the object in a consistent
12
+ # manner that will not be excessivly long.
13
+ def rider_display
12
14
  ":#{self}"
13
15
  end
14
16
  end
@@ -28,6 +28,8 @@ module RiderServer
28
28
  end
29
29
 
30
30
  unless ::Exception.included_modules.include?(RiderServer::ExceptionExtension)
31
+ # Extend the +exception+ class so that RIDER can capture the
32
+ # backtraces for inspection.
31
33
  class ::Exception
32
34
  prepend RiderServer::ExceptionExtension
33
35
  end
@@ -22,52 +22,128 @@ module RiderServer
22
22
  eval(code, TOPLEVEL_BINDING, file, line) # rubocop:disable Security/Eval
23
23
  end
24
24
 
25
- def self.class(obj)
25
+ def self.safely_location(src)
26
+ loc = safely_eval(src, __FILE__, __LINE__)
27
+ if loc.length == 2 && loc[0].is_a?(String) && loc[1].is_a?(Integer)
28
+ loc
29
+ else
30
+ []
31
+ end
32
+ end
33
+
34
+ def self.inspect_class(obj)
26
35
  klass = obj.class
27
36
  {
28
37
  "name" => klass.to_s,
29
- "value" => Utils.rider_inspect(safely_eval("Object.const_get('#{klass}')", __FILE__, __LINE__)),
38
+ "value" => Utils.rider_display(safely_eval("Object.const_get('#{klass}')", __FILE__, __LINE__)),
30
39
  "inspect-location" => "toplevel_const_get:#{klass.inspect}",
31
40
  "source-location" => safely_eval("Object.const_source_location('#{klass}')", __FILE__, __LINE__) || []
32
41
  }
33
42
  end
34
43
 
35
- def self.ancestors(obj)
44
+ def self.inspect_singleton_class(obj)
45
+ klass = obj.singleton_class
46
+ {
47
+ "name" => klass.to_s,
48
+ "value" => Utils.rider_display(klass),
49
+ "inspect-location" => "singleton_class",
50
+ "source-location" => []
51
+ }
52
+ rescue => e # integers have no singleton
53
+ {
54
+ "name" => e.to_s,
55
+ "value" => Utils.rider_display(e)
56
+ }
57
+ end
58
+
59
+ def self.inspect_ancestors(obj)
36
60
  if obj.respond_to?(:ancestors)
37
61
  obj.ancestors.map do |item|
38
- {
39
- "name" => item.to_s,
40
- "value" => Utils.rider_inspect(item),
41
- "inspect-location" => "ancestor_find:#{item}",
42
- "source-location" => safely_eval("Object.const_source_location('#{item}')", __FILE__, __LINE__) || []
43
- }
62
+ if item.instance_of? ::Module
63
+ {
64
+ "name" => item.to_s,
65
+ "value" => Utils.rider_display(item),
66
+ "inspect-location" => "ancestor_find:#{item}",
67
+ "source-location" => safely_location("Object.const_source_location('#{item}')")
68
+ }
69
+ else
70
+ {
71
+ "name" => item.to_s,
72
+ "value" => Utils.rider_display(item),
73
+ "inspect-location" => "ancestor_find:#{item}",
74
+ "source-location" => []
75
+ }
76
+ end
44
77
  end
45
78
  else
46
79
  []
47
80
  end
48
81
  end
49
82
 
50
- def self.constants(obj)
83
+ def self.inspect_constants(obj)
51
84
  if obj.respond_to?(:constants)
52
- constants = safely_eval("#{obj.inspect}.constants", __FILE__, __LINE__)
85
+ constants = safely_eval("#{obj.rider_inspect}.constants", __FILE__, __LINE__)
53
86
  return [] if constants.nil? # Eigen classes have no constants
54
87
  constants.map do |item|
55
- {
56
- "name" => item.to_s,
57
- "value" => Utils.rider_inspect(safely_eval("#{obj.inspect}.const_get('#{item}')", __FILE__, __LINE__)),
58
- "inspect-location" => "const_get:#{obj.inspect}::#{item}",
59
- "source-location" => safely_eval("#{obj.inspect}.const_source_location('#{item}')", __FILE__, __LINE__) || []
60
- }
61
- end.sort_by { |hash| hash["name"] }
88
+ [
89
+ {
90
+ "name" => item.to_s
91
+ },
92
+ {
93
+ "name" => item.to_s,
94
+ "value" => Utils.rider_display(safely_eval("#{obj.rider_inspect}.const_get('#{item}')", __FILE__, __LINE__)),
95
+ "inspect-location" => "const_get:#{obj.rider_inspect}::#{item}",
96
+ "source-location" => safely_location("#{obj.rider_inspect}.const_source_location('#{item}')")
97
+ }
98
+ ]
99
+ end.sort_by { |hash| hash[0]["name"] }
62
100
  else
63
101
  []
64
102
  end
65
103
  end
66
104
 
105
+ def self.inspect_parameters(parameters)
106
+ alpha = Enumerator.new do |y|
107
+ ("a".."z").each { |char| y << char }
108
+ end
109
+
110
+ parameters.map do |params|
111
+ arg, name = params
112
+ if arg == :rest
113
+ "*#{name || "args"}"
114
+ elsif arg == :keyrest
115
+ if name.nil? || name == "**"
116
+ "**kwargs"
117
+ else
118
+ name
119
+ end
120
+ elsif arg == :req
121
+ name || alpha.next
122
+ elsif arg == :keyreq
123
+ "#{name || alpha.next}: ..."
124
+ elsif arg == :key
125
+ "#{name || alpha.next}:"
126
+ elsif arg == :opt
127
+ "#{name || alpha.next}=..."
128
+ elsif arg == :block
129
+ "&block"
130
+ else
131
+ raise "Unknown prameter format #{arg}"
132
+ end.to_s
133
+ end
134
+ end
135
+
67
136
  def self.describe_method(method)
137
+ loc = method.source_location
138
+ method_location = if !loc.nil? && loc.length == 2 && loc[0].is_a?(String) && loc[1].is_a?(Integer)
139
+ loc
140
+ else
141
+ []
142
+ end
143
+
68
144
  {
69
145
  "name" => method.name.to_s,
70
- "value" => Utils.rider_inspect(method),
146
+ "value" => Utils.rider_display(method),
71
147
  "visibility" => if method.private?
72
148
  ":private"
73
149
  elsif method.protected?
@@ -77,15 +153,15 @@ module RiderServer
77
153
  else
78
154
  ":unknown"
79
155
  end,
80
- "owner" => method.owner.inspect,
81
- "source-location" => method.source_location || [],
82
- "parameters" => method.parameters.map { |subarray| subarray.map(&:to_s) }
156
+ "owner" => method.owner.rider_inspect,
157
+ "source-location" => method_location,
158
+ "parameters" => inspect_parameters(method.parameters)
83
159
  }
84
160
  end
85
161
 
86
- def self.methods(obj)
87
- if obj.respond_to?(:methods)
88
- obj.methods.map do |name|
162
+ def self.inspect_methods(obj)
163
+ if obj.respond_to?(:rider_methods)
164
+ obj.rider_methods.map do |name|
89
165
  describe_method(obj.method(name))
90
166
  end
91
167
  else
@@ -93,9 +169,9 @@ module RiderServer
93
169
  end
94
170
  end
95
171
 
96
- def self.instance_methods(obj)
97
- if obj.respond_to?(:instance_methods)
98
- obj.instance_methods.map do |item|
172
+ def self.inspect_instance_methods(obj)
173
+ if obj.respond_to?(:rider_instance_methods)
174
+ obj.rider_instance_methods.map do |item|
99
175
  describe_method(obj.instance_method(item))
100
176
  end
101
177
  else
@@ -103,7 +179,7 @@ module RiderServer
103
179
  end
104
180
  end
105
181
 
106
- def self.instance_variables(obj)
182
+ def self.inspect_instance_variables(obj)
107
183
  if obj.respond_to?(:instance_variables)
108
184
  obj.instance_variables.map do |item|
109
185
  [
@@ -112,7 +188,7 @@ module RiderServer
112
188
  },
113
189
  {
114
190
  "name" => obj.instance_variable_get(item).to_s,
115
- "value" => Utils.rider_inspect(obj.instance_variable_get(item)),
191
+ "value" => Utils.rider_display(obj.instance_variable_get(item)),
116
192
  "inspect-location" => "instance_variable_get:#{item}"
117
193
  }
118
194
  ]
@@ -122,7 +198,7 @@ module RiderServer
122
198
  end
123
199
  end
124
200
 
125
- def self.class_variables(obj)
201
+ def self.inspect_class_variables(obj)
126
202
  if obj.respond_to?(:class_variables)
127
203
  obj.class_variables.map do |item|
128
204
  [
@@ -131,7 +207,7 @@ module RiderServer
131
207
  },
132
208
  {
133
209
  "name" => obj.class_variable_get(item).to_s,
134
- "value" => Utils.rider_inspect(obj.class_variable_get(item)),
210
+ "value" => Utils.rider_display(obj.class_variable_get(item)),
135
211
  "inspect-location" => "class_variable_get:#{item}"
136
212
  }
137
213
  ]
@@ -2,12 +2,19 @@ require "logger"
2
2
 
3
3
  module RiderServer
4
4
  module Logger
5
- def log
6
- @logger ||= begin
7
- log_level = (ENV["LOG_LEVEL"] || "INFO").upcase.to_sym
5
+ class << self
6
+ def configure_logger(logdev: ::STDERR, level: ENV["LOG_LEVEL"] || "INFO") # rubocop:disable Style/GlobalStdStream
7
+ log_level = level.upcase.to_sym
8
+ @@logger = ::Logger.new(logdev, level: log_level)
9
+ end
8
10
 
9
- ::Logger.new(STDERR, level: log_level) # rubocop:disable Style/GlobalStdStream
11
+ def log
12
+ @@logger ||= configure_logger
10
13
  end
11
14
  end
15
+
16
+ def log
17
+ Logger.log
18
+ end
12
19
  end
13
20
  end
@@ -13,38 +13,57 @@ module RiderServer
13
13
  class Operation
14
14
  include RiderServer::Logger
15
15
 
16
- attr_reader :documentation, :arguments, :controller
17
- def self.operation_name
18
- name.split("::").last.gsub(/(.)([A-Z])/, '\1_\2').downcase
16
+ # Operations registry
17
+ @operations = {}
18
+ class << self
19
+ attr_reader :operations
19
20
  end
20
21
 
21
- def self.documentation(desc)
22
- @documentation = desc
22
+ def self.handles?(request)
23
+ @operations.key? request.op
23
24
  end
24
25
 
25
- def self.argument(name, type, description, required: false)
26
- @arguments ||= []
26
+ def self.handle(context, request)
27
+ operation = @operations[request.op]
28
+ operation.validate_request!(request)
29
+ operation.handle(context, request)
30
+ end
27
31
 
28
- raise ArgumentError, "Invalid argument type #{type}" \
29
- unless [:string, :integer, :array].include?(type)
32
+ def self.define(&block)
33
+ instance = new
34
+ instance.instance_eval(&block)
35
+ raise ArgumentError, "Operation #{self} must have a name" if instance.name.empty?
36
+ raise ArgumentError, "Operation #{self} must have a documentation string" if instance.documentation.empty?
37
+ raise ArgumentError, "Operation #{self} must have at least one argument" if instance.arguments.empty?
38
+ @operations[instance.name] = instance
39
+ instance
40
+ end
30
41
 
31
- @arguments << {name: name, type: type, required: required, description: description}
42
+ attr_reader :arguments
43
+
44
+ def documentation(value = nil)
45
+ @documentation = value if value
46
+ @documentation
32
47
  end
33
48
 
34
- def initialize(controller)
35
- @controller = controller
36
- @documentation = self.class.instance_variable_get(:@documentation) || ""
37
- @arguments = self.class.instance_variable_get(:@arguments) || []
38
- raise ArgumentError, "Operation must have a documentation string" if @documentation.empty?
39
- raise ArgumentError, "Operation must have at least one argument" if @arguments.empty?
49
+ def name(value = nil)
50
+ @name = value if value
51
+ @name
40
52
  end
41
53
 
42
- def create_response(operation)
43
- Utils.create_response(operation)
54
+ def initialize
55
+ @name = ""
56
+ @arguments = []
57
+ @documentation = ""
44
58
  end
45
59
 
46
- def send_response(response)
47
- controller.send_response(response)
60
+ def argument(name, type, description, required: false)
61
+ @arguments ||= []
62
+
63
+ raise ArgumentError, "Invalid argument type #{type}" \
64
+ unless [:string, :integer, :array].include?(type)
65
+
66
+ @arguments << {name: name, type: type, required: required, description: description}
48
67
  end
49
68
 
50
69
  def validate_request!(request)
@@ -3,14 +3,15 @@ require "rider_server/response"
3
3
 
4
4
  module RiderServer
5
5
  module Ops
6
- class Clone < Operation
6
+ Operation.define do
7
+ name "clone"
7
8
  documentation "Clone a session"
8
9
 
9
10
  argument :id, :string, "The request id", required: true
10
11
  argument :session, :string, "The session to clone"
11
12
 
12
13
  # Handle the clone operation, session will be nil
13
- def handle(session, operation)
14
+ def handle(controller, operation)
14
15
  response = Response.new(operation)
15
16
 
16
17
  # Clone a specific session if specified