dependabot-nuget 0.268.0 → 0.270.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +6 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +16 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/Requirement.cs +8 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/SdkPackageUpdater.cs +17 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +689 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +187 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +84 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/RequirementTests.cs +14 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryEnvironment.cs +23 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +164 -55
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +65 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +785 -1
- data/lib/dependabot/nuget/file_updater.rb +29 -13
- data/lib/dependabot/nuget/native_helpers.rb +6 -1
- metadata +7 -5
@@ -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
|
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
|
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 {
|
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(
|
550
|
+
if (!badPackagesAndCandidateVersionsDictionary.ContainsKey(PackageName))
|
373
551
|
{
|
374
|
-
badPackagesAndCandidateVersionsDictionary.Add(
|
552
|
+
badPackagesAndCandidateVersionsDictionary.Add(PackageName, new HashSet<NuGetVersion>());
|
375
553
|
}
|
376
554
|
|
377
|
-
HashSet<NuGetVersion> foundVersions = badPackagesAndCandidateVersionsDictionary[
|
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
|
609
|
-
var isTransitive = !topLevelPackagesNames.Contains(
|
610
|
-
return new Dependency(
|
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
|
+
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs
CHANGED
@@ -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 (
|
1667
|
-
|
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
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
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
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
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
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
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
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
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]
|