Skip to content

Commit ae526c0

Browse files
committed
changing dotnet helper back
1 parent 271f420 commit ae526c0

File tree

1 file changed

+82
-39
lines changed

1 file changed

+82
-39
lines changed

src/Cli/func/Helpers/DotnetHelpers.cs

Lines changed: 82 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See LICENSE in the project root for license information.
33

44
using System.Reflection;
@@ -15,6 +15,8 @@ public static class DotnetHelpers
1515
{
1616
private const string WebJobsTemplateBasePackId = "Microsoft.Azure.WebJobs";
1717
private const string IsolatedTemplateBasePackId = "Microsoft.Azure.Functions.Worker";
18+
private const string TemplatesLockFileName = "func_dotnet_templates.lock";
19+
private static readonly Lazy<Task<HashSet<string>>> _installedTemplatesList = new(GetInstalledTemplatePackageIds);
1820

1921
public static void EnsureDotnet()
2022
{
@@ -67,7 +69,7 @@ public static async Task<string> DetermineTargetFramework(string projectDirector
6769

6870
public static async Task DeployDotnetProject(string name, bool force, WorkerRuntime workerRuntime, string targetFramework = "")
6971
{
70-
await TemplateOperation(
72+
await TemplateOperationAsync(
7173
async () =>
7274
{
7375
var frameworkString = string.IsNullOrEmpty(targetFramework)
@@ -89,7 +91,7 @@ await TemplateOperation(
8991
public static async Task DeployDotnetFunction(string templateName, string functionName, string namespaceStr, string language, WorkerRuntime workerRuntime, AuthorizationLevel? httpAuthorizationLevel = null)
9092
{
9193
ColoredConsole.WriteLine($"{Environment.NewLine}Creating dotnet function...");
92-
await TemplateOperation(
94+
await TemplateOperationAsync(
9395
async () =>
9496
{
9597
// In .NET 6.0, the 'dotnet new' command requires the short name.
@@ -275,87 +277,128 @@ public static string GetCsprojOrFsproj()
275277
}
276278
}
277279

278-
private static Task TemplateOperation(Func<Task> action, WorkerRuntime workerRuntime)
280+
private static async Task TemplateOperationAsync(Func<Task> action, WorkerRuntime workerRuntime)
279281
{
280282
EnsureDotnet();
281283

282284
if (workerRuntime == WorkerRuntime.DotnetIsolated)
283285
{
284-
return IsolatedTemplateOperation(action);
286+
await EnsureIsolatedTemplatesInstalled();
285287
}
286288
else
287289
{
288-
return WebJobsTemplateOperation(action);
290+
await EnsureWebJobsTemplatesInstalled();
289291
}
292+
293+
await action();
290294
}
291295

292-
private static async Task IsolatedTemplateOperation(Func<Task> action)
296+
private static async Task EnsureIsolatedTemplatesInstalled()
293297
{
294-
try
298+
if (AreDotnetTemplatePackagesInstalled(await _installedTemplatesList.Value, WebJobsTemplateBasePackId))
295299
{
296300
await UninstallWebJobsTemplates();
297-
await InstallIsolatedTemplates();
298-
await action();
299301
}
300-
finally
302+
303+
if (AreDotnetTemplatePackagesInstalled(await _installedTemplatesList.Value, IsolatedTemplateBasePackId))
301304
{
302-
await UninstallIsolatedTemplates();
305+
return;
303306
}
307+
308+
await FileLockHelper.WithFileLockAsync(TemplatesLockFileName, InstallIsolatedTemplates);
304309
}
305310

306-
private static async Task WebJobsTemplateOperation(Func<Task> action)
311+
private static async Task EnsureWebJobsTemplatesInstalled()
307312
{
308-
try
313+
if (AreDotnetTemplatePackagesInstalled(await _installedTemplatesList.Value, IsolatedTemplateBasePackId))
309314
{
310315
await UninstallIsolatedTemplates();
311-
await InstallWebJobsTemplates();
312-
await action();
313316
}
314-
finally
317+
318+
if (AreDotnetTemplatePackagesInstalled(await _installedTemplatesList.Value, WebJobsTemplateBasePackId))
315319
{
316-
await UninstallWebJobsTemplates();
320+
return;
317321
}
322+
323+
await FileLockHelper.WithFileLockAsync(TemplatesLockFileName, InstallWebJobsTemplates);
318324
}
319325

320-
private static async Task UninstallIsolatedTemplates()
326+
internal static bool AreDotnetTemplatePackagesInstalled(HashSet<string> templates, string packageIdPrefix)
321327
{
322-
string projTemplates = $"{IsolatedTemplateBasePackId}.ProjectTemplates";
323-
string itemTemplates = $"{IsolatedTemplateBasePackId}.ItemTemplates";
324-
325-
var exe = new Executable("dotnet", $"new -u \"{projTemplates}\"");
326-
await exe.RunAsync();
328+
var hasProjectTemplates = templates.Contains($"{packageIdPrefix}.ProjectTemplates", StringComparer.OrdinalIgnoreCase);
329+
var hasItemTemplates = templates.Contains($"{packageIdPrefix}.ItemTemplates", StringComparer.OrdinalIgnoreCase);
327330

328-
exe = new Executable("dotnet", $"new -u \"{itemTemplates}\"");
329-
await exe.RunAsync();
331+
return hasProjectTemplates && hasItemTemplates;
330332
}
331333

332-
private static async Task UninstallWebJobsTemplates()
334+
private static async Task<HashSet<string>> GetInstalledTemplatePackageIds()
333335
{
334-
string projTemplates = $"{WebJobsTemplateBasePackId}.ProjectTemplates";
335-
string itemTemplates = $"{WebJobsTemplateBasePackId}.ItemTemplates";
336+
var exe = new Executable("dotnet", "new uninstall", shareConsole: false);
337+
var output = new StringBuilder();
338+
var exitCode = await exe.RunAsync(o => output.AppendLine(o), e => output.AppendLine(e));
339+
340+
if (exitCode != 0)
341+
{
342+
throw new CliException("Failed to get list of installed template packages");
343+
}
344+
345+
var lines = output.ToString()
346+
.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
347+
348+
var packageIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
349+
350+
const string uninstallPrefix = "dotnet new uninstall ";
351+
352+
foreach (var line in lines)
353+
{
354+
var trimmed = line.Trim();
336355

337-
var exe = new Executable("dotnet", $"new -u \"{projTemplates}\"");
338-
await exe.RunAsync();
356+
if (trimmed.StartsWith(uninstallPrefix, StringComparison.OrdinalIgnoreCase))
357+
{
358+
var packageId = trimmed.Substring(uninstallPrefix.Length).Trim();
359+
if (!string.IsNullOrWhiteSpace(packageId))
360+
{
361+
packageIds.Add(packageId);
362+
}
363+
}
364+
}
339365

340-
exe = new Executable("dotnet", $"new -u \"{itemTemplates}\"");
341-
await exe.RunAsync();
366+
return packageIds;
342367
}
343368

369+
private static Task UninstallIsolatedTemplates() => DotnetTemplatesAction("uninstall", nugetPackageList: [$"{IsolatedTemplateBasePackId}.ProjectTemplates", $"{IsolatedTemplateBasePackId}.ItemTemplates"]);
370+
371+
private static Task UninstallWebJobsTemplates() => DotnetTemplatesAction("uninstall", nugetPackageList: [$"{WebJobsTemplateBasePackId}.ProjectTemplates", $"{WebJobsTemplateBasePackId}.ItemTemplates"]);
372+
344373
private static Task InstallWebJobsTemplates() => DotnetTemplatesAction("install", "templates");
345374

346375
private static Task InstallIsolatedTemplates() => DotnetTemplatesAction("install", Path.Combine("templates", $"net-isolated"));
347376

348-
private static async Task DotnetTemplatesAction(string action, string templateDirectory)
377+
private static async Task DotnetTemplatesAction(string action, string templateDirectory = null, string[] nugetPackageList = null)
349378
{
350-
var templatesLocation = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), templateDirectory);
351-
if (!FileSystemHelpers.DirectoryExists(templatesLocation))
379+
string[] list;
380+
381+
if (!string.IsNullOrEmpty(templateDirectory))
382+
{
383+
var templatesLocation = Path.Combine(
384+
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
385+
templateDirectory);
386+
387+
if (!FileSystemHelpers.DirectoryExists(templatesLocation))
388+
{
389+
throw new CliException($"Can't find templates location. Looked under '{templatesLocation}'");
390+
}
391+
392+
list = Directory.GetFiles(templatesLocation, "*.nupkg", SearchOption.TopDirectoryOnly);
393+
}
394+
else
352395
{
353-
throw new CliException($"Can't find templates location. Looked under '{templatesLocation}'");
396+
list = nugetPackageList ?? Array.Empty<string>();
354397
}
355398

356-
foreach (var nupkg in Directory.GetFiles(templatesLocation, "*.nupkg", SearchOption.TopDirectoryOnly))
399+
foreach (var nupkg in list)
357400
{
358-
var exe = new Executable("dotnet", $"new --{action} \"{nupkg}\"");
401+
var exe = new Executable("dotnet", $"new {action} \"{nupkg}\"");
359402
await exe.RunAsync();
360403
}
361404
}

0 commit comments

Comments
 (0)