From c447b1cce0eeefcf1e5a7000f09d59df82f9cb27 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Thu, 25 Apr 2024 15:33:48 -0400 Subject: [PATCH] Allow configuring extra chruby paths --- vscode/package.json | 4 ++++ vscode/src/ruby/chruby.ts | 26 ++++++++++++++++++++++- vscode/src/test/suite/ruby/chruby.test.ts | 18 ++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) 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..f758006551 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,15 @@ export class Chruby extends VersionManager { vscode.Uri.joinPath(vscode.Uri.file(os.homedir()), ".rubies"), ]; + constructor( + workspaceFolder: vscode.WorkspaceFolder, + outputChannel: WorkspaceChannel, + ) { + super(workspaceFolder, outputChannel); + + this.rubyInstallationUris.push(...this.extraRubies()); + } + async activate(): Promise { const versionInfo = await this.discoverRubyVersion(); const rubyUri = await this.findRubyUri(versionInfo); @@ -48,6 +58,19 @@ export class Chruby extends VersionManager { }; } + extraRubies(): vscode.Uri[] { + const rubies: vscode.Uri[] = []; + const configuredRubies = vscode.workspace + .getConfiguration("rubyLsp") + .get("rubyVersionManager.chrubyRubies"); + + if (configuredRubies) { + rubies.push(...configuredRubies.map((path) => vscode.Uri.file(path))); + } + + return rubies; + } + // Returns the full URI to the Ruby executable protected async findRubyUri(rubyVersion: RubyVersion): Promise { // If an engine was specified in the .ruby-version file, we favor looking for that first and also try just the @@ -72,7 +95,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..ca6e4ed815 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,21 @@ 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 extraRubiesStub = sinon + .stub(chruby, "extraRubies") + .returns([vscode.Uri.file(path.join(rootPath, "opt", "rubies"))]); + + const { env, version, yjit } = await chruby.activate(); + extraRubiesStub.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); + }); });