Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

Commit

Permalink
Fallback to guessing the active workspace if none is found based on U…
Browse files Browse the repository at this point in the history
…RI (#976)

* Fallback to guessing the active workspace if none is found based on URI

* Reduce workspace dependency for launching debugger
  • Loading branch information
vinistock authored Jan 12, 2024
1 parent aeecf73 commit 79d5355
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
31 changes: 14 additions & 17 deletions src/debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export class Debugger
private debugProcess?: ChildProcessWithoutNullStreams;
private readonly console = vscode.debug.activeDebugConsole;
private readonly workspaceResolver: (
uri: vscode.Uri,
uri: vscode.Uri | undefined,
) => Workspace | undefined;

constructor(
context: vscode.ExtensionContext,
workspaceResolver: (uri: vscode.Uri) => Workspace | undefined,
workspaceResolver: (uri: vscode.Uri | undefined) => Workspace | undefined,
) {
this.workspaceResolver = workspaceResolver;

Expand Down Expand Up @@ -86,14 +86,12 @@ export class Debugger
debugConfiguration: vscode.DebugConfiguration,
_token?: vscode.CancellationToken,
): vscode.ProviderResult<vscode.DebugConfiguration> {
if (!folder) {
throw new Error("Debugging requires a workspace folder to be opened");
}

const workspace = this.workspaceResolver(folder.uri);
const workspace = this.workspaceResolver(folder?.uri);

if (!workspace) {
throw new Error(`Couldn't find workspace ${folder.name}`);
throw new Error(
`Couldn't find a workspace for URI: ${folder?.uri} or editor: ${vscode.window.activeTextEditor}`,
);
}

if (debugConfiguration.env) {
Expand All @@ -106,6 +104,8 @@ export class Debugger
debugConfiguration.env = workspace.ruby.env;
}

debugConfiguration.workspace = workspace;

const workspacePath = workspace.workspaceFolder.uri.fsPath;

let customGemfilePath = path.join(workspacePath, ".ruby-lsp", "Gemfile");
Expand Down Expand Up @@ -165,14 +165,11 @@ export class Debugger
let initialMessage = "";
let initialized = false;

const workspaceFolder = session.workspaceFolder;
if (!workspaceFolder) {
throw new Error("Debugging requires a workspace folder to be opened");
}

const cwd = workspaceFolder.uri.fsPath;
const sockPath = this.socketPath(cwd);
const configuration = session.configuration;
const workspaceFolder: vscode.WorkspaceFolder =
configuration.workspace.workspaceFolder;
const cwd = workspaceFolder.uri.fsPath;
const sockPath = this.socketPath(workspaceFolder.name);

return new Promise((resolve, reject) => {
const args = [
Expand Down Expand Up @@ -241,14 +238,14 @@ export class Debugger

// Generate a socket path so that Ruby debug doesn't have to create one for us. This makes coordination easier since
// we always know the path to the socket
private socketPath(cwd: string) {
private socketPath(workspaceName: string) {
const socketsDir = path.join("/", "tmp", "ruby-lsp-debug-sockets");
if (!fs.existsSync(socketsDir)) {
fs.mkdirSync(socketsDir);
}

let socketIndex = 0;
const prefix = `ruby-debug-${path.basename(cwd)}`;
const prefix = `ruby-debug-${workspaceName}`;
const existingSockets = fs
.readdirSync(socketsDir)
.map((file) => file)
Expand Down
24 changes: 23 additions & 1 deletion src/rubyLsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class RubyLsp {
this.telemetry,
this.currentActiveWorkspace.bind(this),
);
this.debug = new Debugger(context, this.getWorkspace.bind(this));
this.debug = new Debugger(context, this.workspaceResolver.bind(this));
this.registerCommands(context);

this.statusItems = new StatusItems();
Expand Down Expand Up @@ -359,6 +359,28 @@ export class RubyLsp {
return this.workspaces.get(uri.toString());
}

private workspaceResolver(
uri: vscode.Uri | undefined,
): Workspace | undefined {
// If no URI is passed, we try to figured out what the active workspace is
if (!uri) {
return this.currentActiveWorkspace();
}

// If a workspace is found for that URI, then we return that one
const workspace = this.workspaces.get(uri.toString());
if (workspace) {
return workspace;
}

// Otherwise, if there's a URI, but we can't find a workspace for it, we fallback to trying to figure out what the
// active workspace is. This situation may happen if we receive a workspace folder URI that is not the actual
// workspace where the Ruby application exists. For example, if you have a monorepo with client and server
// directories and the `launch.json` file is in the top level directory, then we may receive the URI for the top
// level, but the actual workspace is the server directory
return this.currentActiveWorkspace();
}

// Displays a quick pick to select which workspace to perform an action on. For example, if multiple workspaces exist,
// then we need to know which workspace to restart the language server on
private async showWorkspacePick(): Promise<Workspace | undefined> {
Expand Down

0 comments on commit 79d5355

Please sign in to comment.