Skip to content

Commit df9dded

Browse files
authored
Merge pull request #26 from badsyntax/scaffold
Add Scaffold feature
2 parents 6988416 + 1a02cc5 commit df9dded

30 files changed

+357
-47
lines changed

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"@typescript-eslint/semi": "warn",
1414
"@typescript-eslint/consistent-type-imports": "error",
1515
"@typescript-eslint/no-unused-vars": [
16-
"error",
16+
"warn",
1717
{ "argsIgnorePattern": "^_" }
1818
],
1919
"@typescript-eslint/no-floating-promises": "error",

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ A VS Code extension to manage Entity Framework migrations.
99
## Features
1010

1111
- List migrations by [`DbContext`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext)
12-
- Add/remove/run/undo migrations
12+
- Add / Remove / Run / Undo migrations
1313
- Show migration applied status
1414
- Export `DbContext` as SQL script
1515
- View `DbContext` information
16+
- [Scaffold](https://learn.microsoft.com/en-us/ef/core/cli/dotnet#dotnet-ef-dbcontext-scaffold) `DbContext` & entity types
1617

1718
## Requirements
1819

@@ -75,6 +76,8 @@ This extension contributes the following settings:
7576
"script",
7677
"--project",
7778
"\"$project\"",
79+
"--startup-project",
80+
"\"$project\"",
7881
"--context",
7982
"\"$dbContext\""
8083
],
@@ -85,6 +88,8 @@ This extension contributes the following settings:
8588
"list",
8689
"--project",
8790
"\"$project\"",
91+
"--startup-project",
92+
"\"$project\"",
8893
"--no-color",
8994
"--json"
9095
],
@@ -97,6 +102,8 @@ This extension contributes the following settings:
97102
"\"$context\"",
98103
"--project",
99104
"\"$project\"",
105+
"--startup-project",
106+
"\"$project\"",
100107
"--no-color",
101108
"--json"
102109
],
@@ -109,6 +116,28 @@ This extension contributes the following settings:
109116
"\"$dbContext\"",
110117
"--project",
111118
"\"$project\"",
119+
"--startup-project",
120+
"\"$project\"",
121+
"--no-color",
122+
"--json"
123+
],
124+
"scaffold": [
125+
"dotnet",
126+
"ef",
127+
"dbcontext",
128+
"scaffold",
129+
"\"$connectionString\"",
130+
"\"$provider\"",
131+
"--output-dir",
132+
"\"$outputDir\"",
133+
"--context",
134+
"\"$context\"",
135+
"--project",
136+
"\"$project\"",
137+
"--context-dir",
138+
"\"$contextDir\"",
139+
"--namespace",
140+
"\"$namespace\"",
112141
"--no-color",
113142
"--json"
114143
]

icons/files_dark.svg

Lines changed: 10 additions & 0 deletions
Loading

icons/files_light.svg

Lines changed: 10 additions & 0 deletions
Loading

package.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@
5858
"dark": "icons/help_dark.svg"
5959
}
6060
},
61+
{
62+
"command": "entityframework.scaffold",
63+
"title": "Scaffold",
64+
"icon": {
65+
"light": "icons/files_light.svg",
66+
"dark": "icons/files_dark.svg"
67+
}
68+
},
6169
{
6270
"command": "entityframework.refreshTree",
6371
"title": "Refresh Migrations",
@@ -121,6 +129,10 @@
121129
"command": "entityframework.dbContextInfo",
122130
"when": "false"
123131
},
132+
{
133+
"command": "entityframework.scaffold",
134+
"when": "false"
135+
},
124136
{
125137
"command": "entityframework.addMigration",
126138
"when": "false"
@@ -205,6 +217,16 @@
205217
"command": "entityframework.dbContextInfo",
206218
"when": "viewItem == dbContext",
207219
"group": "context@1"
220+
},
221+
{
222+
"command": "entityframework.scaffold",
223+
"when": "viewItem == project",
224+
"group": "inline@1"
225+
},
226+
{
227+
"command": "entityframework.scaffold",
228+
"when": "viewItem == project",
229+
"group": "context@1"
208230
}
209231
]
210232
},
@@ -267,6 +289,8 @@
267289
"script",
268290
"--project",
269291
"\"$project\"",
292+
"--startup-project",
293+
"\"$project\"",
270294
"--context",
271295
"\"$dbContext\""
272296
],
@@ -277,6 +301,8 @@
277301
"list",
278302
"--project",
279303
"\"$project\"",
304+
"--startup-project",
305+
"\"$project\"",
280306
"--no-color",
281307
"--json"
282308
],
@@ -289,6 +315,8 @@
289315
"\"$context\"",
290316
"--project",
291317
"\"$project\"",
318+
"--startup-project",
319+
"\"$project\"",
292320
"--no-color",
293321
"--json"
294322
],
@@ -301,6 +329,28 @@
301329
"\"$dbContext\"",
302330
"--project",
303331
"\"$project\"",
332+
"--startup-project",
333+
"\"$project\"",
334+
"--no-color",
335+
"--json"
336+
],
337+
"scaffold": [
338+
"dotnet",
339+
"ef",
340+
"dbcontext",
341+
"scaffold",
342+
"\"$connectionString\"",
343+
"\"$provider\"",
344+
"--output-dir",
345+
"\"$outputDir\"",
346+
"--context",
347+
"\"$context\"",
348+
"--project",
349+
"\"$project\"",
350+
"--context-dir",
351+
"\"$contextDir\"",
352+
"--namespace",
353+
"\"$namespace\"",
304354
"--no-color",
305355
"--json"
306356
]

sample_dotnet/ExampleAPI/DB/DB.cs renamed to sample_dotnet/ExampleAPI/DbContext/BloggingContext.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ public class BloggingContext : DbContext
1111

1212
public BloggingContext()
1313
{
14-
var folder = Environment.SpecialFolder.LocalApplicationData;
15-
var path = Environment.GetFolderPath(folder);
16-
DbPath = System.IO.Path.Join(path, "blogging.db");
14+
DbPath = "blogging.db";
1715
}
1816

1917
// The following configures EF to create a Sqlite database file in the

sample_dotnet/ExampleAPI/blogging.db

28 KB
Binary file not shown.

src/actions/AddMigrationAction.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ export class AddMigrationAction extends TerminalAction {
3131
public async run() {
3232
const migrationName = await vscode.window.showInputBox({
3333
title: 'Enter Migration Name',
34-
placeHolder: 'eg MigrationName',
35-
prompt: 'For example: MigrationName',
34+
prompt: 'EG: MigrationName',
3635
});
3736
if (!migrationName) {
3837
return '';

src/actions/ScaffoldAction.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import * as vscode from 'vscode';
2+
import { CLI } from '../cli/CLI';
3+
import { CommandProvider } from '../commands/CommandProvider';
4+
import { RefreshTreeCommand } from '../commands/RefreshTreeCommand';
5+
import { getCommandsConfig } from '../config/config';
6+
import { DEFAULT_EFCORE_PROVIDERS } from '../constants/constants';
7+
8+
import type { TerminalProvider } from '../terminal/TerminalProvider';
9+
import { projectsCache, ProjectTreeItem } from '../treeView/ProjectTreeItem';
10+
import type { ProjectFile } from '../types/ProjectFile';
11+
import { InputWizard } from '../util/InputWizard';
12+
13+
import { TerminalAction } from './TerminalAction';
14+
15+
type ScaffoldResult = {
16+
contextFile: string;
17+
entityTypeFiles: string[];
18+
};
19+
20+
export class ScaffoldAction extends TerminalAction {
21+
constructor(
22+
terminalProvider: TerminalProvider,
23+
private readonly projectFile: ProjectFile,
24+
) {
25+
super(
26+
terminalProvider,
27+
getCommandsConfig().scaffold,
28+
{
29+
project: projectFile.name,
30+
},
31+
projectFile.workspaceRoot,
32+
);
33+
}
34+
35+
public async run() {
36+
const packages = this.projectFile.project.packages || [];
37+
const defaultProvider =
38+
packages.find(pkg => DEFAULT_EFCORE_PROVIDERS.includes(pkg.name))?.name ||
39+
'';
40+
const [
41+
context,
42+
connectionString,
43+
provider,
44+
outputDir,
45+
contextDir,
46+
namespace,
47+
] = await InputWizard.getInputs([
48+
{
49+
options: {
50+
title: 'Context Name',
51+
value: '',
52+
},
53+
required: true,
54+
},
55+
{
56+
options: {
57+
title: 'Connection String',
58+
value: '',
59+
},
60+
required: true,
61+
},
62+
{
63+
options: {
64+
title: 'EFCore Provider',
65+
value: defaultProvider,
66+
},
67+
required: true,
68+
},
69+
{
70+
options: {
71+
title: 'Output Directory',
72+
value: 'Scaffold_Out/Models',
73+
},
74+
required: true,
75+
},
76+
{
77+
options: {
78+
title: 'Context Directory',
79+
value: 'Scaffold_Out/Context',
80+
},
81+
required: false,
82+
},
83+
{
84+
options: {
85+
title: 'Namespace',
86+
value: '',
87+
},
88+
required: false,
89+
},
90+
]);
91+
92+
if (!context || !connectionString || !provider || !outputDir) {
93+
return '';
94+
}
95+
const output = JSON.parse(
96+
CLI.getDataFromStdOut(
97+
await super.run({
98+
...this.params,
99+
context,
100+
connectionString,
101+
provider,
102+
outputDir,
103+
contextDir,
104+
namespace,
105+
}),
106+
),
107+
) as ScaffoldResult;
108+
109+
const uri = vscode.Uri.file(output.contextFile);
110+
const doc = await vscode.workspace.openTextDocument(uri);
111+
await vscode.window.showTextDocument(doc);
112+
113+
const cacheId = ProjectTreeItem.getCacheId(
114+
this.projectFile.workspaceRoot,
115+
this.projectFile.name,
116+
);
117+
projectsCache.clear(cacheId);
118+
await vscode.commands.executeCommand(
119+
CommandProvider.getCommandName(RefreshTreeCommand.commandName),
120+
false,
121+
);
122+
return '';
123+
}
124+
}

src/actions/TerminalAction.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ export abstract class TerminalAction implements IAction {
1212

1313
public async run(params = this.params): Promise<string> {
1414
const terminal = this.terminalProvider.provideTerminal();
15-
return await terminal.exec(
16-
CLI.getInterpolatedArgs(this.args, params),
17-
this.workingFolder,
18-
);
15+
const args = CLI.getInterpolatedArgs(this.args, params);
16+
return await terminal.exec(args, this.workingFolder);
1917
}
2018
}

0 commit comments

Comments
 (0)