Skip to content

Commit

Permalink
Fix launcher file paths on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Jan 22, 2025
1 parent a7420e7 commit fdd3279
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 34 deletions.
5 changes: 4 additions & 1 deletion exe/ruby-lsp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ if ENV["BUNDLE_GEMFILE"].nil?
# which gives us the opportunity to control which specs are activated and enter degraded mode if any gems failed to
# install rather than failing to boot the server completely
if options[:launcher]
command = +"#{Gem.ruby} #{File.expand_path("ruby-lsp-launcher", __dir__)}"
# Run `/path/to/ruby /path/to/exe/ruby-lsp-launcher` and ensuring that the Windows long format path is normalized
# for exec
command = +"#{Gem.ruby.delete_prefix("//?/")} "
command << File.expand_path("ruby-lsp-launcher", __dir__).delete_prefix("//?/")
command << " --debug" if options[:debug]
exit exec(command)
end
Expand Down
34 changes: 1 addition & 33 deletions vscode/src/test/suite/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,39 +33,7 @@ import Client from "../../client";
import { WorkspaceChannel } from "../../workspaceChannel";
import { RUBY_VERSION, MAJOR, MINOR } from "../rubyVersion";

import { FAKE_TELEMETRY } from "./fakeTelemetry";

class FakeLogger {
receivedMessages = "";

trace(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

debug(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

info(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

warn(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

error(error: string | Error, ..._args: any[]): void {
this.receivedMessages += error.toString();
}

append(value: string): void {
this.receivedMessages += value;
}

appendLine(value: string): void {
this.receivedMessages += value;
}
}
import { FAKE_TELEMETRY, FakeLogger } from "./fakeTelemetry";

async function launchClient(workspaceUri: vscode.Uri) {
const workspaceFolder: vscode.WorkspaceFolder = {
Expand Down
32 changes: 32 additions & 0 deletions vscode/src/test/suite/fakeTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,35 @@ export const FAKE_TELEMETRY = vscode.env.createTelemetryLogger(
ignoreUnhandledErrors: true,
},
);

export class FakeLogger {
receivedMessages = "";

trace(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

debug(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

info(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

warn(message: string, ..._args: any[]): void {
this.receivedMessages += message;
}

error(error: string | Error, ..._args: any[]): void {
this.receivedMessages += error.toString();
}

append(value: string): void {
this.receivedMessages += value;
}

appendLine(value: string): void {
this.receivedMessages += value;
}
}
123 changes: 123 additions & 0 deletions vscode/src/test/suite/launch.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* eslint-disable no-process-env */
import assert from "assert";
import path from "path";

import * as vscode from "vscode";
import { State, WorkDoneProgress } from "vscode-languageclient/node";
import sinon from "sinon";

import { ManagerIdentifier, Ruby } from "../../ruby";
import Client from "../../client";
import { WorkspaceChannel } from "../../workspaceChannel";
import * as common from "../../common";

import { FAKE_TELEMETRY, FakeLogger } from "./fakeTelemetry";

suite("Launch integrations", () => {
const workspacePath = path.dirname(
path.dirname(path.dirname(path.dirname(__dirname))),
);
const workspaceUri = vscode.Uri.file(workspacePath);
const workspaceFolder: vscode.WorkspaceFolder = {
uri: workspaceUri,
name: path.basename(workspaceUri.fsPath),
index: 0,
};

const context = {
extensionMode: vscode.ExtensionMode.Test,
subscriptions: [],
workspaceState: {
get: (_name: string) => undefined,
update: (_name: string, _value: any) => Promise.resolve(),
},
extensionUri: vscode.Uri.joinPath(workspaceUri, "vscode"),
} as unknown as vscode.ExtensionContext;
const fakeLogger = new FakeLogger();
const outputChannel = new WorkspaceChannel("fake", fakeLogger as any);

async function createClient() {
const ruby = new Ruby(
context,
workspaceFolder,
outputChannel,
FAKE_TELEMETRY,
);

if (process.env.CI) {
await ruby.activateRuby({ identifier: ManagerIdentifier.None });

try {
await common.asyncExec("gem install ruby-lsp", {
cwd: workspacePath,
env: ruby.env,
});
} catch (error: any) {
assert.fail(`Failed to install ruby-lsp: ${error.message}`);
}
} else {
await ruby.activateRuby();
}

const client = new Client(
context,
FAKE_TELEMETRY,
ruby,
() => {},
workspaceFolder,
outputChannel,
new Map<string, string>(),
);

client.clientOptions.initializationFailedHandler = (error) => {
assert.fail(
`Failed to start server ${error.message}\n${fakeLogger.receivedMessages}`,
);
};

return client;
}

async function startClient(client: Client) {
try {
await client.start();
} catch (error: any) {
assert.fail(
`Failed to start server ${error.message}\n${fakeLogger.receivedMessages}`,
);
}
assert.strictEqual(client.state, State.Running);

// Wait for composing the bundle and indexing to finish. We don't _need_ the codebase to be indexed for these tests,
// but trying to stop the server in the middle of composing the bundle may timeout, so this makes the tests more
// robust
return new Promise<Client>((resolve) => {
client.onProgress(
WorkDoneProgress.type,
"indexing-progress",
(value: any) => {
if (value.kind === "end") {
resolve(client);
}
},
);
});
}

test("with launcher mode enabled", async () => {
const featureStub = sinon.stub(common, "featureEnabled").returns(true);
const client = await createClient();
featureStub.restore();

await startClient(client);

try {
await client.stop();
await client.dispose();
} catch (error: any) {
assert.fail(
`Failed to stop server: ${error.message}\n${fakeLogger.receivedMessages}`,
);
}
}).timeout(120000);
});

0 comments on commit fdd3279

Please sign in to comment.