|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using NuGet.Versioning;
namespace Microsoft.DotNet.Build.Tasks
{
public class CalculateTemplateVersions : Task
{
// Group BundledTemplates by TemplateFrameworkVersion
// In each group, get the version of the template with UseVersionForTemplateInstallPath=true
// From that version number, get the BundledTemplateInstallPath, BundledTemplateMajorMinorVersion, and BundledTemplateMajorMinorPatchVersion
[Required]
public ITaskItem [] BundledTemplates { get; set; }
[Required]
public string FullNugetVersion { get; set; }
[Required]
public string ProductMonikerRid { get; set; }
public string InstallerExtension { get; set; }
[Required]
public int CombinedBuildNumberAndRevision { get; set; }
// Should be the BundledTemplates with BundledTemplateInstallPath metadata set to the value calculated for that group
[Output]
public ITaskItem [] BundledTemplatesWithInstallPaths { get; set; }
// For each group of templates (grouped by TemplateFrameworkVersion), this should be the following
// ItemSpec: NetCore60Templates
// TemplateBaseFilename: dotnet-60templates
// TemplatesMajorMinorVersion: 6.0 (from BundledTemplateMajorMinorVersion from group)
// InstallerUpgradeCode: Guid generated using GenerateGuidFromName, combining TemplateBaseFilename, FullNugetVersion, ProductMonikerRid, and InstallerExtension
// MSIVersion: Result of calling GenerateMsiVersionFromFullVersion logic with CombinedBuildNumberAndRevision and BundledTemplateMajorMinorPatchVersion from template group
[Output]
public ITaskItem [] TemplatesComponents { get; set; }
private const int PatchVersionResetOffset = 1;
public override bool Execute()
{
var groups = BundledTemplates.GroupBy(bt => bt.GetMetadata("TemplateFrameworkVersion"))
.ToDictionary(g => g.Key, g =>
{
var itemWithVersion = g.SingleOrDefault(i => i.GetMetadata("UseVersionForTemplateInstallPath").Equals("true", StringComparison.OrdinalIgnoreCase));
if (itemWithVersion == null)
{
throw new InvalidOperationException("Could not find single item with UseVersionForTemplateInstallPath for templates with TemplateFrameworkVersion: " + g.Key);
}
return Calculate(itemWithVersion.GetMetadata("PackageVersion"));
});
BundledTemplatesWithInstallPaths = BundledTemplates.Select(t =>
{
var templateWithInstallPath = new TaskItem(t);
templateWithInstallPath.SetMetadata("BundledTemplateInstallPath", groups[t.GetMetadata("TemplateFrameworkVersion")].InstallPath);
return templateWithInstallPath;
}).ToArray();
TemplatesComponents = groups.Select(g =>
{
string majorMinorWithoutDots = g.Value.MajorMinorVersion.Replace(".", "");
var componentItem = new TaskItem($"NetCore{majorMinorWithoutDots}Templates");
var templateBaseFilename = $"dotnet-{majorMinorWithoutDots}templates";
componentItem.SetMetadata("TemplateBaseFilename", templateBaseFilename);
componentItem.SetMetadata("TemplatesMajorMinorVersion", g.Value.MajorMinorVersion);
var installerUpgradeCode = GenerateGuidFromName.GenerateGuid(string.Join("-", templateBaseFilename, FullNugetVersion, ProductMonikerRid) + InstallerExtension).ToString().ToUpper();
componentItem.SetMetadata("InstallerUpgradeCode", installerUpgradeCode);
componentItem.SetMetadata("MSIVersion", GenerateMsiVersionFromFullVersion.GenerateMsiVersion(CombinedBuildNumberAndRevision, g.Value.MajorMinorPatchVersion));
var brandName = System.Version.Parse(g.Key).Major >= 5 ?
$"Microsoft .NET {g.Key} Templates" :
$"Microsoft .NET Core {g.Key} Templates";
componentItem.SetMetadata("BrandNameWithoutVersion", brandName);
return componentItem;
}).ToArray();
return true;
}
public static BundledTemplate Calculate(string aspNetCorePackageVersionTemplate)
{
var aspNetCoreTemplate = NuGetVersion.Parse(aspNetCorePackageVersionTemplate);
NuGetVersion baseMajorMinorPatch = GetBaseMajorMinorPatch(aspNetCoreTemplate);
string bundledTemplateInstallPath = aspNetCoreTemplate.IsPrerelease
? $"{baseMajorMinorPatch.Major}.{baseMajorMinorPatch.Minor}.{baseMajorMinorPatch.Patch}-{aspNetCoreTemplate.Release}"
: $"{baseMajorMinorPatch.Major}.{baseMajorMinorPatch.Minor}.{baseMajorMinorPatch.Patch}";
return new BundledTemplate
{
InstallPath = bundledTemplateInstallPath,
MajorMinorVersion = $"{baseMajorMinorPatch.Major}.{baseMajorMinorPatch.Minor}",
MajorMinorPatchVersion = $"{baseMajorMinorPatch.Major}.{baseMajorMinorPatch.Minor}.{baseMajorMinorPatch.Patch}"
};
}
private static NuGetVersion GetBaseMajorMinorPatch(NuGetVersion aspNetCoreTemplate)
{
// due to historical bug https://github.com/dotnet/core-sdk/issues/6243
// we need to increase patch version by one in order to "reset" existing install ComponentId
// more in the above bug's detail.
// There is no non-deterministic existing ComponentId under Major version 5.
// so only apply the patch bump when below 5
int basePatch = aspNetCoreTemplate.Major < 5 ?
aspNetCoreTemplate.Patch + PatchVersionResetOffset :
aspNetCoreTemplate.Patch;
return new NuGetVersion(aspNetCoreTemplate.Major, aspNetCoreTemplate.Minor, basePatch);
}
}
public class BundledTemplate
{
public string InstallPath { get; set; }
public string MajorMinorVersion { get; set; }
public string MajorMinorPatchVersion { get; set; }
}
}
|