dependabot-nuget 0.352.0 → 0.353.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.
- checksums.yaml +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +15 -41
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +102 -46
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +0 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +19 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +23 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/OutOfDisk.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IApiHandler.cs +11 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +25 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +3 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +20 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +41 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +93 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +2 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +21 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +23 -104
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -66
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ApiModel/JobTests.cs +39 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +142 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +76 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +30 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +25 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +250 -0
- metadata +5 -4
|
@@ -30,7 +30,7 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
|
|
|
30
30
|
{
|
|
31
31
|
var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
|
|
32
32
|
var jobDependencies = job.Dependencies.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
33
|
-
foreach (var directory in job.GetAllDirectories())
|
|
33
|
+
foreach (var directory in job.GetAllDirectories(repoContentsPath.FullName))
|
|
34
34
|
{
|
|
35
35
|
var discoveryResult = await discoveryWorker.RunAsync(repoContentsPath.FullName, directory);
|
|
36
36
|
logger.ReportDiscovery(discoveryResult);
|
|
@@ -81,7 +81,7 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
|
|
|
81
81
|
var dependencyName = dependencyUpdatesToPerform.Key;
|
|
82
82
|
var dependencyInfosToUpdate = dependencyUpdatesToPerform.Value
|
|
83
83
|
.Where(o => !job.IsDependencyIgnoredByNameOnly(o.Dependency.Name))
|
|
84
|
-
.Select(o => (o.ProjectPath, o.Dependency, RunWorker.GetDependencyInfo(job, o.Dependency, allowCooldown: true)))
|
|
84
|
+
.Select(o => (o.ProjectPath, o.Dependency, RunWorker.GetDependencyInfo(job, o.Dependency, groupMatchers: [], allowCooldown: true)))
|
|
85
85
|
.ToArray();
|
|
86
86
|
|
|
87
87
|
foreach (var (projectPath, dependency, dependencyInfo) in dependencyInfosToUpdate)
|
|
@@ -108,7 +108,7 @@ internal static class PackageReferenceUpdater
|
|
|
108
108
|
return [.. updateOperations];
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
internal static async Task<(Dictionary<string, HashSet<string>> PackageParents, Dictionary<string, NuGetVersion> PackageVersions)> GetPackageGraphForDependencies(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> topLevelDependencies, ILogger logger)
|
|
112
112
|
{
|
|
113
113
|
var packageParents = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
|
|
114
114
|
var packageVersions = new Dictionary<string, NuGetVersion>(StringComparer.OrdinalIgnoreCase);
|
|
@@ -117,37 +117,34 @@ internal static class PackageReferenceUpdater
|
|
|
117
117
|
{
|
|
118
118
|
// generate project.assets.json
|
|
119
119
|
var parsedTargetFramework = NuGetFramework.Parse(targetFramework);
|
|
120
|
-
var tempProject = await MSBuildHelper.CreateTempProjectAsync(tempDir, repoRoot, projectPath, targetFramework, topLevelDependencies, logger, importDependencyTargets:
|
|
121
|
-
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["
|
|
120
|
+
var tempProject = await MSBuildHelper.CreateTempProjectAsync(tempDir, repoRoot, projectPath, targetFramework, topLevelDependencies, logger, importDependencyTargets: true);
|
|
121
|
+
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["msbuild", tempProject, "/t:Restore,GenerateBuildDependencyFile"], tempDir.FullName);
|
|
122
122
|
var assetsJsonPath = Path.Join(tempDir.FullName, "obj", "project.assets.json");
|
|
123
123
|
var assetsJsonContent = await File.ReadAllTextAsync(assetsJsonPath);
|
|
124
124
|
|
|
125
125
|
// build reverse dependency graph
|
|
126
126
|
var assets = JsonDocument.Parse(assetsJsonContent).RootElement;
|
|
127
|
-
|
|
127
|
+
var tfmObjects = assets.GetProperty("targets").EnumerateObject().ToImmutableArray();
|
|
128
|
+
if (tfmObjects.Length != 1)
|
|
128
129
|
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// not interested in this target framework
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
130
|
+
logger.Error($"Expected exactly one target framework group compatible with {targetFramework} but found {tfmObjects.Length}. Values: {tfmObjects.Select(t => t.Name)}");
|
|
131
|
+
return (packageParents, packageVersions);
|
|
132
|
+
}
|
|
135
133
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
foreach (var parentObject in tfmObjects[0].Value.EnumerateObject())
|
|
135
|
+
{
|
|
136
|
+
var parts = parentObject.Name.Split('/');
|
|
137
|
+
var parentName = parts[0];
|
|
138
|
+
var parentVersion = parts[1];
|
|
139
|
+
packageVersions[parentName] = NuGetVersion.Parse(parentVersion);
|
|
142
140
|
|
|
143
|
-
|
|
141
|
+
if (parentObject.Value.TryGetProperty("dependencies", out var dependencies))
|
|
142
|
+
{
|
|
143
|
+
foreach (var childObject in dependencies.EnumerateObject())
|
|
144
144
|
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
var parentSet = packageParents.GetOrAdd(childName, () => new(StringComparer.OrdinalIgnoreCase));
|
|
149
|
-
parentSet.Add(parentName);
|
|
150
|
-
}
|
|
145
|
+
var childName = childObject.Name;
|
|
146
|
+
var parentSet = packageParents.GetOrAdd(childName, () => new(StringComparer.OrdinalIgnoreCase));
|
|
147
|
+
parentSet.Add(parentName);
|
|
151
148
|
}
|
|
152
149
|
}
|
|
153
150
|
}
|
|
@@ -493,7 +493,7 @@ internal static partial class MSBuildHelper
|
|
|
493
493
|
var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
494
494
|
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, logger, importDependencyTargets: false);
|
|
495
495
|
|
|
496
|
-
var experimentsManager = new ExperimentsManager()
|
|
496
|
+
var experimentsManager = new ExperimentsManager();
|
|
497
497
|
var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(repoRoot, tempDirectory.FullName, tempProjectPath, experimentsManager, logger);
|
|
498
498
|
var allDependencies = projectDiscovery
|
|
499
499
|
.Where(p => p.FilePath == Path.GetFileName(tempProjectPath))
|
|
@@ -545,6 +545,37 @@ internal static partial class MSBuildHelper
|
|
|
545
545
|
return targets;
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
internal static async Task<ImmutableArray<string>> GetProjectTargetFrameworksAsync(string projectPath, ILogger logger)
|
|
549
|
+
{
|
|
550
|
+
var extension = Path.GetExtension(projectPath)?.ToLowerInvariant();
|
|
551
|
+
if (extension == ".sln" || extension == ".slnx")
|
|
552
|
+
{
|
|
553
|
+
// solution files don't specify target frameworks, so we can skip the process invocation
|
|
554
|
+
return [];
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
var projectDirectory = Path.GetDirectoryName(projectPath)!;
|
|
558
|
+
var args = new[]
|
|
559
|
+
{
|
|
560
|
+
"msbuild",
|
|
561
|
+
projectPath,
|
|
562
|
+
"-getProperty:TargetFrameworks"
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(args, projectDirectory);
|
|
566
|
+
if (exitCode != 0)
|
|
567
|
+
{
|
|
568
|
+
logger.Warn($"Unable to determine target frameworks for project [{projectPath}]:\nSTDOUT:\n{stdOut}\nSTDERR:\n{stdErr}\n");
|
|
569
|
+
return [];
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
var tfms = Regex.Replace(stdOut, "@[\r\n\t ]", "")
|
|
573
|
+
.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
|
574
|
+
.OrderBy(t => t)
|
|
575
|
+
.ToImmutableArray();
|
|
576
|
+
return tfms;
|
|
577
|
+
}
|
|
578
|
+
|
|
548
579
|
internal static string? GetMissingFile(string output)
|
|
549
580
|
{
|
|
550
581
|
var missingFilePatterns = new[]
|
|
@@ -571,6 +602,7 @@ internal static partial class MSBuildHelper
|
|
|
571
602
|
ThrowOnTimeout(output);
|
|
572
603
|
ThrowOnBadResponse(output);
|
|
573
604
|
ThrowOnUnparseableFile(output);
|
|
605
|
+
ThrowOnMultipleProjectsForPackagesConfig(output);
|
|
574
606
|
}
|
|
575
607
|
|
|
576
608
|
private static void ThrowOnUnauthenticatedFeed(string stdout)
|
|
@@ -704,6 +736,14 @@ internal static partial class MSBuildHelper
|
|
|
704
736
|
}
|
|
705
737
|
}
|
|
706
738
|
|
|
739
|
+
private static void ThrowOnMultipleProjectsForPackagesConfig(string output)
|
|
740
|
+
{
|
|
741
|
+
if (output.Contains("Found multiple project files for "))
|
|
742
|
+
{
|
|
743
|
+
throw new Exception("Multiple project files found for single packages.config");
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
707
747
|
internal static bool TryGetGlobalJsonPath(string repoRootPath, string workspacePath, [NotNullWhen(returnValue: true)] out string? globalJsonPath)
|
|
708
748
|
{
|
|
709
749
|
globalJsonPath = PathHelper.GetFileInDirectoryOrParent(workspacePath, repoRootPath, "global.json", caseSensitive: false);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
using System.Collections.Immutable;
|
|
1
2
|
using System.Runtime.InteropServices;
|
|
3
|
+
using System.Text;
|
|
2
4
|
using System.Text.RegularExpressions;
|
|
3
5
|
|
|
4
6
|
namespace NuGetUpdater.Core;
|
|
@@ -248,4 +250,95 @@ internal static class PathHelper
|
|
|
248
250
|
|
|
249
251
|
return candidateFilePath.StartsWith(directoryPath);
|
|
250
252
|
}
|
|
253
|
+
|
|
254
|
+
public static ImmutableArray<string> GetMatchingDirectoriesUnder(string rootDirectory, string searchPattern, bool caseSensitive)
|
|
255
|
+
{
|
|
256
|
+
// translate pattern to regex
|
|
257
|
+
searchPattern = searchPattern.Replace("\\", "/"); // unix-style paths make things easier
|
|
258
|
+
searchPattern = searchPattern.TrimStart('/'); // pattern shouldn't be rooted
|
|
259
|
+
if (searchPattern == string.Empty)
|
|
260
|
+
{
|
|
261
|
+
searchPattern = "/"; // special case repo root
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
var pb = new StringBuilder();
|
|
265
|
+
pb.Append('^');
|
|
266
|
+
var appendAnchor = true;
|
|
267
|
+
for (int i = 0; i < searchPattern.Length; i++)
|
|
268
|
+
{
|
|
269
|
+
// special case recursive wildcard
|
|
270
|
+
if (searchPattern[i..] == "/**/*")
|
|
271
|
+
{
|
|
272
|
+
pb.Append("($|/.*$)"); // capture just this directory and every subdirectory
|
|
273
|
+
appendAnchor = false;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
var c = searchPattern[i];
|
|
278
|
+
switch (c)
|
|
279
|
+
{
|
|
280
|
+
case '*':
|
|
281
|
+
// could be single level or multi-level
|
|
282
|
+
var isRecursiveMatch = i < searchPattern.Length - 2
|
|
283
|
+
&& searchPattern[i + 1] == '*'
|
|
284
|
+
&& searchPattern[i + 2] == '/';
|
|
285
|
+
if (isRecursiveMatch)
|
|
286
|
+
{
|
|
287
|
+
// match anything
|
|
288
|
+
pb.Append(".*");
|
|
289
|
+
i += 2; // consume the extra characters
|
|
290
|
+
}
|
|
291
|
+
else
|
|
292
|
+
{
|
|
293
|
+
// only match up to a directory separator
|
|
294
|
+
pb.Append("[^/]*");
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
case '?':
|
|
298
|
+
pb.Append(".");
|
|
299
|
+
break;
|
|
300
|
+
case '/':
|
|
301
|
+
pb.Append("/");
|
|
302
|
+
break;
|
|
303
|
+
default:
|
|
304
|
+
if ("+()^$.{}[]|\\".Contains(c))
|
|
305
|
+
{
|
|
306
|
+
pb.Append('\\');
|
|
307
|
+
}
|
|
308
|
+
pb.Append(c);
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (appendAnchor)
|
|
314
|
+
{
|
|
315
|
+
pb.Append('$');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
var pattern = new Regex(pb.ToString(), caseSensitive ? RegexOptions.IgnoreCase : RegexOptions.None);
|
|
319
|
+
|
|
320
|
+
// find all directories
|
|
321
|
+
var allDirectories = Directory.EnumerateDirectories(rootDirectory, "*", SearchOption.AllDirectories)
|
|
322
|
+
.Select(d => Path.GetRelativePath(rootDirectory, d).NormalizePathToUnix())
|
|
323
|
+
.ToImmutableArray();
|
|
324
|
+
|
|
325
|
+
// filter
|
|
326
|
+
var matchingDirectories = allDirectories.Where(pattern.IsMatch)
|
|
327
|
+
.OrderBy(d => d, caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase)
|
|
328
|
+
.Select(d => d.EnsurePrefix("/")) // paths must appear rooted from here on out
|
|
329
|
+
.ToImmutableArray();
|
|
330
|
+
|
|
331
|
+
// special case some well-known directories that are hard to generate patterns for
|
|
332
|
+
switch (searchPattern)
|
|
333
|
+
{
|
|
334
|
+
case "/":
|
|
335
|
+
case ".":
|
|
336
|
+
case "/.":
|
|
337
|
+
case "**/*":
|
|
338
|
+
matchingDirectories = [.. matchingDirectories.Prepend("/")];
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return matchingDirectories;
|
|
343
|
+
}
|
|
251
344
|
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs
CHANGED
|
@@ -61,13 +61,10 @@ public partial class DiscoveryWorkerTests
|
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
[
|
|
65
|
-
|
|
66
|
-
[InlineData(false)]
|
|
67
|
-
public async Task DiscoveryIsMergedWithPackageReferences(bool useSingleRestore)
|
|
64
|
+
[Fact]
|
|
65
|
+
public async Task DiscoveryIsMergedWithPackageReferences()
|
|
68
66
|
{
|
|
69
67
|
await TestDiscoveryAsync(
|
|
70
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
71
68
|
packages:
|
|
72
69
|
[
|
|
73
70
|
MockNuGetPackage.CreateSimplePackage("Package.A", "1.0.0", "net46"),
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs
CHANGED
|
@@ -626,7 +626,7 @@ public partial class DiscoveryWorkerTests
|
|
|
626
626
|
("src/project.csproj", """
|
|
627
627
|
<Project Sdk="Microsoft.NET.Sdk">
|
|
628
628
|
<PropertyGroup>
|
|
629
|
-
<TargetFrameworks>net8.0-
|
|
629
|
+
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-macos;net8.0-windows</TargetFrameworks>
|
|
630
630
|
</PropertyGroup>
|
|
631
631
|
<ItemGroup>
|
|
632
632
|
<PackageReference Include="Some.Package" Version="1.2.3" />
|
|
@@ -645,7 +645,7 @@ public partial class DiscoveryWorkerTests
|
|
|
645
645
|
new("Some.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0-android", "net8.0-ios", "net8.0-maccatalyst", "net8.0-macos", "net8.0-windows"], IsDirect: true),
|
|
646
646
|
],
|
|
647
647
|
Properties = [
|
|
648
|
-
new("TargetFrameworks", "net8.0-
|
|
648
|
+
new("TargetFrameworks", "net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-macos;net8.0-windows", @"src/project.csproj"),
|
|
649
649
|
],
|
|
650
650
|
TargetFrameworks = ["net8.0-android", "net8.0-ios", "net8.0-maccatalyst", "net8.0-macos", "net8.0-windows"],
|
|
651
651
|
ReferencedProjectPaths = [],
|
|
@@ -737,7 +737,7 @@ public partial class DiscoveryWorkerTests
|
|
|
737
737
|
|
|
738
738
|
// The SDK package handling is detected in a very specific circumstance; an assembly being removed from the
|
|
739
739
|
// `@(References)` item group in the `_HandlePackageFileConflicts` target. Since we don't want to involve
|
|
740
|
-
// the real SDK, we fake some required targets.
|
|
740
|
+
// the real SDK, we fake some required targets in the same shape as the real SDK.
|
|
741
741
|
await TestDiscoveryAsync(
|
|
742
742
|
packages: [],
|
|
743
743
|
workspacePath: "",
|
|
@@ -764,6 +764,14 @@ public partial class DiscoveryWorkerTests
|
|
|
764
764
|
<Reference Include="@(RuntimeCopyLocalItems)" />
|
|
765
765
|
</ItemGroup>
|
|
766
766
|
|
|
767
|
+
<Target Name="ResolveProjectReferences">
|
|
768
|
+
<!-- this target needs to exist for discovery to work -->
|
|
769
|
+
</Target>
|
|
770
|
+
|
|
771
|
+
<Target Name="Restore">
|
|
772
|
+
<!-- this target needs to exist for discovery to work -->
|
|
773
|
+
</Target>
|
|
774
|
+
|
|
767
775
|
<Target Name="_HandlePackageFileConflicts">
|
|
768
776
|
<!-- this target needs to exist for discovery to work -->
|
|
769
777
|
<ItemGroup>
|
|
@@ -775,21 +783,25 @@ public partial class DiscoveryWorkerTests
|
|
|
775
783
|
</ItemGroup>
|
|
776
784
|
</Target>
|
|
777
785
|
|
|
778
|
-
<Target Name="
|
|
786
|
+
<Target Name="ResolvePackageAssets">
|
|
779
787
|
<!-- this target needs to exist for discovery to work -->
|
|
780
788
|
</Target>
|
|
781
789
|
|
|
782
|
-
<Target Name="
|
|
790
|
+
<Target Name="ResolveFrameworkReferences" DependsOnTargets="ResolvePackageAssets">
|
|
791
|
+
<!-- this target needs to exist for discovery to work -->
|
|
792
|
+
</Target>
|
|
793
|
+
|
|
794
|
+
<Target Name="ResolveRuntimePackAssets" DependsOnTargets="ResolveFrameworkReferences">
|
|
795
|
+
<!-- this target needs to exist for discovery to work -->
|
|
796
|
+
</Target>
|
|
797
|
+
|
|
798
|
+
<Target Name="GenerateBuildDependencyFile" DependsOnTargets="_HandlePackageFileConflicts;ResolveRuntimePackAssets">
|
|
783
799
|
<!-- this target needs to exist for discovery to work -->
|
|
784
800
|
<ItemGroup>
|
|
785
801
|
<!-- this removal is what removes the regular package reference from the project -->
|
|
786
802
|
<RuntimeCopyLocalItems Remove="TestOnlyAssembly.dll" />
|
|
787
803
|
</ItemGroup>
|
|
788
804
|
</Target>
|
|
789
|
-
|
|
790
|
-
<Target Name="ResolvePackageAssets">
|
|
791
|
-
<!-- this target needs to exist for discovery to work -->
|
|
792
|
-
</Target>
|
|
793
805
|
</Project>
|
|
794
806
|
""")
|
|
795
807
|
],
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
using System.Collections.Immutable;
|
|
2
2
|
using System.Text.Json;
|
|
3
3
|
|
|
4
|
+
using Microsoft.Build.Evaluation;
|
|
5
|
+
|
|
4
6
|
using NuGetUpdater.Core.Discover;
|
|
5
7
|
using NuGetUpdater.Core.Run.ApiModel;
|
|
6
8
|
using NuGetUpdater.Core.Test.Utilities;
|
|
@@ -164,13 +166,10 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
164
166
|
);
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
[
|
|
168
|
-
|
|
169
|
-
[InlineData(false)]
|
|
170
|
-
public async Task TestDependenciesSeparatedBySemicolon(bool useSingleRestore)
|
|
169
|
+
[Fact]
|
|
170
|
+
public async Task TestDependenciesSeparatedBySemicolon()
|
|
171
171
|
{
|
|
172
172
|
await TestDiscoveryAsync(
|
|
173
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
174
173
|
packages:
|
|
175
174
|
[
|
|
176
175
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net8.0"),
|
|
@@ -369,13 +368,10 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
369
368
|
);
|
|
370
369
|
}
|
|
371
370
|
|
|
372
|
-
[
|
|
373
|
-
|
|
374
|
-
[InlineData(false)]
|
|
375
|
-
public async Task TestPackageConfig(bool useSingleRestore)
|
|
371
|
+
[Fact]
|
|
372
|
+
public async Task TestPackageConfig()
|
|
376
373
|
{
|
|
377
374
|
await TestDiscoveryAsync(
|
|
378
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
379
375
|
packages:
|
|
380
376
|
[
|
|
381
377
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "7.0.1", "net45"),
|
|
@@ -492,14 +488,11 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
492
488
|
);
|
|
493
489
|
}
|
|
494
490
|
|
|
495
|
-
[
|
|
496
|
-
|
|
497
|
-
[InlineData(false)]
|
|
498
|
-
public async Task TestRepo(bool useSingleRestore)
|
|
491
|
+
[Fact]
|
|
492
|
+
public async Task TestRepo()
|
|
499
493
|
{
|
|
500
494
|
var solutionPath = "solution.sln";
|
|
501
495
|
await TestDiscoveryAsync(
|
|
502
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
503
496
|
packages:
|
|
504
497
|
[
|
|
505
498
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net7.0"),
|
|
@@ -625,13 +618,10 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
625
618
|
);
|
|
626
619
|
}
|
|
627
620
|
|
|
628
|
-
[
|
|
629
|
-
|
|
630
|
-
[InlineData(false)]
|
|
631
|
-
public async Task TestRepo_Sln(bool useSingleRestore)
|
|
621
|
+
[Fact]
|
|
622
|
+
public async Task TestRepo_Sln()
|
|
632
623
|
{
|
|
633
624
|
await TestDiscoveryAsync(
|
|
634
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
635
625
|
packages: [
|
|
636
626
|
MockNuGetPackage.CreateSimplePackage("Package.A", "1.2.3", "net8.0"),
|
|
637
627
|
MockNuGetPackage.CreateSimplePackage("Package.B", "4.5.6", "net8.0"),
|
|
@@ -721,14 +711,11 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
721
711
|
);
|
|
722
712
|
}
|
|
723
713
|
|
|
724
|
-
[
|
|
725
|
-
|
|
726
|
-
[InlineData(false)]
|
|
727
|
-
public async Task TestRepo_Slnx(bool useSingleRestore)
|
|
714
|
+
[Fact]
|
|
715
|
+
public async Task TestRepo_Slnx()
|
|
728
716
|
{
|
|
729
717
|
var solutionPath = "solution.slnx";
|
|
730
718
|
await TestDiscoveryAsync(
|
|
731
|
-
experimentsManager: new ExperimentsManager() { UseSingleRestore = useSingleRestore },
|
|
732
719
|
packages:
|
|
733
720
|
[
|
|
734
721
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net7.0"),
|
|
@@ -864,77 +851,6 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
864
851
|
);
|
|
865
852
|
}
|
|
866
853
|
|
|
867
|
-
[Fact]
|
|
868
|
-
public async Task TestDirsProj_CasingMismatchIsResolved()
|
|
869
|
-
{
|
|
870
|
-
var dirsProjPath = "dirs.proj";
|
|
871
|
-
await TestDiscoveryAsync(
|
|
872
|
-
packages:
|
|
873
|
-
[
|
|
874
|
-
MockNuGetPackage.CreateSimplePackage("Some.Package", "9.0.1", "net7.0"),
|
|
875
|
-
],
|
|
876
|
-
workspacePath: "",
|
|
877
|
-
files: new[]
|
|
878
|
-
{
|
|
879
|
-
("src/project.csproj", """
|
|
880
|
-
<Project Sdk="Microsoft.NET.Sdk">
|
|
881
|
-
<PropertyGroup>
|
|
882
|
-
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
|
883
|
-
</PropertyGroup>
|
|
884
|
-
|
|
885
|
-
<ItemGroup>
|
|
886
|
-
<PackageReference Include="Some.Package" />
|
|
887
|
-
</ItemGroup>
|
|
888
|
-
</Project>
|
|
889
|
-
"""),
|
|
890
|
-
("Directory.Build.props", "<Project />"),
|
|
891
|
-
("Directory.Packages.props", """
|
|
892
|
-
<Project>
|
|
893
|
-
<PropertyGroup>
|
|
894
|
-
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
|
895
|
-
<SomePackageVersion>9.0.1</SomePackageVersion>
|
|
896
|
-
</PropertyGroup>
|
|
897
|
-
|
|
898
|
-
<ItemGroup>
|
|
899
|
-
<PackageVersion Include="Some.Package" Version="$(SomePackageVersion)" />
|
|
900
|
-
</ItemGroup>
|
|
901
|
-
</Project>
|
|
902
|
-
"""),
|
|
903
|
-
// Introduce a casing difference in the project reference
|
|
904
|
-
(dirsProjPath, """
|
|
905
|
-
<Project>
|
|
906
|
-
<ItemGroup>
|
|
907
|
-
<ProjectReference Include="SRC/PROJECT.CSPROJ" />
|
|
908
|
-
</ItemGroup>
|
|
909
|
-
</Project>
|
|
910
|
-
""")
|
|
911
|
-
},
|
|
912
|
-
expectedResult: new()
|
|
913
|
-
{
|
|
914
|
-
Path = "",
|
|
915
|
-
Projects = [
|
|
916
|
-
new()
|
|
917
|
-
{
|
|
918
|
-
FilePath = "src/project.csproj",
|
|
919
|
-
TargetFrameworks = ["net7.0", "net8.0"],
|
|
920
|
-
Dependencies = [
|
|
921
|
-
new("Some.Package", "9.0.1", DependencyType.PackageReference, TargetFrameworks: ["net7.0", "net8.0"], IsDirect: true)
|
|
922
|
-
],
|
|
923
|
-
Properties = [
|
|
924
|
-
new("TargetFrameworks", "net7.0;net8.0", "src/project.csproj"),
|
|
925
|
-
],
|
|
926
|
-
ReferencedProjectPaths = [],
|
|
927
|
-
ImportedFiles = [
|
|
928
|
-
"../Directory.Build.props",
|
|
929
|
-
"../Directory.Packages.props",
|
|
930
|
-
],
|
|
931
|
-
AdditionalFiles = [],
|
|
932
|
-
}
|
|
933
|
-
],
|
|
934
|
-
}
|
|
935
|
-
);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
854
|
[Fact]
|
|
939
855
|
public async Task NonSupportedProjectExtensionsAreSkipped()
|
|
940
856
|
{
|
|
@@ -1619,20 +1535,23 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
1619
1535
|
);
|
|
1620
1536
|
}
|
|
1621
1537
|
|
|
1622
|
-
[
|
|
1623
|
-
|
|
1624
|
-
[InlineData(@"$(MSBuildThisFileDirectory)..\project2\project2.csproj")] // absolute
|
|
1625
|
-
public async Task ExpandEntryPoints(string projectReferencePath)
|
|
1538
|
+
[Fact]
|
|
1539
|
+
public async Task ExpandEntryPoints()
|
|
1626
1540
|
{
|
|
1627
1541
|
using var tempDir = await TemporaryDirectory.CreateWithContentsAsync(
|
|
1542
|
+
("src/dirs.proj", """
|
|
1543
|
+
<Project>
|
|
1544
|
+
<ItemGroup>
|
|
1545
|
+
<ProjectFile Include="project1\project1.csproj" /><!-- relative -->
|
|
1546
|
+
<ProjectFile Include="$(MSBuildThisFileDirectory)project2\project2.csproj" /><!-- absolute -->
|
|
1547
|
+
</ItemGroup>
|
|
1548
|
+
</Project>
|
|
1549
|
+
"""),
|
|
1628
1550
|
("src/project1/project1.csproj", $"""
|
|
1629
1551
|
<Project Sdk="Microsoft.NET.Sdk">
|
|
1630
1552
|
<PropertyGroup>
|
|
1631
1553
|
<TargetFramework>net9.0</TargetFramework>
|
|
1632
1554
|
</PropertyGroup>
|
|
1633
|
-
<ItemGroup>
|
|
1634
|
-
<ProjectReference Include="{projectReferencePath}" />
|
|
1635
|
-
</ItemGroup>
|
|
1636
1555
|
</Project>
|
|
1637
1556
|
"""),
|
|
1638
1557
|
("src/project2/project2.csproj", """
|
|
@@ -1643,7 +1562,7 @@ public partial class DiscoveryWorkerTests : DiscoveryWorkerTestBase
|
|
|
1643
1562
|
</Project>
|
|
1644
1563
|
""")
|
|
1645
1564
|
);
|
|
1646
|
-
var actualEntryPoints = (await DiscoveryWorker.ExpandEntryPointsIntoProjectsAsync([Path.Combine(tempDir.DirectoryPath, "src/
|
|
1565
|
+
var actualEntryPoints = (await DiscoveryWorker.ExpandEntryPointsIntoProjectsAsync([Path.Combine(tempDir.DirectoryPath, "src/dirs.proj")], new ExperimentsManager()))
|
|
1647
1566
|
.Select(p => p.NormalizePathToUnix())
|
|
1648
1567
|
.ToArray();
|
|
1649
1568
|
var expectedEntryPoints = new[]
|
|
@@ -580,63 +580,12 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
|
580
580
|
);
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
-
[Fact]
|
|
584
|
-
public async Task ExistingPackageIncompatibilityShouldNotPreventRestore()
|
|
585
|
-
{
|
|
586
|
-
// Package.A tries to pull in a transitive dependency of Transitive.Package/2.0.0 but that package is explicitly pinned at 1.0.0
|
|
587
|
-
// Normally this would cause a restore failure which means discovery would also fail
|
|
588
|
-
// This test ensures we can still run discovery
|
|
589
|
-
await TestDiscoverAsync(
|
|
590
|
-
useSingleRestore: false,
|
|
591
|
-
packages: [
|
|
592
|
-
MockNuGetPackage.CreateSimplePackage("Package.A", "1.0.0", "net8.0", [(null, [("Transitive.Package", "2.0.0")])]),
|
|
593
|
-
MockNuGetPackage.CreateSimplePackage("Transitive.Package", "1.0.0", "net8.0"),
|
|
594
|
-
MockNuGetPackage.CreateSimplePackage("Transitive.Package", "2.0.0", "net8.0"),
|
|
595
|
-
],
|
|
596
|
-
startingDirectory: "src",
|
|
597
|
-
projectPath: "src/library.csproj",
|
|
598
|
-
files: [
|
|
599
|
-
("src/library.csproj", """
|
|
600
|
-
<Project Sdk="Microsoft.NET.Sdk">
|
|
601
|
-
<PropertyGroup>
|
|
602
|
-
<TargetFramework>net8.0</TargetFramework>
|
|
603
|
-
</PropertyGroup>
|
|
604
|
-
<ItemGroup>
|
|
605
|
-
<PackageReference Include="Package.A" Version="1.0.0" />
|
|
606
|
-
<PackageReference Include="Transitive.Package" Version="1.0.0" />
|
|
607
|
-
</ItemGroup>
|
|
608
|
-
</Project>
|
|
609
|
-
""")
|
|
610
|
-
],
|
|
611
|
-
expectedProjects: [
|
|
612
|
-
new()
|
|
613
|
-
{
|
|
614
|
-
FilePath = "library.csproj",
|
|
615
|
-
Dependencies =
|
|
616
|
-
[
|
|
617
|
-
new("Package.A", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
|
|
618
|
-
new("Transitive.Package", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true)
|
|
619
|
-
],
|
|
620
|
-
ImportedFiles = [],
|
|
621
|
-
Properties =
|
|
622
|
-
[
|
|
623
|
-
new("TargetFramework", "net8.0", "src/library.csproj"),
|
|
624
|
-
],
|
|
625
|
-
TargetFrameworks = ["net8.0"],
|
|
626
|
-
ReferencedProjectPaths = [],
|
|
627
|
-
AdditionalFiles = [],
|
|
628
|
-
}
|
|
629
|
-
]
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
583
|
[Fact]
|
|
634
584
|
public async Task DependenciesCanBeDiscoveredWithoutCompiling_FromProjectWithSingleTfm()
|
|
635
585
|
{
|
|
636
586
|
using var tempDir = new TemporaryDirectory();
|
|
637
587
|
var errorSentinelPath = Path.Combine(tempDir.DirectoryPath, "error-sentinel.txt");
|
|
638
588
|
await TestDiscoverAsync(
|
|
639
|
-
useSingleRestore: true,
|
|
640
589
|
startingDirectory: "src",
|
|
641
590
|
packages: [
|
|
642
591
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
|
|
@@ -691,7 +640,6 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
|
691
640
|
using var tempDir = new TemporaryDirectory();
|
|
692
641
|
var errorSentinelPath = Path.Combine(tempDir.DirectoryPath, "error-sentinel.txt");
|
|
693
642
|
await TestDiscoverAsync(
|
|
694
|
-
useSingleRestore: true,
|
|
695
643
|
startingDirectory: "src",
|
|
696
644
|
packages: [
|
|
697
645
|
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0"),
|
|
@@ -747,19 +695,6 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
|
747
695
|
ImmutableArray<ExpectedSdkProjectDiscoveryResult> expectedProjects,
|
|
748
696
|
MockNuGetPackage[]? packages = null
|
|
749
697
|
)
|
|
750
|
-
{
|
|
751
|
-
await TestDiscoverAsync(useSingleRestore: true, startingDirectory, projectPath, files, expectedProjects, packages);
|
|
752
|
-
await TestDiscoverAsync(useSingleRestore: false, startingDirectory, projectPath, files, expectedProjects, packages);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
private static async Task TestDiscoverAsync(
|
|
756
|
-
bool useSingleRestore,
|
|
757
|
-
string startingDirectory,
|
|
758
|
-
string projectPath,
|
|
759
|
-
TestFile[] files,
|
|
760
|
-
ImmutableArray<ExpectedSdkProjectDiscoveryResult> expectedProjects,
|
|
761
|
-
MockNuGetPackage[]? packages = null
|
|
762
|
-
)
|
|
763
698
|
{
|
|
764
699
|
using var testDirectory = await TemporaryDirectory.CreateWithContentsAsync(files);
|
|
765
700
|
|
|
@@ -767,7 +702,7 @@ public class SdkProjectDiscoveryTests : DiscoveryWorkerTestBase
|
|
|
767
702
|
|
|
768
703
|
var logger = new TestLogger();
|
|
769
704
|
var fullProjectPath = Path.Combine(testDirectory.DirectoryPath, projectPath);
|
|
770
|
-
var experimentsManager = new ExperimentsManager()
|
|
705
|
+
var experimentsManager = new ExperimentsManager();
|
|
771
706
|
var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(testDirectory.DirectoryPath, Path.GetDirectoryName(fullProjectPath)!, fullProjectPath, experimentsManager, logger);
|
|
772
707
|
ValidateProjectResults(expectedProjects, projectDiscovery);
|
|
773
708
|
}
|