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

Commit 1072615

Browse files
committed
Add code lens for running migrations
Adds code lens to run migrations to specific versions in the terminal. This is convenient because it allows developers to quickly rollback or fast-forward to specific schema versions with a click.
1 parent ca4f02a commit 1072615

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
"category": "Ruby LSP",
8484
"when": "editorActive && editorLangId == ruby"
8585
},
86+
{
87+
"command": "rubyLsp.runMigrationInTerminal",
88+
"title": "Run current migration in terminal",
89+
"category": "Ruby LSP",
90+
"when": "editorActive && editorLangId == ruby"
91+
},
8692
{
8793
"command": "rubyLsp.showSyntaxTree",
8894
"title": "Show syntax tree",

src/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export enum Command {
1919
RunTest = "rubyLsp.runTest",
2020
RunTestInTerminal = "rubyLsp.runTestInTerminal",
2121
DebugTest = "rubyLsp.debugTest",
22+
RunMigrationInTerminal = "rubyLsp.runMigrationInTerminal",
2223
OpenLink = "rubyLsp.openLink",
2324
ShowSyntaxTree = "rubyLsp.showSyntaxTree",
2425
}

src/migrationController.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import * as vscode from "vscode";
2+
3+
import { Telemetry } from "./telemetry";
4+
import { Workspace } from "./workspace";
5+
6+
export class MigrationController {
7+
private terminal: vscode.Terminal | undefined;
8+
private readonly telemetry: Telemetry;
9+
private readonly currentWorkspace: () => Workspace | undefined;
10+
11+
constructor(
12+
_context: vscode.ExtensionContext,
13+
telemetry: Telemetry,
14+
currentWorkspace: () => Workspace | undefined,
15+
) {
16+
this.telemetry = telemetry;
17+
this.currentWorkspace = currentWorkspace;
18+
19+
vscode.window.onDidCloseTerminal((terminal: vscode.Terminal): void => {
20+
if (terminal === this.terminal) this.terminal = undefined;
21+
});
22+
}
23+
24+
async runMigrationInTerminal(command?: string) {
25+
// eslint-disable-next-line no-param-reassign
26+
command ??= "bin/rails db:migrate";
27+
28+
if (this.terminal === undefined) {
29+
this.terminal = this.getTerminal();
30+
}
31+
32+
this.terminal.show();
33+
this.terminal.sendText(command);
34+
35+
const workspace = this.currentWorkspace();
36+
37+
if (workspace?.lspClient?.serverVersion) {
38+
await this.telemetry.sendCodeLensEvent(
39+
"migrate_in_terminal",
40+
workspace.lspClient.serverVersion,
41+
);
42+
}
43+
}
44+
45+
// Get an existing terminal or create a new one. For multiple workspaces, it's important to create a new terminal for
46+
// each workspace because they might be using different Ruby versions. If there's no workspace, we fallback to a
47+
// generic name
48+
private getTerminal() {
49+
const workspace = this.currentWorkspace();
50+
const name = workspace
51+
? `${workspace.workspaceFolder.name}: migration`
52+
: "Ruby LSP: migration";
53+
54+
const previousTerminal = vscode.window.terminals.find(
55+
(terminal) => terminal.name === name,
56+
);
57+
58+
return previousTerminal
59+
? previousTerminal
60+
: vscode.window.createTerminal({
61+
name,
62+
});
63+
}
64+
}

src/rubyLsp.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Command, STATUS_EMITTER, pathExists } from "./common";
1010
import { VersionManager } from "./ruby";
1111
import { StatusItems } from "./status";
1212
import { TestController } from "./testController";
13+
import { MigrationController } from "./migrationController";
1314
import { Debugger } from "./debugger";
1415

1516
// The RubyLsp class represents an instance of the entire extension. This should only be instantiated once at the
@@ -21,6 +22,7 @@ export class RubyLsp {
2122
private readonly context: vscode.ExtensionContext;
2223
private readonly statusItems: StatusItems;
2324
private readonly testController: TestController;
25+
private readonly migrationController: MigrationController;
2426
private readonly debug: Debugger;
2527

2628
constructor(context: vscode.ExtensionContext) {
@@ -31,6 +33,11 @@ export class RubyLsp {
3133
this.telemetry,
3234
this.currentActiveWorkspace.bind(this),
3335
);
36+
this.migrationController = new MigrationController(
37+
context,
38+
this.telemetry,
39+
this.currentActiveWorkspace.bind(this),
40+
);
3441
this.debug = new Debugger(context, this.workspaceResolver.bind(this));
3542
this.registerCommands(context);
3643

@@ -328,6 +335,10 @@ export class RubyLsp {
328335
Command.DebugTest,
329336
this.testController.debugTest.bind(this.testController),
330337
),
338+
vscode.commands.registerCommand(
339+
Command.RunMigrationInTerminal,
340+
this.testController.debugTest.bind(this.migrationController),
341+
),
331342
);
332343
}
333344

src/telemetry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface ConfigurationEvent {
2020
}
2121

2222
export interface CodeLensEvent {
23-
type: "test" | "debug" | "test_in_terminal" | "link";
23+
type: "test" | "debug" | "test_in_terminal" | "migrate_in_terminal" | "link";
2424
lspVersion: string;
2525
}
2626

0 commit comments

Comments
 (0)