Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { AzExtFsExtra, DialogResponses, nonNullValueAndProp, type IActionContext } from '@microsoft/vscode-azext-utils';
import { AzExtFsExtra, DialogResponses, nonNullValueAndProp, randomUtils, type IActionContext } from '@microsoft/vscode-azext-utils';
import { composeArgs, withArg, withNamedArg } from '@microsoft/vscode-processutils';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { getMajorVersion, type FuncVersion } from '../../../FuncVersion';
import { ConnectionKey, ProjectLanguage, gitignoreFileName, hostFileName, localSettingsFileName } from '../../../constants';
Expand Down Expand Up @@ -35,18 +37,7 @@ export class DotnetProjectCreateStep extends ProjectCreateStepBase {
const projName: string = projectName + language === ProjectLanguage.FSharp ? '.fsproj' : '.csproj';

const workerRuntime = nonNullProp(context, 'workerRuntime');
// For containerized function apps we need to call func init before intialization as we want the .csproj file to be overwritten with the correct version
// currentely the version created by func init is behind the template version
if (context.containerizedProject) {
const runtime = context.workerRuntime?.capabilities.includes('isolated') ? 'dotnet-isolated' : 'dotnet';
const args = composeArgs(
withArg('init'),
withNamedArg('--worker-runtime', runtime),
withNamedArg('--target-framework', runtime === 'dotnet' ? undefined : nonNullValueAndProp(context.workerRuntime, 'targetFramework')), // targetFramework is only supported for dotnet-isolated projects
withArg('--docker'),
)();
await cpUtils.executeCommand(ext.outputChannel, context.projectPath, "func", args);
} else {
if (!context.containerizedProject) {
await this.confirmOverwriteExisting(context, projName);
}

Expand All @@ -66,8 +57,40 @@ export class DotnetProjectCreateStep extends ProjectCreateStepBase {
templateArgs.Framework = context.workerRuntime.targetFramework;
}

// Create the project from the .NET template first so files are written into a clean directory
await executeDotnetTemplateCreate(context, version, projTemplateKey, context.projectPath, identity, templateArgs);

// For containerized projects, generate the Dockerfile by running func init --docker in an
// isolated temp directory, then copy only the Dockerfile into the project. This avoids
// func init's internal dotnet new conflicting with files already created by the template.
if (context.containerizedProject) {
const runtime = context.workerRuntime?.capabilities.includes('isolated') ? 'dotnet-isolated' : 'dotnet';
const tempDir = path.join(os.tmpdir(), `azfunc-docker-${randomUtils.getRandomHexString()}`);
try {
await fs.promises.mkdir(tempDir, { recursive: true });
const args = composeArgs(
withArg('init'),
withNamedArg('--worker-runtime', runtime),
withNamedArg('--target-framework', runtime === 'dotnet' ? undefined : nonNullValueAndProp(context.workerRuntime, 'targetFramework')),
withArg('--docker'),
)();
await cpUtils.executeCommand(ext.outputChannel, tempDir, "func", args);

// Copy only the Dockerfile (and .dockerignore if present) into the project
for (const file of ['Dockerfile', '.dockerignore']) {
const src = path.join(tempDir, file);
const dest = path.join(context.projectPath, file);
try {
await fs.promises.copyFile(src, dest);
} catch {
// .dockerignore may not exist, that's fine
}
}
} finally {
await fs.promises.rm(tempDir, { recursive: true, force: true }).catch(() => { /* best-effort cleanup */ });
}
}

await setLocalAppSetting(context, context.projectPath, ConnectionKey.Storage, '', MismatchBehavior.Overwrite);
}

Expand Down
Loading