dependabot-nuget 0.267.0 → 0.268.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.Core/Updater/SdkPackageUpdater.cs +16 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +39 -14
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.Sdk.cs +121 -0
- data/lib/dependabot/nuget/file_updater.rb +15 -9
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dbd572d869f156e22c4020848387b9b54611ad236c08be6b3ca4cce3e5e7ebc
|
4
|
+
data.tar.gz: f9578fc6352ff07629255fdd1bb2032cda9b0109090507fc39eed9e1b369a68d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c91cd7ef8d66d4aa48de704d70d41087ad8b6f867946f1cf59038a22f22d06febb5227e637d339fe93ec8fa5c086f8d410e16d00c3f70a4c8c348993de01c28
|
7
|
+
data.tar.gz: 161deea8269b8c3fe00013ef83da37e96ddedf9518e9463bdf952034a03ef00be0fac713495b4706ccbcb3d08d072aec700b7921dcbf01506e8e4d432c4fc634
|
@@ -31,7 +31,7 @@ internal static class SdkPackageUpdater
|
|
31
31
|
|
32
32
|
if (isTransitive)
|
33
33
|
{
|
34
|
-
await
|
34
|
+
await UpdateTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, buildFiles, logger);
|
35
35
|
}
|
36
36
|
else
|
37
37
|
{
|
@@ -123,7 +123,7 @@ internal static class SdkPackageUpdater
|
|
123
123
|
return true;
|
124
124
|
}
|
125
125
|
|
126
|
-
private static async Task
|
126
|
+
private static async Task UpdateTransitiveDependencyAsync(string repoRootPath, string projectPath, string dependencyName, string newDependencyVersion, ImmutableArray<ProjectBuildFile> buildFiles, Logger logger)
|
127
127
|
{
|
128
128
|
var directoryPackagesWithPinning = buildFiles.OfType<ProjectBuildFile>()
|
129
129
|
.FirstOrDefault(bf => IsCpmTransitivePinningEnabled(bf));
|
@@ -133,7 +133,7 @@ internal static class SdkPackageUpdater
|
|
133
133
|
}
|
134
134
|
else
|
135
135
|
{
|
136
|
-
await AddTransitiveDependencyAsync(projectPath, dependencyName, newDependencyVersion, logger);
|
136
|
+
await AddTransitiveDependencyAsync(repoRootPath, projectPath, dependencyName, newDependencyVersion, logger);
|
137
137
|
}
|
138
138
|
}
|
139
139
|
|
@@ -222,17 +222,21 @@ internal static class SdkPackageUpdater
|
|
222
222
|
directoryPackages.Update(updatedXml);
|
223
223
|
}
|
224
224
|
|
225
|
-
private static async Task AddTransitiveDependencyAsync(string projectPath, string dependencyName, string newDependencyVersion, Logger logger)
|
225
|
+
private static async Task AddTransitiveDependencyAsync(string repoRootPath, string projectPath, string dependencyName, string newDependencyVersion, Logger logger)
|
226
226
|
{
|
227
|
-
|
228
|
-
|
229
|
-
// see https://learn.microsoft.com/nuget/consume-packages/install-use-packages-dotnet-cli
|
230
|
-
var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", $"add {projectPath} package {dependencyName} --version {newDependencyVersion}", workingDirectory: Path.GetDirectoryName(projectPath));
|
231
|
-
MSBuildHelper.ThrowOnUnauthenticatedFeed(stdout);
|
232
|
-
if (exitCode != 0)
|
227
|
+
var projectDirectory = Path.GetDirectoryName(projectPath)!;
|
228
|
+
await MSBuildHelper.SidelineGlobalJsonAsync(projectDirectory, repoRootPath, async () =>
|
233
229
|
{
|
234
|
-
logger.Log($"
|
235
|
-
|
230
|
+
logger.Log($" Adding [{dependencyName}/{newDependencyVersion}] as a top-level package reference.");
|
231
|
+
|
232
|
+
// see https://learn.microsoft.com/nuget/consume-packages/install-use-packages-dotnet-cli
|
233
|
+
var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("dotnet", $"add {projectPath} package {dependencyName} --version {newDependencyVersion}", workingDirectory: projectDirectory);
|
234
|
+
MSBuildHelper.ThrowOnUnauthenticatedFeed(stdout);
|
235
|
+
if (exitCode != 0)
|
236
|
+
{
|
237
|
+
logger.Log($" Transitive dependency [{dependencyName}/{newDependencyVersion}] was not added.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}");
|
238
|
+
}
|
239
|
+
}, retainMSBuildSdks: true);
|
236
240
|
}
|
237
241
|
|
238
242
|
/// <summary>
|
@@ -31,29 +31,54 @@ internal static partial class MSBuildHelper
|
|
31
31
|
// Ensure MSBuild types are registered before calling a method that loads the types
|
32
32
|
if (!IsMSBuildRegistered)
|
33
33
|
{
|
34
|
-
|
35
|
-
var globalJsonPaths = candidateDirectories.Select(d => Path.Combine(d, "global.json")).Where(File.Exists).Select(p => (p, p + Guid.NewGuid().ToString())).ToArray();
|
36
|
-
foreach (var (globalJsonPath, tempGlobalJsonPath) in globalJsonPaths)
|
37
|
-
{
|
38
|
-
Console.WriteLine($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}` for MSBuild detection.");
|
39
|
-
File.Move(globalJsonPath, tempGlobalJsonPath);
|
40
|
-
}
|
41
|
-
|
42
|
-
try
|
34
|
+
SidelineGlobalJsonAsync(currentDirectory, rootDirectory, () =>
|
43
35
|
{
|
44
36
|
var defaultInstance = MSBuildLocator.QueryVisualStudioInstances().First();
|
45
37
|
MSBuildPath = defaultInstance.MSBuildPath;
|
46
38
|
MSBuildLocator.RegisterInstance(defaultInstance);
|
47
|
-
|
48
|
-
|
39
|
+
return Task.CompletedTask;
|
40
|
+
}).Wait();
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
public static async Task SidelineGlobalJsonAsync(string currentDirectory, string rootDirectory, Func<Task> action, bool retainMSBuildSdks = false)
|
45
|
+
{
|
46
|
+
var candidateDirectories = PathHelper.GetAllDirectoriesToRoot(currentDirectory, rootDirectory);
|
47
|
+
var globalJsonPaths = candidateDirectories.Select(d => Path.Combine(d, "global.json")).Where(File.Exists).Select(p => (p, p + Guid.NewGuid().ToString())).ToArray();
|
48
|
+
foreach (var (globalJsonPath, tempGlobalJsonPath) in globalJsonPaths)
|
49
|
+
{
|
50
|
+
Console.WriteLine($"Temporarily removing `global.json` from `{Path.GetDirectoryName(globalJsonPath)}`{(retainMSBuildSdks ? " and retaining MSBuild SDK declarations" : string.Empty)}.");
|
51
|
+
File.Move(globalJsonPath, tempGlobalJsonPath);
|
52
|
+
if (retainMSBuildSdks)
|
49
53
|
{
|
50
|
-
|
54
|
+
// custom SDKs might need to be retained for other operations; rebuild `global.json` with only the relevant key
|
55
|
+
var originalContent = await File.ReadAllTextAsync(tempGlobalJsonPath);
|
56
|
+
var jsonNode = JsonHelper.ParseNode(originalContent);
|
57
|
+
if (jsonNode is JsonObject obj &&
|
58
|
+
obj.TryGetPropertyValue("msbuild-sdks", out var sdks) &&
|
59
|
+
sdks is not null)
|
51
60
|
{
|
52
|
-
|
53
|
-
|
61
|
+
var newObj = new JsonObject()
|
62
|
+
{
|
63
|
+
["msbuild-sdks"] = sdks.DeepClone(),
|
64
|
+
};
|
65
|
+
await File.WriteAllTextAsync(globalJsonPath, newObj.ToJsonString());
|
54
66
|
}
|
55
67
|
}
|
56
68
|
}
|
69
|
+
|
70
|
+
try
|
71
|
+
{
|
72
|
+
await action();
|
73
|
+
}
|
74
|
+
finally
|
75
|
+
{
|
76
|
+
foreach (var (globalJsonpath, tempGlobalJsonPath) in globalJsonPaths)
|
77
|
+
{
|
78
|
+
Console.WriteLine($"Restoring `global.json` to `{Path.GetDirectoryName(globalJsonpath)}`.");
|
79
|
+
File.Move(tempGlobalJsonPath, globalJsonpath, overwrite: retainMSBuildSdks);
|
80
|
+
}
|
81
|
+
}
|
57
82
|
}
|
58
83
|
|
59
84
|
public static IEnumerable<string> GetProjectPathsFromSolution(string solutionPath)
|
@@ -532,6 +532,127 @@ public partial class UpdateWorkerTests
|
|
532
532
|
);
|
533
533
|
}
|
534
534
|
|
535
|
+
[Fact]
|
536
|
+
public async Task TransitiveDependencyCanBeAddedWithMismatchingSdk()
|
537
|
+
{
|
538
|
+
await TestUpdateForProject("Some.Transitive.Package", "1.0.0", "1.0.1", isTransitive: true,
|
539
|
+
packages:
|
540
|
+
[
|
541
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", [(null, [("Some.Transitive.Package", "1.0.0")])]),
|
542
|
+
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Package", "1.0.0", "net8.0"),
|
543
|
+
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Package", "1.0.1", "net8.0"),
|
544
|
+
],
|
545
|
+
projectContents: """
|
546
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
547
|
+
<PropertyGroup>
|
548
|
+
<TargetFramework>net8.0</TargetFramework>
|
549
|
+
</PropertyGroup>
|
550
|
+
<ItemGroup>
|
551
|
+
<PackageReference Include="Some.Package" Version="1.0.0" />
|
552
|
+
</ItemGroup>
|
553
|
+
</Project>
|
554
|
+
""",
|
555
|
+
additionalFiles:
|
556
|
+
[
|
557
|
+
("global.json", """
|
558
|
+
{
|
559
|
+
"sdk": {
|
560
|
+
"version": "99.99.999" // this version doesn't match anything that's installed
|
561
|
+
}
|
562
|
+
}
|
563
|
+
""")
|
564
|
+
],
|
565
|
+
expectedProjectContents: """
|
566
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
567
|
+
<PropertyGroup>
|
568
|
+
<TargetFramework>net8.0</TargetFramework>
|
569
|
+
</PropertyGroup>
|
570
|
+
<ItemGroup>
|
571
|
+
<PackageReference Include="Some.Package" Version="1.0.0" />
|
572
|
+
<PackageReference Include="Some.Transitive.Package" Version="1.0.1" />
|
573
|
+
</ItemGroup>
|
574
|
+
</Project>
|
575
|
+
"""
|
576
|
+
);
|
577
|
+
}
|
578
|
+
|
579
|
+
[Fact]
|
580
|
+
public async Task TransitiveDependencyCanBeAddedWithCustomMSBuildSdk()
|
581
|
+
{
|
582
|
+
await TestUpdateForProject("Some.Transitive.Package", "1.0.0", "1.0.1", isTransitive: true,
|
583
|
+
packages:
|
584
|
+
[
|
585
|
+
MockNuGetPackage.CreateSimplePackage("Some.Package", "1.0.0", "net8.0", [(null, [("Some.Transitive.Package", "1.0.0")])]),
|
586
|
+
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Package", "1.0.0", "net8.0"),
|
587
|
+
MockNuGetPackage.CreateSimplePackage("Some.Transitive.Package", "1.0.1", "net8.0"),
|
588
|
+
MockNuGetPackage.CreateMSBuildSdkPackage("Custom.MSBuild.Sdk", "1.2.3"),
|
589
|
+
],
|
590
|
+
projectContents: """
|
591
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
592
|
+
<PropertyGroup>
|
593
|
+
<TargetFramework>net8.0</TargetFramework>
|
594
|
+
</PropertyGroup>
|
595
|
+
<ItemGroup>
|
596
|
+
<PackageReference Include="Some.Package" />
|
597
|
+
</ItemGroup>
|
598
|
+
</Project>
|
599
|
+
""",
|
600
|
+
additionalFiles:
|
601
|
+
[
|
602
|
+
("Directory.Build.props", """
|
603
|
+
<Project>
|
604
|
+
<Import Project="Sdk.props" Sdk="Custom.MSBuild.Sdk" />
|
605
|
+
</Project>
|
606
|
+
"""),
|
607
|
+
("Directory.Packages.props", """
|
608
|
+
<Project>
|
609
|
+
<PropertyGroup>
|
610
|
+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
611
|
+
</PropertyGroup>
|
612
|
+
<ItemGroup>
|
613
|
+
<PackageVersion Include="Some.Package" Version="1.0.0" />
|
614
|
+
</ItemGroup>
|
615
|
+
</Project>
|
616
|
+
"""),
|
617
|
+
("global.json", """
|
618
|
+
{
|
619
|
+
"sdk": {
|
620
|
+
"version": "99.99.999" // this version doesn't match anything that's installed
|
621
|
+
},
|
622
|
+
"msbuild-sdks": {
|
623
|
+
"Custom.MSBuild.Sdk": "1.2.3"
|
624
|
+
}
|
625
|
+
}
|
626
|
+
""")
|
627
|
+
],
|
628
|
+
expectedProjectContents: """
|
629
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
630
|
+
<PropertyGroup>
|
631
|
+
<TargetFramework>net8.0</TargetFramework>
|
632
|
+
</PropertyGroup>
|
633
|
+
<ItemGroup>
|
634
|
+
<PackageReference Include="Some.Package" />
|
635
|
+
<PackageReference Include="Some.Transitive.Package" />
|
636
|
+
</ItemGroup>
|
637
|
+
</Project>
|
638
|
+
""",
|
639
|
+
additionalFilesExpected:
|
640
|
+
[
|
641
|
+
("Directory.Packages.props", """
|
642
|
+
<Project>
|
643
|
+
<PropertyGroup>
|
644
|
+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
645
|
+
</PropertyGroup>
|
646
|
+
<ItemGroup>
|
647
|
+
<PackageVersion Include="Some.Package" Version="1.0.0" />
|
648
|
+
<PackageVersion Include="Some.Transitive.Package" Version="1.0.1" />
|
649
|
+
</ItemGroup>
|
650
|
+
</Project>
|
651
|
+
""")
|
652
|
+
]
|
653
|
+
);
|
654
|
+
}
|
655
|
+
|
535
656
|
[Fact]
|
536
657
|
public async Task UpdateVersionAttribute_InProjectFile_ForAnalyzerPackageReferenceInclude()
|
537
658
|
{
|
@@ -31,6 +31,20 @@ module Dependabot
|
|
31
31
|
]
|
32
32
|
end
|
33
33
|
|
34
|
+
sig { params(original_content: T.nilable(String), updated_content: String).returns(T::Boolean) }
|
35
|
+
def self.differs_in_more_than_blank_lines?(original_content, updated_content)
|
36
|
+
# Compare the line counts of the original and updated content, but ignore lines only containing white-space.
|
37
|
+
# This prevents false positives when there are trailing empty lines in the original content, for example.
|
38
|
+
original_lines = (original_content&.lines || []).map(&:strip).reject(&:empty?)
|
39
|
+
updated_lines = updated_content.lines.map(&:strip).reject(&:empty?)
|
40
|
+
|
41
|
+
# if the line count differs, then something changed
|
42
|
+
return true unless original_lines.count == updated_lines.count
|
43
|
+
|
44
|
+
# check each line pair, ignoring blanks (filtered above)
|
45
|
+
original_lines.zip(updated_lines).any? { |pair| pair[0] != pair[1] }
|
46
|
+
end
|
47
|
+
|
34
48
|
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
35
49
|
def updated_dependency_files
|
36
50
|
base_dir = "/"
|
@@ -45,7 +59,7 @@ module Dependabot
|
|
45
59
|
normalized_content = normalize_content(f, updated_content)
|
46
60
|
next if normalized_content == f.content
|
47
61
|
|
48
|
-
next
|
62
|
+
next unless FileUpdater.differs_in_more_than_blank_lines?(f.content, normalized_content)
|
49
63
|
|
50
64
|
puts "The contents of file [#{f.name}] were updated."
|
51
65
|
|
@@ -217,14 +231,6 @@ module Dependabot
|
|
217
231
|
|
218
232
|
raise "No project file or packages.config!"
|
219
233
|
end
|
220
|
-
|
221
|
-
sig { params(original_content: T.nilable(String), updated_content: String).returns(T::Boolean) }
|
222
|
-
def only_deleted_lines?(original_content, updated_content)
|
223
|
-
original_lines = original_content&.lines || []
|
224
|
-
updated_lines = updated_content.lines
|
225
|
-
|
226
|
-
original_lines.count > updated_lines.count
|
227
|
-
end
|
228
234
|
end
|
229
235
|
end
|
230
236
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-nuget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.268.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.268.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.268.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubyzip
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -461,7 +461,7 @@ licenses:
|
|
461
461
|
- MIT
|
462
462
|
metadata:
|
463
463
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
464
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
464
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.268.0
|
465
465
|
post_install_message:
|
466
466
|
rdoc_options: []
|
467
467
|
require_paths:
|