Skip to content

Commit b5c1001

Browse files
authored
Set default output device to stderr (#451)
1 parent 00d02cc commit b5c1001

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

lib/ruby_lsp/ruby_lsp_rails/server.rb

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,22 @@ class Server
1212
VOID = Object.new
1313

1414
def initialize
15-
$stdin.sync = true
16-
$stdout.sync = true
17-
$stdin.binmode
18-
$stdout.binmode
15+
# Grab references to the original pipes so that we can change the default output device further down
16+
@stdin = $stdin
17+
@stdout = $stdout
18+
@stderr = $stderr
19+
@stdin.sync = true
20+
@stdout.sync = true
21+
@stderr.sync = true
22+
@stdin.binmode
23+
@stdout.binmode
24+
@stderr.binmode
25+
26+
# # Set the default output device to be $stderr. This means that using `puts` by itself will default to printing
27+
# # to $stderr and only explicit `$stdout.puts` will go to $stdout. This reduces the chance that output coming
28+
# # from the Rails app will be accidentally sent to the client
29+
$> = $stderr
30+
1931
@running = true
2032
end
2133

@@ -25,18 +37,18 @@ def start
2537
routes_reloader.execute_unless_loaded if routes_reloader&.respond_to?(:execute_unless_loaded)
2638

2739
initialize_result = { result: { message: "ok", root: ::Rails.root.to_s } }.to_json
28-
$stdout.write("Content-Length: #{initialize_result.length}\r\n\r\n#{initialize_result}")
40+
@stdout.write("Content-Length: #{initialize_result.length}\r\n\r\n#{initialize_result}")
2941

3042
while @running
31-
headers = $stdin.gets("\r\n\r\n")
32-
json = $stdin.read(headers[/Content-Length: (\d+)/i, 1].to_i)
43+
headers = @stdin.gets("\r\n\r\n")
44+
json = @stdin.read(headers[/Content-Length: (\d+)/i, 1].to_i)
3345

3446
request = JSON.parse(json, symbolize_names: true)
3547
response = execute(request.fetch(:method), request[:params])
3648
next if response == VOID
3749

3850
json_response = response.to_json
39-
$stdout.write("Content-Length: #{json_response.length}\r\n\r\n#{json_response}")
51+
@stdout.write("Content-Length: #{json_response.length}\r\n\r\n#{json_response}")
4052
end
4153
end
4254

test/ruby_lsp_rails/server_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,22 @@ def <(other)
134134
assert_equal "GET", result[:verb]
135135
assert_equal "/users(.:format)", result[:path]
136136
end
137+
138+
test "prints in the Rails application or server are automatically redirected to stderr" do
139+
server = RubyLsp::Rails::Server.new
140+
141+
server.instance_eval do
142+
def resolve_route_info(requirements)
143+
puts "Hello"
144+
super
145+
end
146+
end
147+
148+
stdout, stderr = capture_subprocess_io do
149+
server.execute("route_info", { controller: "UsersController", action: "index" })
150+
end
151+
152+
assert_empty(stdout)
153+
assert_equal("Hello\n", stderr)
154+
end
137155
end

0 commit comments

Comments
 (0)