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
@@ -0,0 +1,82 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+
4
+ module RiderServer
5
+ SessionOperation.define do
6
+ name "set-namespace"
7
+ documentation "Set the namespace to the given location."
8
+
9
+ argument :id, :string, "The request id", required: true
10
+ argument :location, :array, "The location to set the namespace to", required: true
11
+
12
+ def handle(session, operation)
13
+ response = Response.new(operation)
14
+ location = operation["location"]
15
+
16
+ value = traverse_location(location, nil, session)
17
+ session.workspace.set_namespace(value)
18
+ response.set("ns", session.workspace.namespace_name)
19
+ response.set("location", location)
20
+ response.status("done")
21
+ response
22
+ end
23
+
24
+ def traverse_location(location, ctx, session)
25
+ loc = location.first
26
+ locs = location.drop(1)
27
+
28
+ if locs.empty?
29
+ lookup_object(loc, ctx, session)
30
+ else
31
+ traverse_location(locs, lookup_object(loc, ctx, session), session)
32
+ end
33
+ end
34
+
35
+ def lookup_object(loc, ctx, session)
36
+ lookup, identifier = loc.split(":", 2)
37
+
38
+ case lookup
39
+ when "rider_main"
40
+ "main"
41
+ when "rider_history"
42
+ rider_history(identifier, nil, session)
43
+ when "rider_exception"
44
+ rider_exception(identifier, nil, session)
45
+ when "rider_stackframe"
46
+ ctx.__rider_bindings_stack[identifier.to_i]
47
+ when "rider_stackframe_variable"
48
+ frame_id, local_var = identifier.split(":", 2)
49
+ ctx.__rider_bindings_stack[frame_id.to_i].local_variable_get(local_var)
50
+ when "rider_array_item"
51
+ ctx[identifier.to_i]
52
+ when "rider_hash_key"
53
+ hash = identifier.to_i
54
+ ctx.keys.find { |key| key.hash == hash }
55
+ when "rider_hash_value"
56
+ hash = identifier.to_i
57
+ key = ctx.keys.find { |key| key.hash == hash }
58
+ ctx.fetch(key)
59
+ when "toplevel_const_get"
60
+ Object.const_get(identifier)
61
+ when "instance_variable_get"
62
+ ctx.instance_variable_get(identifier)
63
+ when "singleton_class"
64
+ ctx.singleton_class
65
+ when "const_get"
66
+ ctx.const_get(identifier)
67
+ when "ancestor_find"
68
+ ctx.class.ancestors.find { |item| item.to_s == identifier }
69
+ else
70
+ raise "Unknown inspect function: #{lookup}"
71
+ end
72
+ end
73
+
74
+ def rider_history(value, ctx, session)
75
+ session.get_result(value)
76
+ end
77
+
78
+ def rider_exception(id, ctx, session)
79
+ session.get_exception(id)["exception"]
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,81 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+
4
+ module RiderServer
5
+ SessionOperation.define do
6
+ name "set-namespace-variable"
7
+ documentation "Set a variable in the current REPL binding."
8
+
9
+ argument :id, :string, "The request id", required: true
10
+ argument :name, :string, "The name of the local variable to set", required: true
11
+ argument :location, :array, "The location to set the namespace to", required: true
12
+
13
+ def handle(session, operation)
14
+ response = Response.new(operation)
15
+ name operation["name"]
16
+ raise "Name must be a valid Ruby identifier" unless /\A[a-zA-Z_]\w*\z/.match?(name)
17
+ location = operation["location"]
18
+
19
+ value = traverse_location(location, nil, session)
20
+ session.workspace.binding_local_variable_set(name, value)
21
+ response.status("done")
22
+ response
23
+ end
24
+
25
+ def traverse_location(location, ctx, session)
26
+ loc = location.first
27
+ locs = location.drop(1)
28
+
29
+ if locs.empty?
30
+ lookup_object(loc, ctx, session)
31
+ else
32
+ traverse_location(locs, lookup_object(loc, ctx, session), session)
33
+ end
34
+ end
35
+
36
+ def lookup_object(loc, ctx, session)
37
+ lookup, identifier = loc.split(":", 2)
38
+
39
+ case lookup
40
+ when "rider_main"
41
+ "main"
42
+ when "rider_history"
43
+ rider_history(identifier, nil, session)
44
+ when "rider_exception"
45
+ rider_exception(identifier, nil, session)
46
+ when "rider_stackframe"
47
+ ctx.__rider_bindings_stack[identifier.to_i]
48
+ when "rider_stackframe_variable"
49
+ frame_id, local_var = identifier.split(":", 2)
50
+ ctx.__rider_bindings_stack[frame_id.to_i].local_variable_get(local_var)
51
+ when "rider_array_item"
52
+ ctx[identifier.to_i]
53
+ when "rider_hash_key"
54
+ hash = identifier.to_i
55
+ ctx.keys.find { |key| key.hash == hash }
56
+ when "rider_hash_value"
57
+ hash = identifier.to_i
58
+ key = ctx.keys.find { |key| key.hash == hash }
59
+ ctx.fetch(key)
60
+ when "toplevel_const_get"
61
+ Object.const_get(identifier)
62
+ when "instance_variable_get"
63
+ ctx.instance_variable_get(identifier)
64
+ when "const_get"
65
+ ctx.const_get(identifier)
66
+ when "ancestor_find"
67
+ ctx.class.ancestors.find { |item| item.to_s == identifier }
68
+ else
69
+ raise "Unknown inspect function: #{lookup}"
70
+ end
71
+ end
72
+
73
+ def rider_history(value, ctx, session)
74
+ session.get_result(value)
75
+ end
76
+
77
+ def rider_exception(id, ctx, session)
78
+ session.get_exception(id)["exception"]
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,19 @@
1
+ require "rider_server/operation"
2
+ require "rider_server/response"
3
+
4
+ module RiderServer
5
+ SessionOperation.define do
6
+ name "stdin"
7
+ documentation "List all exceptions that have occurred in the session."
8
+
9
+ argument :id, :string, "The request id", required: true
10
+ argument :stdin, :string, "The input to write to the stdin of the process", required: true
11
+
12
+ def handle(session, operation)
13
+ session.stdin.write(operation["stdin"])
14
+ response = Response.new(operation)
15
+ response.status("done")
16
+ response
17
+ end
18
+ end
19
+ end
@@ -30,19 +30,19 @@ module RiderServer
30
30
  end
31
31
  module_function :create_listeners
32
32
 
33
- def rider_inspect(obj)
34
- if obj.respond_to?(:rider_inspect)
35
- obj.rider_inspect
33
+ def rider_display(obj)
34
+ if obj.respond_to?(:rider_display)
35
+ obj.rider_display
36
36
  else
37
37
  obj.inspect
38
38
  end
39
39
  end
40
- module_function :rider_inspect
40
+ module_function :rider_display
41
41
 
42
42
  class FixedArray < Array
43
- def initialize(*args)
44
- @max_size = args[0] || 10
45
- super
43
+ def initialize(*args, max_size: 10)
44
+ @max_size = max_size
45
+ super(*args)
46
46
  end
47
47
 
48
48
  def <<(element)
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # array.rb -- Simple validation of arrays
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class Array < Base
15
+ def initialize(element_validator)
16
+ @element_validator = element_validator
17
+ end
18
+
19
+ def validate(data, loc = "")
20
+ fail(data, loc, "be an array") unless data.is_a?(::Array)
21
+
22
+ data.map.with_index do |element, index|
23
+ @element_validator.validate(element, "#{loc}[#{index}]")
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.array(element_validator)
29
+ Array.new(element_validator)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ require "rider_server/validate/predicates"
2
+
3
+ module RiderServer
4
+ module Validate
5
+ class ValidationError < StandardError
6
+ end
7
+
8
+ class Base
9
+ include PredicateLogic
10
+
11
+ def self.validate(data)
12
+ new.validate(data)
13
+ end
14
+
15
+ def validate(data)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def fail(value, loc, reason)
20
+ if loc == ""
21
+ raise ValidationError, "#{value.inspect}, #{reason}"
22
+ else
23
+ raise ValidationError, "#{value.inspect}, found at #{loc} #{reason}"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # boolean.rb -- Simple validation of booleans
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class Boolean < Base
15
+ TRUE_STRINGS = ["yes", "true", "on"]
16
+
17
+ def default(value)
18
+ @default = value
19
+ self
20
+ end
21
+
22
+ def validate(data, loc = "")
23
+ if data.nil? && @default
24
+ data = @default
25
+ elsif data.nil?
26
+ fail(data, loc, "no default value set")
27
+ end
28
+
29
+ case data
30
+
31
+ when ::TrueClass, ::FalseClass
32
+ data
33
+ when ::String
34
+ TRUE_STRINGS.member? data.downcase
35
+ when ::Integer
36
+ data > 0
37
+ else
38
+ fail(data, loc, "can't convert to a boolean")
39
+ end
40
+ end
41
+ end
42
+
43
+ def self.bool
44
+ Boolean.new
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # hash.rb -- Simple validation of hashes
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class Hash < Base
15
+ def initialize(schema)
16
+ @schema = schema
17
+ end
18
+
19
+ def validate(data, loc = "")
20
+ @schema.map do |key, validator|
21
+ if data.key? key
22
+ [key, validator.validate(data[key], "#{loc}[#{key}]")]
23
+ end
24
+ end.to_h
25
+ end
26
+ end
27
+
28
+ def self.hash(schema)
29
+ Hash.new(schema)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # integer.rb -- Simple validation of integers
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class Integer < Base
15
+ def default(value)
16
+ @default = value
17
+ self
18
+ end
19
+
20
+ def greater_than(value)
21
+ add_predicate { |data| [data > value, "must be greater than #{value}"] }
22
+ self
23
+ end
24
+
25
+ def less_than(value)
26
+ add_predicate { |data| [data < value, "must be less than #{value}"] }
27
+ self
28
+ end
29
+
30
+ def validate(data, loc = "")
31
+ if data.nil? && @default
32
+ data = @default
33
+ elsif data.nil?
34
+ fail(data, loc, "no default value set")
35
+ end
36
+
37
+ begin
38
+ data = data.to_i
39
+ rescue
40
+ fail(data, loc, "can't convert to an integer")
41
+ end
42
+
43
+ result, reason = check_predicates(data)
44
+ unless result
45
+ fail(data, loc, reason)
46
+ end
47
+
48
+ data
49
+ end
50
+ end
51
+
52
+ def self.integer
53
+ Integer.new
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # predicates.rb -- Predicates for values
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ module RiderServer
11
+ module Validate
12
+ module PredicateLogic
13
+ def add_predicate(&block)
14
+ @predicates ||= []
15
+ @predicates << block
16
+ end
17
+
18
+ def check_predicates(data)
19
+ return [true, ""] if @predicates.nil?
20
+ @predicates.each do |predicate|
21
+ result, reason = predicate.call(data)
22
+ unless result
23
+ return [result, reason]
24
+ end
25
+ end
26
+ [true, ""]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # string.rb -- Simple validation of strings
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class String < Base
15
+ def default(value)
16
+ @default = value
17
+ self
18
+ end
19
+
20
+ def empty
21
+ add_predicate do |data|
22
+ [data.empty?, "must be empty"]
23
+ end
24
+ self
25
+ end
26
+
27
+ def not_empty
28
+ add_predicate do |data|
29
+ [!data.empty?, "must not be empty"]
30
+ end
31
+ self
32
+ end
33
+
34
+ def validate(data, loc = "")
35
+ if data.nil? && @default
36
+ data = @default
37
+ elsif data.nil?
38
+ fail(data, loc, "no default value set")
39
+ end
40
+
41
+ begin
42
+ data = data.to_s
43
+ rescue
44
+ fail(data, loc, "can't convert to a string")
45
+ end
46
+
47
+ result, reason = check_predicates(data)
48
+ unless result
49
+ fail(data, loc, reason)
50
+ end
51
+
52
+ data
53
+ end
54
+ end
55
+
56
+ def self.string
57
+ Validate::String.new
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # symbol.rb -- Simple validation of symbols
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/base"
11
+
12
+ module RiderServer
13
+ module Validate
14
+ class Symbol < Base
15
+ def default(value)
16
+ @default = value
17
+ self
18
+ end
19
+
20
+ # Require that the input be one of the +values+.
21
+ def one_of(*values)
22
+ raise ArgumentError, "one_of requires at least one value" if values.empty?
23
+ values.each do |value|
24
+ raise ArgumentError, "one_of requires all values to be symbols but #{value.inspect} is not" \
25
+ unless value.is_a?(::Symbol)
26
+ end
27
+
28
+ add_predicate do |data|
29
+ [values.member?(data), "must one of #{values.inspect}"]
30
+ end
31
+ self
32
+ end
33
+
34
+ # Require that the input be empty.
35
+ def empty
36
+ add_predicate do |data|
37
+ [data.empty?, "must be empty"]
38
+ end
39
+ self
40
+ end
41
+
42
+ # Require that the input be not empty.
43
+ def not_empty
44
+ add_predicate do |data|
45
+ [!data.empty?, "must not be empty"]
46
+ end
47
+ self
48
+ end
49
+
50
+ # Convert the input to an upcase version if possible.
51
+ def upcase
52
+ @upcase = true
53
+ self
54
+ end
55
+
56
+ def validate(data, loc = "")
57
+ if data.nil? && @default
58
+ data = @default
59
+ elsif data.nil?
60
+ fail(data, loc, "no default value set")
61
+ end
62
+
63
+ if data.respond_to?(:upcase)
64
+ begin
65
+ data = data.upcase if @upcase
66
+ rescue
67
+ fail(data, loc, "can't upcase symbol")
68
+ end
69
+ end
70
+
71
+ begin
72
+ data = data.to_sym
73
+ rescue
74
+ fail(data, loc, "can't convert to a symbol")
75
+ end
76
+
77
+ result, reason = check_predicates(data)
78
+ unless result
79
+ fail(data, loc, reason)
80
+ end
81
+
82
+ data
83
+ end
84
+ end
85
+
86
+ def self.symbol
87
+ Symbol.new
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # validate.rb -- Simple validation library
5
+ #
6
+ # Author: Russell Sim
7
+ # Copyright (c) 2024 Russell Sim
8
+ # SPDX-License-Identifier: MIT
9
+
10
+ require "rider_server/validate/array"
11
+ require "rider_server/validate/boolean"
12
+ require "rider_server/validate/hash"
13
+ require "rider_server/validate/integer"
14
+ require "rider_server/validate/string"
15
+ require "rider_server/validate/symbol"
@@ -8,5 +8,5 @@
8
8
  # SPDX-License-Identifier: MIT
9
9
 
10
10
  module RiderServer
11
- VERSION = "0.1.1"
11
+ VERSION = "0.1.2"
12
12
  end
@@ -90,7 +90,7 @@ module RiderServer
90
90
 
91
91
  def create_binding(obj)
92
92
  if obj.is_a?(Binding)
93
- [obj, obj.inspect]
93
+ [obj, obj.to_s]
94
94
  elsif obj.is_a?(Class)
95
95
  [obj.class_eval("binding", __FILE__, __LINE__), obj.name]
96
96
  elsif obj.is_a?(Module)
data/lib/rider_server.rb CHANGED
@@ -2,4 +2,6 @@
2
2
  # Copyright (c) 2024 Russell Sim
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- require_relative "rider_server/version"
5
+ require "rider_server/version"
6
+ require "rider_server/config"
7
+ require "rider_server/server"