dotnet-installer/src/core-sdk-tasks/CalculateTemplateVersions.cs

130 lines
6.4 KiB
C#

// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NuGet.Versioning;
namespace Microsoft.DotNet.Cli.Build
{
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")].BundledTemplateInstallPath);
return templateWithInstallPath;
}).ToArray();
TemplatesComponents = groups.Select(g =>
{
string majorMinorWithoutDots = g.Value.BundledTemplateMajorMinorVersion.Replace(".", "");
var componentItem = new TaskItem($"NetCore{majorMinorWithoutDots}Templates");
var templateBaseFilename = $"dotnet-{majorMinorWithoutDots}templates";
componentItem.SetMetadata("TemplateBaseFilename", templateBaseFilename);
componentItem.SetMetadata("TemplatesMajorMinorVersion", g.Value.BundledTemplateMajorMinorVersion);
var installerUpgradeCode = GenerateGuidFromName.GenerateGuid(string.Join("-", templateBaseFilename, FullNugetVersion, ProductMonikerRid) + InstallerExtension).ToString().ToUpper();
componentItem.SetMetadata("InstallerUpgradeCode", installerUpgradeCode);
componentItem.SetMetadata("MSIVersion", GenerateMsiVersionFromFullVersion.GenerateMsiVersion(CombinedBuildNumberAndRevision, g.Value.BundledTemplateMajorMinorPatchVersion));
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
(string BundledTemplateInstallPath,
string BundledTemplateMajorMinorVersion,
string BundledTemplateMajorMinorPatchVersion)
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 (
bundledTemplateInstallPath,
$"{baseMajorMinorPatch.Major}.{baseMajorMinorPatch.Minor}",
$"{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;
var baseMajorMinorPatch = new NuGetVersion(aspNetCoreTemplate.Major, aspNetCoreTemplate.Minor,
basePatch);
return baseMajorMinorPatch;
}
}
}