File: ruby-lsp

package info (click to toggle)
ruby-ruby-lsp 0.26.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,676 kB
  • sloc: ruby: 35,294; javascript: 29; sh: 7; makefile: 4
file content (160 lines) | stat: -rwxr-xr-x 4,632 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env ruby
# frozen_string_literal: true

require "optparse"

original_args = ARGV.dup
options = {}
parser = OptionParser.new do |opts|
  opts.banner = "Usage: ruby-lsp [options]"

  opts.on("--version", "Print ruby-lsp version") do
    require "ruby-lsp"
    puts RubyLsp::VERSION
    exit(0)
  end

  opts.on("--debug", "Launch the Ruby LSP with a debugger attached") do
    options[:debug] = true
  end

  opts.on("--time-index", "Measure the time it takes to index the project") do
    options[:time_index] = true
  end

  opts.on(
    "--branch [BRANCH]",
    "Launch the Ruby LSP using the specified branch rather than the release version",
  ) do |branch|
    options[:branch] = branch
  end

  opts.on("--doctor", "Run troubleshooting steps") do
    options[:doctor] = true
  end

  opts.on("--use-launcher", "[EXPERIMENTAL] Use launcher mechanism to handle missing dependencies gracefully") do
    options[:launcher] = true
  end

  opts.on("-h", "--help", "Print this help") do
    puts opts.help
    puts
    puts "See https://shopify.github.io/ruby-lsp/ for more information"
    exit(0)
  end
end

begin
  parser.parse!
rescue OptionParser::InvalidOption => e
  warn(e)
  warn("")
  warn(parser.help)
  exit(1)
end

# When we're running without bundler, then we need to make sure the composed bundle is fully configured and re-execute
# using `BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle exec ruby-lsp` so that we have access to the gems that are a part of
# the application's bundle
if ENV["BUNDLE_GEMFILE"].nil?
  # Substitute the current process by the launcher. RubyGems activates all dependencies of a gem's executable eagerly,
  # but we can't have that happen because we want to invoke Bundler.setup ourselves with the composed bundle and avoid
  # duplicate spec activation errors. Replacing the process with the launcher executable will clear the activated specs,
  # which gives us the opportunity to control which specs are activated and enter degraded mode if any gems failed to
  # install rather than failing to boot the server completely
  if options[:launcher]
    flags = []
    flags << "--debug" if options[:debug]
    exit exec(Gem.ruby, File.expand_path("ruby-lsp-launcher", __dir__), *flags)
  end

  require_relative "../lib/ruby_lsp/setup_bundler"

  begin
    env = RubyLsp::SetupBundler.new(Dir.pwd, **options).setup!
  rescue RubyLsp::SetupBundler::BundleNotLocked
    warn("Project contains a Gemfile, but no Gemfile.lock. Run `bundle install` to lock gems and restart the server")
    exit(78)
  end

  bundler_path = File.join(Gem.default_bindir, "bundle")
  base_command = (!Gem.win_platform? && File.exist?(bundler_path) ? "#{Gem.ruby} #{bundler_path}" : "bundle").dup

  if env["BUNDLER_VERSION"]
    base_command << " _#{env["BUNDLER_VERSION"]}_"
  end

  exit exec(env, "#{base_command} exec ruby-lsp #{original_args.join(" ")}".strip)
end

$stdin.sync = true
$stdout.sync = true
$stderr.sync = true
$stdin.binmode
$stdout.binmode
$stderr.binmode

$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))

require "ruby_lsp/internal"

if options[:debug]
  if ["x64-mingw-ucrt", "x64-mingw32"].include?(RUBY_PLATFORM)
    $stderr.puts "Debugging is not supported on Windows"
    exit 1
  end

  begin
    ENV.delete("RUBY_DEBUG_IRB_CONSOLE")
    require "debug/open_nonstop"
  rescue LoadError
    $stderr.puts("You need to install the debug gem to use the --debug flag")
  end
end

if options[:time_index]
  index = RubyIndexer::Index.new

  time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  index.index_all
  elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start

  entries = index.instance_variable_get(:@entries)
  entries_by_entry_type = entries.values.flatten.group_by(&:class)

  puts <<~MSG
    Ruby LSP v#{RubyLsp::VERSION}: Indexing took #{elapsed_time.round(5)} seconds and generated:
    - #{entries_by_entry_type.sort_by { |k, _| k.to_s }.map { |k, v| "#{k.name.split("::").last}: #{v.size}" }.join("\n- ")}
  MSG
  return
end

if options[:doctor]
  index = RubyIndexer::Index.new

  if File.exist?(".index.yml")
    begin
      config = YAML.parse_file(".index.yml").to_ruby
    rescue => e
      abort("Error parsing config: #{e.message}")
    end
    index.configuration.apply_config(config)
  end

  puts "Globbing for indexable files"

  index.configuration.indexable_uris.each do |uri|
    puts "indexing: #{uri}"
    index.index_file(uri)
  end
  return
end

server = RubyLsp::Server.new

# Ensure all output goes out stderr by default to allow puts/p/pp to work
# without specifying output device.
$> = $stderr

server.start