Skip to content

Commit a294d28

Browse files
committed
Implement Rv using Mise as base class
1 parent 9d4ef87 commit a294d28

File tree

3 files changed

+69
-76
lines changed

3 files changed

+69
-76
lines changed

vscode/src/ruby/mise.ts

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,81 @@ import { pathToUri } from "../common";
1010
//
1111
// Learn more: https://github.com/jdx/mise
1212
export class Mise extends VersionManager {
13+
static async detect(
14+
_workspaceFolder: vscode.WorkspaceFolder,
15+
_outputChannel: WorkspaceChannel,
16+
): Promise<vscode.Uri | undefined> {
17+
return this.findFirst(this.getPossiblePaths());
18+
}
19+
20+
async activate(): Promise<ActivationResult> {
21+
const execUri = await this.findVersionManagerUri();
22+
23+
const parsedResult = await this.runEnvActivationScript(this.getExecutionCommand(execUri.fsPath));
24+
25+
return {
26+
env: { ...process.env, ...parsedResult.env },
27+
yjit: parsedResult.yjit,
28+
version: parsedResult.version,
29+
gemPath: parsedResult.gemPath,
30+
};
31+
}
32+
1333
// Possible mise installation paths
1434
//
1535
// 1. Installation from curl | sh (per mise.jdx.dev Getting Started)
1636
// 2. Homebrew M series
1737
// 3. Installation from `apt install mise`
18-
private static getPossiblePaths(): vscode.Uri[] {
38+
protected static getPossiblePaths(): vscode.Uri[] {
1939
return [
2040
pathToUri(os.homedir(), ".local", "bin", "mise"),
2141
pathToUri("/", "opt", "homebrew", "bin", "mise"),
2242
pathToUri("/", "usr", "bin", "mise"),
2343
];
2444
}
2545

26-
static async detect(
27-
_workspaceFolder: vscode.WorkspaceFolder,
28-
_outputChannel: WorkspaceChannel,
29-
): Promise<vscode.Uri | undefined> {
30-
return VersionManager.findFirst(Mise.getPossiblePaths());
46+
protected getVersionManagerName(): string {
47+
return "Mise";
3148
}
3249

33-
async activate(): Promise<ActivationResult> {
34-
const miseUri = await this.findVersionManagerUri(
35-
"Mise",
36-
"rubyVersionManager.miseExecutablePath",
37-
Mise.getPossiblePaths(),
38-
() => Mise.detect(this.workspaceFolder, this.outputChannel),
39-
);
50+
protected getConfigKey(): string {
51+
return "rubyVersionManager.miseExecutablePath";
52+
}
4053

54+
protected getExecutionCommand(executablePath: string): string {
4155
// The exec command in Mise is called `x`
42-
const parsedResult = await this.runEnvActivationScript(`${miseUri.fsPath} x -- ruby`);
56+
return `${executablePath} x -- ruby`;
57+
}
4358

44-
return {
45-
env: { ...process.env, ...parsedResult.env },
46-
yjit: parsedResult.yjit,
47-
version: parsedResult.version,
48-
gemPath: parsedResult.gemPath,
49-
};
59+
private async findVersionManagerUri(): Promise<vscode.Uri> {
60+
const constructor = this.constructor as typeof Mise;
61+
const managerName = this.getVersionManagerName();
62+
const configKey = this.getConfigKey();
63+
64+
const config = vscode.workspace.getConfiguration("rubyLsp");
65+
const configuredPath = config.get<string | undefined>(configKey);
66+
67+
if (configuredPath) {
68+
const uri = vscode.Uri.file(configuredPath);
69+
70+
try {
71+
await vscode.workspace.fs.stat(uri);
72+
return uri;
73+
} catch (_error: any) {
74+
throw new Error(`${managerName} executable configured as ${uri.fsPath}, but that file doesn't exist`);
75+
}
76+
}
77+
78+
const detectedPath = await constructor.detect(this.workspaceFolder, this.outputChannel);
79+
80+
if (detectedPath) {
81+
return detectedPath;
82+
}
83+
84+
const possiblePaths = constructor.getPossiblePaths();
85+
throw new Error(
86+
`The Ruby LSP version manager is configured to be ${managerName}, but could not find ${managerName} installation. Searched in
87+
${possiblePaths.map((p) => p.fsPath).join(", ")}`,
88+
);
5089
}
5190
}

vscode/src/ruby/rv.ts

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

3-
import { VersionManager, ActivationResult } from "./versionManager";
43
import { pathToUri } from "../common";
5-
import { WorkspaceChannel } from "../workspaceChannel";
4+
import { Mise } from "./mise";
65

76
// Manage your Ruby environment with rv
87
//
98
// Learn more: https://github.com/spinel-coop/rv
10-
export class Rv extends VersionManager {
11-
private static getPossiblePaths(): vscode.Uri[] {
9+
export class Rv extends Mise {
10+
protected static getPossiblePaths(): vscode.Uri[] {
1211
return [
1312
pathToUri("/", "home", "linuxbrew", ".linuxbrew", "bin", "rv"),
1413
pathToUri("/", "usr", "local", "bin", "rv"),
@@ -17,27 +16,15 @@ export class Rv extends VersionManager {
1716
];
1817
}
1918

20-
static async detect(
21-
_workspaceFolder: vscode.WorkspaceFolder,
22-
_outputChannel: WorkspaceChannel,
23-
): Promise<vscode.Uri | undefined> {
24-
return VersionManager.findFirst(Rv.getPossiblePaths());
19+
protected getVersionManagerName(): string {
20+
return "Rv";
2521
}
2622

27-
async activate(): Promise<ActivationResult> {
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 --`);
23+
protected getConfigKey(): string {
24+
return "rubyVersionManager.rvExecutablePath";
25+
}
3526

36-
return {
37-
env: { ...process.env, ...parsedResult.env },
38-
yjit: parsedResult.yjit,
39-
version: parsedResult.version,
40-
gemPath: parsedResult.gemPath,
41-
};
27+
protected getExecutionCommand(executablePath: string): string {
28+
return `${executablePath} ruby run --`;
4229
}
4330
}

vscode/src/ruby/versionManager.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -150,37 +150,4 @@ 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-
}
186153
}

0 commit comments

Comments
 (0)