Skip to content

Commit 9d4ef87

Browse files
committed
Make the Rv version manager confirm with the new detection mechanism
1 parent 110bf63 commit 9d4ef87

File tree

6 files changed

+71
-75
lines changed

6 files changed

+71
-75
lines changed

vscode/src/ruby.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -319,18 +319,6 @@ export class Ruby implements RubyInterface {
319319
}
320320

321321
private async discoverVersionManager() {
322-
const managersWithToolExists = [ManagerIdentifier.Rv];
323-
324-
for (const tool of managersWithToolExists) {
325-
const exists = await VersionManager.toolExists(tool, this.workspaceFolder, this.outputChannel);
326-
327-
if (exists) {
328-
this.versionManager = tool;
329-
return;
330-
}
331-
}
332-
333-
// Check all managers for detection
334322
const entries = Object.entries(VERSION_MANAGERS) as [ManagerIdentifier, ManagerClass][];
335323

336324
for (const [identifier, ManagerClass] of entries) {

vscode/src/ruby/mise.ts

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ export class Mise extends VersionManager {
3131
}
3232

3333
async activate(): Promise<ActivationResult> {
34-
const miseUri = await this.findMiseUri();
34+
const miseUri = await this.findVersionManagerUri(
35+
"Mise",
36+
"rubyVersionManager.miseExecutablePath",
37+
Mise.getPossiblePaths(),
38+
() => Mise.detect(this.workspaceFolder, this.outputChannel),
39+
);
3540

3641
// The exec command in Mise is called `x`
3742
const parsedResult = await this.runEnvActivationScript(`${miseUri.fsPath} x -- ruby`);
@@ -43,32 +48,4 @@ export class Mise extends VersionManager {
4348
gemPath: parsedResult.gemPath,
4449
};
4550
}
46-
47-
async findMiseUri(): Promise<vscode.Uri> {
48-
const config = vscode.workspace.getConfiguration("rubyLsp");
49-
const misePath = config.get<string | undefined>("rubyVersionManager.miseExecutablePath");
50-
51-
if (misePath) {
52-
const configuredPath = vscode.Uri.file(misePath);
53-
54-
try {
55-
await vscode.workspace.fs.stat(configuredPath);
56-
return configuredPath;
57-
} catch (_error: any) {
58-
throw new Error(`Mise executable configured as ${configuredPath.fsPath}, but that file doesn't exist`);
59-
}
60-
}
61-
62-
const detectedPath = await Mise.detect(this.workspaceFolder, this.outputChannel);
63-
64-
if (detectedPath) {
65-
return detectedPath;
66-
}
67-
68-
const possiblePaths = Mise.getPossiblePaths();
69-
throw new Error(
70-
`The Ruby LSP version manager is configured to be Mise, but could not find Mise installation. Searched in
71-
${possiblePaths.join(", ")}`,
72-
);
73-
}
7451
}

vscode/src/ruby/rv.ts

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
11
import * as vscode from "vscode";
22

33
import { VersionManager, ActivationResult } from "./versionManager";
4+
import { pathToUri } from "../common";
5+
import { WorkspaceChannel } from "../workspaceChannel";
46

57
// Manage your Ruby environment with rv
68
//
79
// Learn more: https://github.com/spinel-coop/rv
810
export class Rv extends VersionManager {
11+
private static getPossiblePaths(): vscode.Uri[] {
12+
return [
13+
pathToUri("/", "home", "linuxbrew", ".linuxbrew", "bin", "rv"),
14+
pathToUri("/", "usr", "local", "bin", "rv"),
15+
pathToUri("/", "opt", "homebrew", "bin", "rv"),
16+
pathToUri("/", "usr", "bin", "rv"),
17+
];
18+
}
19+
20+
static async detect(
21+
_workspaceFolder: vscode.WorkspaceFolder,
22+
_outputChannel: WorkspaceChannel,
23+
): Promise<vscode.Uri | undefined> {
24+
return VersionManager.findFirst(Rv.getPossiblePaths());
25+
}
26+
927
async activate(): Promise<ActivationResult> {
10-
const rvExec = await this.findRv();
11-
const parsedResult = await this.runEnvActivationScript(`${rvExec} ruby run --`);
28+
const rvExec = await this.findVersionManagerUri(
29+
"Rv",
30+
"rubyVersionManager.rvExecutablePath",
31+
Rv.getPossiblePaths(),
32+
() => Rv.detect(this.workspaceFolder, this.outputChannel),
33+
);
34+
const parsedResult = await this.runEnvActivationScript(`${rvExec.fsPath} ruby run --`);
1235

1336
return {
1437
env: { ...process.env, ...parsedResult.env },
@@ -17,30 +40,4 @@ export class Rv extends VersionManager {
1740
gemPath: parsedResult.gemPath,
1841
};
1942
}
20-
21-
private async findRv(): Promise<string> {
22-
const config = vscode.workspace.getConfiguration("rubyLsp");
23-
const configuredRvPath = config.get<string | undefined>("rubyVersionManager.rvExecutablePath");
24-
25-
if (configuredRvPath) {
26-
return this.ensureRvExistsAt(configuredRvPath);
27-
} else {
28-
const possiblePaths = [
29-
vscode.Uri.joinPath(vscode.Uri.file("/"), "home", "linuxbrew", ".linuxbrew", "bin"),
30-
vscode.Uri.joinPath(vscode.Uri.file("/"), "usr", "local", "bin"),
31-
vscode.Uri.joinPath(vscode.Uri.file("/"), "opt", "homebrew", "bin"),
32-
vscode.Uri.joinPath(vscode.Uri.file("/"), "usr", "bin"),
33-
];
34-
return this.findExec(possiblePaths, "rv");
35-
}
36-
}
37-
38-
private async ensureRvExistsAt(path: string): Promise<string> {
39-
try {
40-
await vscode.workspace.fs.stat(vscode.Uri.file(path));
41-
return path;
42-
} catch (_error: any) {
43-
throw new Error(`The Ruby LSP version manager is configured to be rv, but ${path} does not exist`);
44-
}
45-
}
4643
}

vscode/src/ruby/versionManager.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,37 @@ export abstract class VersionManager {
150150

151151
return execName;
152152
}
153+
154+
// Common helper to find a version manager executable with configuration support
155+
protected async findVersionManagerUri(
156+
managerName: string,
157+
configKey: string,
158+
possiblePaths: vscode.Uri[],
159+
detectFn: () => Promise<vscode.Uri | undefined>,
160+
): Promise<vscode.Uri> {
161+
const config = vscode.workspace.getConfiguration("rubyLsp");
162+
const configuredPath = config.get<string | undefined>(configKey);
163+
164+
if (configuredPath) {
165+
const uri = vscode.Uri.file(configuredPath);
166+
167+
try {
168+
await vscode.workspace.fs.stat(uri);
169+
return uri;
170+
} catch (_error: any) {
171+
throw new Error(`${managerName} executable configured as ${uri.fsPath}, but that file doesn't exist`);
172+
}
173+
}
174+
175+
const detectedPath = await detectFn();
176+
177+
if (detectedPath) {
178+
return detectedPath;
179+
}
180+
181+
throw new Error(
182+
`The Ruby LSP version manager is configured to be ${managerName}, but could not find ${managerName} installation. Searched in
183+
${possiblePaths.map((p) => p.fsPath).join(", ")}`,
184+
);
185+
}
153186
}

vscode/src/test/suite/ruby/mise.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ suite("Mise", () => {
5252
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
5353
});
5454
const findStub = sandbox
55-
.stub(mise, "findMiseUri")
55+
.stub(mise, "findVersionManagerUri" as any)
5656
.resolves(common.pathToUri(os.homedir(), ".local", "bin", "mise"));
5757

5858
const { env, version, yjit } = await mise.activate();

vscode/src/test/suite/ruby/rv.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ suite("Rv", () => {
5353
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
5454
});
5555

56-
// Stub findRv to return the executable path
57-
sandbox.stub(rv, "findRv" as any).resolves("rv");
56+
// Stub findVersionManagerUri to return the executable path as a Uri
57+
const rvPath = vscode.Uri.file("rv");
58+
sandbox.stub(rv, "findVersionManagerUri" as any).resolves(rvPath);
5859

5960
const { env, version, yjit } = await rv.activate();
6061

6162
assert.ok(
62-
execStub.calledOnceWithExactly(`rv ruby run -- -EUTF-8:UTF-8 '${activationPath.fsPath}'`, {
63+
execStub.calledOnceWithExactly(`${rvPath.fsPath} ruby run -- -EUTF-8:UTF-8 '${activationPath.fsPath}'`, {
6364
cwd: workspacePath,
6465
shell: vscode.env.shell,
6566

@@ -94,8 +95,8 @@ suite("Rv", () => {
9495
const rvPath = path.join(workspacePath, "rv");
9596
fs.writeFileSync(rvPath, "fakeRvBinary");
9697

97-
// Stub findRv to return the configured executable path
98-
sandbox.stub(rv, "findRv" as any).resolves(rvPath);
98+
// Stub findVersionManagerUri to return the configured executable path as a Uri
99+
sandbox.stub(rv, "findVersionManagerUri" as any).resolves(vscode.Uri.file(rvPath));
99100

100101
const configStub = sinon.stub(vscode.workspace, "getConfiguration").returns({
101102
get: (name: string) => {

0 commit comments

Comments
 (0)