diff --git a/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs b/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs index 08345e35a..1209d9fd2 100644 --- a/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs +++ b/src/Cli/func/Actions/LocalActions/CreateFunctionAction.cs @@ -1,19 +1,12 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text.RegularExpressions; -using System.Threading.Tasks; +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; using Azure.Functions.Cli.Interfaces; using Colors.Net; using Fclp; -using Microsoft.Azure.AppService.Proxy.Common.Context; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Script; using Newtonsoft.Json; @@ -129,7 +122,21 @@ public async override 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", ""), workerRuntime, AuthorizationLevel); + try + { + await DotnetHelpers.DeployDotnetFunction(TemplateName.Replace(" ", string.Empty), Utilities.SanitizeClassName(FunctionName), Utilities.SanitizeNameSpace(namespaceStr), Language.Replace("-isolated", ""), 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 4238647dd..709b56c7d 100644 --- a/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs +++ b/src/Cli/func/Actions/LocalActions/ListTemplatesAction.cs @@ -1,7 +1,5 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Azure.Functions.Cli.Interfaces; +using Azure.Functions.Cli.Interfaces; +using Azure.Functions.Cli.Common; using Colors.Net; using Fclp; using static Azure.Functions.Cli.Common.OutputTheme; @@ -45,6 +43,13 @@ 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 6ba842bc6..5bf8b7c02 100644 --- a/src/Cli/func/Helpers/DotnetHelpers.cs +++ b/src/Cli/func/Helpers/DotnetHelpers.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; 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; @@ -145,7 +141,7 @@ await TemplateOperation(async () => "daprpublishoutputbinding" => "daprPublishOutputBinding", "daprserviceinvocationtrigger" => "daprServiceInvocationTrigger", "daprtopictrigger" => "daprTopicTrigger", - _ => throw new ArgumentException($"Unknown template '{templateName}'", nameof(templateName)) + _ => throw new CsTemplateNotFoundException(templateName) }; internal static IEnumerable GetTemplates(WorkerRuntime workerRuntime) @@ -246,14 +242,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();