Repository: Shopify/ruby-lsp (Ruby)

Issue:
Crash on git gem in Gemfile
### Description

ruby-lsp 0.21.0 crashes if you have a git gem in your Gemfile with the following format:

`gem "gem_name", git: "git@git.example.com:username/repo.git", branch: "master"`

This bug appears to have been introduced here: https://github.com/Shopify/ruby-lsp/commit/eadd4314fdee47ca1d5cfe88a14f220ba4f59977#diff-f6924adc23e6f34611ac67f8365789f93c0a71d7ccf25c626582755d85204eafR304


### Ruby LSP Information

#### VS Code Version

1.94.2

#### Ruby LSP Extension Version

0.8.12

#### Ruby LSP Server Version

Unknown

#### Ruby LSP Addons



#### Ruby Version

3.3.5

#### Ruby Version Manager

custom

#### Installed Extensions

<details>
<summary>Click to expand</summary>

- amx-netlinx (0.6.1)
- better-toml (0.3.2)
- copy-text (0.4.9)
- cpptools (1.22.10)
- csharp (2.50.27)
- elixir-ls (0.24.2)
- gitlens (15.6.2)
- go (0.42.1)
- haml (1.4.1)
- isort (2023.10.1)
- material-icon-theme (5.12.0)
- platformio-ide (3.3.3)
- postcss (2.0.0)
- python (2024.16.1)
- ruby-lsp (0.8.12)
- rust-analyzer (0.3.2162)
- vscode-dotnet-runtime (2.2.2)
- vscode-eslint (3.0.10)
- vscode-npm-script (0.3.29)
- vscode-projects-plus (1.24.0)
- vscode-zipfs (3.0.0)
</details>

#### Ruby LSP Settings

<details>
<summary>Click to expand</summary>

##### Workspace

```json
{}
```

##### User

```json
{
  "enableExperimentalFeatures": false,
  "enabledFeatures": {
    "codeActions": true,
    "diagnostics": true,
    "documentHighlights": true,
    "documentLink": true,
    "documentSymbols": true,
    "foldingRanges": true,
    "formatting": true,
    "hover": true,
    "inlayHint": true,
    "onTypeFormatting": true,
    "selectionRanges": true,
    "semanticHighlighting": true,
    "completion": true,
    "codeLens": true,
    "definition": true,
    "workspaceSymbol": true,
    "signatureHelp": true,
    "typeHierarchy": true
  },
  "featuresConfiguration": {},
  "addonSettings": {},
  "rubyVersionManager": {
    "identifier": "custom"
  },
  "customRubyCommand": "rbenv init - fish | source",
  "formatter": "auto",
  "linters": null,
  "bundleGemfile": "",
  "testTimeout": 30,
  "branch": "",
  "pullDiagnosticsOn": "both",
  "useBundlerCompose": false,
  "bypassTypechecker": false,
  "rubyExecutablePath": "",
  "indexing": {},
  "erbSupport": true,
  "useLauncher": false
}
```

</details>


**Code snippet or error message (anonymized)**
```
2024-10-31 08:48:03.930 [info] (project) /home/dan/.rbenv/versions/3.3.5/lib/ruby/3.3.0/uri/rfc3986_parser.rb:130:in `split': bad URI(is not URI?): "git@git.example.com:username/repo.git" (URI::InvalidURIError)
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/3.3.0/uri/rfc3986_parser.rb:135:in `parse'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/3.3.0/uri/common.rb:187:in `parse'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/3.3.0/uri/common.rb:848:in `URI'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/ruby-lsp-0.21.0/lib/ruby_lsp/setup_bundler.rb:357:in `block in correct_relative_remote_paths'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/ruby-lsp-0.21.0/lib/ruby_lsp/setup_bundler.rb:352:in `gsub!'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/ruby-lsp-0.21.0/lib/ruby_lsp/setup_bundler.rb:352:in `correct_relative_remote_paths'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/call_validation.rb:270:in `bind_call'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/call_validation.rb:270:in `validate_call'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/_methods.rb:277:in `block in _on_method_added'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/ruby-lsp-0.21.0/lib/ruby_lsp/setup_bundler.rb:105:in `setup!'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/call_validation.rb:270:in `bind_call'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/call_validation.rb:270:in `validate_call'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/sorbet-runtime-0.5.11577/lib/types/private/methods/_methods.rb:277:in `block in _on_method_added'
	from /home/dan/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/ruby-lsp-0.21.0/exe/ruby-lsp:75:in `<top (required)>'
	from /home/dan/.rbenv/versions/3.3/bin/ruby-lsp:25:in `load'
	from /home/dan/.rbenv/versions/3.3/bin/ruby-lsp:25:in `<main>'
```


Discussion:
Thank you for the report! Looking into it.
Just cut [v0.21.1](https://github.com/Shopify/ruby-lsp/releases/tag/v0.21.1) with the fix. Please update the global installation of the gem so that you're using the version with the fix `gem update ruby-lsp`.



Patch:
diff --git a/lib/ruby_lsp/setup_bundler.rb b/lib/ruby_lsp/setup_bundler.rb
index 316820a8db..769dfe7578 100644
--- a/lib/ruby_lsp/setup_bundler.rb
+++ b/lib/ruby_lsp/setup_bundler.rb
@@ -359,6 +359,9 @@ def correct_relative_remote_paths
         else
           match
         end
+      rescue URI::InvalidURIError, URI::InvalidComponentError
+        # If the path raises an invalid error, it might be a git ssh path, which indeed isn't a URI
+        match
       end
 
       @custom_lockfile.write(content)


Test patch:
diff --git a/test/setup_bundler_test.rb b/test/setup_bundler_test.rb
index 823c58f789..a9a3793dc7 100644
--- a/test/setup_bundler_test.rb
+++ b/test/setup_bundler_test.rb
@@ -739,6 +739,53 @@ def test_progress_is_printed_to_stderr
     end
   end
 
+  def test_succeeds_when_using_ssh_git_sources_instead_of_https
+    Dir.mktmpdir do |dir|
+      Dir.chdir(dir) do
+        File.write(File.join(dir, "Gemfile"), <<~GEMFILE)
+          source "https://rubygems.org"
+          gem "rbi", git: "git@github.com:Shopify/rbi.git", branch: "main"
+        GEMFILE
+
+        File.write(File.join(dir, "Gemfile.lock"), <<~LOCKFILE)
+          GIT
+            remote: git@github.com:Shopify/rbi.git
+            revision: d2e59a207c0b2f07d9bbaf1eb4b6d2500a4782ea
+            branch: main
+            specs:
+              rbi (0.2.1)
+                prism (~> 1.0)
+                sorbet-runtime (>= 0.5.9204)
+
+          GEM
+            remote: https://rubygems.org/
+            specs:
+              prism (1.2.0)
+              sorbet-runtime (0.5.11630)
+
+          PLATFORMS
+            arm64-darwin-23
+            ruby
+
+          DEPENDENCIES
+            rbi!
+
+          BUNDLED WITH
+            2.5.22
+        LOCKFILE
+
+        Bundler.with_unbundled_env do
+          capture_subprocess_io do
+            stub_bundle_with_env(bundle_env(dir, ".ruby-lsp/Gemfile"))
+            run_script(dir)
+          end
+        end
+
+        assert_match("remote: git@github.com:Shopify/rbi.git", File.read(".ruby-lsp/Gemfile.lock"))
+      end
+    end
+  end
+
   private
 
   def with_default_external_encoding(encoding, &block)