Skip to content

Commit 8b4f29e

Browse files
committed
Use log trace instead of printing to stderr
1 parent d39ed11 commit 8b4f29e

File tree

9 files changed

+174
-59
lines changed

9 files changed

+174
-59
lines changed

lib/ruby_lsp/ruby_lsp_rails/addon.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ def initialize
2828
# the real client is initialized, features that depend on it will not be blocked by using the NullClient
2929
@rails_runner_client = T.let(NullClient.new, RunnerClient)
3030
@global_state = T.let(nil, T.nilable(GlobalState))
31+
@message_queue = T.let(nil, T.nilable(Thread::Queue))
3132
@addon_mutex = T.let(Mutex.new, Mutex)
3233
@client_mutex = T.let(Mutex.new, Mutex)
3334
@client_mutex.lock
3435

3536
Thread.new do
3637
@addon_mutex.synchronize do
3738
# We need to ensure the Rails client is fully loaded before we activate the server addons
38-
@client_mutex.synchronize { @rails_runner_client = RunnerClient.create_client }
39+
@client_mutex.synchronize { @rails_runner_client = RunnerClient.create_client(T.must(@message_queue)) }
3940
end
4041
end
4142
end
@@ -48,7 +49,9 @@ def rails_runner_client
4849
sig { override.params(global_state: GlobalState, message_queue: Thread::Queue).void }
4950
def activate(global_state, message_queue)
5051
@global_state = global_state
51-
$stderr.puts("Activating Ruby LSP Rails addon v#{VERSION}")
52+
@message_queue = message_queue
53+
@message_queue << Notification.window_log_message("Activating Ruby LSP Rails addon v#{VERSION}")
54+
5255
register_additional_file_watchers(global_state: global_state, message_queue: message_queue)
5356
@global_state.index.register_enhancement(IndexingEnhancement.new)
5457

lib/ruby_lsp/ruby_lsp_rails/runner_client.rb

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,28 @@ class RunnerClient
1010
class << self
1111
extend T::Sig
1212

13-
sig { returns(RunnerClient) }
14-
def create_client
13+
sig { params(message_queue: Thread::Queue).returns(RunnerClient) }
14+
def create_client(message_queue)
1515
if File.exist?("bin/rails")
16-
new
16+
new(message_queue)
1717
else
18-
$stderr.puts(<<~MSG)
19-
Ruby LSP Rails failed to locate bin/rails in the current directory: #{Dir.pwd}"
20-
MSG
21-
$stderr.puts("Server dependent features will not be available")
18+
message_queue << RubyLsp::Notification.window_log_message(
19+
<<~MESSAGE.chomp,
20+
Ruby LSP Rails failed to locate bin/rails in the current directory: #{Dir.pwd}
21+
Server dependent features will not be available
22+
MESSAGE
23+
type: RubyLsp::Constant::MessageType::WARNING,
24+
)
2225
NullClient.new
2326
end
2427
rescue Errno::ENOENT, StandardError => e # rubocop:disable Lint/ShadowedException
25-
$stderr.puts("Ruby LSP Rails failed to initialize server: #{e.message}\n#{e.backtrace&.join("\n")}")
26-
$stderr.puts("Server dependent features will not be available")
28+
message_queue << RubyLsp::Notification.window_log_message(
29+
<<~MESSAGE.chomp,
30+
Ruby LSP Rails failed to initialize server: #{e.full_message}
31+
Server dependent features will not be available
32+
MESSAGE
33+
type: Constant::MessageType::ERROR,
34+
)
2735
NullClient.new
2836
end
2937
end
@@ -39,8 +47,9 @@ class EmptyMessageError < StandardError; end
3947
sig { returns(String) }
4048
attr_reader :rails_root
4149

42-
sig { void }
43-
def initialize
50+
sig { params(message_queue: Thread::Queue).void }
51+
def initialize(message_queue)
52+
@message_queue = T.let(message_queue, Thread::Queue)
4453
@mutex = T.let(Mutex.new, Mutex)
4554
# Spring needs a Process session ID. It uses this ID to "attach" itself to the parent process, so that when the
4655
# parent ends, the spring process ends as well. If this is not set, Spring will throw an error while trying to
@@ -69,24 +78,27 @@ def initialize
6978
@stdout.binmode
7079
@stderr.binmode
7180

72-
$stderr.puts("Ruby LSP Rails booting server")
81+
@message_queue << RubyLsp::Notification.window_log_message("Ruby LSP Rails booting server")
7382
count = 0
7483

7584
begin
7685
count += 1
7786
initialize_response = T.must(read_response)
7887
@rails_root = T.let(initialize_response[:root], String)
7988
rescue EmptyMessageError
80-
$stderr.puts("Ruby LSP Rails is retrying initialize (#{count})")
89+
@message_queue << RubyLsp::Notification.window_log_message("Ruby LSP Rails is retrying initialize (#{count})")
8190
retry if count < MAX_RETRIES
8291
end
8392

84-
$stderr.puts("Finished booting Ruby LSP Rails server")
93+
@message_queue << RubyLsp::Notification.window_log_message("Finished booting Ruby LSP Rails server")
8594

8695
unless ENV["RAILS_ENV"] == "test"
8796
at_exit do
8897
if @wait_thread.alive?
89-
$stderr.puts("Ruby LSP Rails is force killing the server")
98+
@message_queue << RubyLsp::Notification.window_log_message(
99+
"Ruby LSP Rails is force killing the server",
100+
type: RubyLsp::Constant::MessageType::ERROR,
101+
)
90102
sleep(0.5) # give the server a bit of time if we already issued a shutdown notification
91103
force_kill
92104
end
@@ -100,15 +112,21 @@ def initialize
100112
def register_server_addon(server_addon_path)
101113
send_notification("server_addon/register", server_addon_path: server_addon_path)
102114
rescue IncompleteMessageError
103-
$stderr.puts("Ruby LSP Rails failed to register server addon #{server_addon_path}")
115+
@message_queue << RubyLsp::Notification.window_log_message(
116+
"Ruby LSP Rails failed to register server addon #{server_addon_path}",
117+
type: RubyLsp::Constant::MessageType::ERROR,
118+
)
104119
nil
105120
end
106121

107122
sig { params(name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
108123
def model(name)
109124
make_request("model", name: name)
110125
rescue IncompleteMessageError
111-
$stderr.puts("Ruby LSP Rails failed to get model information: #{@stderr.read}")
126+
@message_queue << RubyLsp::Notification.window_log_message(
127+
"Ruby LSP Rails failed to get model information: #{@stderr.read}",
128+
type: RubyLsp::Constant::MessageType::ERROR,
129+
)
112130
nil
113131
end
114132

@@ -125,37 +143,50 @@ def association_target_location(model_name:, association_name:)
125143
association_name: association_name,
126144
)
127145
rescue => e
128-
$stderr.puts("Ruby LSP Rails failed with #{e.message}: #{@stderr.read}")
146+
@message_queue << RubyLsp::Notification.window_log_message(
147+
"Ruby LSP Rails failed with #{e.message}: #{@stderr.read}",
148+
type: RubyLsp::Constant::MessageType::ERROR,
149+
)
150+
nil
129151
end
130152

131153
sig { params(name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
132154
def route_location(name)
133155
make_request("route_location", name: name)
134156
rescue IncompleteMessageError
135-
$stderr.puts("Ruby LSP Rails failed to get route location: #{@stderr.read}")
157+
@message_queue << RubyLsp::Notification.window_log_message(
158+
"Ruby LSP Rails failed to get route location: #{@stderr.read}",
159+
type: RubyLsp::Constant::MessageType::ERROR,
160+
)
136161
nil
137162
end
138163

139164
sig { params(controller: String, action: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
140165
def route(controller:, action:)
141166
make_request("route_info", controller: controller, action: action)
142167
rescue IncompleteMessageError
143-
$stderr.puts("Ruby LSP Rails failed to get route information: #{@stderr.read}")
168+
@message_queue << RubyLsp::Notification.window_log_message(
169+
"Ruby LSP Rails failed to get route information: #{@stderr.read}",
170+
type: RubyLsp::Constant::MessageType::ERROR,
171+
)
144172
nil
145173
end
146174

147175
sig { void }
148176
def trigger_reload
149-
$stderr.puts("Reloading Rails application")
177+
@message_queue << RubyLsp::Notification.window_log_message("Reloading Rails application")
150178
send_notification("reload")
151179
rescue IncompleteMessageError
152-
$stderr.puts("Ruby LSP Rails failed to trigger reload")
180+
@message_queue << RubyLsp::Notification.window_log_message(
181+
"Ruby LSP Rails failed to trigger reload",
182+
type: RubyLsp::Constant::MessageType::ERROR,
183+
)
153184
nil
154185
end
155186

156187
sig { void }
157188
def shutdown
158-
$stderr.puts("Ruby LSP Rails shutting down server")
189+
@message_queue << RubyLsp::Notification.window_log_message("Ruby LSP Rails shutting down server")
159190
send_message("shutdown")
160191
sleep(0.5) # give the server a bit of time to shutdown
161192
[@stdin, @stdout, @stderr].each(&:close)
@@ -214,7 +245,10 @@ def read_response
214245
response = JSON.parse(T.must(raw_response), symbolize_names: true)
215246

216247
if response[:error]
217-
$stderr.puts("Ruby LSP Rails error: " + response[:error])
248+
@message_queue << RubyLsp::Notification.window_log_message(
249+
"Ruby LSP Rails error: #{response[:error]}",
250+
type: RubyLsp::Constant::MessageType::ERROR,
251+
)
218252
return
219253
end
220254

test/ruby_lsp_rails/addon_test.rb

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,41 @@ module RubyLsp
77
module Rails
88
class AddonTest < ActiveSupport::TestCase
99
test "name returns addon name" do
10+
message_queue = Thread::Queue.new
1011
addon = Addon.new
12+
13+
thread = Thread.new do
14+
addon.rails_runner_client
15+
end
16+
17+
addon.activate(RubyLsp::GlobalState.new, message_queue)
18+
thread.join
1119
assert_equal("Ruby LSP Rails", addon.name)
20+
ensure
21+
T.must(message_queue).close
1222
end
1323

1424
test "sends reload notification if db/schema.rb is changed" do
25+
message_queue = Thread::Queue.new
1526
changes = [
1627
{
1728
uri: "file://#{dummy_root}/db/schema.rb",
1829
type: RubyLsp::Constant::FileChangeType::CHANGED,
1930
},
2031
]
2132

22-
RunnerClient.any_instance.expects(:send_notification).with("reload").once
2333
addon = Addon.new
24-
addon.workspace_did_change_watched_files(changes)
34+
35+
thread = Thread.new do
36+
client = addon.rails_runner_client
37+
client.expects(:send_notification).with("reload").once
38+
addon.workspace_did_change_watched_files(changes)
39+
end
40+
41+
addon.activate(RubyLsp::GlobalState.new, message_queue)
42+
thread.join
43+
ensure
44+
T.must(message_queue).close
2545
end
2646

2747
test "sends reload notification if a *structure.sql file is changed" do
@@ -32,9 +52,19 @@ class AddonTest < ActiveSupport::TestCase
3252
},
3353
]
3454

35-
RunnerClient.any_instance.expects(:send_notification).with("reload").once
55+
message_queue = Thread::Queue.new
3656
addon = Addon.new
37-
addon.workspace_did_change_watched_files(changes)
57+
58+
thread = Thread.new do
59+
client = addon.rails_runner_client
60+
client.expects(:send_notification).with("reload").once
61+
addon.workspace_did_change_watched_files(changes)
62+
end
63+
64+
addon.activate(RubyLsp::GlobalState.new, message_queue)
65+
thread.join
66+
ensure
67+
T.must(message_queue).close
3868
end
3969

4070
test "does not send reload notification if schema is not changed" do
@@ -45,9 +75,19 @@ class AddonTest < ActiveSupport::TestCase
4575
},
4676
]
4777

48-
RunnerClient.any_instance.expects(:send_notification).never
78+
message_queue = Thread::Queue.new
4979
addon = Addon.new
50-
addon.workspace_did_change_watched_files(changes)
80+
81+
thread = Thread.new do
82+
client = addon.rails_runner_client
83+
client.expects(:send_notification).never
84+
addon.workspace_did_change_watched_files(changes)
85+
end
86+
87+
addon.activate(RubyLsp::GlobalState.new, message_queue)
88+
thread.join
89+
ensure
90+
T.must(message_queue).close
5191
end
5292
end
5393
end

test/ruby_lsp_rails/code_lens_test.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,17 +401,15 @@ def index
401401

402402
def generate_code_lens_for_source(source, file: "/fake.rb")
403403
with_server(source, URI(file)) do |server, uri|
404-
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
404+
wait_for_rails_addon_activation
405405

406406
server.process_message(
407407
id: 1,
408408
method: "textDocument/codeLens",
409409
params: { textDocument: { uri: uri }, position: { line: 0, character: 0 } },
410410
)
411411

412-
result = server.pop_response
413-
414-
assert_instance_of(RubyLsp::Result, result)
412+
result = pop_result(server)
415413
result.response
416414
end
417415
end

test/ruby_lsp_rails/definition_test.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,15 @@ def baz; end
225225

226226
def generate_definitions_for_source(source, position)
227227
with_server(source) do |server, uri|
228-
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
228+
wait_for_rails_addon_activation
229229

230230
server.process_message(
231231
id: 1,
232232
method: "textDocument/definition",
233233
params: { textDocument: { uri: uri }, position: position },
234234
)
235235

236-
result = server.pop_response
237-
assert_instance_of(RubyLsp::Result, result)
236+
result = pop_result(server)
238237
result.response
239238
end
240239
end

test/ruby_lsp_rails/document_symbol_test.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,13 +431,16 @@ class FooModel < ApplicationRecord
431431

432432
def generate_document_symbols_for_source(source)
433433
with_server(source) do |server, uri|
434+
wait_for_rails_addon_activation
435+
434436
server.process_message(
435437
id: 1,
436438
method: "textDocument/documentSymbol",
437439
params: { textDocument: { uri: uri }, position: { line: 0, character: 0 } },
438440
)
439441

440-
server.pop_response.response
442+
result = pop_result(server)
443+
result.response
441444
end
442445
end
443446
end

test/ruby_lsp_rails/hover_test.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,16 @@ class ActiveRecord::Base
244244

245245
def hover_on_source(source, position)
246246
with_server(source, stub_no_typechecker: true) do |server, uri|
247+
wait_for_rails_addon_activation
248+
247249
server.process_message(
248250
id: 1,
249251
method: "textDocument/hover",
250252
params: { textDocument: { uri: uri }, position: position },
251253
)
252254

253-
server.pop_response.response
255+
result = pop_result(server)
256+
result.response
254257
end
255258
end
256259
end

0 commit comments

Comments
 (0)