Skip to content

Commit

Permalink
Always run Ruby activation using cmd for RubyInstaller
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Aug 26, 2024
1 parent d53c934 commit 2710f33
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
19 changes: 19 additions & 0 deletions vscode/src/ruby/rubyInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import os from "os";

import * as vscode from "vscode";

import { asyncExec } from "../common";

import { Chruby } from "./chruby";

interface RubyVersion {
Expand Down Expand Up @@ -52,4 +54,21 @@ export class RubyInstaller extends Chruby {
Searched in ${possibleInstallationUris.map((uri) => uri.fsPath).join(", ")}`,
);
}

// Override the `runScript` method to ensure that we do not pass any `shell` to `asyncExec`. The activation script is
// only compatible with `cmd.exe`, and not Powershell, due to escaping of quotes. We need to ensure to always run the
// script on `cmd.exe`.
protected runScript(command: string) {
this.outputChannel.info(
`Running command: \`${command}\` in ${this.bundleUri.fsPath}`,
);
this.outputChannel.debug(
`Environment used for command: ${JSON.stringify(process.env)}`,
);

return asyncExec(command, {
cwd: this.bundleUri.fsPath,
env: process.env,
});
}
}
41 changes: 41 additions & 0 deletions vscode/src/test/suite/ruby/rubyInstaller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import assert from "assert";
import path from "path";
import os from "os";

import sinon from "sinon";
import { before, after } from "mocha";
import * as vscode from "vscode";

import * as common from "../../../common";
import { RubyInstaller } from "../../../ruby/rubyInstaller";
import { WorkspaceChannel } from "../../../workspaceChannel";
import { LOG_CHANNEL } from "../../../common";
Expand Down Expand Up @@ -100,4 +102,43 @@ suite("RubyInstaller", () => {
force: true,
});
});

test("Doesn't set the shell when invoking activation script", async () => {
const [major, minor, _patch] = RUBY_VERSION.split(".").map(Number);
fs.symlinkSync(
path.join(
"C:",
"hostedtoolcache",
"windows",
"Ruby",
RUBY_VERSION,
"x64",
),
path.join(os.homedir(), `Ruby${major}${minor}-${os.arch()}`),
);

fs.writeFileSync(path.join(workspacePath, ".ruby-version"), RUBY_VERSION);

const windows = new RubyInstaller(workspaceFolder, outputChannel);
const execStub = sinon.stub(common, "asyncExec").resolves({
stdout: "",
stderr: JSON.stringify({
env: { ANY: "true" },
yjit: true,
version: "3.0.0",
}),
});

await windows.activate();
execStub.restore();

assert.strictEqual(execStub.callCount, 1);
const callArgs = execStub.getCall(0).args;
assert.strictEqual(callArgs[1]?.shell, undefined);

fs.rmSync(path.join(os.homedir(), `Ruby${major}${minor}-${os.arch()}`), {
recursive: true,
force: true,
});
});
});

0 comments on commit 2710f33

Please sign in to comment.