Skip to content

Commit 12537e3

Browse files
committed
fix add project sdk list dynamically
1 parent 7077fdf commit 12537e3

File tree

2 files changed

+192
-141
lines changed

2 files changed

+192
-141
lines changed

media/index.html

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,7 @@ <h3>Select the project template</h3>
3939
<label for="framework">Framework</label>
4040
<br />
4141
<select id="custom-select2" name="framework">
42-
<option value="netcoreapp2.0">2.0</option>
43-
<option value="netcoreapp2.1">2.1</option>
44-
<option value="netcoreapp2.2">2.2</option>
45-
<option value="netcoreapp3.0">3.0</option>
46-
<option value="netcoreapp3.1">3.1</option>
47-
<option value="net5.0" selected="selected">5.0</option>
48-
<option value="net6.0" selected="selected">6.0</option>
42+
{{sdkOptions}}
4943
</select>
5044
<button id="create-project-button">Create Project</button>
5145
<script nonce="{{nonce}}" src="{{script}}"></script>
Lines changed: 191 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,236 @@
1-
import {window, Uri, ViewColumn, WebviewPanel, ExtensionContext, WebviewOptions, workspace} from 'vscode';
2-
import * as path from 'path';
3-
import * as fs from 'fs';
1+
import {
2+
window,
3+
Uri,
4+
ViewColumn,
5+
WebviewPanel,
6+
ExtensionContext,
7+
WebviewOptions,
8+
workspace,
9+
} from "vscode";
10+
import * as path from "path";
11+
import * as fs from "fs";
12+
import { getTargetFrameworks } from "../../utils/sdk.provider";
13+
14+
type FrameworkCommand = {
15+
[key: string]: string;
16+
};
17+
18+
const frameworkCommands: FrameworkCommand = {
19+
["3.1"]: "netcoreapp3.1",
20+
["5.0"]: "net5.0",
21+
["6.0"]: "net6.0",
22+
["7.0"]: "net7.0",
23+
["8.0"]: "net8.0",
24+
};
425

526
export class Panel {
6-
7-
readonly _context: ExtensionContext;
27+
readonly _context: ExtensionContext;
828
private _webViewPanel: WebviewPanel | undefined = undefined;
929
private _vscodeCss!: Uri;
1030
private _resetCss!: Uri;
1131
private _script!: Uri;
1232
private _projectName: string;
1333
private _solution: string;
14-
private _sdks!: Uri;
15-
34+
private _sdksResources!: Uri;
35+
private _sdks!: string[];
36+
1637
constructor(
17-
context: ExtensionContext,
18-
projectName: string,
19-
solution: string,
20-
title: string,
21-
iconPath: {folder: string, file: string} = {folder:'', file:''},
22-
viewColumn: ViewColumn = ViewColumn.One,
23-
preserveFocus: boolean = false,
24-
enableFindWidget: boolean = false,
25-
retainContextWhenHidden: boolean = false
38+
context: ExtensionContext,
39+
projectName: string,
40+
solution: string,
41+
title: string,
42+
iconPath: { folder: string; file: string } = { folder: "", file: "" },
43+
viewColumn: ViewColumn = ViewColumn.One,
44+
preserveFocus: boolean = false,
45+
enableFindWidget: boolean = false,
46+
retainContextWhenHidden: boolean = false
2647
) {
2748
// context from the extension main entry point
2849
this._context = context;
2950
this._projectName = projectName;
3051
this._solution = solution;
3152

32-
let _viewType:string = title.replace(/[^A-Z0-9]/ig,"-");
33-
53+
let _viewType: string = title.replace(/[^A-Z0-9]/gi, "-");
54+
3455
if (this._webViewPanel) {
35-
this._webViewPanel.reveal(window.activeTextEditor?.viewColumn);
56+
this._webViewPanel.reveal(window.activeTextEditor?.viewColumn);
3657
} else {
37-
// creating the panel
38-
this._webViewPanel = window.createWebviewPanel(_viewType, title, {preserveFocus, viewColumn},{enableFindWidget, retainContextWhenHidden});
39-
this._webViewPanel.iconPath = Uri.file(path.join(this._context.extensionPath,iconPath.folder, iconPath.file));
40-
41-
// webview options
42-
this._webViewPanel.webview.options = {
43-
enableCommandUris: false,
44-
enableScripts: true,
45-
localResourceRoots: [
46-
Uri.file(path.join(this._context.extensionPath, 'media')),
47-
Uri.file(path.join(this._context.extensionPath, 'out')),
48-
],
49-
portMapping: []
50-
};
51-
52-
// html content
53-
// Review: review th sdks. They are manually being inserted currently
54-
//this._sdks = this._webViewPanel.webview.asWebviewUri(Uri.file(path.join(this._context.extensionPath, 'media', 'sdks.txt')));
55-
//this._sdks = this.getTargetFrameworks(sdksResource);
56-
this._resetCss = this._webViewPanel.webview.asWebviewUri(Uri.file(path.join(this._context.extensionPath, 'media', 'reset.css')));
57-
this._vscodeCss = this._webViewPanel.webview.asWebviewUri(Uri.file(path.join(this._context.extensionPath, 'media', 'vscode.css')));
58-
this._script = this._webViewPanel.webview.asWebviewUri(Uri.file(path.join(this._context.extensionPath, 'media', 'addProject.js')));
59-
this._webViewPanel.webview.html = this.baseHtml('index.html', this._resetCss, this._vscodeCss,this._script);
58+
// creating the panel
59+
this._webViewPanel = window.createWebviewPanel(
60+
_viewType,
61+
title,
62+
{ preserveFocus, viewColumn },
63+
{ enableFindWidget, retainContextWhenHidden }
64+
);
65+
this._webViewPanel.iconPath = Uri.file(
66+
path.join(this._context.extensionPath, iconPath.folder, iconPath.file)
67+
);
68+
69+
// webview options
70+
this._webViewPanel.webview.options = {
71+
enableCommandUris: false,
72+
enableScripts: true,
73+
localResourceRoots: [
74+
Uri.file(path.join(this._context.extensionPath, "media")),
75+
Uri.file(path.join(this._context.extensionPath, "out")),
76+
],
77+
portMapping: [],
78+
};
79+
80+
this._sdksResources = this._webViewPanel.webview.asWebviewUri(
81+
Uri.file(path.join(this._context.extensionPath, "media", "sdks.txt"))
82+
);
83+
this._sdks = getTargetFrameworks(this._sdksResources);
84+
this._resetCss = this._webViewPanel.webview.asWebviewUri(
85+
Uri.file(path.join(this._context.extensionPath, "media", "reset.css"))
86+
);
87+
this._vscodeCss = this._webViewPanel.webview.asWebviewUri(
88+
Uri.file(path.join(this._context.extensionPath, "media", "vscode.css"))
89+
);
90+
this._script = this._webViewPanel.webview.asWebviewUri(
91+
Uri.file(path.join(this._context.extensionPath, "media", "addProject.js"))
92+
);
93+
this._webViewPanel.webview.html = this.baseHtml(
94+
"index.html",
95+
this._resetCss,
96+
this._vscodeCss,
97+
this._script
98+
);
6099
}
61100

62101
// control event listener
63-
this._webViewPanel.webview.onDidReceiveMessage(
64-
async (message) => {
102+
this._webViewPanel.webview.onDidReceiveMessage(async (message) => {
65103
switch (message.command) {
66-
case "addProject":
67-
await this.addProject(message);
68-
return;
104+
case "addProject":
105+
await this.addProject(message);
106+
return;
69107
}
70-
}
71-
);
72-
}
73-
74-
// TODO: Add the framework list in the add project load
75-
private getSDKs(sdksResource: Uri): string[] {
76-
77-
const sdksList: string = fs.readFileSync(sdksResource.fsPath, 'utf8');
78-
let lines: string[] = sdksList.split('\n');
79-
let sdks: string[] = [];
80-
81-
lines.forEach((line: string) => {
82-
let lineUpdated: string = line.replace(/\s+/g, '');
83-
lineUpdated = lineUpdated.replace(/[^a-z0-9A-Z.]/g,'');
84-
let sdk: string = lineUpdated.substring(0,3);
85-
if (sdk) {
86-
sdks.push(sdk);
87-
}
88-
});
89-
90-
// Eliminate duplicates
91-
sdks = sdks.filter((value, index, self) => self.indexOf(value) === index);
92-
93-
return sdks;
94-
108+
});
95109
}
96110

97111
private async addProject(message: any): Promise<void> {
98-
99-
let root = workspace.workspaceFolders?.map(folder => folder.uri.path)[0]
100-
.replace(/\//g,'\\');
101-
root = root?.slice(1, root.length);
102-
103-
const terminal = window.createTerminal();
104-
terminal.show(true);
105-
terminal.sendText("dotnet new "+message.template+" --language c# -n "+message.project+" -o "+root+"\\"+message.project+" -f "+message.framework+" --force");
106-
terminal.sendText("dotnet sln "+this._solution+" add "+root+"\\"+message.project+"\\"+message.project+".csproj");
112+
let root = workspace.workspaceFolders
113+
?.map((folder) => folder.uri.path)[0]
114+
.replace(/\//g, "\\");
115+
root = root?.slice(1, root.length);
116+
117+
// Get the framework command
118+
message.framework = frameworkCommands[message.framework];
119+
120+
const terminal = window.createTerminal();
121+
terminal.show(true);
122+
terminal.sendText(
123+
"dotnet new " +
124+
message.template +
125+
" --language c# -n " +
126+
message.project +
127+
" -o " +
128+
root +
129+
"\\" +
130+
message.project +
131+
" -f " +
132+
message.framework +
133+
" --force"
134+
);
135+
terminal.sendText(
136+
"dotnet sln " +
137+
this._solution +
138+
" add " +
139+
root +
140+
"\\" +
141+
message.project +
142+
"\\" +
143+
message.project +
144+
".csproj"
145+
);
107146
}
108147

109148
private getNonce() {
110-
let text = '';
111-
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
112-
for (let i:number = 0; i < 32; i++)
113-
{
114-
text += possible.charAt(Math.floor(Math.random() * possible.length));
115-
}
116-
return text;
149+
let text = "";
150+
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
151+
for (let i: number = 0; i < 32; i++) {
152+
text += possible.charAt(Math.floor(Math.random() * possible.length));
153+
}
154+
return text;
117155
}
118156

119-
public get webViewPanel(): WebviewPanel | undefined {return this._webViewPanel;}
120-
public set webViewPanel(panelInstance: WebviewPanel | undefined) { this._webViewPanel = panelInstance;}
157+
public get webViewPanel(): WebviewPanel | undefined {
158+
return this._webViewPanel;
159+
}
160+
public set webViewPanel(panelInstance: WebviewPanel | undefined) {
161+
this._webViewPanel = panelInstance;
162+
}
121163

122-
public set iconPath(icon: {folder: string, file: string} | {folder: string, file: string}[]) {
123-
if (this._webViewPanel) {
124-
if (Array.isArray(icon)) {
125-
this._webViewPanel.iconPath = {
126-
dark: Uri.file(path.join(this._context.extensionPath,icon[0].folder, icon[0].file)),
127-
light: Uri.file(path.join(this._context.extensionPath,icon[1].folder, icon[1].file))
128-
};
129-
} else {
130-
this._webViewPanel.iconPath = Uri.file(path.join(this._context.extensionPath,icon.folder, icon.file));
164+
public set iconPath(
165+
icon: { folder: string; file: string } | { folder: string; file: string }[]
166+
) {
167+
if (this._webViewPanel) {
168+
if (Array.isArray(icon)) {
169+
this._webViewPanel.iconPath = {
170+
dark: Uri.file(
171+
path.join(this._context.extensionPath, icon[0].folder, icon[0].file)
172+
),
173+
light: Uri.file(
174+
path.join(this._context.extensionPath, icon[1].folder, icon[1].file)
175+
),
176+
};
177+
} else {
178+
this._webViewPanel.iconPath = Uri.file(
179+
path.join(this._context.extensionPath, icon.folder, icon.file)
180+
);
181+
}
131182
}
132-
}
133183
}
134184

135185
public set options(options: WebviewOptions) {
136-
if (this._webViewPanel) {
137-
this._webViewPanel.webview.options = options;
138-
}
139-
}
140-
public allowedLocalResource(...folders: string[])
141-
{
142-
if (this._webViewPanel) {
143-
let foldersRoot: Uri[] = [];
144-
145-
for (let i:number = 0; i < folders.length; i++)
146-
{
147-
foldersRoot[i] = Uri.file(path.join(this._context.extensionPath, folders[i]));
186+
if (this._webViewPanel) {
187+
this._webViewPanel.webview.options = options;
148188
}
189+
}
190+
public allowedLocalResource(...folders: string[]) {
191+
if (this._webViewPanel) {
192+
let foldersRoot: Uri[] = [];
149193

150-
this._webViewPanel.webview.options = {
151-
localResourceRoots: foldersRoot
152-
};
153-
}
194+
for (let i: number = 0; i < folders.length; i++) {
195+
foldersRoot[i] = Uri.file(path.join(this._context.extensionPath, folders[i]));
196+
}
197+
198+
this._webViewPanel.webview.options = {
199+
localResourceRoots: foldersRoot,
200+
};
201+
}
154202
}
155203

156204
public set html(htmlDoc: string) {
157-
if (this._webViewPanel) {
158-
this._webViewPanel.webview.html = htmlDoc;
159-
};
205+
if (this._webViewPanel) {
206+
this._webViewPanel.webview.html = htmlDoc;
207+
}
160208
}
161209

162-
public addResource(content: {folder: string, resource: string}): Uri | undefined {
163-
const diskResource = Uri.file(path.join(this._context.extensionPath, content.folder, content.resource));
164-
return this._webViewPanel?.webview.asWebviewUri(diskResource);
210+
public addResource(content: { folder: string; resource: string }): Uri | undefined {
211+
const diskResource = Uri.file(
212+
path.join(this._context.extensionPath, content.folder, content.resource)
213+
);
214+
return this._webViewPanel?.webview.asWebviewUri(diskResource);
165215
}
166216

167-
private baseHtml(page:string, ...resource: Uri[]): string {
168-
let html = fs.readFileSync(path.join(this._context.extensionPath, 'media', page), 'utf-8');
169-
html = html.replace(`{{project}}`, this._projectName);
170-
html = html.replace(`{{stylesResetUri}}`, resource[0].toString());
171-
html = html.replace(`{{stylesMainUri}}`, resource[1].toString());
172-
html = html.replace(`{{script}}`, resource[2].toString());
173-
if (this._webViewPanel) {
174-
html = html.split(`{{nonce}}`).join(this.getNonce());
175-
html = html.split(`{{cspSource}}`).join( this._webViewPanel.webview.cspSource);
176-
};
177-
return html.toString();
217+
private baseHtml(page: string, ...resource: Uri[]): string {
218+
let html = fs.readFileSync(path.join(this._context.extensionPath, "media", page), "utf-8");
219+
html = html.replace(`{{project}}`, this._projectName);
220+
html = html.replace(`{{stylesResetUri}}`, resource[0].toString());
221+
html = html.replace(`{{stylesMainUri}}`, resource[1].toString());
222+
html = html.replace(`{{script}}`, resource[2].toString());
223+
224+
const sdkOptions = this._sdks
225+
.map((sdk) => `<option value="${sdk}">${sdk}</option>`)
226+
.join("");
227+
228+
html = html.replace(`{{sdkOptions}}`, sdkOptions);
229+
230+
if (this._webViewPanel) {
231+
html = html.split(`{{nonce}}`).join(this.getNonce());
232+
html = html.split(`{{cspSource}}`).join(this._webViewPanel.webview.cspSource);
233+
}
234+
return html.toString();
178235
}
179-
}
236+
}

0 commit comments

Comments
 (0)