@@ -49,7 +49,7 @@ public void InstallAndRunNativeAotGlobalTool()
49
49
{
50
50
NativeAOT = true
51
51
} ;
52
- string toolPackagesPath = ToolBuilder . CreateTestTool ( Log , toolSettings ) ;
52
+ string toolPackagesPath = ToolBuilder . CreateTestTool ( Log , toolSettings , collectBinlogs : true ) ;
53
53
54
54
var testDirectory = _testAssetsManager . CreateTestDirectory ( ) ;
55
55
@@ -138,10 +138,9 @@ public void InstallAndRunNativeAotLocalTool()
138
138
[ Fact ]
139
139
public void PackagesMultipleToolsWithASingleInvocation ( )
140
140
{
141
-
142
141
var toolSettings = new TestToolBuilder . TestToolSettings ( )
143
142
{
144
- SelfContained = true
143
+ RidSpecific = true
145
144
} ;
146
145
string toolPackagesPath = ToolBuilder . CreateTestTool ( Log , toolSettings ) ;
147
146
@@ -154,21 +153,15 @@ public void PackagesMultipleToolsWithASingleInvocation()
154
153
{
155
154
var packageName = $ "{ toolSettings . ToolPackageId } .{ rid } .{ toolSettings . ToolPackageVersion } ";
156
155
var package = packages . FirstOrDefault ( p => p . EndsWith ( packageName + ".nupkg" ) ) ;
157
- package . Should ( ) . NotBeNull ( $ "Package { packageName } should be present in the tool packages directory") ;
156
+ package . Should ( )
157
+ . NotBeNull ( $ "Package { packageName } should be present in the tool packages directory")
158
+ . And . Satisfy < string > ( EnsurePackageIsAnExecutable ) ;
158
159
}
159
160
160
161
// top-level package should declare all of the rids
161
162
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" ) ;
163
+ var foundRids = GetRidsInSettingsFile ( topLevelPackage ) ;
164
+ foundRids . Should ( ) . BeEquivalentTo ( expectedRids , "The top-level package should declare all of the RIDs for the tools it contains" ) ;
172
165
}
173
166
174
167
[ Fact ]
@@ -189,22 +182,94 @@ public void PackagesMultipleTrimmedToolsWithASingleInvocation()
189
182
{
190
183
var packageName = $ "{ toolSettings . ToolPackageId } .{ rid } .{ toolSettings . ToolPackageVersion } ";
191
184
var package = packages . FirstOrDefault ( p => p . EndsWith ( packageName + ".nupkg" ) ) ;
192
- package . Should ( ) . NotBeNull ( $ "Package { packageName } should be present in the tool packages directory") ;
193
- EnsurePackageLacksTrimmedDependency ( package ! , "System.Xml.dll" ) ;
185
+ package . Should ( )
186
+ . NotBeNull ( $ "Package { packageName } should be present in the tool packages directory")
187
+ . And . Satisfy < string > ( EnsurePackageIsAnExecutable )
188
+ . And . Satisfy ( ( string package ) => EnsurePackageLacksTrimmedDependency ( package , "System.Xml.dll" ) ) ;
194
189
}
195
190
196
191
// top-level package should declare all of the rids
197
192
var topLevelPackage = packages . First ( p => p . EndsWith ( $ "{ packageIdentifier } .{ toolSettings . ToolPackageVersion } .nupkg") ) ;
198
- using var zipArchive = ZipFile . OpenRead ( topLevelPackage ) ;
199
- var nuspecEntry = zipArchive . GetEntry ( $ "tools/{ ToolsetInfo . CurrentTargetFramework } /any/DotnetToolSettings.xml") ! ;
200
- var stream = nuspecEntry . Open ( ) ;
201
- var xml = XDocument . Load ( stream , LoadOptions . None ) ;
202
- var packageNodes =
203
- ( xml . Root ! . Nodes ( )
193
+ var foundRids = GetRidsInSettingsFile ( topLevelPackage ) ;
194
+ foundRids . Should ( ) . BeEquivalentTo ( expectedRids , "The top-level package should declare all of the RIDs for the tools it contains" ) ;
195
+ }
196
+
197
+ [ Fact ]
198
+ public void PackagesFrameworkDependentRidSpecificPackagesCorrectly ( )
199
+ {
200
+ var toolSettings = new TestToolBuilder . TestToolSettings ( )
201
+ {
202
+ RidSpecific = true ,
203
+ } ;
204
+ string toolPackagesPath = ToolBuilder . CreateTestTool ( Log , toolSettings , collectBinlogs : true ) ;
205
+
206
+ var packages = Directory . GetFiles ( toolPackagesPath , "*.nupkg" ) ;
207
+ var packageIdentifier = toolSettings . ToolPackageId ;
208
+ var expectedRids = ToolsetInfo . LatestRuntimeIdentifiers . Split ( ';' ) ;
209
+
210
+ packages . Length . Should ( ) . Be ( expectedRids . Length + 1 , "There should be one package for the tool-wrapper and one for each RID" ) ;
211
+ foreach ( string rid in expectedRids )
212
+ {
213
+ var packageName = $ "{ toolSettings . ToolPackageId } .{ rid } .{ toolSettings . ToolPackageVersion } ";
214
+ var package = packages . FirstOrDefault ( p => p . EndsWith ( packageName + ".nupkg" ) ) ;
215
+ package . Should ( )
216
+ . NotBeNull ( $ "Package { packageName } should be present in the tool packages directory")
217
+ . And . Satisfy < string > ( EnsurePackageIsAnExecutable ) ;
218
+ }
219
+
220
+ // top-level package should declare all of the rids
221
+ var topLevelPackage = packages . First ( p => p . EndsWith ( $ "{ packageIdentifier } .{ toolSettings . ToolPackageVersion } .nupkg") ) ;
222
+ var foundRids = GetRidsInSettingsFile ( topLevelPackage ) ;
223
+ foundRids . Should ( ) . BeEquivalentTo ( expectedRids , "The top-level package should declare all of the RIDs for the tools it contains" ) ;
224
+ }
225
+
226
+
227
+ private void EnsurePackageIsFdd ( string packagePath )
228
+ {
229
+ var settingsXml = GetToolSettingsFile ( packagePath ) ;
230
+ var runner = GetRunnerFromSettingsFile ( settingsXml ) ;
231
+ runner . Should ( ) . Be ( "dotnet" , "The tool should be packaged as a framework-dependent executable (FDD) with a 'dotnet' runner." ) ;
232
+ }
233
+
234
+ private void EnsurePackageIsAnExecutable ( string packagePath )
235
+ {
236
+ var settingsXml = GetToolSettingsFile ( packagePath ) ;
237
+ var runner = GetRunnerFromSettingsFile ( settingsXml ) ;
238
+ runner . Should ( ) . Be ( "executable" , "The tool should be packaged as a executable with an 'executable' runner." ) ;
239
+ }
240
+
241
+ private object GetRunnerFromSettingsFile ( XElement settingsXml )
242
+ {
243
+ return settingsXml . Elements ( "Commands" ) . First ( ) . Elements ( "Command" ) . First ( ) . Attribute ( "Runner" ) ? . Value
244
+ ?? throw new InvalidOperationException ( "The tool settings file does not contain a 'Runner' attribute." ) ;
245
+ }
246
+
247
+ private string [ ] GetRidsInSettingsFile ( string packagePath )
248
+ {
249
+ var settingsXml = GetToolSettingsFile ( packagePath ) ;
250
+ var rids = GetRidsInSettingsFile ( settingsXml ) ;
251
+ rids . Should ( ) . NotBeEmpty ( "The tool settings file should contain at least one RuntimeIdentifierPackage element." ) ;
252
+ return rids ;
253
+ }
254
+
255
+ private string [ ] GetRidsInSettingsFile ( XElement settingsXml )
256
+ {
257
+ var nodes = ( settingsXml . Nodes ( )
204
258
. First ( n => n is XElement e && e . Name == "RuntimeIdentifierPackages" ) as XElement ) ! . Nodes ( )
205
259
. Where ( n => ( n as XElement ) ! . Name == "RuntimeIdentifierPackage" )
206
- . Select ( e => ( e as XElement ) ! . Attributes ( ) . First ( a => a . Name == "RuntimeIdentifier" ) . Value ) ;
207
- packageNodes . Should ( ) . BeEquivalentTo ( expectedRids , "The top-level package should declare all of the RIDs for the tools it contains" ) ;
260
+ . Select ( e => ( e as XElement ) ! . Attributes ( ) . First ( a => a . Name == "RuntimeIdentifier" ) . Value )
261
+ . ToArray ( ) ;
262
+ return nodes ;
263
+ }
264
+
265
+ private XElement GetToolSettingsFile ( string packagePath )
266
+ {
267
+ using var zipArchive = ZipFile . OpenRead ( packagePath ) ;
268
+ var nuspecEntry = zipArchive . Entries . First ( e => e . Name == "DotnetToolSettings.xml" ) ! ;
269
+ var stream = nuspecEntry . Open ( ) ;
270
+ var xml = XDocument . Load ( stream , LoadOptions . None ) ;
271
+ return xml . Root ! ;
272
+
208
273
}
209
274
210
275
/// <summary>
0 commit comments