diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateManifestMsiTests.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateManifestMsiTests.cs new file mode 100644 index 00000000000..778467bfd73 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateManifestMsiTests.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests +{ + public class GenerateManifestMsiTests + { + [WindowsOnlyFact] + public void ItThrowsIfPayloadRelativePathIsTooLong() + { + var task = new GenerateManifestMsi(); + task.MsiVersion = "1.2.3.11111"; + + Exception e = Assert.Throws(() => task.GenerateSwixPackageAuthoring(@"C:\Foo\Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100.6.0.0-preview.7.21377.12-x64.msi", + "Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100", "x64")); + Assert.Equal(@"Payload relative path exceeds max length (182): Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100,version=1.2.3,chip=x64,productarch=neutral\Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.100.6.0.0-preview.7.21377.12-x64.msi", e.Message); + } + } +} diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateVisualStudioWorkloadTests.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateVisualStudioWorkloadTests.cs index da88129a328..c298b028d1c 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateVisualStudioWorkloadTests.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/GenerateVisualStudioWorkloadTests.cs @@ -3,11 +3,11 @@ using System; using System.Collections.Generic; -using System.Linq; using System.IO; +using System.Linq; using Microsoft.Arcade.Test.Common; -using Microsoft.Build.Utilities; using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; using Xunit; namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests @@ -20,6 +20,42 @@ public class GenerateVisualStudioWorkloadTests public string TestIntermediateBaseOutputPath => Path.Combine(IntermediateBaseOutputPath, Path.GetFileNameWithoutExtension(Path.GetTempFileName())); + [Fact] + public void ItIgnoresNotApplicableAliasedPacks() + { + string workloadManifest = Path.Combine(AppContext.BaseDirectory, "testassets", "AbstractWorkloadsNonWindowsPacks.json"); + + var buildTask = new GenerateVisualStudioWorkload() + { + WorkloadManifests = new TaskItem[] + { + new TaskItem(workloadManifest) + }, + ComponentVersions = new TaskItem[] + { + new TaskItem("microsoft-net-runtime-ios", new Dictionary { { "Version", "6.5.38766" } }), + new TaskItem("runtimes-ios", new Dictionary { { "Version", "6.5.38766" } }), + new TaskItem("microsoft-net-runtime-mono-tooling", new Dictionary { { "Version", "6.5.38766" } }), + }, + GenerateMsis = false, + IntermediateBaseOutputPath = TestIntermediateBaseOutputPath, + WixToolsetPath = "", + BuildEngine = new MockBuildEngine() + }; + + Assert.True(buildTask.Execute()); + string outputPath = Path.GetDirectoryName(buildTask.SwixProjects[0].GetMetadata("FullPath")); + string componentSwr = File.ReadAllText(Path.Combine(outputPath, "component.swr")); + + Assert.Contains(@"package name=microsoft.net.runtime.ios", componentSwr); + Assert.DoesNotContain(@"vs.dependency id=Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm", componentSwr); + Assert.DoesNotContain(@"vs dependency id=Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64", componentSwr); + Assert.DoesNotContain(@"vs dependency id=Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64", componentSwr); + Assert.DoesNotContain(@"vs dependency id=Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64", componentSwr); + Assert.DoesNotContain(@"vs dependency id=Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x86", componentSwr); + Assert.Contains(@"vs.dependency id=runtimes.ios", componentSwr); + } + [Fact] public void ItGeneratesASwixProjectFromAWorkloadManifest() { diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/TestHelper.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/TestHelper.cs new file mode 100644 index 00000000000..278b859b41a --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/TestHelper.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Xunit; + +namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests +{ + public class WindowsOnlyFactAttribute : FactAttribute + { + public WindowsOnlyFactAttribute() + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + Skip = "Not running on Windows"; + } + } + } +} diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/AbstractWorkloadsNonWindowsPacks.json b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/AbstractWorkloadsNonWindowsPacks.json new file mode 100644 index 00000000000..0494cc63651 --- /dev/null +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/testassets/AbstractWorkloadsNonWindowsPacks.json @@ -0,0 +1,262 @@ +{ + "version": "6.0.0-preview.7.21358.4", + "depends-on": { + "Microsoft.NET.Workload.Emscripten": "6.0.0-preview.7.21330.1" + }, + "workloads": { + "microsoft-net-runtime-ios": { + "abstract": true, + "description": "iOS Mono Runtime and AOT Workload", + "packs": [ + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm", + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64", + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x86" + ], + "extends": [ "runtimes-ios" ], + "platforms": [ "win-x64", "osx-arm64", "osx-x64" ] + }, + "runtimes-ios": { + "abstract": true, + "description": "iOS Mono Runtime Packs", + "packs": [ + "Microsoft.NETCore.App.Runtime.Mono.ios-arm", + "Microsoft.NETCore.App.Runtime.Mono.ios-arm64", + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64", + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64", + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86" + ], + "extends": [ "microsoft-net-runtime-mono-tooling" ], + "platforms": [ "win-x64", "osx-arm64", "osx-x64" ] + }, + "microsoft-net-runtime-mono-tooling": { + "abstract": true, + "description": "Shared native build tooling for Mono runtime", + "packs": [ + "Microsoft.NET.Runtime.MonoAOTCompiler.Task", + "Microsoft.NET.Runtime.MonoTargets.Sdk" + ] + }, + }, + "packs": { + "Microsoft.NET.Runtime.MonoAOTCompiler.Task": { + "kind": "Sdk", + "version": "2.3.4.5" + }, + "Microsoft.NET.Runtime.MonoTargets.Sdk": { + "kind": "Sdk", + "version": "2.3.4.5" + }, + "Microsoft.NET.Runtime.WebAssembly.Sdk": { + "kind": "Sdk", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-arm": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.android-x86": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-x86", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-x86", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x86", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x86" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-x64", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-x64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-arm", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-arm", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.android-arm64", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.android-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.android-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.maccatalyst-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.osx-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.osx-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.osx-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.osx-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.ios-arm": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.ios-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.iossimulator-x86": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvos-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvos-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.tvos-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-arm64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.Mono.tvossimulator-x64": { + "kind": "framework", + "version": "2.3.4.5" + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.maccatalyst-x64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.maccatalyst-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.tvossimulator-x64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.tvossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.ios-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.ios-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-arm64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-arm64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x64": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x64" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.iossimulator-x86": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x86", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.iossimulator-x86" + } + }, + "Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm": { + "kind": "Sdk", + "version": "2.3.4.5", + "alias-to": { + "win-x64": "Microsoft.NETCore.App.Runtime.AOT.win-x64.Cross.browser-wasm", + "linux-x64": "Microsoft.NETCore.App.Runtime.AOT.linux-x64.Cross.browser-wasm", + "osx-x64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.browser-wasm", + "osx-arm64": "Microsoft.NETCore.App.Runtime.AOT.osx-x64.Cross.browser-wasm" + } + }, + "Microsoft.NETCore.App.Runtime.Mono.browser-wasm": { + "kind": "framework", + "version": "2.3.4.5" + } + } +} diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs index 86b4bf68b90..a9ab8650c44 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateManifestMsi.cs @@ -79,6 +79,15 @@ public string SdkVersion set; } + /// + /// An item group containing information to shorten the names of packages. + /// + public ITaskItem[] ShortNames + { + get; + set; + } + /// /// Semicolon sepearate list of ICEs to suppress. /// @@ -147,10 +156,6 @@ public override bool Execute() productName = nupkg.Id; } - - - - // Extract once, but harvest multiple times because some generated attributes are platform dependent. string packageContentsDirectory = Path.Combine(PackageDirectory, $"{nupkg.Identity}"); nupkg.Extract(packageContentsDirectory, Enumerable.Empty()); @@ -192,6 +197,8 @@ public override bool Execute() var productCode = Guid.NewGuid(); Log.LogMessage($"UC: {upgradeCode}, PC: {productCode}, {SdkFeatureBandVersion}, {SdkVersion}, {platform}"); + string providerKeyName = $"{ManifestId},{SdkFeatureBandVersion},{platform}"; + // Compile the MSI sources string candleIntermediateOutputPath = Path.Combine(IntermediateBaseOutputPath, "wixobj", $"{nupkg.Id}", $"{nupkg.Version}", platform); @@ -219,7 +226,7 @@ public override bool Execute() candle.PreprocessorDefinitions.Add($@"ProductCode={productCode}"); candle.PreprocessorDefinitions.Add($@"UpgradeCode={upgradeCode}"); // Override the default provider key - candle.PreprocessorDefinitions.Add($@"DependencyProviderKeyName={ManifestId},{SdkFeatureBandVersion},{platform}"); + candle.PreprocessorDefinitions.Add($@"DependencyProviderKeyName={providerKeyName}"); candle.PreprocessorDefinitions.Add($@"ProductName={productName}"); candle.PreprocessorDefinitions.Add($@"Platform={platform}"); candle.PreprocessorDefinitions.Add($@"SourceDir={packageContentsDataDirectory}"); @@ -273,7 +280,7 @@ public override bool Execute() Payload = Path.GetFileName(msiPath), ProductCode = MsiUtils.GetProperty(msiPath, "ProductCode"), ProductVersion = MsiUtils.GetProperty(msiPath, "ProductVersion"), - ProviderKeyName = $"{nupkg.Id},{nupkg.Version},{platform}", + ProviderKeyName = $"{providerKeyName}", UpgradeCode = MsiUtils.GetProperty(msiPath, "UpgradeCode"), RelatedProducts = MsiUtils.GetRelatedProducts(msiPath) }; @@ -289,7 +296,7 @@ public override bool Execute() if (GenerateSwixAuthoring && IsSupportedByVisualStudio(platform)) { - string swixPackageId = $"{nupkg.Id}"; + string swixPackageId = $"{nupkg.Id.ToString().Replace(ShortNames)}"; string swixProject = GenerateSwixPackageAuthoring(light.OutputFile, swixPackageId, platform); @@ -406,7 +413,7 @@ private void WriteItem(XmlWriter writer, string itemName, string include, string writer.WriteEndElement(); } - private string GenerateSwixPackageAuthoring(string msiPath, string packageId, string platform) + internal string GenerateSwixPackageAuthoring(string msiPath, string packageId, string platform) { GenerateVisualStudioMsiPackageProject swixTask = new() { @@ -414,9 +421,13 @@ private string GenerateSwixPackageAuthoring(string msiPath, string packageId, st IntermediateBaseOutputPath = this.IntermediateBaseOutputPath, PackageName = packageId, MsiPath = msiPath, + Version = !string.IsNullOrEmpty(MsiVersion) ? new Version(MsiVersion) : null, BuildEngine = this.BuildEngine, }; + string vsPayloadRelativePath = $"{swixTask.PackageName},version={swixTask.Version.ToString(3)},chip={swixTask.Chip},productarch={swixTask.ProductArch}\\{Path.GetFileName(msiPath)}"; + CheckRelativePayloadPath(vsPayloadRelativePath); + if (!swixTask.Execute()) { Log.LogError($"Failed to generate SWIX authoring for '{msiPath}'"); diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateTaskBase.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateTaskBase.cs index 54f9f2cbbfb..5c0e0163053 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateTaskBase.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateTaskBase.cs @@ -12,6 +12,8 @@ namespace Microsoft.DotNet.Build.Tasks.Workloads { public abstract class GenerateTaskBase : Task { + public const int MaxPayloadRelativePath = 182; + public static readonly string[] SupportedVisualStudioPlatforms = { "x86", "x64" }; /// @@ -68,5 +70,14 @@ protected bool IsSupportedByVisualStudio(string platform) { return SupportedVisualStudioPlatforms.Contains(platform); } + + protected void CheckRelativePayloadPath(string relativePath) + { + if (relativePath.Length > MaxPayloadRelativePath) + { + // We'll let the task's execute method take care of logging this and terminating. + throw new Exception($"Payload relative path exceeds max length ({MaxPayloadRelativePath}): {relativePath}"); + } + } } } diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs index e1583969a02..3b2573fa438 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs @@ -104,6 +104,10 @@ public override bool Execute() Log.LogMessage($"Using MSI version for package version: {Version}"); } + // Try to catch VS manifest validation errors before we get to VS. + string vsPayloadRelativePath = $"{PackageName},version={Version.ToString(3)},chip={Chip},productarch={ProductArch}\\{Path.GetFileName(MsiPath)}"; + CheckRelativePayloadPath(vsPayloadRelativePath); + string swixSourceDirectory = Path.Combine(SwixDirectory, PackageName, Chip); string msiSwr = EmbeddedTemplates.Extract("msi.swr", swixSourceDirectory); string fullProjectName = $"{PackageName}.{Version.ToString(3)}.{Chip}"; diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs index a3eb28d860c..bf7af320a1b 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs @@ -239,6 +239,9 @@ internal IEnumerable ProcessWorkloadManifestFile(string workloadManif Log?.LogError($"Visual Studio components '{component.Name}' must have at least one dependency."); } + string vsPayloadRelativePath = $"{component.Name},version={component.Version}\\_package.json"; + CheckRelativePayloadPath(vsPayloadRelativePath); + swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0"))); } diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj index 161b0654020..e44ad1cc54a 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj @@ -1,4 +1,4 @@ - + net472;netcoreapp3.1 @@ -34,7 +34,7 @@ - + diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs index 22b083a99b5..47cb493151c 100644 --- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs +++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs @@ -18,6 +18,8 @@ namespace Microsoft.DotNet.Build.Tasks.Workloads /// public class VisualStudioComponent { + private static readonly string[] s_SupportedRids = new string[] { "win7", "win10", "any", "win", "win-x64", "win-x86", "win-arm64" }; + /// /// The component category. /// @@ -262,16 +264,30 @@ public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManife foreach (WorkloadPackId packId in packIds) { - log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} "); - - if (manifest.Packs.ContainsKey(packId)) + // Check whether the pack dependency is aliased to non-Windows RIDs. If so, we can't add a dependency for the pack + // because we won't be able to create installers. + if (manifest.Packs.TryGetValue(packId, out WorkloadPack pack)) { - component.AddDependency(manifest.Packs[packId]); - } - else - { - log?.LogMessage(MessageImportance.High, $"Missing Visual Studio component dependency, packId: {packId}."); + if (pack.IsAlias && !pack.AliasTo.Keys.Any(rid => s_SupportedRids.Contains(rid))) + { + log?.LogMessage($"Workload {workload.Id} supports Windows, but none of its aliased packs do. Only the following pack aliases were found: {String.Join("", "", pack.AliasTo.Keys)}."); + continue; + } + else + { + log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} "); + component.AddDependency(manifest.Packs[packId]); + } } + + //if (manifest.Packs.ContainsKey(packId)) + //{ + // component.AddDependency(manifest.Packs[packId]); + //} + //else + //{ + // log?.LogMessage(MessageImportance.High, $"Missing Visual Studio component dependency, packId: {packId}."); + //} } }