-
Notifications
You must be signed in to change notification settings - Fork 253
Expand file tree
/
Copy pathrails.ts
More file actions
98 lines (77 loc) · 3.11 KB
/
rails.ts
File metadata and controls
98 lines (77 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import * as vscode from "vscode";
import { Workspace } from "./workspace";
import { isWindows } from "./common";
const BASE_COMMAND = isWindows() ? "ruby bin/rails" : "bin/rails";
export class Rails {
private readonly showWorkspacePick: () => Promise<Workspace | undefined>;
constructor(showWorkspacePick: () => Promise<Workspace | undefined>) {
this.showWorkspacePick = showWorkspacePick;
}
// Runs `bin/rails generate` with the given generator (e.g.: `controller`, `model`, etc.) and the desired arguments
async generate(generatorWithArguments: string, selectedWorkspace: Workspace | undefined) {
const workspace = selectedWorkspace ?? (await this.showWorkspacePick());
if (!workspace) {
return;
}
const createdFiles: string[] = [];
const command = `${BASE_COMMAND} generate ${generatorWithArguments}`;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: "Running Rails generate",
},
async (progress) => {
progress.report({ message: `Running "${command}"` });
const { stdout } = await workspace.execute(command, true);
stdout.split("\n").forEach((line) => {
const match = /create\s*(.*\..*)/.exec(line);
if (match) {
createdFiles.push(match[1]);
}
});
progress.report({ message: "Revealing generated files" });
await this.revealFormattedFiles(workspace, createdFiles);
},
);
}
// Invokes `bin/rails destroy` to undo the changes made by a `generate` command
async destroy(generatorWithArguments: string, selectedWorkspace: Workspace | undefined) {
const workspace = selectedWorkspace ?? (await this.showWorkspacePick());
if (!workspace) {
return;
}
const deletedFiles: string[] = [];
const command = `${BASE_COMMAND} destroy ${generatorWithArguments}`;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: "Running Rails destroy",
},
async (progress) => {
progress.report({ message: `Running "${command}"` });
const { stdout } = await workspace.execute(command, true);
stdout.split("\n").forEach((line) => {
const match = /remove\s*(.*\..*)/.exec(line);
if (match) {
deletedFiles.push(match[1]);
}
});
progress.report({ message: "Closing deleted files" });
for (const file of deletedFiles) {
await vscode.commands.executeCommand(
"workbench.action.closeActiveEditor",
vscode.Uri.joinPath(workspace.workspaceFolder.uri, file),
);
}
},
);
}
private async revealFormattedFiles(workspace: Workspace, createdFiles: string[]) {
for (const file of createdFiles) {
const uri = vscode.Uri.joinPath(workspace.workspaceFolder.uri, file);
await vscode.window.showTextDocument(uri, { preview: false });
await vscode.commands.executeCommand("editor.action.formatDocument", uri);
await vscode.commands.executeCommand("workbench.action.files.save", uri);
}
}
}