dependabot-nuget 0.268.0 → 0.270.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.
@@ -13,9 +13,12 @@ using Microsoft.Build.Exceptions;
13
13
  using Microsoft.Build.Locator;
14
14
  using Microsoft.Extensions.FileSystemGlobbing;
15
15
 
16
+ using NuGet;
16
17
  using NuGet.Configuration;
18
+ using NuGet.Frameworks;
17
19
  using NuGet.Versioning;
18
20
 
21
+ using NuGetUpdater.Core.Analyze;
19
22
  using NuGetUpdater.Core.Utilities;
20
23
 
21
24
  namespace NuGetUpdater.Core;
@@ -331,7 +334,182 @@ internal static partial class MSBuildHelper
331
334
  }
332
335
  }
333
336
 
334
- internal static async Task<Dependency[]?> ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Logger logger)
337
+ internal static bool UseNewDependencySolver()
338
+ {
339
+ return Environment.GetEnvironmentVariable("UseNewNugetPackageResolver") == "true";
340
+ }
341
+
342
+ internal static async Task<Dependency[]?> ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Dependency[] update, Logger logger)
343
+ {
344
+ if (UseNewDependencySolver())
345
+ {
346
+ return await ResolveDependencyConflictsNew(repoRoot, projectPath, targetFramework, packages, update, logger);
347
+ }
348
+ else
349
+ {
350
+ return await ResolveDependencyConflictsOld(repoRoot, projectPath, targetFramework, packages, logger);
351
+ }
352
+ }
353
+
354
+ internal static async Task<Dependency[]?> ResolveDependencyConflictsNew(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Dependency[] update, Logger logger)
355
+ {
356
+ var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
357
+ PackageManager packageManager = new PackageManager(repoRoot, projectPath);
358
+
359
+ try
360
+ {
361
+ string tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages);
362
+ var (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", $"restore \"{tempProjectPath}\"", workingDirectory: tempDirectory.FullName);
363
+
364
+ // Add Dependency[] packages to List<PackageToUpdate> existingPackages
365
+ List<PackageToUpdate> existingPackages = packages
366
+ .Select(existingPackage => new PackageToUpdate
367
+ {
368
+ PackageName = existingPackage.Name,
369
+ CurrentVersion = existingPackage.Version
370
+ })
371
+ .ToList();
372
+
373
+ // Add Dependency[] update to List<PackageToUpdate> packagesToUpdate
374
+ List<PackageToUpdate> packagesToUpdate = update
375
+ .Where(package => package.Version != null)
376
+ .Select(package => new PackageToUpdate
377
+ {
378
+ PackageName = package.Name,
379
+ NewVersion = package.Version.ToString()
380
+ })
381
+ .ToList();
382
+
383
+ foreach (PackageToUpdate existing in existingPackages)
384
+ {
385
+ var foundPackage = packagesToUpdate.Where(p => string.Equals(p.PackageName, existing.PackageName, StringComparison.OrdinalIgnoreCase));
386
+ if (!foundPackage.Any())
387
+ {
388
+ existing.NewVersion = existing.CurrentVersion;
389
+ }
390
+ }
391
+
392
+ // Create a duplicate set of existingPackages for flexible package reference addition and removal
393
+ List<PackageToUpdate> existingDuplicate = new List<PackageToUpdate>(existingPackages);
394
+
395
+ // Bool to keep track of if anything was added to the existingDuplicate list
396
+ bool added = false;
397
+
398
+ // If package 'isnt there, add it to the existingDuplicate list
399
+ foreach (PackageToUpdate package in packagesToUpdate)
400
+ {
401
+ if (!existingDuplicate.Any(p => string.Equals(p.PackageName, package.PackageName, StringComparison.OrdinalIgnoreCase)))
402
+ {
403
+ existingDuplicate.Add(package);
404
+ added = true;
405
+ }
406
+ }
407
+
408
+ // If you have to use the existingDuplicate list
409
+ if (added == true)
410
+ {
411
+ // Add existing versions to existing list
412
+ packageManager.UpdateExistingPackagesWithNewVersions(existingDuplicate, packagesToUpdate);
413
+
414
+ // Make relationships
415
+ await packageManager.PopulatePackageDependenciesAsync(existingDuplicate, targetFramework, Path.GetDirectoryName(projectPath));
416
+
417
+ // Update all to new versions
418
+ foreach (var package in existingDuplicate)
419
+ {
420
+ string updateResult = await packageManager.UpdateVersion(existingDuplicate, package, targetFramework, Path.GetDirectoryName(projectPath));
421
+ }
422
+ }
423
+
424
+ // Editing existing list because nothing was added to existingDuplicate
425
+ else
426
+ {
427
+ // Add existing versions to existing list
428
+ packageManager.UpdateExistingPackagesWithNewVersions(existingPackages, packagesToUpdate);
429
+
430
+ // Make relationships
431
+ await packageManager.PopulatePackageDependenciesAsync(existingPackages, targetFramework, Path.GetDirectoryName(projectPath));
432
+
433
+ // Update all to new versions
434
+ foreach (var package in existingPackages)
435
+ {
436
+ string updateResult = await packageManager.UpdateVersion(existingPackages, package, targetFramework, Path.GetDirectoryName(projectPath));
437
+ }
438
+ }
439
+
440
+ // Make new list to remove and differentiate between existingDuplicate and existingPackages lists
441
+ List<PackageToUpdate> packagesToRemove = existingDuplicate
442
+ .Where(existingPackageDupe => !existingPackages.Contains(existingPackageDupe) && existingPackageDupe.IsSpecific == true)
443
+ .ToList();
444
+
445
+ foreach (PackageToUpdate package in packagesToRemove)
446
+ {
447
+ existingDuplicate.Remove(package);
448
+ }
449
+
450
+ if (existingDuplicate != null)
451
+ {
452
+ existingPackages = existingDuplicate;
453
+ }
454
+
455
+ // Convert back to Dependency [], use NewVersion if available, otherwise use CurrentVersion
456
+ List<Dependency> candidatePackages = existingPackages
457
+ .Select(package => new Dependency(
458
+ package.PackageName,
459
+ package.NewVersion ?? package.CurrentVersion,
460
+ DependencyType.Unknown,
461
+ null,
462
+ null,
463
+ false,
464
+ false,
465
+ false,
466
+ false,
467
+ false
468
+ ))
469
+ .ToList();
470
+
471
+ // Return as array
472
+ Dependency[] candidatePackagesArray = candidatePackages.ToArray();
473
+
474
+ var targetFrameworks = new NuGetFramework[] { NuGetFramework.Parse(targetFramework) };
475
+
476
+ var resolveProjectPath = projectPath;
477
+
478
+ if (!Path.IsPathRooted(resolveProjectPath) || !File.Exists(resolveProjectPath))
479
+ {
480
+ resolveProjectPath = Path.GetFullPath(Path.Join(repoRoot, resolveProjectPath));
481
+ }
482
+
483
+ NuGetContext nugetContext = new NuGetContext(Path.GetDirectoryName(resolveProjectPath));
484
+
485
+ // Target framework compatibility check
486
+ foreach (var package in candidatePackages)
487
+ {
488
+ if (!NuGetVersion.TryParse(package.Version, out var nuGetVersion))
489
+ {
490
+ // If version is not valid, return original packages and revert
491
+ return packages;
492
+ }
493
+
494
+ var packageIdentity = new NuGet.Packaging.Core.PackageIdentity(package.Name, nuGetVersion);
495
+
496
+ bool isNewPackageCompatible = await CompatibilityChecker.CheckAsync(packageIdentity, targetFrameworks.ToImmutableArray(), nugetContext, logger, CancellationToken.None);
497
+ if (!isNewPackageCompatible)
498
+ {
499
+ // If the package target framework is not compatible, return original packages and revert
500
+ return packages;
501
+ }
502
+ }
503
+
504
+ return candidatePackagesArray;
505
+ }
506
+ finally
507
+ {
508
+ tempDirectory.Delete(recursive: true);
509
+ }
510
+ }
511
+
512
+ internal static async Task<Dependency[]?> ResolveDependencyConflictsOld(string repoRoot, string projectPath, string targetFramework, Dependency[] packages, Logger logger)
335
513
  {
336
514
  var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
337
515
  try
@@ -359,22 +537,22 @@ internal static partial class MSBuildHelper
359
537
  Dictionary<string, HashSet<NuGetVersion>> badPackagesAndCandidateVersionsDictionary = new(StringComparer.OrdinalIgnoreCase);
360
538
 
361
539
  // and for each of those packages, find all versions greater than the one that's currently installed
362
- foreach ((string packageName, NuGetVersion packageVersion) in badPackagesAndVersions)
540
+ foreach ((string PackageName, NuGetVersion packageVersion) in badPackagesAndVersions)
363
541
  {
364
542
  // this command dumps a JSON object with all versions of the specified package from all package sources
365
- (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", $"package search {packageName} --exact-match --format json", workingDirectory: tempDirectory.FullName);
543
+ (exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", $"package search {PackageName} --exact-match --format json", workingDirectory: tempDirectory.FullName);
366
544
  if (exitCode != 0)
367
545
  {
368
546
  continue;
369
547
  }
370
548
 
371
549
  // ensure collection exists
372
- if (!badPackagesAndCandidateVersionsDictionary.ContainsKey(packageName))
550
+ if (!badPackagesAndCandidateVersionsDictionary.ContainsKey(PackageName))
373
551
  {
374
- badPackagesAndCandidateVersionsDictionary.Add(packageName, new HashSet<NuGetVersion>());
552
+ badPackagesAndCandidateVersionsDictionary.Add(PackageName, new HashSet<NuGetVersion>());
375
553
  }
376
554
 
377
- HashSet<NuGetVersion> foundVersions = badPackagesAndCandidateVersionsDictionary[packageName];
555
+ HashSet<NuGetVersion> foundVersions = badPackagesAndCandidateVersionsDictionary[PackageName];
378
556
 
379
557
  var json = JsonHelper.ParseNode(stdOut);
380
558
  if (json?["searchResult"] is JsonArray searchResults)
@@ -605,9 +783,9 @@ internal static partial class MSBuildHelper
605
783
  .Where(match => match.Success)
606
784
  .Select(match =>
607
785
  {
608
- var packageName = match.Groups["PackageName"].Value;
609
- var isTransitive = !topLevelPackagesNames.Contains(packageName);
610
- return new Dependency(packageName, match.Groups["PackageVersion"].Value, DependencyType.Unknown, TargetFrameworks: tfms, IsTransitive: isTransitive);
786
+ var PackageName = match.Groups["PackageName"].Value;
787
+ var isTransitive = !topLevelPackagesNames.Contains(PackageName);
788
+ return new Dependency(PackageName, match.Groups["PackageVersion"].Value, DependencyType.Unknown, TargetFrameworks: tfms, IsTransitive: isTransitive);
611
789
  })
612
790
  .ToArray();
613
791
 
@@ -264,6 +264,46 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
264
264
 
265
265
  [Fact]
266
266
  public async Task ReturnsUpToDate_ForMissingDependency()
267
+ {
268
+ await TestAnalyzeAsync(
269
+ packages:
270
+ [
271
+ // no packages listed
272
+ ],
273
+ discovery: new()
274
+ {
275
+ Path = "/",
276
+ Projects = [
277
+ new()
278
+ {
279
+ FilePath = "./project.csproj",
280
+ TargetFrameworks = ["net8.0"],
281
+ Dependencies = [
282
+ new("Some.Package", "1.0.0", DependencyType.PackageReference), // this was found in the source, but doesn't exist in any feed
283
+ ],
284
+ },
285
+ ],
286
+ },
287
+ dependencyInfo: new()
288
+ {
289
+ Name = "Some.Package",
290
+ Version = "1.0.0",
291
+ IgnoredVersions = [],
292
+ IsVulnerable = false,
293
+ Vulnerabilities = [],
294
+ },
295
+ expectedResult: new()
296
+ {
297
+ UpdatedVersion = "1.0.0",
298
+ CanUpdate = false,
299
+ VersionComesFromMultiDependencyProperty = false,
300
+ UpdatedDependencies = [],
301
+ }
302
+ );
303
+ }
304
+
305
+ [Fact]
306
+ public async Task ReturnsUpToDate_ForIgnoredRequirements()
267
307
  {
268
308
  await TestAnalyzeAsync(
269
309
  packages:
@@ -307,6 +347,50 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
307
347
  );
308
348
  }
309
349
 
350
+ [Fact]
351
+ public async Task IgnoredVersionsCanHandleWildcardSpecification()
352
+ {
353
+ await TestAnalyzeAsync(
354
+ packages:
355
+ [
356
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"), // initially this
357
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.1.0", "net8.0"), // should update to this
358
+ MockNuGetPackage.CreateSimplePackage("Some.Package", "1.2.0", "net8.0"), // `IgnoredVersions` should prevent this from being selected
359
+ ],
360
+ discovery: new()
361
+ {
362
+ Path = "/",
363
+ Projects = [
364
+ new()
365
+ {
366
+ FilePath = "./project.csproj",
367
+ TargetFrameworks = ["net8.0"],
368
+ Dependencies = [
369
+ new("Some.Package", "1.0.0", DependencyType.PackageReference),
370
+ ],
371
+ },
372
+ ],
373
+ },
374
+ dependencyInfo: new()
375
+ {
376
+ Name = "Some.Package",
377
+ Version = "1.0.0",
378
+ IgnoredVersions = [Requirement.Parse("> 1.1.*")],
379
+ IsVulnerable = false,
380
+ Vulnerabilities = [],
381
+ },
382
+ expectedResult: new()
383
+ {
384
+ UpdatedVersion = "1.1.0",
385
+ CanUpdate = true,
386
+ VersionComesFromMultiDependencyProperty = false,
387
+ UpdatedDependencies = [
388
+ new("Some.Package", "1.1.0", DependencyType.Unknown, TargetFrameworks: ["net8.0"]),
389
+ ],
390
+ }
391
+ );
392
+ }
393
+
310
394
  [Fact]
311
395
  public async Task VersionFinderCanHandle404FromPackageSource_V2()
312
396
  {
@@ -33,6 +33,8 @@ public class RequirementTests
33
33
  [InlineData("1", "~> 1", true)]
34
34
  [InlineData("2", "~> 1", false)]
35
35
  [InlineData("5.3.8", "< 6, > 5.2.4", true)]
36
+ [InlineData("1.0-preview", ">= 1.x", false)] // wildcards
37
+ [InlineData("1.1-preview", ">= 1.x", true)]
36
38
  public void IsSatisfiedBy(string versionString, string requirementString, bool expected)
37
39
  {
38
40
  var version = NuGetVersion.Parse(versionString);
@@ -43,6 +45,18 @@ public class RequirementTests
43
45
  Assert.Equal(expected, actual);
44
46
  }
45
47
 
48
+ [Theory]
49
+ [InlineData("> 1.*", "> 1.0")] // standard wildcard, single digit
50
+ [InlineData("> 1.2.*", "> 1.2.0")] // standard wildcard, multiple digit
51
+ [InlineData("> 1.a", "> 1.0")] // alternate wildcard, single digit
52
+ [InlineData("> 1.2.a", "> 1.2.0")] // alternate wildcard, multiple digit
53
+ public void Parse_ConvertsWildcardInVersion(string givenRequirementString, string expectedRequirementString)
54
+ {
55
+ var parsedRequirement = Requirement.Parse(givenRequirementString);
56
+ var actualRequirementString = parsedRequirement.ToString();
57
+ Assert.Equal(expectedRequirementString, actualRequirementString);
58
+ }
59
+
46
60
  [Theory]
47
61
  [InlineData("> = 1.0.0")] // Invalid format
48
62
  [InlineData("<>= 1.0.0")] // Invalid Operator
@@ -0,0 +1,23 @@
1
+ namespace NuGetUpdater.Core.Test;
2
+
3
+ public class TemporaryEnvironment : IDisposable
4
+ {
5
+ private readonly List<(string Name, string? Value)> _originalVariables = new();
6
+
7
+ public TemporaryEnvironment((string Name, string Value)[] variables)
8
+ {
9
+ foreach (var (name, value) in variables)
10
+ {
11
+ _originalVariables.Add((name, Environment.GetEnvironmentVariable(name)));
12
+ Environment.SetEnvironmentVariable(name, value);
13
+ }
14
+ }
15
+
16
+ public void Dispose()
17
+ {
18
+ foreach (var (name, value) in _originalVariables)
19
+ {
20
+ Environment.SetEnvironmentVariable(name, value);
21
+ }
22
+ }
23
+ }
@@ -1,6 +1,9 @@
1
1
  using System.Collections.Immutable;
2
+ using System.Text;
2
3
  using System.Text.Json;
3
4
 
5
+ using NuGet;
6
+
4
7
  using NuGetUpdater.Core.Updater;
5
8
 
6
9
  using Xunit;
@@ -1663,67 +1666,173 @@ public partial class UpdateWorkerTests
1663
1666
  [Fact]
1664
1667
  public async Task PackageCanBeUpdatedWhenAnotherInstalledPackageHasBeenDelisted()
1665
1668
  {
1666
- // updating one package (Newtonsoft.Json) when another installed package (FSharp.Core/5.0.3-beta.21369.4) has been delisted
1667
- await TestUpdateForProject("Newtonsoft.Json", "7.0.1", "13.0.1",
1669
+ // updating one package (Some.Package) when another installed package (Delisted.Package/5.0.0) has been delisted
1670
+ // this test can't be faked with a local package source and requires an HTTP endpoint; the important part is
1671
+ // the `"listed": false` in the registration index
1672
+ static (int, byte[]) TestHttpHandler(string uriString)
1673
+ {
1674
+ var uri = new Uri(uriString, UriKind.Absolute);
1675
+ var baseUrl = $"{uri.Scheme}://{uri.Host}:{uri.Port}";
1676
+ return uri.PathAndQuery switch
1677
+ {
1678
+ "/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1679
+ {
1680
+ "version": "3.0.0",
1681
+ "resources": [
1682
+ {
1683
+ "@id": "{{baseUrl}}/download",
1684
+ "@type": "PackageBaseAddress/3.0.0"
1685
+ },
1686
+ {
1687
+ "@id": "{{baseUrl}}/query",
1688
+ "@type": "SearchQueryService"
1689
+ },
1690
+ {
1691
+ "@id": "{{baseUrl}}/registrations",
1692
+ "@type": "RegistrationsBaseUrl"
1693
+ }
1694
+ ]
1695
+ }
1696
+ """)),
1697
+ "/registrations/delisted.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1698
+ {
1699
+ "count": 1,
1700
+ "items": [
1701
+ {
1702
+ "lower": "5.0.0",
1703
+ "upper": "5.0.0",
1704
+ "items": [
1705
+ {
1706
+ "catalogEntry": {
1707
+ "id": "Delisted.Package",
1708
+ "listed": false,
1709
+ "version": "5.0.0"
1710
+ },
1711
+ "packageContent": "{{baseUrl}}/download/delisted.package/5.0.0/delisted.package.5.0.0.nupkg",
1712
+ }
1713
+ ]
1714
+ }
1715
+ ]
1716
+ }
1717
+ """)),
1718
+ "/registrations/some.package/index.json" => (200, Encoding.UTF8.GetBytes($$"""
1719
+ {
1720
+ "count": 1,
1721
+ "items": [
1722
+ {
1723
+ "lower": "1.0.0",
1724
+ "upper": "2.0.0",
1725
+ "items": [
1726
+ {
1727
+ "catalogEntry": {
1728
+ "id": "Some.Package",
1729
+ "listed": true,
1730
+ "version": "1.0.0"
1731
+ },
1732
+ "packageContent": "{{baseUrl}}/download/some.package/1.0.0/some.package.1.0.0.nupkg",
1733
+ },
1734
+ {
1735
+ "catalogEntry": {
1736
+ "id": "Some.Package",
1737
+ "listed": true,
1738
+ "version": "2.0.0"
1739
+ },
1740
+ "packageContent": "{{baseUrl}}/download/some.package/2.0.0/some.package.2.0.0.nupkg",
1741
+ }
1742
+ ]
1743
+ }
1744
+ ]
1745
+ }
1746
+ """)),
1747
+ "/download/delisted.package/5.0.0/delisted.package.5.0.0.nupkg" =>
1748
+ (200, MockNuGetPackage.CreateSimplePackage("Delisted.Package", "5.0.0", "net45").GetZipStream().ReadAllBytes()),
1749
+ "/download/some.package/1.0.0/some.package.1.0.0.nupkg" =>
1750
+ (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net45").GetZipStream().ReadAllBytes()),
1751
+ "/download/some.package/2.0.0/some.package.2.0.0.nupkg" =>
1752
+ (200, MockNuGetPackage.CreateSimplePackage("Some.Package", "2.0.0", "net45").GetZipStream().ReadAllBytes()),
1753
+ _ => (404, Encoding.UTF8.GetBytes("{}")), // everything is missing
1754
+ };
1755
+ }
1756
+ using var cache = new TemporaryDirectory();
1757
+ using var env = new TemporaryEnvironment([
1758
+ ("NUGET_PACKAGES", Path.Join(cache.DirectoryPath, "NUGET_PACKAGES")),
1759
+ ("NUGET_HTTP_CACHE_PATH", Path.Join(cache.DirectoryPath, "NUGET_HTTP_CACHE_PATH")),
1760
+ ("NUGET_SCRATCH", Path.Join(cache.DirectoryPath, "NUGET_SCRATCH")),
1761
+ ("NUGET_PLUGINS_CACHE_PATH", Path.Join(cache.DirectoryPath, "NUGET_PLUGINS_CACHE_PATH")),
1762
+ ]);
1763
+ using var http = TestHttpServer.CreateTestServer(TestHttpHandler);
1764
+ await TestUpdateForProject("Some.Package", "1.0.0", "2.0.0",
1668
1765
  // existing
1669
1766
  projectContents: """
1670
- <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1671
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1672
- <PropertyGroup>
1673
- <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1674
- </PropertyGroup>
1675
- <ItemGroup>
1676
- <None Include="packages.config" />
1677
- </ItemGroup>
1678
- <ItemGroup>
1679
- <Reference Include="FSharp.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
1680
- <HintPath>packages\FSharp.Core.5.0.3-beta.21369.4\lib\netstandard2.0\FSharp.Core.dll</HintPath>
1681
- <Private>True</Private>
1682
- </Reference>
1683
- <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1684
- <HintPath>packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
1685
- <Private>True</Private>
1686
- </Reference>
1687
- </ItemGroup>
1688
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1689
- </Project>
1690
- """,
1767
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1768
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1769
+ <PropertyGroup>
1770
+ <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1771
+ </PropertyGroup>
1772
+ <ItemGroup>
1773
+ <None Include="packages.config" />
1774
+ </ItemGroup>
1775
+ <ItemGroup>
1776
+ <Reference Include="Delisted.Package">
1777
+ <HintPath>packages\Delisted.Package.5.0.0\lib\net45\Delisted.Package.dll</HintPath>
1778
+ <Private>True</Private>
1779
+ </Reference>
1780
+ <Reference Include="Some.Package">
1781
+ <HintPath>packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
1782
+ <Private>True</Private>
1783
+ </Reference>
1784
+ </ItemGroup>
1785
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1786
+ </Project>
1787
+ """,
1691
1788
  packagesConfigContents: """
1692
- <packages>
1693
- <package id="FSharp.Core" version="5.0.3-beta.21369.4" targetFramework="net462" />
1694
- <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net462" />
1695
- </packages>
1696
- """,
1789
+ <packages>
1790
+ <package id="Delisted.Package" version="5.0.0" targetFramework="net462" />
1791
+ <package id="Some.Package" version="1.0.0" targetFramework="net462" />
1792
+ </packages>
1793
+ """,
1794
+ additionalFiles:
1795
+ [
1796
+ ("NuGet.Config", $"""
1797
+ <configuration>
1798
+ <packageSources>
1799
+ <clear />
1800
+ <add key="private_feed" value="{http.BaseUrl.TrimEnd('/')}/index.json" allowInsecureConnections="true" />
1801
+ </packageSources>
1802
+ </configuration>
1803
+ """)
1804
+ ],
1697
1805
  // expected
1698
1806
  expectedProjectContents: """
1699
- <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1700
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1701
- <PropertyGroup>
1702
- <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1703
- </PropertyGroup>
1704
- <ItemGroup>
1705
- <None Include="packages.config" />
1706
- </ItemGroup>
1707
- <ItemGroup>
1708
- <Reference Include="FSharp.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
1709
- <HintPath>packages\FSharp.Core.5.0.3-beta.21369.4\lib\netstandard2.0\FSharp.Core.dll</HintPath>
1710
- <Private>True</Private>
1711
- </Reference>
1712
- <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
1713
- <HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
1714
- <Private>True</Private>
1715
- </Reference>
1716
- </ItemGroup>
1717
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1718
- </Project>
1719
- """,
1807
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1808
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1809
+ <PropertyGroup>
1810
+ <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1811
+ </PropertyGroup>
1812
+ <ItemGroup>
1813
+ <None Include="packages.config" />
1814
+ </ItemGroup>
1815
+ <ItemGroup>
1816
+ <Reference Include="Delisted.Package">
1817
+ <HintPath>packages\Delisted.Package.5.0.0\lib\net45\Delisted.Package.dll</HintPath>
1818
+ <Private>True</Private>
1819
+ </Reference>
1820
+ <Reference Include="Some.Package">
1821
+ <HintPath>packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
1822
+ <Private>True</Private>
1823
+ </Reference>
1824
+ </ItemGroup>
1825
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
1826
+ </Project>
1827
+ """,
1720
1828
  expectedPackagesConfigContents: """
1721
- <?xml version="1.0" encoding="utf-8"?>
1722
- <packages>
1723
- <package id="FSharp.Core" version="5.0.3-beta.21369.4" targetFramework="net462" />
1724
- <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net462" />
1725
- </packages>
1726
- """);
1829
+ <?xml version="1.0" encoding="utf-8"?>
1830
+ <packages>
1831
+ <package id="Delisted.Package" version="5.0.0" targetFramework="net462" />
1832
+ <package id="Some.Package" version="2.0.0" targetFramework="net462" />
1833
+ </packages>
1834
+ """
1835
+ );
1727
1836
  }
1728
1837
 
1729
1838
  [Fact]