Show quickpicks if there are multiple runtime matches for `targetFramework` (#4165)

* Reverse list

* change to quickpicks

* add test

* remove

* Add another test

* remove

* update comment

* update again

* see if tests work

* delete

* add
This commit is contained in:
Megan Mott 2024-07-08 13:41:29 -04:00 коммит произвёл GitHub
Родитель fe58f7faca
Коммит 6867559c16
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 68 добавлений и 11 удалений

Просмотреть файл

@ -16,9 +16,17 @@ export class DotnetRuntimeStep extends AzureWizardPromptStep<IProjectWizardConte
public static async createStep(context: IProjectWizardContext): Promise<DotnetRuntimeStep> { public static async createStep(context: IProjectWizardContext): Promise<DotnetRuntimeStep> {
if (context.targetFramework) { if (context.targetFramework) {
context.targetFramework = typeof context.targetFramework === 'string' ? [context.targetFramework] : context.targetFramework; context.targetFramework = typeof context.targetFramework === 'string' ? [context.targetFramework] : context.targetFramework;
const runtimes = await getRuntimes(context); const runtimes = (await getRuntimes(context));
// if a targetFramework was provided from createNewProject // if a targetFramework was provided from createNewProject
const workerRuntime = runtimes.find(runtime => context.targetFramework?.includes(runtime.targetFramework)); const filteredRuntimes = runtimes.filter(runtime => context.targetFramework?.includes(runtime.targetFramework));
let workerRuntime: cliFeedUtils.IWorkerRuntime | undefined = undefined;
if (filteredRuntimes.length > 1) {
const placeHolder: string = localize('selectWorkerRuntime', 'Select a .NET runtime');
workerRuntime = (await context.ui.showQuickPick(new DotnetRuntimeStep().getPicks(context, filteredRuntimes), { placeHolder })).data;
} else if (filteredRuntimes.length === 1) {
workerRuntime = filteredRuntimes[0];
}
if (!workerRuntime) { if (!workerRuntime) {
throw new Error(localize('unknownFramework', 'Unrecognized target frameworks: "{0}". Available frameworks: {1}.', throw new Error(localize('unknownFramework', 'Unrecognized target frameworks: "{0}". Available frameworks: {1}.',
context.targetFramework.map(tf => `"${tf}"`).join(', '), context.targetFramework.map(tf => `"${tf}"`).join(', '),
@ -49,8 +57,11 @@ export class DotnetRuntimeStep extends AzureWizardPromptStep<IProjectWizardConte
return !context.workerRuntime; return !context.workerRuntime;
} }
private async getPicks(context: IProjectWizardContext): Promise<IAzureQuickPickItem<cliFeedUtils.IWorkerRuntime | undefined>[]> { private async getPicks(context: IProjectWizardContext, runtimes?: cliFeedUtils.IWorkerRuntime[]): Promise<IAzureQuickPickItem<cliFeedUtils.IWorkerRuntime | undefined>[]> {
const runtimes = await getRuntimes(context); if (!runtimes) {
runtimes = await getRuntimes(context);
}
const picks: IAzureQuickPickItem<cliFeedUtils.IWorkerRuntime | undefined>[] = []; const picks: IAzureQuickPickItem<cliFeedUtils.IWorkerRuntime | undefined>[] = [];
for (const runtime of runtimes) { for (const runtime of runtimes) {
picks.push({ picks.push({

Просмотреть файл

@ -7,11 +7,11 @@ import { runWithInputs } from '@microsoft/vscode-azext-dev';
import { type apiUtils } from "@microsoft/vscode-azext-utils"; import { type apiUtils } from "@microsoft/vscode-azext-utils";
import * as path from 'path'; import * as path from 'path';
import { extensions, type Extension } from "vscode"; import { extensions, type Extension } from "vscode";
import { ProjectLanguage, extensionId, nonNullValue, registerOnActionStartHandler } from '../extension.bundle'; import { FuncVersion, ProjectLanguage, extensionId, nonNullValue, registerOnActionStartHandler } from '../extension.bundle';
// eslint-disable-next-line no-restricted-imports // eslint-disable-next-line no-restricted-imports
import { type AzureFunctionsExtensionApi } from '../src/vscode-azurefunctions.api'; import { type AzureFunctionsExtensionApi } from '../src/vscode-azurefunctions.api';
import { getTestWorkspaceFolder, testFolderPath } from './global.test'; import { getTestWorkspaceFolder, testFolderPath } from './global.test';
import { getJavaScriptValidateOptions, validateProject, type IValidateProjectOptions } from './project/validateProject'; import { getCSharpValidateOptions, getJavaScriptValidateOptions, validateProject, type IValidateProjectOptions } from './project/validateProject';
suite(`AzureFunctionsExtensionApi`, () => { suite(`AzureFunctionsExtensionApi`, () => {
let api: AzureFunctionsExtensionApi; let api: AzureFunctionsExtensionApi;
@ -73,4 +73,49 @@ suite(`AzureFunctionsExtensionApi`, () => {
); );
await validateProject(folderPath, validateOptions); await validateProject(folderPath, validateOptions);
}); });
test('createFunction dotnet with targetFramework', async () => {
const functionName: string = 'endpoint1';
const language: string = ProjectLanguage.CSharp;
const workspaceFolder = getTestWorkspaceFolder();
const projectSubpath = 'api';
const folderPath: string = path.join(workspaceFolder, projectSubpath);
await runWithInputs('api.createFunction', [language, /6/i, 'Company.Function', 'Anonymous'], registerOnActionStartHandler, async () => {
await api.createFunction({
folderPath,
functionName,
templateId: 'HttpTrigger',
languageFilter: /^C\#$/i,
functionSettings: { authLevel: 'anonymous' },
targetFramework: ['net8.0', 'net7.0', 'net6.0']
});
});
const validateOptions: IValidateProjectOptions = getCSharpValidateOptions('net6.0', FuncVersion.v4, 1, projectSubpath, workspaceFolder);
// Exclude .git because the test workspace folders are already inside a git repo so we don't do git init.
validateOptions.excludedPaths?.push('.git');
await validateProject(folderPath, validateOptions);
});
// Intentionally pass a version (8) that hasn't been specified in targetFramework (6 & 7) to verify it isn't a possible pick. In the correct case (when 8 isn't a pick) we throw an error. api.createFunction swallows the error and returns undefined.
// In the incorrect case (when 8 is a pick) the test fails since the 2 provided test inputs have already been used, but there are more prompts.
test('createFunction with language not in targetFramework', async () => {
const functionName: string = 'endpoint1';
const language: string = ProjectLanguage.CSharp;
const workspaceFolder = getTestWorkspaceFolder();
const projectSubpath = 'api';
const folderPath: string = path.join(workspaceFolder, projectSubpath);
await runWithInputs('api.createFunction', [language, /8/i], registerOnActionStartHandler, async () => {
await api.createFunction({
folderPath,
functionName,
templateId: 'HttpTrigger',
languageFilter: /^C\#$/i,
functionSettings: { authLevel: 'anonymous' },
targetFramework: ['net7.0', 'net6.0']
})
});
});
}); });

Просмотреть файл

@ -81,7 +81,7 @@ export function getTypeScriptValidateOptions(options?: { version?: FuncVersion,
return result; return result;
} }
export function getCSharpValidateOptions(targetFramework: string, version: FuncVersion = defaultTestFuncVersion, numCsproj: number = 1): IValidateProjectOptions { export function getCSharpValidateOptions(targetFramework: string, version: FuncVersion = defaultTestFuncVersion, numCsproj: number = 1, projectSubpath?: string, workspaceFolder?: string): IValidateProjectOptions {
return { return {
language: ProjectLanguage.CSharp, language: ProjectLanguage.CSharp,
version, version,
@ -89,17 +89,17 @@ export function getCSharpValidateOptions(targetFramework: string, version: FuncV
'azureFunctions.projectLanguage': ProjectLanguage.CSharp, 'azureFunctions.projectLanguage': ProjectLanguage.CSharp,
'azureFunctions.projectRuntime': version, 'azureFunctions.projectRuntime': version,
'azureFunctions.preDeployTask': 'publish (functions)', 'azureFunctions.preDeployTask': 'publish (functions)',
'azureFunctions.deploySubpath': `bin/Release/${targetFramework}/publish`, 'azureFunctions.deploySubpath': path.join(projectSubpath ?? '', `bin/Release/${targetFramework}/publish`),
'debug.internalConsoleOptions': 'neverOpen', 'debug.internalConsoleOptions': 'neverOpen',
}, },
expectedPaths: [ expectedPaths: [
{ globPattern: '*.csproj', numMatches: numCsproj } { globPattern: path.join(projectSubpath ?? '', '*.csproj'), numMatches: numCsproj }
], ],
expectedExtensionRecs: [ expectedExtensionRecs: [
'ms-dotnettools.csharp' 'ms-dotnettools.csharp'
], ],
excludedPaths: [ excludedPaths: [
'.funcignore' path.join(projectSubpath ?? '', '.funcignore')
], ],
expectedDebugConfigs: [ expectedDebugConfigs: [
'Attach to .NET Functions' 'Attach to .NET Functions'
@ -110,7 +110,8 @@ export function getCSharpValidateOptions(targetFramework: string, version: FuncV
'clean release (functions)', 'clean release (functions)',
'publish (functions)', 'publish (functions)',
'host start' 'host start'
] ],
workspaceFolder
}; };
} }