diff --git a/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs b/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs index 6651040f1..f76763e0a 100644 --- a/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs +++ b/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs @@ -3,6 +3,7 @@ using System.Text.RegularExpressions; using Azure.Functions.Cli.Common; +using Azure.Functions.Cli.Exceptions; using Azure.Functions.Cli.ExtensionBundle; using Azure.Functions.Cli.Extensions; using Azure.Functions.Cli.Helpers; @@ -131,7 +132,21 @@ public override async Task RunAsync() FunctionName = FunctionName ?? Console.ReadLine(); ColoredConsole.WriteLine(FunctionName); var namespaceStr = Path.GetFileName(Environment.CurrentDirectory); - await DotnetHelpers.DeployDotnetFunction(TemplateName.Replace(" ", string.Empty), Utilities.SanitizeClassName(FunctionName), Utilities.SanitizeNameSpace(namespaceStr), Language.Replace("-isolated", string.Empty), _workerRuntime, AuthorizationLevel); + try + { + await DotnetHelpers.DeployDotnetFunction(TemplateName.Replace(" ", string.Empty), Utilities.SanitizeClassName(FunctionName), Utilities.SanitizeNameSpace(namespaceStr), Language.Replace("-isolated", string.Empty), _workerRuntime, AuthorizationLevel); + } + catch (CsTemplateNotFoundException) + { + if (_templates.Value + .Where(x => x.Metadata.Language.Equals(Languages.CSharp, StringComparison.InvariantCultureIgnoreCase)) + .Any(x => x.Metadata.Name.Equals(TemplateName, StringComparison.InvariantCultureIgnoreCase))) + { + throw new CsxTemplateReferredWithoutCsxOptionException(TemplateName); + } + + throw; + } } else if (IsNewPythonProgrammingModel()) { diff --git a/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs b/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs index 036cbcff0..a1d57b548 100644 --- a/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs +++ b/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. using Azure.Functions.Cli.Interfaces; +using Azure.Functions.Cli.Common; using Colors.Net; using Fclp; using static Azure.Functions.Cli.Common.OutputTheme; @@ -46,6 +47,12 @@ public override async Task RunAsync() ColoredConsole.WriteLine($" {template.Metadata.Name}"); } + if (Constants.Languages.CSharp.Equals(languageGrouping.Key, StringComparison.InvariantCultureIgnoreCase)) + { + ColoredConsole.WriteLine($"(Use the templates above with 'func function new ls--csx --template' command within in-process model projects.)"); + ColoredConsole.WriteLine($"(More templates are available for C#. To list those run 'func funciton new' command without '--template'.)"); + } + ColoredConsole.WriteLine(); } } diff --git a/src/Cli/func/Exceptions/CsTemplateNotFoundException.cs b/src/Cli/func/Exceptions/CsTemplateNotFoundException.cs new file mode 100644 index 000000000..0acba2349 --- /dev/null +++ b/src/Cli/func/Exceptions/CsTemplateNotFoundException.cs @@ -0,0 +1,4 @@ +namespace Azure.Functions.Cli.Exceptions; + +public class CsTemplateNotFoundException(string templateName) + : Exception($"Unknown template '{templateName}'. Retry without --template option to see available templates.") {} diff --git a/src/Cli/func/Exceptions/CsxTemplateReferredWithoutCsxOptionException.cs b/src/Cli/func/Exceptions/CsxTemplateReferredWithoutCsxOptionException.cs new file mode 100644 index 000000000..7073a1dfd --- /dev/null +++ b/src/Cli/func/Exceptions/CsxTemplateReferredWithoutCsxOptionException.cs @@ -0,0 +1,4 @@ +namespace Azure.Functions.Cli.Exceptions; + +public class CsxTemplateReferredWithoutCsxOptionException(string templateName) + : Exception($"Template '{templateName}' is for C# script in in-process model. Retry with --csx option to use the template. Or, retry without --template option to see available templates.") {} diff --git a/src/Cli/func/Helpers/DotnetHelpers.cs b/src/Cli/func/Helpers/DotnetHelpers.cs index ddf6ce654..b35c00183 100644 --- a/src/Cli/func/Helpers/DotnetHelpers.cs +++ b/src/Cli/func/Helpers/DotnetHelpers.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Text; using Azure.Functions.Cli.Common; +using Azure.Functions.Cli.Exceptions; using Colors.Net; using Microsoft.Azure.WebJobs.Extensions.Http; using static Azure.Functions.Cli.Common.OutputTheme; @@ -149,7 +150,7 @@ await TemplateOperation( "daprpublishoutputbinding" => "daprPublishOutputBinding", "daprserviceinvocationtrigger" => "daprServiceInvocationTrigger", "daprtopictrigger" => "daprTopicTrigger", - _ => throw new ArgumentException($"Unknown template '{templateName}'", nameof(templateName)) + _ => throw new CsTemplateNotFoundException(templateName) }; internal static IEnumerable GetTemplates(WorkerRuntime workerRuntime) @@ -256,14 +257,14 @@ public static async Task BuildDotnetProject(string outputPath, string dotn public static string GetCsprojOrFsproj() { EnsureDotnet(); - var csProjFiles = FileSystemHelpers.GetFiles(Environment.CurrentDirectory, searchPattern: "*.csproj").ToList(); + var csProjFiles = FileSystemHelpers.GetFiles(Environment.CurrentDirectory, searchPattern: "*.csproj", excludedDirectories: ["obj"]).ToList(); if (csProjFiles.Count == 1) { return csProjFiles.First(); } else { - var fsProjFiles = FileSystemHelpers.GetFiles(Environment.CurrentDirectory, searchPattern: "*.fsproj").ToList(); + var fsProjFiles = FileSystemHelpers.GetFiles(Environment.CurrentDirectory, searchPattern: "*.fsproj", excludedDirectories: ["obj"]).ToList(); if (fsProjFiles.Count == 1) { return fsProjFiles.First();