Class: Mbeditor::AvailabilityProbe
- Inherits:
-
Object
- Object
- Mbeditor::AvailabilityProbe
- Defined in:
- app/services/mbeditor/availability_probe.rb
Constant Summary collapse
- NEGATIVE_PROBE_TTL =
A tool that was found stays cached forever (nothing uninstalls mid-session), but a missing tool is re-probed after this many seconds so installing e.g. rubocop or ripgrep while the server runs is picked up.
60
Class Method Summary collapse
- .git(workspace_root) ⇒ Object
- .haml_lint(workspace_root) ⇒ Object
- .haml_lint_command(workspace_root) ⇒ Object
- .reset! ⇒ Object
- .rg ⇒ Object
- .rubocop(workspace_root) ⇒ Object
- .rubocop_command(workspace_root) ⇒ Object
-
.rubocop_server_flag(workspace_root) ⇒ Object
"--server" when rubocop supports server mode (>= 1.31) and it isn't disabled via config, else "--no-server".
- .ruby_lsp(workspace_root) ⇒ Object
- .ruby_lsp_command(workspace_root) ⇒ Object
Class Method Details
.git(workspace_root) ⇒ Object
107 108 109 110 111 112 113 |
# File 'app/services/mbeditor/availability_probe.rb', line 107 def self.git(workspace_root) key = "git:#{workspace_root}" probe_cached(key) do _out, _err, status = Open3.capture3("git", "-C", workspace_root.to_s, "rev-parse", "--is-inside-work-tree") status.success? end end |
.haml_lint(workspace_root) ⇒ Object
46 47 48 49 50 51 52 53 |
# File 'app/services/mbeditor/availability_probe.rb', line 46 def self.haml_lint(workspace_root) cmd = haml_lint_command(workspace_root) key = "haml_lint:#{cmd.join(' ')}" probe_cached(key) do _out, _err, status = Open3.capture3(*cmd, "--version") status.success? end end |
.haml_lint_command(workspace_root) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 |
# File 'app/services/mbeditor/availability_probe.rb', line 25 def self.haml_lint_command(workspace_root) root = Pathname.new(workspace_root) workspace_bin = root.join("bin", "haml-lint") return [workspace_bin.to_s] if workspace_bin.exist? begin [Gem.bin_path("haml_lint", "haml-lint")] rescue Gem::Exception, Gem::GemNotFoundException ["haml-lint"] end end |
.reset! ⇒ Object
127 128 129 130 |
# File 'app/services/mbeditor/availability_probe.rb', line 127 def self.reset! MUTEX.synchronize { @cache = {} } nil end |
.rg ⇒ Object
120 121 122 123 124 125 |
# File 'app/services/mbeditor/availability_probe.rb', line 120 def self.rg probe_cached("rg") do _out, _err, status = Open3.capture3("rg", "--version") status.success? end end |
.rubocop(workspace_root) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'app/services/mbeditor/availability_probe.rb', line 37 def self.rubocop(workspace_root) key = "rubocop:#{Mbeditor.configuration.rubocop_command}" probe_cached(key) do cmd = rubocop_command(workspace_root) _out, _err, status = Open3.capture3(*cmd, "--version") status.success? end end |
.rubocop_command(workspace_root) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'app/services/mbeditor/availability_probe.rb', line 11 def self.rubocop_command(workspace_root) root = Pathname.new(workspace_root) command = Mbeditor.configuration.rubocop_command.to_s.strip command = "rubocop" if command.empty? tokens = Shellwords.split(command) local_bin = root.join("bin", "rubocop") return [local_bin.to_s] if tokens == ["rubocop"] && local_bin.exist? tokens rescue ArgumentError ["rubocop"] end |
.rubocop_server_flag(workspace_root) ⇒ Object
"--server" when rubocop supports server mode (>= 1.31) and it isn't disabled via config, else "--no-server". Server mode keeps a daemon with the app's cop config loaded, cutting per-lint latency from seconds to ~100ms; rubocop starts/reuses the daemon automatically.
59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'app/services/mbeditor/availability_probe.rb', line 59 def self.rubocop_server_flag(workspace_root) return "--no-server" unless Mbeditor.configuration.rubocop_server key = "rubocop_server:#{Mbeditor.configuration.rubocop_command}" supported = probe_cached(key) do cmd = rubocop_command(workspace_root) # Bounded: a misbehaving rubocop_command must not hang the probe. result = ProcessRunner.call(cmd + ["--version"], timeout: 5) version = result[:stdout].to_s.strip[/\d+(?:\.\d+)+/] result[:exit_status]&.success? && version && Gem::Version.new(version) >= Gem::Version.new("1.31") end supported ? "--server" : "--no-server" end |
.ruby_lsp(workspace_root) ⇒ Object
96 97 98 99 100 101 102 103 104 105 |
# File 'app/services/mbeditor/availability_probe.rb', line 96 def self.ruby_lsp(workspace_root) return false if Mbeditor.configuration.ruby_lsp == false cmd = ruby_lsp_command(workspace_root) key = "ruby_lsp:#{cmd.join(' ')}" probe_cached(key) do result = ProcessRunner.call(cmd + ["--version"], timeout: 10, chdir: workspace_root.to_s) result[:exit_status]&.success? || false end end |
.ruby_lsp_command(workspace_root) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'app/services/mbeditor/availability_probe.rb', line 73 def self.ruby_lsp_command(workspace_root) configured = Mbeditor.configuration.ruby_lsp_command if configured return configured.map(&:to_s) if configured.is_a?(Array) begin return Shellwords.split(configured.to_s) rescue ArgumentError return ["ruby-lsp"] end end root = Pathname.new(workspace_root) local_bin = root.join("bin", "ruby-lsp") return [local_bin.to_s] if local_bin.exist? begin [Gem.bin_path("ruby-lsp", "ruby-lsp")] rescue Gem::Exception, Gem::GemNotFoundException ["bundle", "exec", "ruby-lsp"] end end |