From 929422dc4f60c7fab045fd4980d72d4d4e299ffc Mon Sep 17 00:00:00 2001 From: Takumi Shotoku Date: Thu, 26 Feb 2026 00:12:30 +0900 Subject: [PATCH] Fix --port option not being passed to LSP socket server The --port CLI option was parsed correctly but never forwarded to Server.start_socket, causing the server to always bind to an OS-assigned random port. --- lib/typeprof/cli/cli.rb | 2 +- lib/typeprof/lsp/server.rb | 4 ++-- test/cli_test.rb | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/typeprof/cli/cli.rb b/lib/typeprof/cli/cli.rb index da1115a34..fe48b1d23 100644 --- a/lib/typeprof/cli/cli.rb +++ b/lib/typeprof/cli/cli.rb @@ -125,7 +125,7 @@ def run_lsp if @lsp_options[:stdio] TypeProf::LSP::Server.start_stdio(@core_options) else - TypeProf::LSP::Server.start_socket(@core_options) + TypeProf::LSP::Server.start_socket(@core_options, @lsp_options[:port]) end rescue Exception puts $!.detailed_message(highlight: false).gsub(/^/, "---") diff --git a/lib/typeprof/lsp/server.rb b/lib/typeprof/lsp/server.rb index ac811a883..92e73ad3e 100644 --- a/lib/typeprof/lsp/server.rb +++ b/lib/typeprof/lsp/server.rb @@ -21,8 +21,8 @@ def self.start_stdio(core_options) new(core_options, reader, writer).run end - def self.start_socket(core_options) - Socket.tcp_server_sockets("localhost", nil) do |servs| + def self.start_socket(core_options, port = 0) + Socket.tcp_server_sockets("localhost", port) do |servs| serv = servs[0].local_address $stdout << JSON.generate({ host: serv.ip_address, diff --git a/test/cli_test.rb b/test/cli_test.rb index 433641592..35b64ec5b 100644 --- a/test/cli_test.rb +++ b/test/cli_test.rb @@ -186,6 +186,32 @@ def test_e2e_no_show_stats assert_not_include(result, "TypeProf Evaluation Statistics") end + def test_lsp_port_option + # Find an available port from OS + tmp_server = TCPServer.new("localhost", 0) + port = tmp_server.addr[1] + tmp_server.close + + read_pipe, write_pipe = IO.pipe + original_stdout = $stdout + $stdout = write_pipe + + cli = TypeProf::CLI::CLI.new(["--lsp", "--port", port.to_s]) + th = Thread.new { cli.run } + + IO.select([read_pipe], nil, nil, 5) + output = read_pipe.read_nonblock(4096) + json = JSON.parse(output, symbolize_names: true) + + assert_equal(port, json[:port]) + ensure + th&.kill + th&.join(1) + $stdout = original_stdout + write_pipe&.close unless write_pipe&.closed? + read_pipe&.close unless read_pipe&.closed? + end + def test_lsp_options_with_lsp_mode assert_nothing_raised { TypeProf::CLI::CLI.new(["--lsp", "--stdio"]) } end