Skip to content

Commit 2444c06

Browse files
committed
Add test for the multi-package tool creation
1 parent 92fb63b commit 2444c06

File tree

5 files changed

+53
-10
lines changed

5 files changed

+53
-10
lines changed

Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
6868
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
6969

70+
<SkipBuildingInstallers Condition="'$(SkipBuildingInstallers)' == ''">true</SkipBuildingInstallers>
71+
7072
<!-- https://github.com/dotnet/source-build/issues/4115. -->
7173
<PublishWindowsPdb>false</PublishWindowsPdb>
7274
</PropertyGroup>

src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Copyright (c) .NET Foundation. All rights reserved.
6262
<_PackToolPublishDependency Condition=" '$(_ToolPackageShouldIncludeImplementation)' != '' and '$(GeneratePackageOnBuild)' == 'true' and $(IsPublishable) == 'true' ">$(_PublishNoBuildAlternativeDependsOn)</_PackToolPublishDependency>
6363

6464
<!-- Trigger RID-specific inner builds if RID-specific mode is enabled-->
65-
<GenerateNuspecDependsOn Condition=" '$(_HasRIDSpecificTools)' == 'true' and '$(PublishAot)' != 'true' ">$(GenerateNuspecDependsOn);_CreateRIDSpecificToolPackages</GenerateNuspecDependsOn>
65+
<GenerateNuspecDependsOn>$(GenerateNuspecDependsOn);_CreateRIDSpecificToolPackages</GenerateNuspecDependsOn>
6666

6767
<!-- finally set up the entrypoint for all tool-content regardless of tool type-->
6868
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackTool</TargetsForTfmSpecificContentInPackage>
@@ -322,7 +322,7 @@ Copyright (c) .NET Foundation. All rights reserved.
322322
</Target>
323323

324324
<!-- orchestrator for making the N RID-specific tool packages -->
325-
<Target Name="_CreateRIDSpecificToolPackages">
325+
<Target Name="_CreateRIDSpecificToolPackages" Condition="'$(RuntimeIdentifier)' == '' and $(_HasRIDSpecificTools) and '$(PublishAot)' != 'true'">
326326
<PropertyGroup>
327327
<_PackageRids>$(ToolPackageRuntimeIdentifiers)</_PackageRids>
328328
<_PackageRids Condition="'$(_PackageRids)' == ''">$(RuntimeIdentifiers)</_PackageRids>

test/Microsoft.DotNet.PackageInstall.Tests/EndToEndToolTests.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
5-
using System.Collections.Generic;
6-
using System.Text;
7-
using Microsoft.Extensions.EnvironmentAbstractions;
4+
using System.IO.Compression;
85

96
namespace Microsoft.DotNet.PackageInstall.Tests
107
{
@@ -136,6 +133,43 @@ public void InstallAndRunNativeAotLocalTool()
136133
.Should().Pass()
137134
.And.HaveStdOutContaining("Hello Tool!");
138135
}
136+
137+
138+
[Fact]
139+
public void PackagesMultipleToolsWithASingleInvocation()
140+
{
141+
142+
var toolSettings = new TestToolBuilder.TestToolSettings()
143+
{
144+
SelfContained = true
145+
};
146+
string toolPackagesPath = ToolBuilder.CreateTestTool(Log, toolSettings);
147+
148+
var packages = Directory.GetFiles(toolPackagesPath, "*.nupkg");
149+
var packageIdentifier = toolSettings.ToolPackageId;
150+
var expectedRids = ToolsetInfo.LatestRuntimeIdentifiers.Split(';');
151+
152+
packages.Length.Should().Be(expectedRids.Length + 1, "There should be one package for the tool-wrapper and one for each RID");
153+
foreach (string rid in expectedRids)
154+
{
155+
var packageName = $"{toolSettings.ToolPackageId}.{rid}.{toolSettings.ToolPackageVersion}";
156+
var package = packages.FirstOrDefault(p => p.EndsWith(packageName + ".nupkg"));
157+
packages.Should().NotBeNull($"Package {packageName} should be present in the tool packages directory");
158+
}
159+
160+
// top-level package should declare all of the rids
161+
var topLevelPackage = packages.First(p => p.EndsWith($"{packageIdentifier}.{toolSettings.ToolPackageVersion}.nupkg"));
162+
using var zipArchive = ZipFile.OpenRead(topLevelPackage);
163+
var nuspecEntry = zipArchive.GetEntry($"tools/{ToolsetInfo.CurrentTargetFramework}/any/DotnetToolSettings.xml")!;
164+
var stream = nuspecEntry.Open();
165+
var xml = XDocument.Load(stream, LoadOptions.None);
166+
var packageNodes =
167+
(xml.Root!.Nodes()
168+
.First(n => n is XElement e && e.Name == "RuntimeIdentifierPackages") as XElement)!.Nodes()
169+
.Where(n => (n as XElement)!.Name == "RuntimeIdentifierPackage")
170+
.Select(e => (e as XElement)!.Attributes().First(a => a.Name == "RuntimeIdentifier").Value);
171+
packageNodes.Should().BeEquivalentTo(expectedRids, "The top-level package should declare all of the RIDs for the tools it contains");
172+
}
139173
}
140174

141175
static class EndToEndToolTestExtensions

test/Microsoft.DotNet.PackageInstall.Tests/TestToolBuilder.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ public class TestToolSettings
3333
public string ToolCommandName { get; set; } = "TestTool";
3434

3535
public bool NativeAOT { get; set; } = false;
36+
public bool SelfContained { get; set; } = false;
3637

37-
public string GetIdentifier() => $"{ToolPackageId}-{ToolPackageVersion}-{ToolCommandName}-{(NativeAOT ? "nativeaot" : "managed")}";
38+
public string GetIdentifier() => $"{ToolPackageId}-{ToolPackageVersion}-{ToolCommandName}-{(NativeAOT ? "nativeaot" : SelfContained ? "selfcontained" : "managed")}";
3839
}
3940

4041

@@ -59,6 +60,12 @@ public string CreateTestTool(ITestOutputHelper log, TestToolSettings toolSetting
5960
testProject.AdditionalProperties["RuntimeIdentifiers"] = RuntimeInformation.RuntimeIdentifier;
6061
}
6162

63+
if (toolSettings.SelfContained)
64+
{
65+
testProject.AdditionalProperties["SelfContained"] = "true";
66+
testProject.AdditionalProperties["RuntimeIdentifiers"] = ToolsetInfo.LatestRuntimeIdentifiers;
67+
}
68+
6269
testProject.SourceFiles.Add("Program.cs", "Console.WriteLine(\"Hello Tool!\");");
6370

6471
var testAssetManager = new TestAssetsManager(log);

test/Microsoft.NET.TestFramework/ToolsetInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class ToolsetInfo
1616
public const string LatestWinRuntimeIdentifier = "win";
1717
public const string LatestLinuxRuntimeIdentifier = "linux";
1818
public const string LatestMacRuntimeIdentifier = "osx";
19-
public const string LatestRuntimeIdentifiers = $"{LatestWinRuntimeIdentifier}-x64;{LatestWinRuntimeIdentifier}-x86;osx-x64;{LatestMacRuntimeIdentifier}-x64;{LatestLinuxRuntimeIdentifier}-x64;linux-musl-x64";
19+
public const string LatestRuntimeIdentifiers = $"{LatestWinRuntimeIdentifier}-x64;{LatestWinRuntimeIdentifier}-x86;{LatestMacRuntimeIdentifier}-x64;{LatestLinuxRuntimeIdentifier}-x64;linux-musl-x64";
2020

2121
public string DotNetRoot { get; }
2222
public string DotNetHostPath { get; }
@@ -138,7 +138,7 @@ private void InitMSBuildVersion()
138138
{
139139
string? msbuildRoot = null;
140140
var msbuildBinPath = Path.GetDirectoryName(FullFrameworkMSBuildPath);
141-
if(msbuildBinPath is not null)
141+
if (msbuildBinPath is not null)
142142
{
143143
msbuildRoot = Directory.GetParent(msbuildBinPath)?.Parent?.FullName;
144144
}
@@ -158,7 +158,7 @@ public void AddTestEnvironmentVariables(IDictionary<string, string> environment)
158158
string sdksPath = Path.Combine(DotNetRoot, "sdk", SdkVersion, "Sdks");
159159

160160
// Use stage 2 MSBuild SDK resolver
161-
if(SdkResolverPath is not null)
161+
if (SdkResolverPath is not null)
162162
{
163163
environment["MSBUILDADDITIONALSDKRESOLVERSFOLDER"] = SdkResolverPath;
164164
}

0 commit comments

Comments
 (0)