dependabot-nuget 0.287.0 → 0.288.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/.gitignore +1 -0
  3. data/helpers/lib/NuGetUpdater/Directory.Build.targets +17 -0
  4. data/helpers/lib/NuGetUpdater/Directory.Packages.props +10 -3
  5. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +7 -3
  6. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
  7. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +72 -51
  8. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +1 -1
  9. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.props +7 -0
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +10 -0
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +36 -19
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +6 -2
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscoveryResult.cs +2 -1
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +5 -0
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +386 -12
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/WorkspaceDiscoveryResult.cs +1 -1
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +11 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +7 -2
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +23 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +0 -4
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/TargetFrameworkReporter.targets +13 -0
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +1 -0
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +2 -0
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/CollectionExtensions.cs +17 -0
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +57 -4
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathComparer.cs +31 -0
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +30 -2
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +50 -0
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +74 -38
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +50 -4
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +5 -5
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +728 -253
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +322 -78
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +2 -6
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +472 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +46 -1
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/NuGetUpdater.Core.Test.csproj +0 -1
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +1 -1
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +33 -0
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +3 -2
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +4 -2
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +3 -2
  43. data/lib/dependabot/nuget/file_parser.rb +7 -1
  44. data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -3
  45. data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +7 -10
  46. data/lib/dependabot/nuget/native_helpers.rb +13 -4
  47. metadata +12 -8
  48. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscovery.cs +0 -69
  49. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DirectoryPackagesPropsDiscoveryResult.cs +0 -11
  50. data/lib/dependabot/nuget/native_discovery/native_directory_packages_props_discovery.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bb2d903f08322511a7917fba47df7b66208dbbaca42e52d30a1954f9ef3eaa2
4
- data.tar.gz: f19cfed3ad2939c93812727546b53ecec603c712641a6c1d0581469cce72d584
3
+ metadata.gz: 970779cacdfb8250a46cf1c24ac9fcda325b69b1502c3f0e99b9f1bf80a1add8
4
+ data.tar.gz: a8c7a1b0aba00354ffdb35a8903e912d60ce00e73521f53b76b5f20458194e2f
5
5
  SHA512:
6
- metadata.gz: a3fdc15bd985678106cf45f57c6af6dd4be57858f54b50abea6f4521a8aed3ab66b7ca67cb54f9e73dabe536d8c012619bbf049662207211bc92cbb5e938c321
7
- data.tar.gz: 3542f489f10b67fe78b3bd55703cc420a58279bf5fb131da4a99be0d99a20fcd7430b124c4b49100929b74f39178b3c7e108e7bb0170baef5f5a91a16dfbd63f
6
+ metadata.gz: 0ae55b0bfbfa8874ef9b2f9a6864587b13d107e9702319397161dbd70c9df97f638b9e906807966f3a0ca2214fce5760c1b4c58eb5b481c68171a270fadbbded
7
+ data.tar.gz: bea5ba0649370308fa5a1a6c8d2211708ebdf99d33da6461d38c3a4a10e095b87be83e8ae39b4050fa7ce40ad096fdb349c7bc715971c7e0971ba5eb1f68265d
@@ -4,3 +4,4 @@ bin/
4
4
  obj/
5
5
  Properties/launchSettings.json
6
6
  NuGetUpdater.sln.DotSettings.user
7
+ *.binlog
@@ -0,0 +1,17 @@
1
+ <Project>
2
+ <ItemGroup>
3
+ <!--
4
+ The NuGetUpdater.Core project needs to reference `Microsoft.Build.*`, et al. packages, but they require some
5
+ special handling. The documentation explains that:
6
+
7
+ https://learn.microsoft.com/en-us/visualstudio/msbuild/find-and-use-msbuild-versions?view=vs-2022#use-nuget-packages-preferred
8
+
9
+ The `ExcludeAssets` attribute doesn't do what we'd like through a <ProjectReference> element, so to get around that
10
+ we're adding the packages to _all_ projects so they all get the `ExcludeAssets` behavior. For more information see
11
+ this: https://github.com/dotnet/sdk/issues/42708
12
+ -->
13
+ <PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" PrivateAssets="all" />
14
+ <PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" PrivateAssets="all" />
15
+ <PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" PrivateAssets="all" />
16
+ </ItemGroup>
17
+ </Project>
@@ -4,19 +4,26 @@
4
4
  <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
5
5
  </PropertyGroup>
6
6
 
7
+ <PropertyGroup>
8
+ <MSBuildPackageVersion>17.5.0</MSBuildPackageVersion>
9
+ </PropertyGroup>
10
+
7
11
  <ItemGroup>
8
12
  <PackageVersion Include="DiffPlex" Version="1.7.1" />
9
13
 
10
14
  <PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.93" />
11
15
 
12
- <PackageVersion Include="Microsoft.Build.Locator" Version="1.6.1" />
13
- <PackageVersion Include="Microsoft.Build" Version="17.5.0" ExcludeAssets="Runtime" PrivateAssets="All" />
14
- <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.5.0" ExcludeAssets="Runtime" PrivateAssets="All" />
16
+ <PackageVersion Include="Microsoft.Build" Version="$(MSBuildPackageVersion)" />
17
+ <PackageVersion Include="Microsoft.Build.Framework" Version="$(MSBuildPackageVersion)" />
18
+ <PackageVersion Include="Microsoft.Build.Locator" Version="1.7.8" />
19
+ <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MSBuildPackageVersion)" />
15
20
 
16
21
  <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
17
22
 
18
23
  <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
19
24
 
25
+ <PackageVersion Include="MSBuild.StructuredLogger" Version="2.2.386" />
26
+
20
27
  <PackageVersion Include="NuGet.Core" Version="2.14.0-rtm-832" Aliases="CoreV2" />
21
28
 
22
29
  <PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
@@ -7,6 +7,7 @@ namespace NuGetUpdater.Cli.Commands;
7
7
 
8
8
  internal static class DiscoverCommand
9
9
  {
10
+ internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
10
11
  internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { IsRequired = true };
11
12
  internal static readonly Option<string> WorkspaceOption = new("--workspace") { IsRequired = true };
12
13
  internal static readonly Option<FileInfo> OutputOption = new("--output") { IsRequired = true };
@@ -15,6 +16,7 @@ internal static class DiscoverCommand
15
16
  {
16
17
  Command command = new("discover", "Generates a report of the workspace dependencies and where they are located.")
17
18
  {
19
+ JobPathOption,
18
20
  RepoRootOption,
19
21
  WorkspaceOption,
20
22
  OutputOption
@@ -22,11 +24,13 @@ internal static class DiscoverCommand
22
24
 
23
25
  command.TreatUnmatchedTokensAsErrors = true;
24
26
 
25
- command.SetHandler(async (repoRoot, workspace, outputPath) =>
27
+ command.SetHandler(async (jobPath, repoRoot, workspace, outputPath) =>
26
28
  {
27
- var worker = new DiscoveryWorker(new ConsoleLogger());
29
+ var logger = new ConsoleLogger();
30
+ var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
31
+ var worker = new DiscoveryWorker(experimentsManager, logger);
28
32
  await worker.RunAsync(repoRoot.FullName, workspace, outputPath.FullName);
29
- }, RepoRootOption, WorkspaceOption, OutputOption);
33
+ }, JobPathOption, RepoRootOption, WorkspaceOption, OutputOption);
30
34
 
31
35
  return command;
32
36
  }
@@ -35,7 +35,7 @@ internal static class RunCommand
35
35
  var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
36
36
  var logger = new ConsoleLogger();
37
37
  var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
38
- var discoverWorker = new DiscoveryWorker(logger);
38
+ var discoverWorker = new DiscoveryWorker(experimentsManager, logger);
39
39
  var analyzeWorker = new AnalyzeWorker(logger);
40
40
  var updateWorker = new UpdaterWorker(experimentsManager, logger);
41
41
  var worker = new RunWorker(apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
@@ -17,12 +17,16 @@ public partial class EntryPointTests
17
17
  {
18
18
  public class Discover : DiscoveryWorkerTestBase
19
19
  {
20
- [Fact]
21
- public async Task PathWithSpaces()
20
+ [Theory]
21
+ [InlineData(true)]
22
+ [InlineData(false)]
23
+ public async Task PathWithSpaces(bool useDirectDiscovery)
22
24
  {
23
25
  await RunAsync(path =>
24
26
  [
25
27
  "discover",
28
+ "--job-path",
29
+ Path.Combine(path, "job.json"),
26
30
  "--repo-root",
27
31
  path,
28
32
  "--workspace",
@@ -30,11 +34,15 @@ public partial class EntryPointTests
30
34
  "--output",
31
35
  Path.Combine(path, DiscoveryWorker.DiscoveryResultFileName),
32
36
  ],
33
- packages: [],
37
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = useDirectDiscovery },
38
+ packages:
39
+ [
40
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.3", "net8.0"),
41
+ ],
34
42
  initialFiles:
35
43
  [
36
44
  ("path/to/some directory with spaces/project.csproj", """
37
- <Project Sdk="Microsoft.NETSdk">
45
+ <Project Sdk="Microsoft.NET.Sdk">
38
46
  <PropertyGroup>
39
47
  <TargetFramework>net8.0</TargetFramework>
40
48
  </PropertyGroup>
@@ -52,8 +60,6 @@ public partial class EntryPointTests
52
60
  {
53
61
  FilePath = "project.csproj",
54
62
  TargetFrameworks = ["net8.0"],
55
- ReferencedProjectPaths = [],
56
- ExpectedDependencyCount = 2,
57
63
  Dependencies = [
58
64
  new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
59
65
  ],
@@ -66,12 +72,16 @@ public partial class EntryPointTests
66
72
  );
67
73
  }
68
74
 
69
- [Fact]
70
- public async Task WithSolution()
75
+ [Theory]
76
+ [InlineData(true)]
77
+ [InlineData(false)]
78
+ public async Task WithSolution(bool useDirectDiscovery)
71
79
  {
72
80
  await RunAsync(path =>
73
81
  [
74
82
  "discover",
83
+ "--job-path",
84
+ Path.Combine(path, "job.json"),
75
85
  "--repo-root",
76
86
  path,
77
87
  "--workspace",
@@ -79,6 +89,7 @@ public partial class EntryPointTests
79
89
  "--output",
80
90
  Path.Combine(path, DiscoveryWorker.DiscoveryResultFileName),
81
91
  ],
92
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = useDirectDiscovery },
82
93
  packages:
83
94
  [
84
95
  MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
@@ -141,26 +152,26 @@ public partial class EntryPointTests
141
152
  {
142
153
  FilePath = "path/to/my.csproj",
143
154
  TargetFrameworks = ["net45"],
144
- ReferencedProjectPaths = [],
145
- ExpectedDependencyCount = 2,
146
155
  Dependencies = [
147
156
  new("Some.Package", "7.0.1", DependencyType.PackagesConfig, TargetFrameworks: ["net45"]),
148
157
  ],
149
- Properties = [
150
- new("TargetFrameworkVersion", "v4.5", "path/to/my.csproj"),
151
- ],
158
+ Properties = [],
152
159
  }
153
160
  ]
154
161
  }
155
162
  );
156
163
  }
157
164
 
158
- [Fact]
159
- public async Task WithProject()
165
+ [Theory]
166
+ [InlineData(true)]
167
+ [InlineData(false)]
168
+ public async Task WithProject(bool useDirectDiscovery)
160
169
  {
161
170
  await RunAsync(path =>
162
171
  [
163
172
  "discover",
173
+ "--job-path",
174
+ Path.Combine(path, "job.json"),
164
175
  "--repo-root",
165
176
  path,
166
177
  "--workspace",
@@ -168,6 +179,7 @@ public partial class EntryPointTests
168
179
  "--output",
169
180
  Path.Combine(path, DiscoveryWorker.DiscoveryResultFileName),
170
181
  ],
182
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = useDirectDiscovery },
171
183
  packages:
172
184
  [
173
185
  MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
@@ -207,27 +219,27 @@ public partial class EntryPointTests
207
219
  {
208
220
  FilePath = "my.csproj",
209
221
  TargetFrameworks = ["net45"],
210
- ReferencedProjectPaths = [],
211
- ExpectedDependencyCount = 2,
212
222
  Dependencies = [
213
223
  new("Some.Package", "7.0.1", DependencyType.PackagesConfig, TargetFrameworks: ["net45"])
214
224
  ],
215
- Properties = [
216
- new("TargetFrameworkVersion", "v4.5", "path/to/my.csproj"),
217
- ],
225
+ Properties = [],
218
226
  }
219
227
  ]
220
228
  }
221
229
  );
222
230
  }
223
231
 
224
- [Fact]
225
- public async Task WithDirectory()
232
+ [Theory]
233
+ [InlineData(true)]
234
+ [InlineData(false)]
235
+ public async Task WithDirectory(bool useDirectDiscovery)
226
236
  {
227
237
  var workspacePath = "path/to/";
228
238
  await RunAsync(path =>
229
239
  [
230
240
  "discover",
241
+ "--job-path",
242
+ Path.Combine(path, "job.json"),
231
243
  "--repo-root",
232
244
  path,
233
245
  "--workspace",
@@ -235,6 +247,7 @@ public partial class EntryPointTests
235
247
  "--output",
236
248
  Path.Combine(path, DiscoveryWorker.DiscoveryResultFileName),
237
249
  ],
250
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = useDirectDiscovery },
238
251
  packages:
239
252
  [
240
253
  MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
@@ -274,14 +287,10 @@ public partial class EntryPointTests
274
287
  {
275
288
  FilePath = "my.csproj",
276
289
  TargetFrameworks = ["net45"],
277
- ReferencedProjectPaths = [],
278
- ExpectedDependencyCount = 2,
279
290
  Dependencies = [
280
291
  new("Some.Package", "7.0.1", DependencyType.PackagesConfig, TargetFrameworks: ["net45"])
281
292
  ],
282
- Properties = [
283
- new("TargetFrameworkVersion", "v4.5", "path/to/my.csproj"),
284
- ],
293
+ Properties = [],
285
294
  }
286
295
  ]
287
296
  }
@@ -294,6 +303,8 @@ public partial class EntryPointTests
294
303
  await RunAsync(path =>
295
304
  [
296
305
  "discover",
306
+ "--job-path",
307
+ Path.Combine(path, "job.json"),
297
308
  "--repo-root",
298
309
  path,
299
310
  "--workspace",
@@ -304,27 +315,33 @@ public partial class EntryPointTests
304
315
  new[]
305
316
  {
306
317
  ("path/to/my.csproj", """
307
- <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
318
+ <Project Sdk="Microsoft.NET.Sdk">
308
319
  <PropertyGroup>
309
320
  <TargetFramework>net8.0</TargetFramework>
321
+ <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
310
322
  </PropertyGroup>
311
323
  <ItemGroup>
312
- <PackageReference Include="Newtonsoft.Json" Version="7.0.1" />
324
+ <PackageReference Include="Package.A" Version="1.2.3" />
313
325
  </ItemGroup>
314
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
315
326
  </Project>
316
327
  """),
317
328
  ("path/Directory.Build.props", """
318
329
  <Project>
319
- <ItemGroup Condition="'$(ManagePackageVersionsCentrally)' == 'true'">
320
- <GlobalPackageReference Include="System.Text.Json" Version="8.0.3" />
321
- </ItemGroup>
322
330
  <ItemGroup Condition="'$(ManagePackageVersionsCentrally)' != 'true'">
323
- <PackageReference Include="System.Text.Json" Version="8.0.3" />
331
+ <PackageReference Include="Package.B" Version="4.5.6" />
332
+ </ItemGroup>
333
+ <ItemGroup Condition="'$(ManagePackageVersionsCentrally)' == 'true'">
334
+ <GlobalPackageReference Include="Package.B" Version="7.8.9" />
324
335
  </ItemGroup>
325
336
  </Project>
326
337
  """)
327
338
  },
339
+ experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
340
+ packages:
341
+ [
342
+ MockNuGetPackage.CreateSimplePackage("Package.A", "1.2.3", "net8.0"),
343
+ MockNuGetPackage.CreateSimplePackage("Package.B", "4.5.6", "net8.0"),
344
+ ],
328
345
  expectedResult: new()
329
346
  {
330
347
  Path = "path/to",
@@ -333,28 +350,19 @@ public partial class EntryPointTests
333
350
  {
334
351
  FilePath = "my.csproj",
335
352
  TargetFrameworks = ["net8.0"],
336
- ReferencedProjectPaths = [],
337
353
  ExpectedDependencyCount = 2,
338
354
  Dependencies = [
339
- new("Newtonsoft.Json", "7.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
340
- // $(ManagePackageVersionsCentrally) evaluates false by default, we only get a PackageReference
341
- new("System.Text.Json", "8.0.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"])
355
+ new("Package.A", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
356
+ new("Package.B", "4.5.6", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
342
357
  ],
343
358
  Properties = [
359
+ new("ManagePackageVersionsCentrally", "false", "path/to/my.csproj"),
344
360
  new("TargetFramework", "net8.0", "path/to/my.csproj"),
345
361
  ],
346
- },
347
- new()
348
- {
349
- FilePath = "../Directory.Build.props",
350
- ReferencedProjectPaths = [],
351
- ExpectedDependencyCount = 2,
352
- Dependencies = [
353
- new("System.Text.Json", "8.0.3", DependencyType.PackageReference, IsDirect: true),
354
- new("System.Text.Json", "8.0.3", DependencyType.GlobalPackageReference, IsDirect: true)
355
- ],
356
- Properties = [],
357
362
  }
363
+ ],
364
+ ImportedFiles = [
365
+ "Directory.Build.props"
358
366
  ]
359
367
  }
360
368
  );
@@ -364,8 +372,10 @@ public partial class EntryPointTests
364
372
  Func<string, string[]> getArgs,
365
373
  TestFile[] initialFiles,
366
374
  ExpectedWorkspaceDiscoveryResult expectedResult,
367
- MockNuGetPackage[]? packages = null)
375
+ MockNuGetPackage[]? packages = null,
376
+ ExperimentsManager? experimentsManager = null)
368
377
  {
378
+ experimentsManager ??= new ExperimentsManager();
369
379
  var actualResult = await RunDiscoveryAsync(initialFiles, async path =>
370
380
  {
371
381
  var sb = new StringBuilder();
@@ -378,8 +388,19 @@ public partial class EntryPointTests
378
388
 
379
389
  try
380
390
  {
391
+ await UpdateWorkerTestBase.MockJobFileInDirectory(path, experimentsManager);
381
392
  await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, path);
382
393
  var args = getArgs(path);
394
+
395
+ // manually pull out the experiments manager for the validate step below
396
+ for (int i = 0; i < args.Length - 1; i++)
397
+ {
398
+ if (args[i] == "--job-path")
399
+ {
400
+ experimentsManager = await ExperimentsManager.FromJobFileAsync(args[i + 1], new TestLogger());
401
+ }
402
+ }
403
+
383
404
  var result = await Program.Main(args);
384
405
  if (result != 0)
385
406
  {
@@ -398,7 +419,7 @@ public partial class EntryPointTests
398
419
  return resultObject!;
399
420
  });
400
421
 
401
- ValidateWorkspaceResult(expectedResult, actualResult);
422
+ ValidateWorkspaceResult(expectedResult, actualResult, experimentsManager);
402
423
  }
403
424
  }
404
425
  }
@@ -391,8 +391,8 @@ public partial class AnalyzeWorker : IAnalyzeWorker
391
391
 
392
392
  var projectFrameworks = projectsWithDependency
393
393
  .SelectMany(p => p.TargetFrameworks)
394
- .Distinct()
395
394
  .Select(NuGetFramework.Parse)
395
+ .Distinct()
396
396
  .ToImmutableArray();
397
397
 
398
398
  // When updating peer dependencies, we only need to consider top-level dependencies.
@@ -0,0 +1,7 @@
1
+ <Project>
2
+ <!-- The following properties enable target framework and dependency discovery when OS-specific workloads are required -->
3
+ <PropertyGroup>
4
+ <DesignTimeBuild>true</DesignTimeBuild>
5
+ <TargetPlatformVersion Condition=" $(TargetFramework.Contains('-')) ">1.0</TargetPlatformVersion>
6
+ </PropertyGroup>
7
+ </Project>
@@ -0,0 +1,10 @@
1
+ <Project>
2
+ <Import Project="DependencyDiscovery.props" />
3
+
4
+ <Target Name="_DiscoverDependencies" DependsOnTargets="GenerateBuildDependencyFile;ResolvePackageAssets">
5
+ <!--
6
+ The target GenerateBuildDependencyFile is sufficient for projects targeting .NET Standard or .NET Core.
7
+ The target ResolvePackageAssets is necessary for projects targeting .NET Framework.
8
+ -->
9
+ </Target>
10
+ </Project>
@@ -16,6 +16,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
16
16
  {
17
17
  public const string DiscoveryResultFileName = "./.dependabot/discovery.json";
18
18
 
19
+ private readonly ExperimentsManager _experimentsManager;
19
20
  private readonly ILogger _logger;
20
21
  private readonly HashSet<string> _processedProjectPaths = new(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> _restoredMSBuildSdks = new(StringComparer.OrdinalIgnoreCase);
21
22
 
@@ -25,8 +26,9 @@ public partial class DiscoveryWorker : IDiscoveryWorker
25
26
  Converters = { new JsonStringEnumConverter() },
26
27
  };
27
28
 
28
- public DiscoveryWorker(ILogger logger)
29
+ public DiscoveryWorker(ExperimentsManager experimentsManager, ILogger logger)
29
30
  {
31
+ _experimentsManager = experimentsManager;
30
32
  _logger = logger;
31
33
  }
32
34
 
@@ -52,6 +54,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
52
54
  ErrorDetails = "(" + string.Join("|", NuGetContext.GetPackageSourceUrls(PathHelper.JoinPath(repoRootPath, workspacePath))) + ")",
53
55
  Path = workspacePath,
54
56
  Projects = [],
57
+ ImportedFiles = [],
55
58
  };
56
59
  }
57
60
 
@@ -60,7 +63,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
60
63
 
61
64
  public async Task<WorkspaceDiscoveryResult> RunAsync(string repoRootPath, string workspacePath)
62
65
  {
63
- MSBuildHelper.RegisterMSBuild(Environment.CurrentDirectory, repoRootPath);
66
+ MSBuildHelper.RegisterMSBuild(repoRootPath, workspacePath);
64
67
 
65
68
  // the `workspacePath` variable is relative to a repository root, so a rooted path actually isn't rooted; the
66
69
  // easy way to deal with this is to just trim the leading "/" if it exists
@@ -74,7 +77,6 @@ public partial class DiscoveryWorker : IDiscoveryWorker
74
77
 
75
78
  DotNetToolsJsonDiscoveryResult? dotNetToolsJsonDiscovery = null;
76
79
  GlobalJsonDiscoveryResult? globalJsonDiscovery = null;
77
- DirectoryPackagesPropsDiscoveryResult? directoryPackagesPropsDiscovery = null;
78
80
 
79
81
  ImmutableArray<ProjectDiscoveryResult> projectResults = [];
80
82
  WorkspaceDiscoveryResult result;
@@ -93,26 +95,30 @@ public partial class DiscoveryWorker : IDiscoveryWorker
93
95
 
94
96
  // this next line should throw or something
95
97
  projectResults = await RunForDirectoryAsnyc(repoRootPath, workspacePath);
96
-
97
- directoryPackagesPropsDiscovery = DirectoryPackagesPropsDiscovery.Discover(repoRootPath, workspacePath, projectResults, _logger);
98
-
99
- if (directoryPackagesPropsDiscovery is not null)
100
- {
101
- projectResults = projectResults.Remove(projectResults.First(p => p.FilePath.Equals(directoryPackagesPropsDiscovery.FilePath, StringComparison.OrdinalIgnoreCase)));
102
- }
103
98
  }
104
99
  else
105
100
  {
106
101
  _logger.Log($"Workspace path [{workspacePath}] does not exist.");
107
102
  }
108
103
 
104
+ var importedFiles = new HashSet<string>(PathComparer.Instance);
105
+ foreach (var project in projectResults)
106
+ {
107
+ // imported files are relative to the project and need to be converted to be relative to the repo root
108
+ var repoRootRelativeImportedFiles = project.ImportedFiles
109
+ .Select(p => Path.Join(Path.GetDirectoryName(project.FilePath) ?? "", p))
110
+ .Select(p => p.NormalizePathToUnix().NormalizeUnixPathParts())
111
+ .ToArray();
112
+ importedFiles.AddRange(repoRootRelativeImportedFiles);
113
+ }
114
+
109
115
  result = new WorkspaceDiscoveryResult
110
116
  {
111
117
  Path = initialWorkspacePath,
112
118
  DotNetToolsJson = dotNetToolsJsonDiscovery,
113
119
  GlobalJson = globalJsonDiscovery,
114
- DirectoryPackagesProps = directoryPackagesPropsDiscovery,
115
120
  Projects = projectResults.OrderBy(p => p.FilePath).ToImmutableArray(),
121
+ ImportedFiles = importedFiles.ToImmutableArray(),
116
122
  };
117
123
 
118
124
  _logger.Log("Discovery complete.");
@@ -288,11 +294,9 @@ public partial class DiscoveryWorker : IDiscoveryWorker
288
294
  }
289
295
  _processedProjectPaths.Add(actualProjectPath);
290
296
 
291
- var relativeProjectPath = Path.GetRelativePath(workspacePath, actualProjectPath);
292
- var packagesConfigDependencies = PackagesConfigDiscovery.Discover(workspacePath, projectPath, _logger)
293
- ?.Dependencies;
294
-
295
- var projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _logger);
297
+ var relativeProjectPath = Path.GetRelativePath(workspacePath, actualProjectPath).NormalizePathToUnix();
298
+ var packagesConfigResult = await PackagesConfigDiscovery.Discover(repoRootPath, workspacePath, actualProjectPath, _logger);
299
+ var projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
296
300
 
297
301
  // Determine if there were unrestored MSBuildSdks
298
302
  var msbuildSdks = projectResults.SelectMany(p => p.Dependencies.Where(d => d.Type == DependencyType.MSBuildSdk)).ToImmutableArray();
@@ -301,7 +305,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
301
305
  // If new SDKs were restored, then we need to rerun SdkProjectDiscovery.
302
306
  if (await TryRestoreMSBuildSdksAsync(repoRootPath, workspacePath, msbuildSdks, _logger))
303
307
  {
304
- projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _logger);
308
+ projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
305
309
  }
306
310
  }
307
311
 
@@ -313,9 +317,9 @@ public partial class DiscoveryWorker : IDiscoveryWorker
313
317
  }
314
318
 
315
319
  // If we had packages.config dependencies, merge them with the project dependencies
316
- if (projectResult.FilePath == relativeProjectPath && packagesConfigDependencies is not null)
320
+ if (projectResult.FilePath == relativeProjectPath && packagesConfigResult is not null)
317
321
  {
318
- packagesConfigDependencies = packagesConfigDependencies.Value
322
+ var packagesConfigDependencies = packagesConfigResult.Dependencies
319
323
  .Select(d => d with { TargetFrameworks = projectResult.TargetFrameworks })
320
324
  .ToImmutableArray();
321
325
 
@@ -329,6 +333,19 @@ public partial class DiscoveryWorker : IDiscoveryWorker
329
333
  results[projectResult.FilePath] = projectResult;
330
334
  }
331
335
  }
336
+
337
+ if (!results.ContainsKey(relativeProjectPath) &&
338
+ packagesConfigResult is not null &&
339
+ packagesConfigResult.Dependencies.Length > 0)
340
+ {
341
+ // project contained only packages.config dependencies
342
+ results[relativeProjectPath] = new ProjectDiscoveryResult()
343
+ {
344
+ FilePath = relativeProjectPath,
345
+ Dependencies = packagesConfigResult.Dependencies,
346
+ TargetFrameworks = packagesConfigResult.TargetFrameworks,
347
+ };
348
+ }
332
349
  }
333
350
 
334
351
  return [.. results.Values];
@@ -4,7 +4,7 @@ namespace NuGetUpdater.Core.Discover;
4
4
 
5
5
  internal static class PackagesConfigDiscovery
6
6
  {
7
- public static PackagesConfigDiscoveryResult? Discover(string workspacePath, string projectPath, ILogger logger)
7
+ public static async Task<PackagesConfigDiscoveryResult?> Discover(string repoRootPath, string workspacePath, string projectPath, ILogger logger)
8
8
  {
9
9
  if (!NuGetHelper.TryGetPackagesConfigFile(projectPath, out var packagesConfigPath))
10
10
  {
@@ -20,10 +20,14 @@ internal static class PackagesConfigDiscovery
20
20
  .OrderBy(d => d.Name)
21
21
  .ToImmutableArray();
22
22
 
23
+ // generate `$(TargetFramework)` via MSBuild
24
+ var tfms = await MSBuildHelper.GetTargetFrameworkValuesFromProject(repoRootPath, projectPath, logger);
25
+
23
26
  return new()
24
27
  {
25
28
  FilePath = packagesConfigFile.RelativePath,
26
- Dependencies = dependencies,
29
+ Dependencies = dependencies.Select(d => d with { TargetFrameworks = tfms }).ToImmutableArray(),
30
+ TargetFrameworks = tfms,
27
31
  };
28
32
  }
29
33
  }
@@ -6,5 +6,6 @@ public sealed record PackagesConfigDiscoveryResult : IDiscoveryResultWithDepende
6
6
  {
7
7
  public required string FilePath { get; init; }
8
8
  public bool IsSuccess { get; init; } = true;
9
- public ImmutableArray<Dependency> Dependencies { get; init; }
9
+ public required ImmutableArray<Dependency> Dependencies { get; init; }
10
+ public required ImmutableArray<string> TargetFrameworks { get; init; }
10
11
  }
@@ -1,4 +1,5 @@
1
1
  using System.Collections.Immutable;
2
+ using System.Text.Json.Serialization;
2
3
 
3
4
  namespace NuGetUpdater.Core.Discover;
4
5
 
@@ -10,4 +11,8 @@ public record ProjectDiscoveryResult : IDiscoveryResultWithDependencies
10
11
  public ImmutableArray<Property> Properties { get; init; } = [];
11
12
  public ImmutableArray<string> TargetFrameworks { get; init; } = [];
12
13
  public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
14
+
15
+ // this is purely for internal record keeping and should not be serialized
16
+ [JsonIgnore]
17
+ public ImmutableArray<string> ImportedFiles { get; init; } = [];
13
18
  }