Skip to content

Commit a7ec207

Browse files
committed
Improve progress states
- Show progres in treeview instead of window - Add cancellation feature (even though right now this is not implemented for custom views)
1 parent 1565904 commit a7ec207

15 files changed

+179
-111
lines changed

src/actions/AddMigrationAction.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import { CommandProvider } from '../commands/CommandProvider';
33
import { RefreshTreeCommand } from '../commands/RefreshTreeCommand';
44
import { getCommandsConfig } from '../config/config';
5+
import { TREE_VIEW_ID } from '../constants/constants';
56

67
import type { TerminalProvider } from '../terminal/TerminalProvider';
78
import {
@@ -40,13 +41,20 @@ export class AddMigrationAction extends TerminalAction {
4041
return vscode.window.withProgress(
4142
{
4243
title: 'Adding Migration...',
43-
location: vscode.ProgressLocation.Window,
44+
location: { viewId: TREE_VIEW_ID },
45+
cancellable: true,
4446
},
45-
async () => {
46-
const output = await super.run({
47+
async (_progress, cancellationToken) => {
48+
cancellationToken.onCancellationRequested(() => {
49+
this.cancel();
50+
});
51+
52+
await this.start({
4753
...this.params,
4854
migrationName,
4955
});
56+
57+
const output = await this.getOutput();
5058
const cacheId = DbContextTreeItem.getCacheId(
5159
this.workspaceRoot,
5260
this.project,

src/actions/DBContextInfoCommandAction.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22

33
import { CLI } from '../cli/CLI';
44
import { getCommandsConfig } from '../config/config';
5+
import { TREE_VIEW_ID } from '../constants/constants';
56

67
import type { TerminalProvider } from '../terminal/TerminalProvider';
78
import { TextDocumentProvider } from '../util/TextDocumentProvider';
@@ -29,15 +30,19 @@ export class DBContextInfoCommandAction extends TerminalAction {
2930
return vscode.window.withProgress(
3031
{
3132
title: 'Getting DbContext Info...',
32-
location: vscode.ProgressLocation.Window,
33+
location: { viewId: TREE_VIEW_ID },
34+
cancellable: true,
3335
},
34-
async () => {
35-
const output = CLI.getDataFromStdOut(
36-
await super.run(undefined, {
37-
removeDataFromOutput: true,
38-
asJson: true,
39-
}),
40-
);
36+
async (_progress, cancellationToken) => {
37+
cancellationToken.onCancellationRequested(() => {
38+
this.cancel();
39+
});
40+
41+
await this.start(undefined, {
42+
removeDataFromOutput: true,
43+
asJson: true,
44+
});
45+
const output = CLI.getDataFromStdOut(await this.getOutput());
4146
const uri = vscode.Uri.parse(
4247
`${TextDocumentProvider.scheme}:${output}`,
4348
);

src/actions/GenerateERDAction.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import util from 'util';
77
import { CLI } from '../cli/CLI';
88
import { getCommandsConfig, getERDConfig } from '../config/config';
99
import { TerminalAction } from './TerminalAction';
10-
import { DEFAULT_EFCORE_PROVIDERS } from '../constants/constants';
10+
import { DEFAULT_EFCORE_PROVIDERS, TREE_VIEW_ID } from '../constants/constants';
1111
import { InputWizard } from '../util/InputWizard';
1212
import { ERDiagramWebViewProvider } from '../util/ERDiagramWebViewProvider';
1313
import { ProjectFilesProvider } from '../solution/ProjectFilesProvider';
@@ -130,9 +130,13 @@ export class GenerateERDAction extends TerminalAction {
130130
return vscode.window.withProgress(
131131
{
132132
title: 'Generating diagram...',
133-
location: vscode.ProgressLocation.Window,
133+
location: { viewId: TREE_VIEW_ID },
134+
cancellable: true,
134135
},
135-
async () => {
136+
async (_progress, cancellationToken) => {
137+
cancellationToken.onCancellationRequested(() => {
138+
this.cancel();
139+
});
136140
try {
137141
// Backup any existing DbContext template
138142
const finalTemplatePathExists = fs.existsSync(finalTemplatePath);
@@ -145,21 +149,19 @@ export class GenerateERDAction extends TerminalAction {
145149
finalConfigPath,
146150
JSON.stringify(erDiagramConfig, null, 2),
147151
);
148-
149-
const output = CLI.getDataFromStdOut(
150-
await super.run(
151-
{
152-
...this.params,
153-
connectionString,
154-
provider,
155-
outputDir: this.outputDir,
156-
},
157-
{
158-
asJson: true,
159-
removeDataFromOutput: true,
160-
},
161-
),
152+
await this.start(
153+
{
154+
...this.params,
155+
connectionString,
156+
provider,
157+
outputDir: this.outputDir,
158+
},
159+
{
160+
asJson: true,
161+
removeDataFromOutput: true,
162+
},
162163
);
164+
const output = CLI.getDataFromStdOut(await this.getOutput());
163165

164166
const result = JSON.parse(output) as ScaffoldResult;
165167

src/actions/GenerateScriptAction.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22

33
import { CLI } from '../cli/CLI';
44
import { getCommandsConfig } from '../config/config';
5+
import { TREE_VIEW_ID } from '../constants/constants';
56
import type { TerminalProvider } from '../terminal/TerminalProvider';
67
import { TextDocumentProvider } from '../util/TextDocumentProvider';
78
import { TerminalAction } from './TerminalAction';
@@ -28,14 +29,17 @@ export class GenerateScriptAction extends TerminalAction {
2829
return vscode.window.withProgress(
2930
{
3031
title: 'Generating script...',
31-
location: vscode.ProgressLocation.Window,
32+
location: { viewId: TREE_VIEW_ID },
33+
cancellable: true,
3234
},
33-
async () => {
34-
const output = CLI.getDataFromStdOut(
35-
await super.run(undefined, {
36-
removeDataFromOutput: true,
37-
}),
38-
);
35+
async (_progress, cancellationToken) => {
36+
cancellationToken.onCancellationRequested(() => {
37+
this.cancel();
38+
});
39+
await this.start(undefined, {
40+
removeDataFromOutput: true,
41+
});
42+
const output = CLI.getDataFromStdOut(await this.getOutput());
3943
const uri = vscode.Uri.parse(
4044
`${TextDocumentProvider.scheme}:${output}`,
4145
);

src/actions/RemoveMigrationAction.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import { CommandProvider } from '../commands/CommandProvider';
33
import { RefreshTreeCommand } from '../commands/RefreshTreeCommand';
44
import { getCommandsConfig } from '../config/config';
5+
import { TREE_VIEW_ID } from '../constants/constants';
56
import type { TerminalProvider } from '../terminal/TerminalProvider';
67
import {
78
dbContextsCache,
@@ -31,10 +32,15 @@ export class RemoveMigrationAction extends TerminalAction {
3132
return vscode.window.withProgress(
3233
{
3334
title: 'Removing Migration...',
34-
location: vscode.ProgressLocation.Window,
35+
location: { viewId: TREE_VIEW_ID },
36+
cancellable: true,
3537
},
36-
async () => {
37-
const output = await super.run();
38+
async (_progress, cancellationToken) => {
39+
cancellationToken.onCancellationRequested(() => {
40+
this.cancel();
41+
});
42+
await this.start();
43+
const output = await this.getOutput();
3844
const cacheId = DbContextTreeItem.getCacheId(
3945
this.workspaceRoot,
4046
this.project,

src/actions/RunMigrationAction.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import { CommandProvider } from '../commands/CommandProvider';
33
import { RefreshTreeCommand } from '../commands/RefreshTreeCommand';
44
import { getCommandsConfig } from '../config/config';
5+
import { TREE_VIEW_ID } from '../constants/constants';
56
import type { TerminalProvider } from '../terminal/TerminalProvider';
67
import {
78
dbContextsCache,
@@ -33,10 +34,15 @@ export class RunMigrationAction extends TerminalAction {
3334
return vscode.window.withProgress(
3435
{
3536
title: 'Running Migration...',
36-
location: vscode.ProgressLocation.Window,
37+
location: { viewId: TREE_VIEW_ID },
38+
cancellable: true,
3739
},
38-
async () => {
39-
const output = await super.run();
40+
async (_progress, cancellationToken) => {
41+
cancellationToken.onCancellationRequested(() => {
42+
this.cancel();
43+
});
44+
await this.start();
45+
const output = await this.getOutput();
4046

4147
const cacheId = DbContextTreeItem.getCacheId(
4248
this.workspaceRoot,

src/actions/ScaffoldAction.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CLI } from '../cli/CLI';
44
import { CommandProvider } from '../commands/CommandProvider';
55
import { RefreshTreeCommand } from '../commands/RefreshTreeCommand';
66
import { getCommandsConfig } from '../config/config';
7-
import { DEFAULT_EFCORE_PROVIDERS } from '../constants/constants';
7+
import { DEFAULT_EFCORE_PROVIDERS, TREE_VIEW_ID } from '../constants/constants';
88
import { ProjectFilesProvider } from '../solution/ProjectFilesProvider';
99

1010
import type { TerminalProvider } from '../terminal/TerminalProvider';
@@ -115,26 +115,29 @@ export class ScaffoldAction extends TerminalAction {
115115
return vscode.window.withProgress(
116116
{
117117
title: 'Scaffolding...',
118-
location: vscode.ProgressLocation.Window,
118+
location: { viewId: TREE_VIEW_ID },
119+
cancellable: true,
119120
},
120-
async () => {
121+
async (_progress, cancellationToken) => {
122+
cancellationToken.onCancellationRequested(() => {
123+
this.cancel();
124+
});
125+
await this.start(
126+
{
127+
...this.params,
128+
context,
129+
connectionString,
130+
provider,
131+
outputDir,
132+
contextDir,
133+
namespace,
134+
},
135+
{
136+
asJson: true,
137+
},
138+
);
121139
const output = JSON.parse(
122-
CLI.getDataFromStdOut(
123-
await super.run(
124-
{
125-
...this.params,
126-
context,
127-
connectionString,
128-
provider,
129-
outputDir,
130-
contextDir,
131-
namespace,
132-
},
133-
{
134-
asJson: true,
135-
},
136-
),
137-
),
140+
CLI.getDataFromStdOut(await this.getOutput()),
138141
) as ScaffoldResult;
139142

140143
const uri = vscode.Uri.file(output.contextFile);

src/actions/TerminalAction.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
1-
import type { ExecOpts } from '../cli/CLI';
2-
import { CLI } from '../cli/CLI';
1+
import type { ExecOpts, ExecProcess } from '../cli/CLI';
32
import type { TerminalProvider } from '../terminal/TerminalProvider';
43
import type { IAction } from './IAction';
54

65
export abstract class TerminalAction implements IAction {
6+
private execProcess: ExecProcess | undefined;
77
constructor(
88
protected readonly terminalProvider: TerminalProvider,
99
private readonly args: string[],
1010
protected readonly params: { [key: string]: string },
1111
private readonly workingFolder: string,
1212
) {}
1313

14-
public async run(
14+
public async run(): Promise<string> {
15+
throw new Error('Not Implemented');
16+
}
17+
18+
public async start(
1519
params = this.params,
1620
execOpts?: Partial<ExecOpts>,
17-
): Promise<string> {
18-
const terminal = this.terminalProvider.provideTerminal();
19-
const args = CLI.getInterpolatedArgs(this.args, params);
20-
return await terminal.exec({
21-
cmdArgs: args,
21+
): Promise<void> {
22+
const terminal = await this.terminalProvider.provideTerminal();
23+
this.execProcess = await terminal.exec({
24+
cmdArgs: this.args,
2225
cwd: this.workingFolder,
26+
params,
2327
...execOpts,
2428
});
2529
}
30+
31+
public async getOutput(): Promise<string> {
32+
return (await this.execProcess?.output) || '';
33+
}
34+
35+
public cancel() {
36+
this.execProcess?.cmd.kill();
37+
}
2638
}

src/cli/CLI.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,22 @@ export type ExecOpts = {
1313
cwd: string;
1414
removeDataFromOutput?: boolean;
1515
asJson?: boolean;
16+
params?: { [key: string]: string };
1617
handlers?: {
1718
onStdOut?: (buffer: string) => void;
1819
onStdErr?: (buffer: string) => void;
1920
};
2021
};
2122

23+
export type ExecProcess = {
24+
cmd: ChildProcess;
25+
output: Promise<string>;
26+
args: string[];
27+
};
28+
2229
export class CLI {
2330
constructor(private readonly logger: Logger) {}
2431

25-
public static getInterpolatedArgs(
26-
args: string[],
27-
params: { [key: string]: string },
28-
) {
29-
return args.map(arg =>
30-
arg.replace(/\$[\w]+/, a => params[a.slice(1)] || ''),
31-
);
32-
}
33-
3432
public static getDataFromStdOut(output: string): string {
3533
return this.stripPrefixFromStdOut(
3634
output
@@ -92,18 +90,32 @@ export class CLI {
9290
.join('\n');
9391
}
9492

95-
public exec({ cmdArgs, cwd, handlers, asJson }: ExecOpts): {
96-
cmd: ChildProcess;
97-
output: Promise<string>;
98-
} {
99-
this.logger.info(cmdArgs.join(' '));
93+
private getInterpolatedArgs(
94+
args: string[],
95+
params: { [key: string]: string },
96+
) {
97+
return args.map(arg =>
98+
arg.replace(/\$[\w]+/, a => params[a.slice(1)] || ''),
99+
);
100+
}
101+
102+
public exec({
103+
cmdArgs,
104+
cwd,
105+
handlers,
106+
asJson,
107+
params = {},
108+
}: ExecOpts): ExecProcess {
109+
const interpolatedArgs = this.getInterpolatedArgs(cmdArgs, params);
110+
111+
this.logger.info(interpolatedArgs.join(' '));
100112

101113
const additionalArgs = ['--prefix-output'];
102-
if (asJson && !cmdArgs.includes('--json')) {
114+
if (asJson && !interpolatedArgs.includes('--json')) {
103115
additionalArgs.push('--json');
104116
}
105117

106-
const args = cmdArgs.concat(additionalArgs);
118+
const args = interpolatedArgs.concat(additionalArgs);
107119

108120
const cmd = spawn(args[0], args.slice(1), {
109121
cwd,
@@ -119,6 +131,7 @@ export class CLI {
119131

120132
return {
121133
cmd,
134+
args: interpolatedArgs,
122135
output: new Promise((res, rej) => {
123136
cmd.stdout.setEncoding('utf-8');
124137
cmd.stderr.setEncoding('utf-8');

0 commit comments

Comments
 (0)