dependabot-nuget 0.301.0 → 0.302.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/DependencyDiscovery.props +4 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/DependencyDiscovery.targets +19 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +85 -81
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +177 -28
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/FrameworkCompatibilityService.cs +15 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/FrameworkChecker/SupportedFrameworks.cs +6 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/{WebApplicationTargetsConditionPatcher.cs → SpecialImportsConditionPatcher.cs} +18 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/XmlFilePreAndPostProcessor.cs +26 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +37 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +54 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +54 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +94 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/FrameworkChecker/FrameworkCompatibilityServiceFacts.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/SpecialFilePatcherTests.cs +99 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +38 -0
- data/lib/dependabot/nuget/file_parser.rb +22 -19
- metadata +7 -6
@@ -2,43 +2,50 @@ using Microsoft.Language.Xml;
|
|
2
2
|
|
3
3
|
namespace NuGetUpdater.Core.Updater
|
4
4
|
{
|
5
|
-
internal class
|
5
|
+
internal class SpecialImportsConditionPatcher : IDisposable
|
6
6
|
{
|
7
|
-
private string
|
7
|
+
private readonly List<string?> _capturedConditions = new List<string?>();
|
8
8
|
private readonly XmlFilePreAndPostProcessor _processor;
|
9
9
|
|
10
|
-
|
10
|
+
private readonly HashSet<string> ImportedFilesToIgnore = new(StringComparer.OrdinalIgnoreCase)
|
11
|
+
{
|
12
|
+
"Microsoft.TextTemplating.targets",
|
13
|
+
"Microsoft.WebApplication.targets"
|
14
|
+
};
|
15
|
+
|
16
|
+
public SpecialImportsConditionPatcher(string projectFilePath)
|
11
17
|
{
|
12
18
|
_processor = new XmlFilePreAndPostProcessor(
|
13
19
|
getContent: () => File.ReadAllText(projectFilePath),
|
14
20
|
setContent: s => File.WriteAllText(projectFilePath, s),
|
15
21
|
nodeFinder: doc => doc.Descendants()
|
16
22
|
.Where(e => e.Name == "Import")
|
17
|
-
.
|
23
|
+
.Where(e =>
|
18
24
|
{
|
19
25
|
var projectPath = e.GetAttributeValue("Project");
|
20
26
|
if (projectPath is not null)
|
21
27
|
{
|
22
28
|
var projectFileName = Path.GetFileName(projectPath.NormalizePathToUnix());
|
23
|
-
return
|
29
|
+
return ImportedFilesToIgnore.Contains(projectFileName);
|
24
30
|
}
|
25
31
|
|
26
32
|
return false;
|
27
33
|
})
|
28
|
-
|
29
|
-
preProcessor: n =>
|
34
|
+
.Cast<XmlNodeSyntax>(),
|
35
|
+
preProcessor: (i, n) =>
|
30
36
|
{
|
31
37
|
var element = (IXmlElementSyntax)n;
|
32
|
-
|
38
|
+
_capturedConditions.Add(element.GetAttributeValue("Condition"));
|
33
39
|
return (XmlNodeSyntax)element.RemoveAttributeByName("Condition").WithAttribute("Condition", "false");
|
34
40
|
},
|
35
|
-
postProcessor: n =>
|
41
|
+
postProcessor: (i, n) =>
|
36
42
|
{
|
37
43
|
var element = (IXmlElementSyntax)n;
|
38
44
|
var newElement = element.RemoveAttributeByName("Condition");
|
39
|
-
|
45
|
+
var capturedCondition = _capturedConditions[i];
|
46
|
+
if (capturedCondition is not null)
|
40
47
|
{
|
41
|
-
newElement = newElement.WithAttribute("Condition",
|
48
|
+
newElement = newElement.WithAttribute("Condition", capturedCondition);
|
42
49
|
}
|
43
50
|
|
44
51
|
return (XmlNodeSyntax)newElement;
|
@@ -1,3 +1,5 @@
|
|
1
|
+
using System.Collections.Immutable;
|
2
|
+
|
1
3
|
using Microsoft.Language.Xml;
|
2
4
|
|
3
5
|
namespace NuGetUpdater.Core.Updater
|
@@ -6,11 +8,11 @@ namespace NuGetUpdater.Core.Updater
|
|
6
8
|
{
|
7
9
|
public Func<string> GetContent { get; }
|
8
10
|
public Action<string> SetContent { get; }
|
9
|
-
public Func<XmlDocumentSyntax, XmlNodeSyntax
|
10
|
-
public Func<XmlNodeSyntax, XmlNodeSyntax> PreProcessor { get; }
|
11
|
-
public Func<XmlNodeSyntax, XmlNodeSyntax> PostProcessor { get; }
|
11
|
+
public Func<XmlDocumentSyntax, IEnumerable<XmlNodeSyntax>> NodeFinder { get; }
|
12
|
+
public Func<int, XmlNodeSyntax, XmlNodeSyntax> PreProcessor { get; }
|
13
|
+
public Func<int, XmlNodeSyntax, XmlNodeSyntax> PostProcessor { get; }
|
12
14
|
|
13
|
-
public XmlFilePreAndPostProcessor(Func<string> getContent, Action<string> setContent, Func<XmlDocumentSyntax, XmlNodeSyntax
|
15
|
+
public XmlFilePreAndPostProcessor(Func<string> getContent, Action<string> setContent, Func<XmlDocumentSyntax, IEnumerable<XmlNodeSyntax>> nodeFinder, Func<int, XmlNodeSyntax, XmlNodeSyntax> preProcessor, Func<int, XmlNodeSyntax, XmlNodeSyntax> postProcessor)
|
14
16
|
{
|
15
17
|
GetContent = getContent;
|
16
18
|
SetContent = setContent;
|
@@ -29,7 +31,7 @@ namespace NuGetUpdater.Core.Updater
|
|
29
31
|
|
30
32
|
private void PostProcess() => RunProcessor(PostProcessor);
|
31
33
|
|
32
|
-
private void RunProcessor(Func<XmlNodeSyntax, XmlNodeSyntax> processor)
|
34
|
+
private void RunProcessor(Func<int, XmlNodeSyntax, XmlNodeSyntax> processor)
|
33
35
|
{
|
34
36
|
var content = GetContent();
|
35
37
|
var xml = Parser.ParseText(content);
|
@@ -38,15 +40,28 @@ namespace NuGetUpdater.Core.Updater
|
|
38
40
|
return;
|
39
41
|
}
|
40
42
|
|
41
|
-
var
|
42
|
-
|
43
|
+
var offset = 0;
|
44
|
+
var nodes = NodeFinder(xml).ToImmutableArray();
|
45
|
+
for (int i = 0; i < nodes.Length; i++)
|
43
46
|
{
|
44
|
-
|
47
|
+
// modify the node...
|
48
|
+
var node = nodes[i];
|
49
|
+
var replacementElement = processor(i, node);
|
50
|
+
|
51
|
+
// ...however, the XML structure we're using is immutable and calling `.ReplaceNode()` below will fail because the nodes are no longer equal
|
52
|
+
// find the equivalent node by offset, accounting for any changes in length
|
53
|
+
var candidateEquivalentNodes = xml.DescendantNodes().OfType<XmlNodeSyntax>().ToArray();
|
54
|
+
var equivalentNode = candidateEquivalentNodes.First(n => n.Start == node.Start + offset);
|
55
|
+
|
56
|
+
// do the actual replacement
|
57
|
+
xml = xml.ReplaceNode(equivalentNode, replacementElement);
|
58
|
+
|
59
|
+
// update our offset
|
60
|
+
var thisNodeOffset = replacementElement.ToFullString().Length - node.ToFullString().Length;
|
61
|
+
offset += thisNodeOffset;
|
45
62
|
}
|
46
63
|
|
47
|
-
var
|
48
|
-
var replacementXml = xml.ReplaceNode(node, replacementElement);
|
49
|
-
var replacementString = replacementXml.ToFullString();
|
64
|
+
var replacementString = xml.ToFullString();
|
50
65
|
SetContent(replacementString);
|
51
66
|
}
|
52
67
|
}
|
@@ -6,6 +6,7 @@ using System.Text.Json;
|
|
6
6
|
using System.Text.Json.Nodes;
|
7
7
|
using System.Text.RegularExpressions;
|
8
8
|
using System.Xml;
|
9
|
+
using System.Xml.Linq;
|
9
10
|
|
10
11
|
using Microsoft.Build.Construction;
|
11
12
|
using Microsoft.Build.Definition;
|
@@ -30,6 +31,8 @@ internal static partial class MSBuildHelper
|
|
30
31
|
|
31
32
|
public static bool IsMSBuildRegistered => MSBuildPath.Length > 0;
|
32
33
|
|
34
|
+
public static string GetFileFromRuntimeDirectory(string fileName) => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, fileName);
|
35
|
+
|
33
36
|
public static void RegisterMSBuild(string currentDirectory, string rootDirectory)
|
34
37
|
{
|
35
38
|
// Ensure MSBuild types are registered before calling a method that loads the types
|
@@ -663,7 +666,7 @@ internal static partial class MSBuildHelper
|
|
663
666
|
}
|
664
667
|
}
|
665
668
|
|
666
|
-
internal static
|
669
|
+
internal static Task<string> CreateTempProjectAsync(
|
667
670
|
DirectoryInfo tempDir,
|
668
671
|
string repoRoot,
|
669
672
|
string projectPath,
|
@@ -671,7 +674,32 @@ internal static partial class MSBuildHelper
|
|
671
674
|
IReadOnlyCollection<Dependency> packages,
|
672
675
|
ExperimentsManager experimentsManager,
|
673
676
|
ILogger logger,
|
674
|
-
bool usePackageDownload = false
|
677
|
+
bool usePackageDownload = false,
|
678
|
+
bool importDependencyTargets = true
|
679
|
+
) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFramework", targetFramework), packages, experimentsManager, logger, usePackageDownload, importDependencyTargets);
|
680
|
+
|
681
|
+
internal static Task<string> CreateTempProjectAsync(
|
682
|
+
DirectoryInfo tempDir,
|
683
|
+
string repoRoot,
|
684
|
+
string projectPath,
|
685
|
+
ImmutableArray<string> targetFrameworks,
|
686
|
+
IReadOnlyCollection<Dependency> packages,
|
687
|
+
ExperimentsManager experimentsManager,
|
688
|
+
ILogger logger,
|
689
|
+
bool usePackageDownload = false,
|
690
|
+
bool importDependencyTargets = true
|
691
|
+
) => CreateTempProjectAsync(tempDir, repoRoot, projectPath, new XElement("TargetFrameworks", string.Join(";", targetFrameworks)), packages, experimentsManager, logger, usePackageDownload, importDependencyTargets);
|
692
|
+
|
693
|
+
private static async Task<string> CreateTempProjectAsync(
|
694
|
+
DirectoryInfo tempDir,
|
695
|
+
string repoRoot,
|
696
|
+
string projectPath,
|
697
|
+
XElement targetFrameworkElement,
|
698
|
+
IReadOnlyCollection<Dependency> packages,
|
699
|
+
ExperimentsManager experimentsManager,
|
700
|
+
ILogger logger,
|
701
|
+
bool usePackageDownload,
|
702
|
+
bool importDependencyTargets)
|
675
703
|
{
|
676
704
|
var projectDirectory = Path.GetDirectoryName(projectPath);
|
677
705
|
projectDirectory ??= repoRoot;
|
@@ -722,16 +750,16 @@ internal static partial class MSBuildHelper
|
|
722
750
|
// If all PackageReferences for a package are update-only mark it as such, otherwise it can cause package incoherence errors which do not exist in the repo.
|
723
751
|
.Select(p => $"<{(usePackageDownload ? "PackageDownload" : "PackageReference")} {(p.IsUpdate ? "Update" : "Include")}=\"{p.Name}\" Version=\"[{p.Version}]\" />"));
|
724
752
|
|
753
|
+
var dependencyTargetsImport = importDependencyTargets
|
754
|
+
? $"""<Import Project="{GetFileFromRuntimeDirectory("DependencyDiscovery.targets")}" />"""
|
755
|
+
: string.Empty;
|
756
|
+
|
725
757
|
var projectContents = $"""
|
726
758
|
<Project Sdk="Microsoft.NET.Sdk">
|
727
759
|
<PropertyGroup>
|
728
|
-
|
729
|
-
<GenerateDependencyFile>true</GenerateDependencyFile>
|
730
|
-
<RunAnalyzers>false</RunAnalyzers>
|
731
|
-
<NuGetInteractive>false</NuGetInteractive>
|
732
|
-
<DesignTimeBuild>true</DesignTimeBuild>
|
733
|
-
<TargetPlatformVersion Condition=" $(TargetFramework.Contains('-')) ">1.0</TargetPlatformVersion>
|
760
|
+
{targetFrameworkElement}
|
734
761
|
</PropertyGroup>
|
762
|
+
{dependencyTargetsImport}
|
735
763
|
<ItemGroup>
|
736
764
|
{packageReferences}
|
737
765
|
</ItemGroup>
|
@@ -763,8 +791,6 @@ internal static partial class MSBuildHelper
|
|
763
791
|
"""
|
764
792
|
<Project>
|
765
793
|
<PropertyGroup>
|
766
|
-
<!-- For Windows-specific apps -->
|
767
|
-
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
768
794
|
<!-- Really ensure CPM is disabled -->
|
769
795
|
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
|
770
796
|
</PropertyGroup>
|
@@ -867,7 +893,7 @@ internal static partial class MSBuildHelper
|
|
867
893
|
try
|
868
894
|
{
|
869
895
|
var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
870
|
-
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger);
|
896
|
+
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger, importDependencyTargets: !experimentsManager.UseDirectDiscovery);
|
871
897
|
|
872
898
|
Dependency[] allDependencies;
|
873
899
|
if (experimentsManager.UseDirectDiscovery)
|
@@ -533,6 +533,60 @@ public partial class AnalyzeWorkerTests : AnalyzeWorkerTestBase
|
|
533
533
|
);
|
534
534
|
}
|
535
535
|
|
536
|
+
[Fact]
|
537
|
+
public async Task WindowsSpecificProjectAndWindowsSpecificDependency()
|
538
|
+
{
|
539
|
+
await TestAnalyzeAsync(
|
540
|
+
experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
|
541
|
+
packages: [
|
542
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net6.0-windows7.0"),
|
543
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.1", "net6.0-windows7.0"),
|
544
|
+
],
|
545
|
+
discovery: new()
|
546
|
+
{
|
547
|
+
Path = "/",
|
548
|
+
Projects = [
|
549
|
+
new()
|
550
|
+
{
|
551
|
+
FilePath = "./project.csproj",
|
552
|
+
TargetFrameworks = ["net9.0-windows"],
|
553
|
+
Dependencies = [
|
554
|
+
new("Some.Package", "1.0.0", DependencyType.PackageReference),
|
555
|
+
],
|
556
|
+
ReferencedProjectPaths = [],
|
557
|
+
ImportedFiles = [],
|
558
|
+
AdditionalFiles = [],
|
559
|
+
},
|
560
|
+
],
|
561
|
+
},
|
562
|
+
dependencyInfo: new()
|
563
|
+
{
|
564
|
+
Name = "Some.Package",
|
565
|
+
Version = "1.0.0",
|
566
|
+
IgnoredVersions = [],
|
567
|
+
IsVulnerable = false,
|
568
|
+
Vulnerabilities = [
|
569
|
+
new()
|
570
|
+
{
|
571
|
+
DependencyName = "Some.Package",
|
572
|
+
PackageManager = "nuget",
|
573
|
+
VulnerableVersions = [],
|
574
|
+
SafeVersions = []
|
575
|
+
}
|
576
|
+
],
|
577
|
+
},
|
578
|
+
expectedResult: new()
|
579
|
+
{
|
580
|
+
UpdatedVersion = "1.0.1",
|
581
|
+
CanUpdate = true,
|
582
|
+
VersionComesFromMultiDependencyProperty = false,
|
583
|
+
UpdatedDependencies = [
|
584
|
+
new("Some.Package", "1.0.1", DependencyType.PackageReference, TargetFrameworks: ["net9.0-windows"], IsDirect: true),
|
585
|
+
],
|
586
|
+
}
|
587
|
+
);
|
588
|
+
}
|
589
|
+
|
536
590
|
[Fact]
|
537
591
|
public async Task VersionFinderCanHandle404FromPackageSource_V2()
|
538
592
|
{
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs
CHANGED
@@ -171,5 +171,59 @@ public partial class DiscoveryWorkerTests
|
|
171
171
|
}
|
172
172
|
);
|
173
173
|
}
|
174
|
+
|
175
|
+
[Fact]
|
176
|
+
public async Task DirectDiscoveryWorksEvenWithTargetsImportsOnlyProvidedByVisualStudio()
|
177
|
+
{
|
178
|
+
await TestDiscoveryAsync(
|
179
|
+
workspacePath: "",
|
180
|
+
experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
|
181
|
+
packages: [
|
182
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net48"),
|
183
|
+
],
|
184
|
+
files: [
|
185
|
+
("project.csproj", """
|
186
|
+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
187
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
188
|
+
<PropertyGroup>
|
189
|
+
<OutputType>Library</OutputType>
|
190
|
+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
191
|
+
</PropertyGroup>
|
192
|
+
<ItemGroup>
|
193
|
+
<None Include="packages.config" />
|
194
|
+
</ItemGroup>
|
195
|
+
<Import Project="$(VSToolsPath)\SomeSubPath\WebApplications\Microsoft.WebApplication.targets" />
|
196
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
197
|
+
</Project>
|
198
|
+
"""),
|
199
|
+
("packages.config", """
|
200
|
+
<?xml version="1.0" encoding="utf-8"?>
|
201
|
+
<packages>
|
202
|
+
<package id="Some.Package" version="1.0.0" targetFramework="net48" />
|
203
|
+
</packages>
|
204
|
+
""")
|
205
|
+
],
|
206
|
+
expectedResult: new()
|
207
|
+
{
|
208
|
+
Path = "",
|
209
|
+
Projects = [
|
210
|
+
new()
|
211
|
+
{
|
212
|
+
FilePath = "project.csproj",
|
213
|
+
Properties = [],
|
214
|
+
TargetFrameworks = ["net48"],
|
215
|
+
Dependencies = [
|
216
|
+
new("Some.Package", "1.0.0", DependencyType.PackagesConfig, TargetFrameworks: ["net48"]),
|
217
|
+
],
|
218
|
+
ReferencedProjectPaths = [],
|
219
|
+
ImportedFiles = [],
|
220
|
+
AdditionalFiles = [
|
221
|
+
"packages.config"
|
222
|
+
],
|
223
|
+
}
|
224
|
+
]
|
225
|
+
}
|
226
|
+
);
|
227
|
+
}
|
174
228
|
}
|
175
229
|
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs
CHANGED
@@ -1116,6 +1116,50 @@ public partial class DiscoveryWorkerTests
|
|
1116
1116
|
);
|
1117
1117
|
}
|
1118
1118
|
|
1119
|
+
[Fact]
|
1120
|
+
public async Task WindowsSpecificProjectAndWindowsSpecificDependency()
|
1121
|
+
{
|
1122
|
+
await TestDiscoveryAsync(
|
1123
|
+
experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
|
1124
|
+
packages: [
|
1125
|
+
MockNuGetPackage.CreateSimplePackage("Some.Os.Package", "1.2.3", "net6.0-windows7.0")
|
1126
|
+
],
|
1127
|
+
workspacePath: "",
|
1128
|
+
files: [
|
1129
|
+
("project.csproj", """
|
1130
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
1131
|
+
<PropertyGroup>
|
1132
|
+
<TargetFramework>net9.0-windows</TargetFramework>
|
1133
|
+
</PropertyGroup>
|
1134
|
+
<ItemGroup>
|
1135
|
+
<PackageReference Include="Some.Os.Package" Version="1.2.3" />
|
1136
|
+
</ItemGroup>
|
1137
|
+
</Project>
|
1138
|
+
""")
|
1139
|
+
],
|
1140
|
+
expectedResult: new()
|
1141
|
+
{
|
1142
|
+
Path = "",
|
1143
|
+
Projects = [
|
1144
|
+
new()
|
1145
|
+
{
|
1146
|
+
FilePath = "project.csproj",
|
1147
|
+
Dependencies = [
|
1148
|
+
new("Some.Os.Package", "1.2.3", DependencyType.PackageReference, TargetFrameworks: ["net9.0-windows"], IsDirect: true)
|
1149
|
+
],
|
1150
|
+
Properties = [
|
1151
|
+
new("TargetFramework", "net9.0-windows", "project.csproj")
|
1152
|
+
],
|
1153
|
+
TargetFrameworks = ["net9.0-windows"],
|
1154
|
+
ReferencedProjectPaths = [],
|
1155
|
+
ImportedFiles = [],
|
1156
|
+
AdditionalFiles = []
|
1157
|
+
}
|
1158
|
+
]
|
1159
|
+
}
|
1160
|
+
);
|
1161
|
+
}
|
1162
|
+
|
1119
1163
|
[Fact]
|
1120
1164
|
public async Task DiscoveryWithTargetPlaformVersion_DirectDiscovery()
|
1121
1165
|
{
|
@@ -1375,5 +1419,55 @@ public partial class DiscoveryWorkerTests
|
|
1375
1419
|
}
|
1376
1420
|
);
|
1377
1421
|
}
|
1422
|
+
|
1423
|
+
[Fact]
|
1424
|
+
public async Task LegacyProjectWithPackageReferencesReportsDependencies()
|
1425
|
+
{
|
1426
|
+
// This is a feature of the VS project system - a legacy project with <PackageReference> elements. The `dotnet` CLI
|
1427
|
+
// can't resolve the transitive dependencies; only the VS project system can, so there are some manual steps to allow
|
1428
|
+
// dependency discovery.
|
1429
|
+
await TestDiscoveryAsync(
|
1430
|
+
experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
|
1431
|
+
packages: [
|
1432
|
+
MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.0.0", "net48", [(null, [("Some.Transitive.Dependency", "2.0.0")])]),
|
1433
|
+
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Dependency", "2.0.0", "net48"),
|
1434
|
+
],
|
1435
|
+
workspacePath: "",
|
1436
|
+
files: [
|
1437
|
+
("project.csproj", """
|
1438
|
+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
1439
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
1440
|
+
<PropertyGroup>
|
1441
|
+
<OutputType>Library</OutputType>
|
1442
|
+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
1443
|
+
</PropertyGroup>
|
1444
|
+
<ItemGroup>
|
1445
|
+
<PackageReference Include="Some.Dependency" Version="1.0.0" />
|
1446
|
+
</ItemGroup>
|
1447
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
1448
|
+
</Project>
|
1449
|
+
""")
|
1450
|
+
],
|
1451
|
+
expectedResult: new()
|
1452
|
+
{
|
1453
|
+
Path = "",
|
1454
|
+
Projects = [
|
1455
|
+
new()
|
1456
|
+
{
|
1457
|
+
FilePath = "project.csproj",
|
1458
|
+
Dependencies = [
|
1459
|
+
new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net48"], IsDirect: true),
|
1460
|
+
new("Some.Transitive.Dependency", "2.0.0", DependencyType.Unknown, TargetFrameworks: ["net48"], IsTransitive: true),
|
1461
|
+
],
|
1462
|
+
Properties = [],
|
1463
|
+
TargetFrameworks = ["net48"],
|
1464
|
+
ReferencedProjectPaths = [],
|
1465
|
+
ImportedFiles = [],
|
1466
|
+
AdditionalFiles = [],
|
1467
|
+
}
|
1468
|
+
]
|
1469
|
+
}
|
1470
|
+
);
|
1471
|
+
}
|
1378
1472
|
}
|
1379
1473
|
}
|
@@ -102,7 +102,7 @@ public class FrameworkCompatibilityServiceFacts
|
|
102
102
|
}
|
103
103
|
|
104
104
|
[Theory]
|
105
|
-
[InlineData("net6.0-windows7.0", "net6.0-windows", "net6.0-windows7.0", "net7.0-windows", "net7.0-windows7.0")]
|
105
|
+
[InlineData("net6.0-windows7.0", "net6.0-windows", "net6.0-windows7.0", "net7.0-windows", "net7.0-windows7.0", "net8.0-windows", "net8.0-windows7.0", "net9.0-windows", "net9.0-windows7.0")]
|
106
106
|
public void WindowsPlatformVersionsShouldContainAllSpecifiedFrameworks(string windowsDefaultVersionFramework, params string[] windowsProjectFrameworks)
|
107
107
|
{
|
108
108
|
var packageFramework = NuGetFramework.Parse(windowsDefaultVersionFramework);
|
@@ -0,0 +1,99 @@
|
|
1
|
+
using NuGetUpdater.Core.Updater;
|
2
|
+
|
3
|
+
using Xunit;
|
4
|
+
|
5
|
+
namespace NuGetUpdater.Core.Test.Update;
|
6
|
+
|
7
|
+
public class SpecialFilePatcherTests
|
8
|
+
{
|
9
|
+
[Theory]
|
10
|
+
[MemberData(nameof(SpecialImportsConditionPatcherTestData))]
|
11
|
+
public async Task SpecialImportsConditionPatcher(string fileContent, string expectedPatchedContent)
|
12
|
+
{
|
13
|
+
// arrange
|
14
|
+
var projectFileName = "project.csproj";
|
15
|
+
using var tempDir = await TemporaryDirectory.CreateWithContentsAsync((projectFileName, fileContent));
|
16
|
+
var projectPath = Path.Join(tempDir.DirectoryPath, projectFileName);
|
17
|
+
|
18
|
+
// act
|
19
|
+
using (var patcher = new SpecialImportsConditionPatcher(projectPath))
|
20
|
+
{
|
21
|
+
var actualPatchedContent = await File.ReadAllTextAsync(projectPath);
|
22
|
+
|
23
|
+
// assert
|
24
|
+
Assert.Equal(expectedPatchedContent.Replace("\r", ""), actualPatchedContent.Replace("\r", ""));
|
25
|
+
}
|
26
|
+
|
27
|
+
// assert again
|
28
|
+
var restoredContent = await File.ReadAllTextAsync(projectPath);
|
29
|
+
Assert.Equal(restoredContent.Replace("\r", ""), fileContent.Replace("\r", ""));
|
30
|
+
}
|
31
|
+
|
32
|
+
public static IEnumerable<object[]> SpecialImportsConditionPatcherTestData()
|
33
|
+
{
|
34
|
+
// one-off test to verify namespaces don't interfere
|
35
|
+
yield return
|
36
|
+
[
|
37
|
+
// fileContent
|
38
|
+
"""
|
39
|
+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
40
|
+
<Import Project="Unrelated.One.targets" />
|
41
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" />
|
42
|
+
<Import Project="Unrelated.Two.targets" />
|
43
|
+
</Project>
|
44
|
+
""",
|
45
|
+
// expectedPatchedContent
|
46
|
+
"""
|
47
|
+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
48
|
+
<Import Project="Unrelated.One.targets" />
|
49
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" Condition="false" />
|
50
|
+
<Import Project="Unrelated.Two.targets" />
|
51
|
+
</Project>
|
52
|
+
"""
|
53
|
+
];
|
54
|
+
|
55
|
+
// one-off test to verify existing conditions are restored
|
56
|
+
yield return
|
57
|
+
[
|
58
|
+
// fileContent
|
59
|
+
"""
|
60
|
+
<Project>
|
61
|
+
<Import Project="Unrelated.One.targets" />
|
62
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" Condition="existing condition" />
|
63
|
+
<Import Project="Unrelated.Two.targets" />
|
64
|
+
</Project>
|
65
|
+
""",
|
66
|
+
// expectedPatchedContent
|
67
|
+
"""
|
68
|
+
<Project>
|
69
|
+
<Import Project="Unrelated.One.targets" />
|
70
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" Condition="false" />
|
71
|
+
<Import Project="Unrelated.Two.targets" />
|
72
|
+
</Project>
|
73
|
+
"""
|
74
|
+
];
|
75
|
+
|
76
|
+
// all file variations - by its nature, also verifies that multiple replacements can occur
|
77
|
+
yield return
|
78
|
+
[
|
79
|
+
// fileContent
|
80
|
+
"""
|
81
|
+
<Project>
|
82
|
+
<Import Project="Unrelated.One.targets" />
|
83
|
+
<Import Project="Some\Path\Microsoft.TextTemplating.targets" />
|
84
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" />
|
85
|
+
<Import Project="Unrelated.Two.targets" />
|
86
|
+
</Project>
|
87
|
+
""",
|
88
|
+
// expectedPatchedContent
|
89
|
+
"""
|
90
|
+
<Project>
|
91
|
+
<Import Project="Unrelated.One.targets" />
|
92
|
+
<Import Project="Some\Path\Microsoft.TextTemplating.targets" Condition="false" />
|
93
|
+
<Import Project="Some\Path\Microsoft.WebApplication.targets" Condition="false" />
|
94
|
+
<Import Project="Unrelated.Two.targets" />
|
95
|
+
</Project>
|
96
|
+
"""
|
97
|
+
];
|
98
|
+
}
|
99
|
+
}
|
data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs
CHANGED
@@ -3707,5 +3707,43 @@ public partial class UpdateWorkerTests
|
|
3707
3707
|
]
|
3708
3708
|
);
|
3709
3709
|
}
|
3710
|
+
|
3711
|
+
[Fact]
|
3712
|
+
public async Task LegacyProjectWithPackageReferencesCanUpdate()
|
3713
|
+
{
|
3714
|
+
await TestUpdateForProject("Some.Dependency", "1.0.0", "1.0.1",
|
3715
|
+
experimentsManager: new ExperimentsManager() { UseDirectDiscovery = true },
|
3716
|
+
packages: [
|
3717
|
+
MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.0.0", "net48"),
|
3718
|
+
MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.0.1", "net48"),
|
3719
|
+
],
|
3720
|
+
projectContents: """
|
3721
|
+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
3722
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
3723
|
+
<PropertyGroup>
|
3724
|
+
<OutputType>Library</OutputType>
|
3725
|
+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
3726
|
+
</PropertyGroup>
|
3727
|
+
<ItemGroup>
|
3728
|
+
<PackageReference Include="Some.Dependency" Version="1.0.0" />
|
3729
|
+
</ItemGroup>
|
3730
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
3731
|
+
</Project>
|
3732
|
+
""",
|
3733
|
+
expectedProjectContents: """
|
3734
|
+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
3735
|
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
3736
|
+
<PropertyGroup>
|
3737
|
+
<OutputType>Library</OutputType>
|
3738
|
+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
3739
|
+
</PropertyGroup>
|
3740
|
+
<ItemGroup>
|
3741
|
+
<PackageReference Include="Some.Dependency" Version="1.0.1" />
|
3742
|
+
</ItemGroup>
|
3743
|
+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
3744
|
+
</Project>
|
3745
|
+
"""
|
3746
|
+
);
|
3747
|
+
}
|
3710
3748
|
}
|
3711
3749
|
}
|