Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance version manager config to accept more fields #1831

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ by clicking `Change version manager` in the language status center or by changin
// "rbenv"
// "rvm"
// "shadowenv"
"rubyLsp.rubyVersionManager": "chruby"
// "mise"
{
"rubyLsp.rubyVersionManager": {
"identifier": "chruby",
},
}
```

To make sure that the Ruby LSP can find the version manager scripts, make sure that they are loaded in the shell's
Expand Down
20 changes: 5 additions & 15 deletions vscode/VERSION_MANAGERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ If you're using a different version manager that's not supported by this extensi
executable into the PATH, you will probably need to define custom activation so that the extension can find the correct
Ruby.

For these cases, set `rubyLsp.rubyVersionManager` to `"custom"` and then set `rubyLsp.customRubyCommand` to a shell
command that will activate the right Ruby version or add the Ruby `bin` folder to the `PATH`. Some examples:
For these cases, set `rubyLsp.rubyVersionManager.identifier` to `"custom"` and then set `rubyLsp.customRubyCommand` to a
shell command that will activate the right Ruby version or add the Ruby `bin` folder to the `PATH`. Some examples:

```jsonc
{
// Don't forget to set the manager to custom when using this option
"rubyLsp.rubyVersionManager": "custom",
"rubyLsp.rubyVersionManager": {
"identifier": "custom",
},

// Using a different version manager than the ones included by default
"rubyLsp.customRubyCommand": "my_custom_version_manager activate",
Expand All @@ -25,15 +27,3 @@ command that will activate the right Ruby version or add the Ruby `bin` folder t
"rubyLsp.customRubyCommand": "PATH=/path/to/ruby/bin:$PATH",
}
```

### mise (formerly rtx)

[mise](https://github.com/jdx/mise) is a Rust clone compatible with asdf. You can use it by adding the following
snippet to your user configuration JSON

```json
{
"rubyLsp.rubyVersionManager": "custom",
"rubyLsp.customRubyCommand": "eval \"$(mise env -s zsh)\"" // Instructions for zsh, change for bash or fish
}
```
36 changes: 22 additions & 14 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,20 +232,28 @@
}
},
"rubyLsp.rubyVersionManager": {
"description": "The Ruby version manager to use",
"type": "string",
"enum": [
"asdf",
"auto",
"chruby",
"none",
"rbenv",
"rvm",
"shadowenv",
"mise",
"custom"
],
"default": "auto"
"type": "object",
"properties": {
"identifier": {
"description": "The Ruby version manager to use",
"type": "string",
"enum": [
"asdf",
"auto",
"chruby",
"none",
"rbenv",
"rvm",
"shadowenv",
"mise",
"custom"
],
"default": "auto"
}
},
"default": {
"identifier": "auto"
}
},
"rubyLsp.customRubyCommand": {
"description": "A shell command to activate the right Ruby version or add a custom Ruby bin folder to the PATH. Only used if rubyVersionManager is set to 'custom'",
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export enum Command {

export interface RubyInterface {
error: boolean;
versionManager?: string;
versionManager: { identifier: string };
rubyVersion?: string;
}

Expand Down
34 changes: 34 additions & 0 deletions vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,42 @@ export async function activate(context: vscode.ExtensionContext) {

extension = new RubyLsp(context);
await extension.activate();

await migrateManagerConfigurations();
}

export async function deactivate(): Promise<void> {
await extension.deactivate();
}

type InspectKeys =
| "globalValue"
| "workspaceValue"
| "workspaceFolderValue"
| "globalLanguageValue"
| "workspaceLanguageValue"
| "workspaceFolderLanguageValue";
// Function to migrate the old version manager configuration to the new format. Remove this after a few months
async function migrateManagerConfigurations() {
const configuration = vscode.workspace.getConfiguration("rubyLsp");
const currentManagerSettings =
configuration.inspect<string>("rubyVersionManager")!;
let identifier: string | undefined;

const targetMap: Record<InspectKeys, vscode.ConfigurationTarget> = {
globalValue: vscode.ConfigurationTarget.Global,
globalLanguageValue: vscode.ConfigurationTarget.Global,
workspaceFolderLanguageValue: vscode.ConfigurationTarget.WorkspaceFolder,
workspaceFolderValue: vscode.ConfigurationTarget.WorkspaceFolder,
workspaceLanguageValue: vscode.ConfigurationTarget.Workspace,
workspaceValue: vscode.ConfigurationTarget.Workspace,
};

for (const [key, target] of Object.entries(targetMap)) {
identifier = currentManagerSettings[key as InspectKeys];

if (identifier && typeof identifier === "string") {
await configuration.update("rubyVersionManager", { identifier }, target);
}
}
}
30 changes: 21 additions & 9 deletions vscode/src/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ export enum ManagerIdentifier {
Custom = "custom",
}

export interface ManagerConfiguration {
identifier: ManagerIdentifier;
}

export class Ruby implements RubyInterface {
public rubyVersion?: string;
// This property indicates that Ruby has been compiled with YJIT support and that we're running on a Ruby version
// where it will be activated, either by the extension or by the server
public yjitEnabled?: boolean;
private readonly workspaceFolder: vscode.WorkspaceFolder;
#versionManager?: ManagerIdentifier;
#versionManager: ManagerConfiguration = vscode.workspace
.getConfiguration("rubyLsp")
.get<ManagerConfiguration>("rubyVersionManager")!;

private readonly shell = process.env.SHELL?.replace(/(\s+)/g, "\\$1");
private _env: NodeJS.ProcessEnv = {};
Expand Down Expand Up @@ -71,12 +77,18 @@ export class Ruby implements RubyInterface {
: this.workspaceFolder.uri.fsPath;
}

get versionManager() {
get versionManager(): ManagerConfiguration {
return this.#versionManager;
}

private set versionManager(versionManager: ManagerIdentifier | undefined) {
this.#versionManager = versionManager;
private set versionManager(
versionManager: ManagerConfiguration | ManagerIdentifier,
) {
if (typeof versionManager === "string") {
this.#versionManager.identifier = versionManager;
} else {
this.#versionManager = versionManager;
}
}

get env() {
Expand All @@ -88,22 +100,22 @@ export class Ruby implements RubyInterface {
}

async activateRuby(
versionManager: ManagerIdentifier = vscode.workspace
versionManager: ManagerConfiguration = vscode.workspace
.getConfiguration("rubyLsp")
.get("rubyVersionManager")!,
.get<ManagerConfiguration>("rubyVersionManager")!,
) {
this.versionManager = versionManager;

// If the version manager is auto, discover the actual manager before trying to activate anything
if (this.versionManager === ManagerIdentifier.Auto) {
if (this.versionManager.identifier === ManagerIdentifier.Auto) {
await this.discoverVersionManager();
this.outputChannel.info(
`Discovered version manager ${this.versionManager}`,
);
}

try {
switch (this.versionManager) {
switch (this.versionManager.identifier) {
case ManagerIdentifier.Asdf:
await this.activate("asdf exec ruby");
break;
Expand Down Expand Up @@ -281,7 +293,7 @@ export class Ruby implements RubyInterface {
await vscode.workspace.fs.stat(
vscode.Uri.joinPath(this.workspaceFolder.uri, ".shadowenv.d"),
);
this.versionManager = ManagerIdentifier.Shadowenv;
this.versionManager.identifier = ManagerIdentifier.Shadowenv;
return;
} catch (error: any) {
// If .shadowenv.d doesn't exist, then we check the other version managers
Expand Down
14 changes: 8 additions & 6 deletions vscode/src/rubyLsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Telemetry } from "./telemetry";
import DocumentProvider from "./documentProvider";
import { Workspace } from "./workspace";
import { Command, STATUS_EMITTER } from "./common";
import { ManagerIdentifier } from "./ruby";
import { ManagerIdentifier, ManagerConfiguration } from "./ruby";
import { StatusItems } from "./status";
import { TestController } from "./testController";
import { Debugger } from "./debugger";
Expand Down Expand Up @@ -286,16 +286,18 @@ export class RubyLsp {
Command.SelectVersionManager,
async () => {
const configuration = vscode.workspace.getConfiguration("rubyLsp");
const managerConfig =
configuration.get<ManagerConfiguration>("rubyVersionManager")!;
const options = Object.values(ManagerIdentifier);
const manager = await vscode.window.showQuickPick(options, {
placeHolder: `Current: ${configuration.get("rubyVersionManager")}`,
});
const manager = (await vscode.window.showQuickPick(options, {
placeHolder: `Current: ${managerConfig.identifier}`,
})) as ManagerIdentifier | undefined;

if (manager !== undefined) {
managerConfig.identifier = manager;
await configuration.update(
"rubyVersionManager",
manager,
true,
managerConfig,
true,
);
}
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class RubyVersionStatus extends StatusItem {
this.item.text = "Failed to activate Ruby";
this.item.severity = vscode.LanguageStatusSeverity.Error;
} else {
this.item.text = `Using Ruby ${workspace.ruby.rubyVersion} with ${workspace.ruby.versionManager}`;
this.item.text = `Using Ruby ${workspace.ruby.rubyVersion} with ${workspace.ruby.versionManager.identifier}`;
this.item.severity = vscode.LanguageStatusSeverity.Information;
}
}
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class Telemetry {
const promises: Promise<void>[] = [
{ namespace: "workbench", field: "colorTheme" },
{ namespace: "rubyLsp", field: "enableExperimentalFeatures" },
{ namespace: "rubyLsp", field: "rubyVersionManager" },
{ namespace: "rubyLsp", field: "rubyVersionManager.identifier" },
{ namespace: "rubyLsp", field: "formatter" },
].map(({ namespace, field }) => {
return this.sendEvent({
Expand Down
7 changes: 6 additions & 1 deletion vscode/src/test/suite/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ suite("Client", () => {
if (process.env.CI) {
await vscode.workspace
.getConfiguration("rubyLsp")
.update("rubyVersionManager", ManagerIdentifier.None, true, true);
.update(
"rubyVersionManager",
{ identifier: ManagerIdentifier.None },
true,
true,
);
}
client = await launchClient(workspaceUri);
});
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/test/suite/debugger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ suite("Debugger", () => {
.returns({
get: (name: string) => {
if (name === "rubyVersionManager") {
return manager;
return { identifier: manager };
} else if (name === "bundleGemfile") {
return "";
} else if (name === "saveBeforeStart") {
Expand Down
4 changes: 2 additions & 2 deletions vscode/src/test/suite/ruby.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ suite("Ruby environment activation", () => {
.returns({
get: (name: string) => {
if (name === "rubyVersionManager") {
return manager;
return { identifier: manager };
} else if (name === "bundleGemfile") {
return "";
}
Expand Down Expand Up @@ -66,7 +66,7 @@ suite("Ruby environment activation", () => {
.returns({
get: (name: string) => {
if (name === "rubyVersionManager") {
return manager;
return { identifier: manager };
} else if (name === "bundleGemfile") {
return "";
}
Expand Down
5 changes: 4 additions & 1 deletion vscode/src/test/suite/status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ suite("StatusItems", () => {

suite("RubyVersionStatus", () => {
beforeEach(() => {
ruby = { rubyVersion: "3.2.0", versionManager: "shadowenv" } as Ruby;
ruby = {
rubyVersion: "3.2.0",
versionManager: { identifier: "shadowenv" },
} as Ruby;
workspace = {
ruby,
lspClient: {
Expand Down
Loading