diff --git a/vscode/package.json b/vscode/package.json index 24ebbf4086..a4f290d976 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -253,6 +253,10 @@ "miseExecutablePath": { "description": "The path to the Mise executable, if not installed in ~/.local/bin/mise", "type": "string" + }, + "chrubyRubies": { + "description": "An array of extra directories to search for Ruby installations when using chruby. Equivalent to the RUBIES environment variable", + "type": "array" } }, "default": { diff --git a/vscode/src/ruby/chruby.ts b/vscode/src/ruby/chruby.ts index 6f863de741..1d6ac0e248 100644 --- a/vscode/src/ruby/chruby.ts +++ b/vscode/src/ruby/chruby.ts @@ -5,6 +5,7 @@ import path from "path"; import * as vscode from "vscode"; import { asyncExec } from "../common"; +import { WorkspaceChannel } from "../workspaceChannel"; import { ActivationResult, VersionManager } from "./versionManager"; @@ -22,6 +23,23 @@ export class Chruby extends VersionManager { vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".rubies"), ]; + constructor( + workspaceFolder: vscode.WorkspaceFolder, + outputChannel: WorkspaceChannel, + ) { + super(workspaceFolder, outputChannel); + + const configuredRubies = vscode.workspace + .getConfiguration("rubyLsp") + .get("rubyVersionManager.chrubyRubies"); + + if (configuredRubies) { + this.rubyInstallationUris.push( + ...configuredRubies.map((path) => vscode.Uri.file(path)), + ); + } + } + async activate(): Promise { const versionInfo = await this.discoverRubyVersion(); const rubyUri = await this.findRubyUri(versionInfo); @@ -72,7 +90,8 @@ export class Chruby extends VersionManager { } throw new Error( - `Cannot find installation directory for Ruby version ${possibleVersionNames.join(" or ")}`, + `Cannot find installation directory for Ruby version ${possibleVersionNames.join(" or ")}. + Searched in ${this.rubyInstallationUris.map((uri) => uri.fsPath).join(", ")}`, ); } diff --git a/vscode/src/test/suite/ruby/chruby.test.ts b/vscode/src/test/suite/ruby/chruby.test.ts index cd4cd8add5..2078b7e900 100644 --- a/vscode/src/test/suite/ruby/chruby.test.ts +++ b/vscode/src/test/suite/ruby/chruby.test.ts @@ -6,6 +6,7 @@ import os from "os"; import { before, after } from "mocha"; import * as vscode from "vscode"; +import sinon from "sinon"; import { Chruby } from "../../../ruby/chruby"; import { WorkspaceChannel } from "../../../workspaceChannel"; @@ -157,4 +158,23 @@ suite("Chruby", () => { assert.strictEqual(version, RUBY_VERSION); assert.notStrictEqual(yjit, undefined); }); + + test("Finds Ruby when extra RUBIES are configured", async () => { + fs.writeFileSync(path.join(workspacePath, ".ruby-version"), RUBY_VERSION); + + const chruby = new Chruby(workspaceFolder, outputChannel); + const configStub = sinon + .stub(vscode.workspace, "getConfiguration") + .returns({ + get: () => [path.join(rootPath, "opt", "rubies")], + } as any); + + const { env, version, yjit } = await chruby.activate(); + configStub.restore(); + + assert.match(env.GEM_PATH!, new RegExp(`ruby/${VERSION_REGEX}`)); + assert.match(env.GEM_PATH!, new RegExp(`lib/ruby/gems/${VERSION_REGEX}`)); + assert.strictEqual(version, RUBY_VERSION); + assert.notStrictEqual(yjit, undefined); + }); });