dependabot-nuget 0.316.0 → 0.317.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b42ebbf0a6556e3766516b2b59eec508929837779a8f9ca2042a4d4f7d629626
4
- data.tar.gz: abb2a60e86d368d9d4a0f09c6311fd7b73f2ac708c1ec73c05d92d1b9409b27d
3
+ metadata.gz: 4f345f9ee257e7f76d38a1895964aaf6f6356182d190037a19df23107f62c18b
4
+ data.tar.gz: 47c6ec4d4a5157c2a644856532129923aa9a65d6710d01a40bf18c59f8483971
5
5
  SHA512:
6
- metadata.gz: 5b266cf823214164397b8e9ed67e5f238364ab95074f33f5cacec47adac5a6cecf147a39ccdb11701e29d0de0ca675b3dabd4a330d75d8ff81dbf7b660c26807
7
- data.tar.gz: fa309cdd55f81b5507329def15d7a7e6c50b7668e8f1f886cc7c0e1498ac8209aab577d6ba617dbe7ecffda79f93be8d696908b692a07415b78c677905bb9fdb
6
+ metadata.gz: 453d1742deef75f810dab148d9d9344a79f39ce893d1dfec90020d7bec36b6018b1acddf0d02c5e109e9957a94f7e3b1d09a4808b2f35e3e9b1e20f5b8bc1e15
7
+ data.tar.gz: 25bf0a85529e9fa9af427d5fa860b4208c7df6cd763d4059ce66fe8c1f6ee04596322f75cf20d5c4cfb6132d0157edb92f63a956191fa67f0c95d43f99444a29
@@ -231,7 +231,6 @@ public class NullAsEmptyStringArrayConverter : JsonConverter<ImmutableArray<stri
231
231
 
232
232
  public override void Write(Utf8JsonWriter writer, ImmutableArray<string> value, JsonSerializerOptions options)
233
233
  {
234
- writer.WriteStartArray();
235
- writer.WriteEndArray();
234
+ JsonSerializer.Serialize(writer, value, options);
236
235
  }
237
236
  }
@@ -97,7 +97,12 @@ public class PullRequestTextGenerator
97
97
  var fromText = dependencySet.Versions.Length == 1 && dependencySet.Versions[0].OldVersion is not null
98
98
  ? $"from {dependencySet.Versions[0].OldVersion} "
99
99
  : string.Empty;
100
- return $"Bump{bumpSuffix} {dependencySet.Name} {fromText}to {string.Join(", ", dependencySet.Versions.Select(v => v.NewVersion.ToString()))}";
100
+ var newVersions = dependencySet.Versions
101
+ .Select(v => v.NewVersion)
102
+ .Distinct()
103
+ .OrderBy(v => v)
104
+ .ToArray();
105
+ return $"Bump{bumpSuffix} {dependencySet.Name} {fromText}to {string.Join(", ", newVersions.Select(v => v.ToString()))}";
101
106
  }
102
107
 
103
108
  private static DependencySet[] GetDependencySets(ImmutableArray<UpdateOperationBase> updateOperationsPerformed)
@@ -57,6 +57,13 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
57
57
  {
58
58
  foreach (var group in job.DependencyGroups)
59
59
  {
60
+ var existingGroupPr = job.ExistingGroupPullRequests.FirstOrDefault(pr => pr.DependencyGroupName == group.Name);
61
+ if (existingGroupPr is not null)
62
+ {
63
+ logger.Info($"Existing pull request found for group {group.Name}. Skipping pull request creation.");
64
+ continue;
65
+ }
66
+
60
67
  logger.Info($"Starting update for group {group.Name}");
61
68
  var groupMatcher = group.GetGroupMatcher();
62
69
  var updateOperationsPerformed = new List<UpdateOperationBase>();
@@ -145,7 +145,9 @@ internal class RefreshGroupUpdatePullRequestHandler : IUpdateHandler
145
145
  var rawDependencies = updatedDependencies.Select(d => new Dependency(d.Name, d.Version, DependencyType.Unknown)).ToArray();
146
146
  if (rawDependencies.Length == 0)
147
147
  {
148
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
148
+ var close = ClosePullRequest.WithUpdateNoLongerPossible(job);
149
+ logger.Info(close.GetReport());
150
+ await apiHandler.ClosePullRequest(close);
149
151
  continue;
150
152
  }
151
153
 
@@ -35,6 +35,7 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
35
35
  logger.ReportDiscovery(discoveryResult);
36
36
  if (discoveryResult.Error is not null)
37
37
  {
38
+ logger.Error($"Reporting error: {discoveryResult.Error.GetReport()}");
38
39
  await apiHandler.RecordUpdateJobError(discoveryResult.Error);
39
40
  return;
40
41
  }
@@ -55,7 +56,9 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
55
56
 
56
57
  if (groupedUpdateOperationsToPerform.Count == 0)
57
58
  {
58
- await apiHandler.ClosePullRequest(ClosePullRequest.WithDependenciesRemoved(job));
59
+ var close = ClosePullRequest.WithDependenciesRemoved(job);
60
+ logger.Info(close.GetReport());
61
+ await apiHandler.ClosePullRequest(close);
59
62
  continue;
60
63
  }
61
64
 
@@ -65,7 +68,9 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
65
68
  .ToImmutableArray();
66
69
  if (missingDependencies.Length > 0)
67
70
  {
68
- await apiHandler.ClosePullRequest(ClosePullRequest.WithDependencyRemoved(job));
71
+ var close = ClosePullRequest.WithDependencyRemoved(job);
72
+ logger.Info(close.GetReport());
73
+ await apiHandler.ClosePullRequest(close);
69
74
  continue;
70
75
  }
71
76
 
@@ -82,7 +87,9 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
82
87
 
83
88
  if (vulnerableDependenciesToUpdate.Length < dependencyGroupToUpdate.Value.Length)
84
89
  {
85
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpToDate(job));
90
+ var close = ClosePullRequest.WithUpToDate(job);
91
+ logger.Info(close.GetReport());
92
+ await apiHandler.ClosePullRequest(close);
86
93
  return;
87
94
  }
88
95
 
@@ -99,8 +106,7 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
99
106
  if (!analysisResult.CanUpdate)
100
107
  {
101
108
  logger.Info($"No updatable version found for {dependency.Name} in {projectPath}.");
102
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
103
- return;
109
+ continue;
104
110
  }
105
111
 
106
112
  logger.Info($"Attempting update of {dependency.Name} from {dependency.Version} to {analysisResult.UpdatedVersion} for {projectPath}.");
@@ -115,13 +121,8 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
115
121
 
116
122
  if (updaterResult.UpdateOperations.Length == 0)
117
123
  {
118
- // nothing was done, but we may have already handled it
119
- var alreadyHandled = updatedDependencies.Where(updated => updated.Name == dependencyName && updated.Version == analysisResult.UpdatedVersion).Any();
120
- if (!alreadyHandled)
121
- {
122
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
123
- return;
124
- }
124
+ logger.Info($"No update operations performed for {dependency.Name}/{dependency.Version} in project {projectPath}.");
125
+ continue;
125
126
  }
126
127
 
127
128
  var patchedUpdateOperations = RunWorker.PatchInOldVersions(updaterResult.UpdateOperations, projectDiscovery);
@@ -138,6 +139,21 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
138
139
  }
139
140
  }
140
141
 
142
+ // ensure we did something
143
+ var updatesNotPerformed = jobDependencies
144
+ .Except(updatedDependencies.Select(d => d.Name), StringComparer.OrdinalIgnoreCase)
145
+ .Distinct()
146
+ .OrderBy(d => d, StringComparer.OrdinalIgnoreCase)
147
+ .ToArray();
148
+
149
+ if (updatesNotPerformed.Length > 0)
150
+ {
151
+ logger.Info($"No updates performed for: {string.Join(", ", updatesNotPerformed)}");
152
+ await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
153
+ continue;
154
+ }
155
+
156
+ // update or create
141
157
  var updatedDependencyFiles = await tracker.StopTrackingAsync();
142
158
  var rawDependencies = updatedDependencies.Select(d => new Dependency(d.Name, d.Version, DependencyType.Unknown)).ToArray();
143
159
  if (rawDependencies.Length > 0)
@@ -53,7 +53,9 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
53
53
 
54
54
  if (relevantUpdateOperationsToPerform.Count == 0)
55
55
  {
56
- await apiHandler.ClosePullRequest(ClosePullRequest.WithDependenciesRemoved(job));
56
+ var close = ClosePullRequest.WithDependenciesRemoved(job);
57
+ logger.Info(close.GetReport());
58
+ await apiHandler.ClosePullRequest(close);
57
59
  continue;
58
60
  }
59
61
 
@@ -63,7 +65,9 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
63
65
  .ToImmutableArray();
64
66
  if (missingDependencies.Length > 0)
65
67
  {
66
- await apiHandler.ClosePullRequest(ClosePullRequest.WithDependencyRemoved(job));
68
+ var close = ClosePullRequest.WithDependencyRemoved(job);
69
+ logger.Info(close.GetReport());
70
+ await apiHandler.ClosePullRequest(close);
67
71
  continue;
68
72
  }
69
73
 
@@ -92,8 +96,7 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
92
96
  if (!analysisResult.CanUpdate)
93
97
  {
94
98
  logger.Info($"No updatable version found for {dependency.Name} in {projectPath}.");
95
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
96
- return;
99
+ continue;
97
100
  }
98
101
 
99
102
  logger.Info($"Attempting update of {dependency.Name} from {dependency.Version} to {analysisResult.UpdatedVersion} for {projectPath}.");
@@ -108,8 +111,8 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
108
111
 
109
112
  if (updaterResult.UpdateOperations.Length == 0)
110
113
  {
111
- await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
112
- return;
114
+ logger.Info($"No update operations performed for {dependency.Name}/{dependency.Version} in project {projectPath}.");
115
+ continue;
113
116
  }
114
117
 
115
118
  var patchedUpdateOperations = RunWorker.PatchInOldVersions(updaterResult.UpdateOperations, projectDiscovery);
@@ -126,6 +129,21 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
126
129
  }
127
130
  }
128
131
 
132
+ // ensure we did something
133
+ var updatesNotPerformed = jobDependencies
134
+ .Except(updatedDependencies.Select(d => d.Name), StringComparer.OrdinalIgnoreCase)
135
+ .Distinct()
136
+ .OrderBy(d => d, StringComparer.OrdinalIgnoreCase)
137
+ .ToArray();
138
+
139
+ if (updatesNotPerformed.Length > 0)
140
+ {
141
+ logger.Info($"No updates performed for: {string.Join(", ", updatesNotPerformed)}");
142
+ await apiHandler.ClosePullRequest(ClosePullRequest.WithUpdateNoLongerPossible(job));
143
+ continue;
144
+ }
145
+
146
+ // update or create
129
147
  var updatedDependencyFiles = await tracker.StopTrackingAsync();
130
148
  var rawDependencies = updatedDependencies.Select(d => new Dependency(d.Name, d.Version, DependencyType.Unknown)).ToArray();
131
149
  if (rawDependencies.Length > 0)
@@ -2,6 +2,8 @@ using System.Collections.Immutable;
2
2
 
3
3
  using Microsoft.Language.Xml;
4
4
 
5
+ using NuGetUpdater.Core.Utilities;
6
+
5
7
  namespace NuGetUpdater.Core.Updater
6
8
  {
7
9
  internal class SpecialImportsConditionPatcher : IDisposable
@@ -24,9 +26,20 @@ namespace NuGetUpdater.Core.Updater
24
26
 
25
27
  public SpecialImportsConditionPatcher(string projectFilePath)
26
28
  {
29
+ var hasBOM = false;
27
30
  _processor = new XmlFilePreAndPostProcessor(
28
- getContent: () => File.ReadAllText(projectFilePath),
29
- setContent: s => File.WriteAllText(projectFilePath, s),
31
+ getContent: () =>
32
+ {
33
+ var content = File.ReadAllText(projectFilePath);
34
+ var rawContent = File.ReadAllBytes(projectFilePath);
35
+ hasBOM = rawContent.HasBOM();
36
+ return content;
37
+ },
38
+ setContent: content =>
39
+ {
40
+ var rawContent = content.SetBOM(hasBOM);
41
+ File.WriteAllBytes(projectFilePath, rawContent);
42
+ },
30
43
  nodeFinder: doc => doc.Descendants()
31
44
  .Where(e => e.Name == "Import")
32
45
  .Where(e =>
@@ -402,6 +402,45 @@ public class PullRequestTextTests
402
402
  - Updated Package.B from 4.0.0 to 4.5.6 in a.txt
403
403
  """
404
404
  ];
405
+
406
+ // multiple updates to the same dependency
407
+ yield return
408
+ [
409
+ // job
410
+ FromCommitOptions(null),
411
+ // updateOperationsPerformed
412
+ new UpdateOperationBase[]
413
+ {
414
+ new DirectUpdate()
415
+ {
416
+ DependencyName = "Some.Package",
417
+ OldVersion = NuGetVersion.Parse("1.0.0"),
418
+ NewVersion = NuGetVersion.Parse("1.2.3"),
419
+ UpdatedFiles = ["a.txt"]
420
+ },
421
+ new DirectUpdate()
422
+ {
423
+ DependencyName = "Some.Package",
424
+ OldVersion = NuGetVersion.Parse("1.0.0"),
425
+ NewVersion = NuGetVersion.Parse("1.2.3"),
426
+ UpdatedFiles = ["b.txt"]
427
+ }
428
+ },
429
+ // dependencyGroupName
430
+ null,
431
+ // expectedTitle
432
+ "Bump Some.Package to 1.2.3",
433
+ // expectedCommitMessage
434
+ """
435
+ Bump Some.Package to 1.2.3
436
+ """,
437
+ // expectedBody
438
+ """
439
+ Performed the following updates:
440
+ - Updated Some.Package from 1.0.0 to 1.2.3 in a.txt
441
+ - Updated Some.Package from 1.0.0 to 1.2.3 in b.txt
442
+ """
443
+ ];
405
444
  }
406
445
 
407
446
  private static Job FromCommitOptions(CommitOptions? commitOptions)
@@ -633,4 +633,166 @@ public class GroupUpdateAllVersionsHandlerTests : UpdateHandlersTestsBase
633
633
  ]
634
634
  );
635
635
  }
636
+
637
+ [Fact]
638
+ public async Task GeneratesCreatePullRequest_Grouped_ExistingPrSkipped()
639
+ {
640
+ // two groups specified, but one has existing PR and is skipped
641
+ await TestAsync(
642
+ job: new Job()
643
+ {
644
+ Source = CreateJobSource("/src"),
645
+ DependencyGroups = [
646
+ new()
647
+ {
648
+ Name = "test-group-1",
649
+ Rules = new()
650
+ {
651
+ ["patterns"] = new[] { "Package.For.Group.One" },
652
+ },
653
+ },
654
+ new()
655
+ {
656
+ Name = "test-group-2", // this group has an existing PR and will be skipped
657
+ Rules = new()
658
+ {
659
+ ["patterns"] = new[] { "Package.For.Group.Two" },
660
+ },
661
+ },
662
+ ],
663
+ ExistingGroupPullRequests = [
664
+ new()
665
+ {
666
+ DependencyGroupName = "test-group-2",
667
+ Dependencies = [
668
+ new()
669
+ {
670
+ DependencyName = "Package.For.Group.Two",
671
+ DependencyVersion = NuGetVersion.Parse("2.0.1"),
672
+ }
673
+ ]
674
+ }
675
+ ]
676
+ },
677
+ files: [
678
+ ("src/project.csproj", "initial contents"),
679
+ ],
680
+ discoveryWorker: TestDiscoveryWorker.FromResults(
681
+ ("/src", new WorkspaceDiscoveryResult()
682
+ {
683
+ Path = "/src",
684
+ Projects = [
685
+ new()
686
+ {
687
+ FilePath = "project.csproj",
688
+ Dependencies = [
689
+ new("Package.For.Group.One", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
690
+ new("Package.For.Group.Two", "2.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"]),
691
+ ],
692
+ ImportedFiles = [],
693
+ AdditionalFiles = [],
694
+ }
695
+ ],
696
+ })
697
+ ),
698
+ analyzeWorker: new TestAnalyzeWorker(input =>
699
+ {
700
+ var repoRoot = input.Item1;
701
+ var discovery = input.Item2;
702
+ var dependencyInfo = input.Item3;
703
+ var newVersion = dependencyInfo.Name switch
704
+ {
705
+ "Package.For.Group.One" => "1.0.1",
706
+ "Package.For.Group.Two" => "2.0.1",
707
+ _ => throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}"),
708
+ };
709
+ return Task.FromResult(new AnalysisResult()
710
+ {
711
+ CanUpdate = true,
712
+ UpdatedVersion = newVersion,
713
+ UpdatedDependencies = [],
714
+ });
715
+ }),
716
+ updaterWorker: new TestUpdaterWorker(async input =>
717
+ {
718
+ var repoRoot = input.Item1;
719
+ var workspacePath = input.Item2;
720
+ var dependencyName = input.Item3;
721
+ var previousVersion = input.Item4;
722
+ var newVersion = input.Item5;
723
+ var isTransitive = input.Item6;
724
+
725
+ await File.WriteAllTextAsync(Path.Join(repoRoot, workspacePath), $"updated contents for {dependencyName}/{newVersion}");
726
+
727
+ return new UpdateOperationResult()
728
+ {
729
+ UpdateOperations = [new DirectUpdate() { DependencyName = dependencyName, NewVersion = NuGetVersion.Parse(newVersion), UpdatedFiles = [workspacePath] }],
730
+ };
731
+ }),
732
+ expectedUpdateHandler: GroupUpdateAllVersionsHandler.Instance,
733
+ expectedApiMessages: [
734
+ new IncrementMetric()
735
+ {
736
+ Metric = "updater.started",
737
+ Tags = new()
738
+ {
739
+ ["operation"] = "group_update_all_versions",
740
+ }
741
+ },
742
+ new UpdatedDependencyList()
743
+ {
744
+ Dependencies = [
745
+ new()
746
+ {
747
+ Name = "Package.For.Group.One",
748
+ Version = "1.0.0",
749
+ Requirements = [
750
+ new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
751
+ ],
752
+ },
753
+ new()
754
+ {
755
+ Name = "Package.For.Group.Two",
756
+ Version = "2.0.0",
757
+ Requirements = [
758
+ new() { Requirement = "2.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
759
+ ],
760
+ },
761
+ ],
762
+ DependencyFiles = ["/src/project.csproj"],
763
+ },
764
+ new CreatePullRequest()
765
+ {
766
+ Dependencies = [
767
+ new()
768
+ {
769
+ Name = "Package.For.Group.One",
770
+ Version = "1.0.1",
771
+ Requirements = [
772
+ new() { Requirement = "1.0.1", File = "/src/project.csproj", Groups = ["dependencies"], Source = new() { SourceUrl = null } },
773
+ ],
774
+ PreviousVersion = "1.0.0",
775
+ PreviousRequirements = [
776
+ new() { Requirement = "1.0.0", File = "/src/project.csproj", Groups = ["dependencies"] },
777
+ ],
778
+ },
779
+ ],
780
+ UpdatedDependencyFiles = [
781
+ new()
782
+ {
783
+ Directory = "/src",
784
+ Name = "project.csproj",
785
+ Content = "updated contents for Package.For.Group.One/1.0.1",
786
+ },
787
+ ],
788
+ BaseCommitSha = "TEST-COMMIT-SHA",
789
+ CommitMessage = RunWorkerTests.TestPullRequestCommitMessage,
790
+ PrTitle = RunWorkerTests.TestPullRequestTitle,
791
+ PrBody = RunWorkerTests.TestPullRequestBody,
792
+ DependencyGroup = "test-group-1",
793
+ },
794
+ new MarkAsProcessed("TEST-COMMIT-SHA"),
795
+ ]
796
+ );
797
+ }
636
798
  }