Skip to content

Commit 040dbb9

Browse files
authored
Add support for creating functions projects with dockerfiles (#3929)
* Add support for creating dockerfile projects * change to javascript * Refactor * requested changes
1 parent c433add commit 040dbb9

File tree

6 files changed

+52
-3
lines changed

6 files changed

+52
-3
lines changed

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@
181181
},
182182
"enablement": "!virtualWorkspace"
183183
},
184+
{
185+
"command": "azureFunctions.createNewProjectWithDockerfile",
186+
"title": "%azureFunctions.createNewProjectWithDockerfile%",
187+
"category": "Azure Functions",
188+
"enablement": "!virtualWorkspace"
189+
},
184190
{
185191
"command": "azureFunctions.createSlot",
186192
"title": "%azureFunctions.createSlot%",
@@ -366,6 +372,10 @@
366372
"command": "azureFunctions.createNewProject",
367373
"group": "1_projects@2"
368374
},
375+
{
376+
"command": "azureFunctions.createNewProjectWithDockerfile",
377+
"group": "1_projects@3"
378+
},
369379
{
370380
"command": "azureFunctions.deploy",
371381
"group": "2_deploy@1"

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"azureFunctions.createFunctionAppAdvanced": "Create Function App in Azure... (Advanced)",
1919
"azureFunctions.createFunctionAppDetail": "For serverless, event driven apps and automation.",
2020
"azureFunctions.createNewProject": "Create New Project...",
21+
"azureFunctions.createNewProjectWithDockerfile": "Create New Containerized Project...",
2122
"azureFunctions.createPythonVenv": "Create a virtual environment when creating a new Python project.",
2223
"azureFunctions.createSlot": "Create Slot...",
2324
"azureFunctions.deleteFunction": "Delete Function...",

src/commands/createNewProject/createNewProject.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { AzureWizard, type IActionContext } from '@microsoft/vscode-azext-utils';
6+
import { AzureWizard, UserCancelledError, type IActionContext } from '@microsoft/vscode-azext-utils';
77
import { window } from 'vscode';
88
import { latestGAVersion, tryParseFuncVersion } from '../../FuncVersion';
99
import { funcVersionSetting, projectLanguageSetting, projectOpenBehaviorSetting, projectTemplateKeySetting, type ProjectLanguage } from '../../constants';
1010
import { ext } from '../../extensionVariables';
1111
import { addLocalFuncTelemetry } from '../../funcCoreTools/getLocalFuncCoreToolsVersion';
1212
import { tryGetLocalFuncVersion } from '../../funcCoreTools/tryGetLocalFuncVersion';
13+
import { validateFuncCoreToolsInstalled } from '../../funcCoreTools/validateFuncCoreToolsInstalled';
1314
import { localize } from '../../localize';
1415
import { getGlobalSetting, getWorkspaceSetting } from '../../vsCodeConfig/settings';
1516
import type * as api from '../../vscode-azurefunctions.api';
@@ -18,6 +19,7 @@ import { FolderListStep } from './FolderListStep';
1819
import { NewProjectLanguageStep } from './NewProjectLanguageStep';
1920
import { OpenBehaviorStep } from './OpenBehaviorStep';
2021
import { OpenFolderStep } from './OpenFolderStep';
22+
import { CreateDockerfileProjectStep } from './dockerfileSteps/CreateDockerfileProjectStep';
2123

2224
/**
2325
* @deprecated Use AzureFunctionsExtensionApi.createFunction instead
@@ -54,6 +56,13 @@ export async function createNewProjectInternal(context: IActionContext, options:
5456
const wizardContext: Partial<IFunctionWizardContext> & IActionContext = Object.assign(context, options, { language, version: tryParseFuncVersion(version), projectTemplateKey });
5557
const optionalExecuteStep = options.executeStep;
5658

59+
if (optionalExecuteStep instanceof CreateDockerfileProjectStep) {
60+
const message: string = localize('installFuncTools', 'You must have the Azure Functions Core Tools installed to run this command.');
61+
if (!await validateFuncCoreToolsInstalled(context, message)) {
62+
throw new UserCancelledError('validateFuncCoreToolsInstalled');
63+
}
64+
}
65+
5766
if (options.folderPath) {
5867
FolderListStep.setProjectPath(wizardContext, options.folderPath);
5968
}
@@ -70,6 +79,7 @@ export async function createNewProjectInternal(context: IActionContext, options:
7079
promptSteps: [new FolderListStep(), new NewProjectLanguageStep(options.templateId, options.functionSettings), new OpenBehaviorStep()],
7180
executeSteps: optionalExecuteStep ? [optionalExecuteStep, new OpenFolderStep()] : [new OpenFolderStep()]
7281
});
82+
7383
await wizard.prompt();
7484
await wizard.execute();
7585

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { ext } from "@microsoft/vscode-azext-serviceconnector";
7+
import { AzureWizardExecuteStep, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
8+
import { cpUtils } from "../../../utils/cpUtils";
9+
import { type IFunctionWizardContext } from "../../createFunction/IFunctionWizardContext";
10+
11+
export class CreateDockerfileProjectStep extends AzureWizardExecuteStep<IFunctionWizardContext>{
12+
public priority: number = 100;
13+
14+
public async execute(context: IFunctionWizardContext): Promise<void> {
15+
let language = nonNullValueAndProp(context, 'language').toLowerCase();
16+
if (language === 'c#') {
17+
language = 'csharp';
18+
}
19+
20+
await cpUtils.executeCommand(ext.outputChannel, nonNullValueAndProp(context, 'projectPath'), "func", "init", "--worker-runtime", language, "--docker");
21+
}
22+
23+
public shouldExecute(): boolean {
24+
return true;
25+
}
26+
}

src/commands/registerCommands.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import { copyFunctionUrl } from './copyFunctionUrl';
2525
import { createChildNode } from './createChildNode';
2626
import { createFunctionFromCommand } from './createFunction/createFunction';
2727
import { createFunctionApp, createFunctionAppAdvanced } from './createFunctionApp/createFunctionApp';
28-
import { createNewProjectFromCommand } from './createNewProject/createNewProject';
28+
import { createNewProjectFromCommand, createNewProjectInternal } from './createNewProject/createNewProject';
29+
import { CreateDockerfileProjectStep } from './createNewProject/dockerfileSteps/CreateDockerfileProjectStep';
2930
import { createSlot } from './createSlot';
3031
import { deleteFunction } from './deleteFunction';
3132
import { deleteFunctionApp } from './deleteFunctionApp';
@@ -79,6 +80,7 @@ export function registerCommands(): void {
7980
registerCommandWithTreeNodeUnwrapping('azureFunctions.createFunctionApp', createFunctionApp);
8081
registerCommandWithTreeNodeUnwrapping('azureFunctions.createFunctionAppAdvanced', createFunctionAppAdvanced);
8182
registerCommand('azureFunctions.createNewProject', createNewProjectFromCommand);
83+
registerCommandWithTreeNodeUnwrapping('azureFunctions.createNewProjectWithDockerfile', async (context: IActionContext) => await createNewProjectInternal(context, { executeStep: new CreateDockerfileProjectStep(), languageFilter: /Python|C\#|(Java|Type)Script|PowerShell$/i }));
8284
registerCommandWithTreeNodeUnwrapping('azureFunctions.createSlot', createSlot);
8385
registerCommandWithTreeNodeUnwrapping('azureFunctions.deleteFunction', deleteFunction);
8486
registerCommandWithTreeNodeUnwrapping('azureFunctions.deleteFunctionApp', deleteFunctionApp);

src/funcCoreTools/validateFuncCoreToolsInstalled.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { getFuncCliPath, hasFuncCliSetting } from './getFuncCliPath';
1818
import { getFuncPackageManagers } from './getFuncPackageManagers';
1919
import { installFuncCoreTools, lastCoreToolsInstallCommand } from './installFuncCoreTools';
2020

21-
export async function validateFuncCoreToolsInstalled(context: IActionContext, message: string, workspacePath: string): Promise<boolean> {
21+
export async function validateFuncCoreToolsInstalled(context: IActionContext, message: string, workspacePath?: string): Promise<boolean> {
2222
let input: MessageItem | undefined;
2323
let installed: boolean = false;
2424
let failedInstall: string = localize('failedInstallFuncTools', 'Core Tools installation has failed and will have to be installed manually.');

0 commit comments

Comments
 (0)