ruby-lsp 0.26.7 → 0.26.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2fb06df12b49f414c218bd2cb6a1ef5b817dff076894fa6e2ae6585a370f172
4
- data.tar.gz: b9fef2a34f9361b8f4b3f74ecb3c64d53226964293bb01f4b7400ce1688746e9
3
+ metadata.gz: 7b12b079fa54de3410e0d0ab2db9bf2241c6413c3c61d3ead21d4bbcc9b4e7d6
4
+ data.tar.gz: dede13048ef29f79079271c7d20d505160f8fe24d495863e08be96c95207c6bf
5
5
  SHA512:
6
- metadata.gz: 5e2c4674e72af204f3b4c78b6053e205c9a4c7ffd5b99642cf78db3c469c0334f3952e3326c7b091b54974e2cd523716dcb8c0b1c17d861b9f80f87bbedd4056
7
- data.tar.gz: d3aaba57e7f33f5a46bdd12a69f7c965e50bcb95049032e1ee12c21d538f4d3ffc6220e798abd0fa6488085f9cb45fea468e7a9318097b16ba9d73923e2ea9a5
6
+ metadata.gz: 922edf8dadc38fa037d2c157c8e0b9bbbd3c759931ac6cda3070b615a3039597028672e8632507e80689f6a8f6cc793e7a1006a49bba28d72489f541e75f2fc3
7
+ data.tar.gz: 046d2d369c16a743f71750a9a6dfed945d8e21b43bb58ad357ce1098fd731dc4e7060ffebcc96e1b78a43a3b2571ac9e31d94dc6c25c380478cb54a979c0f461
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.26.7
1
+ 0.26.9
data/exe/ruby-lsp CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  require "optparse"
5
5
 
6
- original_args = ARGV.dup
7
6
  options = {}
8
7
  parser = OptionParser.new do |opts|
9
8
  opts.banner = "Usage: ruby-lsp [options]"
@@ -22,13 +21,6 @@ parser = OptionParser.new do |opts|
22
21
  options[:time_index] = true
23
22
  end
24
23
 
25
- opts.on(
26
- "--branch [BRANCH]",
27
- "Launch the Ruby LSP using the specified branch rather than the release version",
28
- ) do |branch|
29
- options[:branch] = branch
30
- end
31
-
32
24
  opts.on("--doctor", "Run troubleshooting steps") do
33
25
  options[:doctor] = true
34
26
  end
@@ -37,6 +29,10 @@ parser = OptionParser.new do |opts|
37
29
  options[:launcher] = true
38
30
  end
39
31
 
32
+ opts.on("--beta", "Use pre-release server gems") do
33
+ options[:beta] = true
34
+ end
35
+
40
36
  opts.on("-h", "--help", "Print this help") do
41
37
  puts opts.help
42
38
  puts
@@ -46,7 +42,7 @@ parser = OptionParser.new do |opts|
46
42
  end
47
43
 
48
44
  begin
49
- parser.parse!
45
+ parser.parse(ARGV)
50
46
  rescue OptionParser::InvalidOption => e
51
47
  warn(e)
52
48
  warn("")
@@ -66,6 +62,7 @@ if ENV["BUNDLE_GEMFILE"].nil?
66
62
  if options[:launcher]
67
63
  flags = []
68
64
  flags << "--debug" if options[:debug]
65
+ flags << "--beta" if options[:beta]
69
66
  exit exec(Gem.ruby, File.expand_path("ruby-lsp-launcher", __dir__), *flags)
70
67
  end
71
68
 
@@ -85,7 +82,7 @@ if ENV["BUNDLE_GEMFILE"].nil?
85
82
  base_command << " _#{env["BUNDLER_VERSION"]}_"
86
83
  end
87
84
 
88
- exit exec(env, "#{base_command} exec ruby-lsp #{original_args.join(" ")}".strip)
85
+ exit exec(env, "#{base_command} exec ruby-lsp #{ARGV.join(" ")}".strip)
89
86
  end
90
87
 
91
88
  $stdin.sync = true
@@ -20,6 +20,10 @@ reboot = false
20
20
  workspace_uri = ARGV.first
21
21
  raw_initialize_path = File.join(".ruby-lsp", "raw_initialize")
22
22
 
23
+ # Extract CLI options that affect bundle composition (e.g. --beta) from the arguments passed by the server
24
+ cli_options = {}
25
+ cli_options[:beta] = true if ARGV.include?("--beta")
26
+
23
27
  raw_initialize = if workspace_uri && !workspace_uri.start_with?("--")
24
28
  # If there's an argument without `--`, then it's the server asking to compose the bundle and passing to this
25
29
  # executable the workspace URI. We can't require gems at this point, so we built a fake initialize request manually
@@ -49,16 +53,20 @@ pid = if Gem.win_platform?
49
53
  ["-I", File.expand_path(path)]
50
54
  end
51
55
 
56
+ cli_flags = []
57
+ cli_flags << "--beta" if cli_options[:beta]
58
+
52
59
  Process.spawn(
53
60
  Gem.ruby,
54
61
  *load_path,
55
62
  File.expand_path("../lib/ruby_lsp/scripts/compose_bundle_windows.rb", __dir__),
56
63
  raw_initialize,
64
+ *cli_flags,
57
65
  )
58
66
  else
59
67
  fork do
60
68
  require_relative "../lib/ruby_lsp/scripts/compose_bundle"
61
- compose(raw_initialize)
69
+ compose(raw_initialize, **cli_options)
62
70
  end
63
71
  end
64
72
 
@@ -165,18 +165,20 @@ module RubyLsp
165
165
 
166
166
  # Check if the request was cancelled before trying to process it
167
167
  @global_state.synchronize do
168
- if id && @cancelled_requests.include?(id)
168
+ if id && @cancelled_requests.delete(id)
169
169
  send_message(Error.new(
170
170
  id: id,
171
171
  code: Constant::ErrorCodes::REQUEST_CANCELLED,
172
172
  message: "Request #{id} was cancelled",
173
173
  ))
174
- @cancelled_requests.delete(id)
174
+
175
175
  return
176
176
  end
177
177
  end
178
178
 
179
179
  process_message(message)
180
+ # Ensure we remove the request if it got cancelled while it was being processed
181
+ @cancelled_requests.delete(id)
180
182
  end
181
183
 
182
184
  #: ((Result | Error | Notification | Request) message) -> void
@@ -197,7 +199,7 @@ module RubyLsp
197
199
 
198
200
  #: (String message, ?type: Integer) -> void
199
201
  def send_log_message(message, type: Constant::MessageType::LOG)
200
- send_message(Notification.window_log_message(message, type: Constant::MessageType::LOG))
202
+ send_message(Notification.window_log_message(message, type: type))
201
203
  end
202
204
  end
203
205
  end
@@ -60,6 +60,7 @@ module RubyLsp
60
60
  @lines_to_comments = comments.to_h do |comment|
61
61
  [comment.location.end_line, comment]
62
62
  end #: Hash[Integer, Prism::Comment]
63
+ @sig_comments = {} #: Hash[Integer, Prism::Comment]
63
64
 
64
65
  dispatcher.register(
65
66
  self,
@@ -68,9 +69,20 @@ module RubyLsp
68
69
  :on_module_node_enter,
69
70
  :on_constant_write_node_enter,
70
71
  :on_constant_path_write_node_enter,
72
+ :on_call_node_enter,
71
73
  )
72
74
  end
73
75
 
76
+ #: (Prism::CallNode node) -> void
77
+ def on_call_node_enter(node)
78
+ return unless node.name == :sig
79
+
80
+ comment = @lines_to_comments[node.location.start_line - 1]
81
+ return unless comment
82
+
83
+ @sig_comments[node.location.end_line] = comment
84
+ end
85
+
74
86
  #: (Prism::DefNode node) -> void
75
87
  def on_def_node_enter(node)
76
88
  extract_document_link(node)
@@ -100,7 +112,7 @@ module RubyLsp
100
112
 
101
113
  #: (Prism::Node node) -> void
102
114
  def extract_document_link(node)
103
- comment = @lines_to_comments[node.location.start_line - 1]
115
+ comment = @lines_to_comments[node.location.start_line - 1] || @sig_comments[node.location.start_line - 1]
104
116
  return unless comment
105
117
 
106
118
  match = comment.location.slice.match(%r{(source://.*#\d+|pkg:gem/.*#.*)$})
@@ -94,7 +94,7 @@ module RubyLsp
94
94
 
95
95
  #: (Prism::MatchWriteNode node) -> void
96
96
  def on_match_write_node_leave(node)
97
- @inside_regex_capture = true if node.call.message == "=~"
97
+ @inside_regex_capture = false if node.call.message == "=~"
98
98
  end
99
99
 
100
100
  #: (Prism::DefNode node) -> void
@@ -162,7 +162,7 @@ module RubyLsp
162
162
 
163
163
  #: (Prism::SelfNode node) -> void
164
164
  def on_self_node_enter(node)
165
- @response_builder.add_token(node.location, :variable, [:default_library])
165
+ @response_builder.add_token(node.location, :variable, [:defaultLibrary])
166
166
  end
167
167
 
168
168
  #: (Prism::LocalVariableWriteNode node) -> void
@@ -43,7 +43,7 @@ module RubyLsp
43
43
  async: 6,
44
44
  modification: 7,
45
45
  documentation: 8,
46
- default_library: 9,
46
+ defaultLibrary: 9,
47
47
  }.freeze #: Hash[Symbol, Integer]
48
48
 
49
49
  #: ((^(Integer arg0) -> Integer | Prism::CodeUnitsCache) code_units_cache) -> void
@@ -184,8 +184,8 @@ module RubyLsp
184
184
  end
185
185
 
186
186
  # Encode an array of modifiers to positions onto a bit flag
187
- # For example, [:default_library] will be encoded as
188
- # 0b1000000000, as :default_library is the 10th bit according
187
+ # For example, [:defaultLibrary] will be encoded as
188
+ # 0b1000000000, as :defaultLibrary is the 10th bit according
189
189
  # to the token modifiers index map.
190
190
  #: (Array[Integer] modifiers) -> Integer
191
191
  def encode_modifiers(modifiers)
@@ -1,7 +1,7 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
- def compose(raw_initialize)
4
+ def compose(raw_initialize, **options)
5
5
  require_relative "../setup_bundler"
6
6
  require "json"
7
7
  require "uri"
@@ -12,7 +12,7 @@ def compose(raw_initialize)
12
12
  workspace_path = workspace_uri && URI(workspace_uri).to_standardized_path
13
13
  workspace_path ||= Dir.pwd
14
14
 
15
- env = RubyLsp::SetupBundler.new(workspace_path, launcher: true).setup!
15
+ env = RubyLsp::SetupBundler.new(workspace_path, launcher: true, **options).setup!
16
16
 
17
17
  File.open(File.join(".ruby-lsp", "bundle_env"), "w") do |f|
18
18
  f.flock(File::LOCK_EX)
@@ -5,4 +5,6 @@ require_relative "compose_bundle"
5
5
 
6
6
  # When this is invoked on Windows, we pass the raw initialize as an argument to this script. On other platforms, we
7
7
  # invoke the compose method from inside a forked process
8
- compose(ARGV.first)
8
+ options = {}
9
+ options[:beta] = true if ARGV.include?("--beta")
10
+ compose(ARGV.first, **options)
@@ -3,6 +3,8 @@
3
3
 
4
4
  module RubyLsp
5
5
  class Server < BaseServer
6
+ NON_REPORTABLE_SETUP_ERRORS = [Bundler::GemNotFound, Bundler::GitError].freeze #: Array[singleton(StandardError)]
7
+
6
8
  # Only for testing
7
9
  #: GlobalState
8
10
  attr_reader :global_state
@@ -315,7 +317,7 @@ module RubyLsp
315
317
 
316
318
  global_state_notifications.each { |notification| send_message(notification) }
317
319
 
318
- if @setup_error
320
+ if @setup_error && NON_REPORTABLE_SETUP_ERRORS.none? { |error_class| @setup_error.is_a?(error_class) }
319
321
  send_message(Notification.telemetry(
320
322
  type: "error",
321
323
  errorMessage: @setup_error.message,
@@ -1211,7 +1213,7 @@ module RubyLsp
1211
1213
  }
1212
1214
  end
1213
1215
  end
1214
- rescue Bundler::GemNotFound, Bundler::GemfileNotFound
1216
+ rescue Bundler::GemNotFound, Bundler::GemfileNotFound, Errno::ENOENT
1215
1217
  []
1216
1218
  end
1217
1219
 
@@ -1436,6 +1438,7 @@ module RubyLsp
1436
1438
  ),
1437
1439
  File.expand_path("../../exe/ruby-lsp-launcher", __dir__),
1438
1440
  @global_state.workspace_uri.to_s,
1441
+ *ARGV,
1439
1442
  chdir: @global_state.workspace_path,
1440
1443
  )
1441
1444
  end
@@ -34,12 +34,13 @@ module RubyLsp
34
34
  # Gems that should be kept up to date in the composed bundle. When updating, any of these gems that are not
35
35
  # already in the user's Gemfile will be updated together.
36
36
  GEMS_TO_UPDATE = ["ruby-lsp", "debug", "prism", "rbs"].freeze #: Array[String]
37
+ RUBY_LSP_MIN_VERSION = "0.18.0" #: String
37
38
 
38
39
  #: (String project_path, **untyped options) -> void
39
40
  def initialize(project_path, **options)
40
41
  @project_path = project_path
41
- @branch = options[:branch] #: String?
42
42
  @launcher = options[:launcher] #: bool?
43
+ @beta = options[:beta] #: bool?
43
44
  force_output_to_stderr! if @launcher
44
45
 
45
46
  # Regular bundle paths
@@ -59,7 +60,7 @@ module RubyLsp
59
60
  @custom_dir = Pathname.new(".ruby-lsp").expand_path(@project_path) #: Pathname
60
61
  @custom_gemfile = @custom_dir + @gemfile_name #: Pathname
61
62
  @custom_lockfile = @custom_dir + (@lockfile&.basename || "Gemfile.lock") #: Pathname
62
- @lockfile_hash_path = @custom_dir + "main_lockfile_hash" #: Pathname
63
+ @freshness_hash_path = @custom_dir + "freshness_hash" #: Pathname
63
64
  @last_updated_path = @custom_dir + "last_updated" #: Pathname
64
65
  @error_path = @custom_dir + "install_error" #: Pathname
65
66
  @already_composed_path = @custom_dir + "bundle_is_composed" #: Pathname
@@ -118,8 +119,14 @@ module RubyLsp
118
119
  return run_bundle_install(@custom_gemfile)
119
120
  end
120
121
 
121
- if @lockfile_hash && @custom_lockfile.exist? && @lockfile_hash_path.exist? &&
122
- @lockfile_hash_path.read == @lockfile_hash
122
+ # Our freshness hash determines if we need to copy the lockfile from the main app again and run bundle install
123
+ # from scratch. We use a combination of the main app's lockfile and the composed Gemfile. The goal is to
124
+ # automatically account for CLI arguments which can change the Gemfile we compose. If the CLI arguments or the
125
+ # main lockfile change, we need to make sure we're re-composing.
126
+ freshness_digest = Digest::SHA256.hexdigest("#{@lockfile_hash}#{@custom_gemfile.read}")
127
+
128
+ if @lockfile_hash && @custom_lockfile.exist? && @freshness_hash_path.exist? &&
129
+ @freshness_hash_path.read == freshness_digest
123
130
  $stderr.puts(
124
131
  "Ruby LSP> Skipping composed bundle setup since #{@custom_lockfile} already exists and is up to date",
125
132
  )
@@ -129,7 +136,7 @@ module RubyLsp
129
136
  @needs_update_path.delete if @needs_update_path.exist?
130
137
  FileUtils.cp(@lockfile.to_s, @custom_lockfile.to_s)
131
138
  correct_relative_remote_paths
132
- @lockfile_hash_path.write(@lockfile_hash)
139
+ @freshness_hash_path.write(freshness_digest)
133
140
  run_bundle_install(@custom_gemfile)
134
141
  end
135
142
 
@@ -169,9 +176,8 @@ module RubyLsp
169
176
  end
170
177
 
171
178
  unless @dependencies["ruby-lsp"]
172
- ruby_lsp_entry = +'gem "ruby-lsp", require: false, group: :development'
173
- ruby_lsp_entry << ", github: \"Shopify/ruby-lsp\", branch: \"#{@branch}\"" if @branch
174
- parts << ruby_lsp_entry
179
+ version = @beta ? "0.a" : RUBY_LSP_MIN_VERSION
180
+ parts << "gem \"ruby-lsp\", \">= #{version}\", require: false, group: :development"
175
181
  end
176
182
 
177
183
  unless @dependencies["debug"]
@@ -239,7 +245,7 @@ module RubyLsp
239
245
  # If no error occurred, then clear previous errors
240
246
  @error_path.delete if @error_path.exist?
241
247
  $stderr.puts("Ruby LSP> Composed bundle installation complete")
242
- rescue Errno::EPIPE, Bundler::HTTPError
248
+ rescue Errno::EPIPE, Bundler::HTTPError, Bundler::InstallError
243
249
  # There are cases where we expect certain errors to happen occasionally, and we don't want to write them to
244
250
  # a file, which would report to telemetry on the next launch.
245
251
  #
@@ -247,6 +253,7 @@ module RubyLsp
247
253
  # install. This situation may happen because, while running bundle install, the server is not yet ready to
248
254
  # receive shutdown requests and we may continue doing work until the process is killed.
249
255
  # - Bundler might also encounter a network error.
256
+ # - Native extension build failures (InstallError) are user environment issues that Ruby LSP cannot resolve.
250
257
  @error_path.delete if @error_path.exist?
251
258
  rescue => e
252
259
  # Write the error object to a file so that we can read it from the parent process
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.7
4
+ version: 0.26.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify