dependabot-nuget 0.319.1 → 0.320.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: bc7266285d2a882d96d89cfedaf0dd736ba016a03780358c4fb1441c96e70e94
4
- data.tar.gz: c695c0d81c43bc373ed7a60edbf7e603946fd03a75ab98f8ccd428870fe5a77c
3
+ metadata.gz: 01f128d072d32926e6e96f7b22267731024c29c8f5612e4c5bff9d9cbcfc697f
4
+ data.tar.gz: 1bbbd11f11bc330310bdf5414c5bd9f848b59910f4111756fb525df6a75391a9
5
5
  SHA512:
6
- metadata.gz: 115fb414c475f54768d5172f59890ec83c1b44c4968a5f38b88bd05d7036c865c9e9f1f5abfb9ddd10f88bdda4d14eced575303504f367828ba7f77cf18428c9
7
- data.tar.gz: d609c852ed7a3298bb68d483d3acc526ea215b509e017361d6308a117ca0e09c9dc45f611130ac7221e02449b46c7971386b7cf376a77387f45c88aaa99a9eaa
6
+ metadata.gz: d17cb789e99b9849e649a0961df43bb9dd74e7840fe4cb35542d4be6cc88ac045aa3445431443d1a8b98d0bf0baef2ac9f4bef50d74bde66a2af04ab711a234c
7
+ data.tar.gz: 733bdc56ef1a9617f6a16b90fdcbf4fcd522e6d86a3f3f4fcbf3f40981135dbd873b85397a06de97710c7794e4dd30158ff1ef1e2e3fb5282c7488109b992754
@@ -11,6 +11,7 @@ internal static class RunCommand
11
11
  {
12
12
  internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
13
13
  internal static readonly Option<DirectoryInfo> RepoContentsPathOption = new("--repo-contents-path") { IsRequired = true };
14
+ internal static readonly Option<DirectoryInfo?> CaseInsensitiveRepoContentsPathOption = new("--case-insensitive-repo-contents-path") { IsRequired = false };
14
15
  internal static readonly Option<Uri> ApiUrlOption = new("--api-url") { IsRequired = true };
15
16
  internal static readonly Option<string> JobIdOption = new("--job-id") { IsRequired = true };
16
17
  internal static readonly Option<FileInfo> OutputPathOption = new("--output-path") { IsRequired = true };
@@ -22,6 +23,7 @@ internal static class RunCommand
22
23
  {
23
24
  JobPathOption,
24
25
  RepoContentsPathOption,
26
+ CaseInsensitiveRepoContentsPathOption,
25
27
  ApiUrlOption,
26
28
  JobIdOption,
27
29
  OutputPathOption,
@@ -30,7 +32,7 @@ internal static class RunCommand
30
32
 
31
33
  command.TreatUnmatchedTokensAsErrors = true;
32
34
 
33
- command.SetHandler(async (jobPath, repoContentsPath, apiUrl, jobId, outputPath, baseCommitSha) =>
35
+ command.SetHandler(async (jobPath, repoContentsPath, caseInsensitiveRepoContentsPath, apiUrl, jobId, outputPath, baseCommitSha) =>
34
36
  {
35
37
  var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
36
38
  var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobId, jobPath.FullName);
@@ -39,8 +41,8 @@ internal static class RunCommand
39
41
  var analyzeWorker = new AnalyzeWorker(jobId, experimentsManager, logger);
40
42
  var updateWorker = new UpdaterWorker(jobId, experimentsManager, logger);
41
43
  var worker = new RunWorker(jobId, apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
42
- await worker.RunAsync(jobPath, repoContentsPath, baseCommitSha, outputPath);
43
- }, JobPathOption, RepoContentsPathOption, ApiUrlOption, JobIdOption, OutputPathOption, BaseCommitShaOption);
44
+ await worker.RunAsync(jobPath, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, outputPath);
45
+ }, JobPathOption, RepoContentsPathOption, CaseInsensitiveRepoContentsPathOption, ApiUrlOption, JobIdOption, OutputPathOption, BaseCommitShaOption);
44
46
 
45
47
  return command;
46
48
  }
@@ -12,6 +12,7 @@ public class ModifiedFilesTracker
12
12
  {
13
13
  public readonly DirectoryInfo RepoContentsPath;
14
14
  private WorkspaceDiscoveryResult? _currentDiscoveryResult = null;
15
+ private readonly ILogger _logger;
15
16
 
16
17
  private readonly Dictionary<string, string> _originalDependencyFileContents = [];
17
18
  private readonly Dictionary<string, EOLType> _originalDependencyFileEOFs = [];
@@ -22,9 +23,10 @@ public class ModifiedFilesTracker
22
23
  //public IReadOnlyDictionary<string, EOLType> OriginalDependencyFileEOFs => _originalDependencyFileEOFs;
23
24
  public IReadOnlyDictionary<string, bool> OriginalDependencyFileBOMs => _originalDependencyFileBOMs;
24
25
 
25
- public ModifiedFilesTracker(DirectoryInfo repoContentsPath)
26
+ public ModifiedFilesTracker(DirectoryInfo repoContentsPath, ILogger logger)
26
27
  {
27
28
  RepoContentsPath = repoContentsPath;
29
+ _logger = logger;
28
30
  }
29
31
 
30
32
  public async Task StartTrackingAsync(WorkspaceDiscoveryResult discoveryResult)
@@ -39,7 +41,7 @@ public class ModifiedFilesTracker
39
41
  // track original contents for later handling
40
42
  async Task TrackOriginalContentsAsync(string directory, string fileName)
41
43
  {
42
- var repoFullPath = Path.Join(directory, fileName).FullyNormalizedRootedPath();
44
+ var repoFullPath = CorrectRepoRelativePathCasing(directory, fileName);
43
45
  var localFullPath = Path.Join(RepoContentsPath.FullName, repoFullPath);
44
46
  var content = await File.ReadAllTextAsync(localFullPath);
45
47
  var rawContent = await File.ReadAllBytesAsync(localFullPath);
@@ -80,7 +82,7 @@ public class ModifiedFilesTracker
80
82
  var updatedDependencyFiles = new Dictionary<string, DependencyFile>();
81
83
  async Task AddUpdatedFileIfDifferentAsync(string directory, string fileName)
82
84
  {
83
- var repoFullPath = Path.Join(directory, fileName).FullyNormalizedRootedPath();
85
+ var repoFullPath = CorrectRepoRelativePathCasing(directory, fileName);
84
86
  var localFullPath = Path.GetFullPath(Path.Join(RepoContentsPath.FullName, repoFullPath));
85
87
  var originalContent = _originalDependencyFileContents[repoFullPath];
86
88
  var updatedContent = await File.ReadAllTextAsync(localFullPath);
@@ -134,6 +136,13 @@ public class ModifiedFilesTracker
134
136
  return updatedDependencyFileList;
135
137
  }
136
138
 
139
+ private string CorrectRepoRelativePathCasing(string directory, string fileName)
140
+ {
141
+ var repoFullPath = Path.Join(directory, fileName).FullyNormalizedRootedPath();
142
+ var correctedRepoFullPath = RunWorker.EnsureCorrectFileCasing(repoFullPath, RepoContentsPath.FullName, _logger);
143
+ return correctedRepoFullPath;
144
+ }
145
+
137
146
  public static ImmutableArray<DependencyFile> MergeUpdatedFileSet(ImmutableArray<DependencyFile> setA, ImmutableArray<DependencyFile> setB)
138
147
  {
139
148
  static string GetFullName(DependencyFile df) => Path.Join(df.Directory, df.Name).NormalizePathToUnix();
@@ -44,12 +44,12 @@ public class RunWorker
44
44
  _updaterWorker = updateWorker;
45
45
  }
46
46
 
47
- public async Task RunAsync(FileInfo jobFilePath, DirectoryInfo repoContentsPath, string baseCommitSha, FileInfo outputFilePath)
47
+ public async Task RunAsync(FileInfo jobFilePath, DirectoryInfo repoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, FileInfo outputFilePath)
48
48
  {
49
49
  var jobFileContent = await File.ReadAllTextAsync(jobFilePath.FullName);
50
50
  var jobWrapper = Deserialize(jobFileContent);
51
51
  var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
52
- var result = await RunAsync(jobWrapper.Job, repoContentsPath, baseCommitSha, experimentsManager);
52
+ var result = await RunAsync(jobWrapper.Job, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, experimentsManager);
53
53
  if (experimentsManager.UseLegacyUpdateHandler)
54
54
  {
55
55
  // only the legacy handler writes this file
@@ -58,16 +58,16 @@ public class RunWorker
58
58
  }
59
59
  }
60
60
 
61
- public async Task<RunResult> RunAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
61
+ public async Task<RunResult> RunAsync(Job job, DirectoryInfo repoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
62
62
  {
63
63
  RunResult result;
64
64
  if (experimentsManager.UseLegacyUpdateHandler)
65
65
  {
66
- result = await RunWithErrorHandlingAsync(job, repoContentsPath, baseCommitSha, experimentsManager);
66
+ result = await RunWithErrorHandlingAsync(job, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, experimentsManager);
67
67
  }
68
68
  else
69
69
  {
70
- await RunScenarioHandlersWithErrorHandlingAsync(job, repoContentsPath, baseCommitSha, experimentsManager);
70
+ await RunScenarioHandlersWithErrorHandlingAsync(job, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, experimentsManager);
71
71
 
72
72
  // the group updater doesn't return this, so we provide an empty object
73
73
  result = new RunResult()
@@ -92,7 +92,7 @@ public class RunWorker
92
92
  public static IUpdateHandler GetUpdateHandler(Job job) =>
93
93
  UpdateHandlers.FirstOrDefault(h => h.CanHandle(job)) ?? throw new InvalidOperationException("Unable to find appropriate update handler.");
94
94
 
95
- private async Task RunScenarioHandlersWithErrorHandlingAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
95
+ private async Task RunScenarioHandlersWithErrorHandlingAsync(Job job, DirectoryInfo repoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
96
96
  {
97
97
  JobErrorBase? error = null;
98
98
 
@@ -100,7 +100,7 @@ public class RunWorker
100
100
  {
101
101
  var handler = GetUpdateHandler(job);
102
102
  _logger.Info($"Starting update job of type {handler.TagName}");
103
- await handler.HandleAsync(job, repoContentsPath, baseCommitSha, _discoveryWorker, _analyzeWorker, _updaterWorker, _apiHandler, experimentsManager, _logger);
103
+ await handler.HandleAsync(job, repoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, _discoveryWorker, _analyzeWorker, _updaterWorker, _apiHandler, experimentsManager, _logger);
104
104
  }
105
105
  catch (Exception ex)
106
106
  {
@@ -115,7 +115,7 @@ public class RunWorker
115
115
  await _apiHandler.MarkAsProcessed(new(baseCommitSha));
116
116
  }
117
117
 
118
- private async Task<RunResult> RunWithErrorHandlingAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
118
+ private async Task<RunResult> RunWithErrorHandlingAsync(Job job, DirectoryInfo repoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, ExperimentsManager experimentsManager)
119
119
  {
120
120
  JobErrorBase? error = null;
121
121
  var currentDirectory = repoContentsPath.FullName; // used for error reporting below
@@ -134,7 +134,7 @@ public class RunWorker
134
134
  {
135
135
  var localPath = PathHelper.JoinPath(repoContentsPath.FullName, directory);
136
136
  currentDirectory = localPath;
137
- var result = await RunForDirectory(job, repoContentsPath, directory, baseCommitSha, experimentsManager);
137
+ var result = await RunForDirectory(job, repoContentsPath, caseInsensitiveRepoContentsPath, directory, baseCommitSha, experimentsManager);
138
138
  foreach (var dependencyFile in result.Base64DependencyFiles)
139
139
  {
140
140
  var uniqueKey = Path.GetFullPath(Path.Join(dependencyFile.Directory, dependencyFile.Name)).NormalizePathToUnix().EnsurePrefix("/");
@@ -163,8 +163,9 @@ public class RunWorker
163
163
  return runResult;
164
164
  }
165
165
 
166
- private async Task<RunResult> RunForDirectory(Job job, DirectoryInfo repoContentsPath, string repoDirectory, string baseCommitSha, ExperimentsManager experimentsManager)
166
+ private async Task<RunResult> RunForDirectory(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string repoDirectory, string baseCommitSha, ExperimentsManager experimentsManager)
167
167
  {
168
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
168
169
  var discoveryResult = await _discoveryWorker.RunAsync(repoContentsPath.FullName, repoDirectory);
169
170
  _logger.ReportDiscovery(discoveryResult);
170
171
 
@@ -180,7 +181,7 @@ public class RunWorker
180
181
  }
181
182
 
182
183
  // report dependencies
183
- var discoveredUpdatedDependencies = GetUpdatedDependencyListFromDiscovery(discoveryResult);
184
+ var discoveredUpdatedDependencies = GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, _logger);
184
185
  await _apiHandler.UpdateDependencyList(discoveredUpdatedDependencies);
185
186
 
186
187
  var incrementMetric = GetIncrementMetric(job);
@@ -190,7 +191,7 @@ public class RunWorker
190
191
  var actualUpdatedDependencies = new List<ReportedDependency>();
191
192
 
192
193
  // track original contents for later handling
193
- var tracker = new ModifiedFilesTracker(repoContentsPath);
194
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, _logger);
194
195
  await tracker.StartTrackingAsync(discoveryResult);
195
196
 
196
197
  // do update
@@ -708,7 +709,28 @@ public class RunWorker
708
709
  return dependencyInfo;
709
710
  }
710
711
 
711
- internal static UpdatedDependencyList GetUpdatedDependencyListFromDiscovery(WorkspaceDiscoveryResult discoveryResult)
712
+ internal static string EnsureCorrectFileCasing(string repoRelativePath, string repoRoot, ILogger logger)
713
+ {
714
+ var fullPath = Path.Join(repoRoot, repoRelativePath);
715
+ var resolvedNames = PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(fullPath, repoRoot);
716
+ if (resolvedNames is null)
717
+ {
718
+ logger.Info($"Unable to resolve correct case for file [{repoRelativePath}]; returning original.");
719
+ return repoRelativePath;
720
+ }
721
+
722
+ if (resolvedNames.Count != 1)
723
+ {
724
+ logger.Info($"Expected exactly 1 normalized file path for [{repoRelativePath}], instead found {resolvedNames.Count}: {string.Join(", ", resolvedNames)}");
725
+ return repoRelativePath;
726
+ }
727
+
728
+ var resolvedName = resolvedNames[0];
729
+ var relativeResolvedName = Path.GetRelativePath(repoRoot, resolvedName).FullyNormalizedRootedPath();
730
+ return relativeResolvedName;
731
+ }
732
+
733
+ internal static UpdatedDependencyList GetUpdatedDependencyListFromDiscovery(WorkspaceDiscoveryResult discoveryResult, string repoRoot, ILogger logger)
712
734
  {
713
735
  string GetFullRepoPath(string path)
714
736
  {
@@ -793,6 +815,7 @@ public class RunWorker
793
815
  var dependencyFiles = discoveryResult.Projects
794
816
  .Select(p => GetFullRepoPath(p.FilePath))
795
817
  .Concat(auxiliaryFiles)
818
+ .Select(p => EnsureCorrectFileCasing(p, repoRoot, logger))
796
819
  .Distinct()
797
820
  .OrderBy(p => p)
798
821
  .ToArray();
@@ -27,8 +27,9 @@ internal class CreateSecurityUpdatePullRequestHandler : IUpdateHandler
27
27
  return job.SecurityUpdatesOnly;
28
28
  }
29
29
 
30
- public async Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
30
+ public async Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
31
31
  {
32
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
32
33
  var jobDependencies = job.Dependencies.ToHashSet(StringComparer.OrdinalIgnoreCase);
33
34
  foreach (var directory in job.GetAllDirectories())
34
35
  {
@@ -40,7 +41,7 @@ internal class CreateSecurityUpdatePullRequestHandler : IUpdateHandler
40
41
  return;
41
42
  }
42
43
 
43
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
44
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
44
45
  await apiHandler.UpdateDependencyList(updatedDependencyList);
45
46
  await this.ReportUpdaterStarted(apiHandler);
46
47
 
@@ -60,7 +61,7 @@ internal class CreateSecurityUpdatePullRequestHandler : IUpdateHandler
60
61
 
61
62
  logger.Info($"Updating dependencies: {string.Join(", ", groupedUpdateOperationsToPerform.Select(g => g.Key).Distinct().OrderBy(d => d, StringComparer.OrdinalIgnoreCase))}");
62
63
 
63
- var tracker = new ModifiedFilesTracker(repoContentsPath);
64
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
64
65
  await tracker.StartTrackingAsync(discoveryResult);
65
66
  foreach (var dependencyGroupToUpdate in groupedUpdateOperationsToPerform)
66
67
  {
@@ -38,23 +38,24 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
38
38
  return true;
39
39
  }
40
40
 
41
- public async Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
41
+ public async Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
42
42
  {
43
43
  // group update, do all directories and merge
44
44
  // ungrouped update, do each dir separate
45
45
  await this.ReportUpdaterStarted(apiHandler);
46
46
  if (job.DependencyGroups.Length > 0)
47
47
  {
48
- await RunGroupedDependencyUpdates(job, repoContentsPath, baseCommitSha, discoveryWorker, analyzeWorker, updaterWorker, apiHandler, experimentsManager, logger);
48
+ await RunGroupedDependencyUpdates(job, originalRepoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, discoveryWorker, analyzeWorker, updaterWorker, apiHandler, experimentsManager, logger);
49
49
  }
50
50
  else
51
51
  {
52
- await RunUngroupedDependencyUpdates(job, repoContentsPath, baseCommitSha, discoveryWorker, analyzeWorker, updaterWorker, apiHandler, experimentsManager, logger);
52
+ await RunUngroupedDependencyUpdates(job, originalRepoContentsPath, caseInsensitiveRepoContentsPath, baseCommitSha, discoveryWorker, analyzeWorker, updaterWorker, apiHandler, experimentsManager, logger);
53
53
  }
54
54
  }
55
55
 
56
- private async Task RunGroupedDependencyUpdates(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
56
+ private async Task RunGroupedDependencyUpdates(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
57
57
  {
58
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
58
59
  foreach (var group in job.DependencyGroups)
59
60
  {
60
61
  var existingGroupPr = job.ExistingGroupPullRequests.FirstOrDefault(pr => pr.DependencyGroupName == group.Name);
@@ -79,10 +80,10 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
79
80
  return;
80
81
  }
81
82
 
82
- var tracker = new ModifiedFilesTracker(repoContentsPath);
83
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
83
84
  await tracker.StartTrackingAsync(discoveryResult);
84
85
 
85
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
86
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
86
87
  await apiHandler.UpdateDependencyList(updatedDependencyList);
87
88
 
88
89
  var updateOperationsToPerform = RunWorker.GetUpdateOperations(discoveryResult).ToArray();
@@ -169,8 +170,9 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
169
170
  }
170
171
  }
171
172
 
172
- private async Task RunUngroupedDependencyUpdates(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
173
+ private async Task RunUngroupedDependencyUpdates(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
173
174
  {
175
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
174
176
  foreach (var directory in job.GetAllDirectories())
175
177
  {
176
178
  var discoveryResult = await discoveryWorker.RunAsync(repoContentsPath.FullName, directory);
@@ -181,10 +183,10 @@ internal class GroupUpdateAllVersionsHandler : IUpdateHandler
181
183
  return;
182
184
  }
183
185
 
184
- var tracker = new ModifiedFilesTracker(repoContentsPath);
186
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
185
187
  await tracker.StartTrackingAsync(discoveryResult);
186
188
 
187
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
189
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
188
190
  await apiHandler.UpdateDependencyList(updatedDependencyList);
189
191
 
190
192
  var updateOperationsPerformed = new List<UpdateOperationBase>();
@@ -6,7 +6,7 @@ public interface IUpdateHandler
6
6
  {
7
7
  string TagName { get; }
8
8
  bool CanHandle(Job job);
9
- Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger);
9
+ Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger);
10
10
  }
11
11
 
12
12
  public static class IUpdateHandlerExtensions
@@ -44,8 +44,9 @@ internal class RefreshGroupUpdatePullRequestHandler : IUpdateHandler
44
44
  return job.UpdatingAPullRequest;
45
45
  }
46
46
 
47
- public async Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
47
+ public async Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
48
48
  {
49
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
49
50
  if (job.DependencyGroupToRefresh is null)
50
51
  {
51
52
  throw new InvalidOperationException($"{nameof(job.DependencyGroupToRefresh)} must be non-null.");
@@ -71,7 +72,7 @@ internal class RefreshGroupUpdatePullRequestHandler : IUpdateHandler
71
72
  return;
72
73
  }
73
74
 
74
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
75
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
75
76
  await apiHandler.UpdateDependencyList(updatedDependencyList);
76
77
  await this.ReportUpdaterStarted(apiHandler);
77
78
 
@@ -85,7 +86,7 @@ internal class RefreshGroupUpdatePullRequestHandler : IUpdateHandler
85
86
  .ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase);
86
87
  logger.Info($"Updating dependencies: {string.Join(", ", groupedUpdateOperationsToPerform.Select(g => g.Key).Distinct().OrderBy(d => d, StringComparer.OrdinalIgnoreCase))}");
87
88
 
88
- var tracker = new ModifiedFilesTracker(repoContentsPath);
89
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
89
90
  await tracker.StartTrackingAsync(discoveryResult);
90
91
  foreach (var dependencyGroupToUpdate in groupedUpdateOperationsToPerform)
91
92
  {
@@ -26,8 +26,9 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
26
26
  return job.UpdatingAPullRequest;
27
27
  }
28
28
 
29
- public async Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
29
+ public async Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
30
30
  {
31
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
31
32
  var jobDependencies = job.Dependencies.ToHashSet(StringComparer.OrdinalIgnoreCase);
32
33
  foreach (var directory in job.GetAllDirectories())
33
34
  {
@@ -40,7 +41,7 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
40
41
  return;
41
42
  }
42
43
 
43
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
44
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
44
45
  await apiHandler.UpdateDependencyList(updatedDependencyList);
45
46
  await this.ReportUpdaterStarted(apiHandler);
46
47
 
@@ -74,7 +75,7 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
74
75
  continue;
75
76
  }
76
77
 
77
- var tracker = new ModifiedFilesTracker(repoContentsPath);
78
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
78
79
  await tracker.StartTrackingAsync(discoveryResult);
79
80
  foreach (var dependencyGroupToUpdate in groupedUpdateOperationsToPerform)
80
81
  {
@@ -85,7 +86,7 @@ internal class RefreshSecurityUpdatePullRequestHandler : IUpdateHandler
85
86
  .Where(set => set.Item3.IsVulnerable)
86
87
  .ToArray();
87
88
 
88
- if (vulnerableDependenciesToUpdate.Length < dependencyGroupToUpdate.Value.Length)
89
+ if (vulnerableDependenciesToUpdate.Length == 0)
89
90
  {
90
91
  var close = ClosePullRequest.WithUpToDate(job);
91
92
  logger.Info(close.GetReport());
@@ -26,8 +26,9 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
26
26
  return job.UpdatingAPullRequest;
27
27
  }
28
28
 
29
- public async Task HandleAsync(Job job, DirectoryInfo repoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
29
+ public async Task HandleAsync(Job job, DirectoryInfo originalRepoContentsPath, DirectoryInfo? caseInsensitiveRepoContentsPath, string baseCommitSha, IDiscoveryWorker discoveryWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updaterWorker, IApiHandler apiHandler, ExperimentsManager experimentsManager, ILogger logger)
30
30
  {
31
+ var repoContentsPath = caseInsensitiveRepoContentsPath ?? originalRepoContentsPath;
31
32
  var jobDependencies = job.Dependencies.ToHashSet(StringComparer.OrdinalIgnoreCase);
32
33
  foreach (var directory in job.GetAllDirectories())
33
34
  {
@@ -39,7 +40,7 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
39
40
  return;
40
41
  }
41
42
 
42
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult);
43
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discoveryResult, originalRepoContentsPath.FullName, logger);
43
44
  await apiHandler.UpdateDependencyList(updatedDependencyList);
44
45
  await this.ReportUpdaterStarted(apiHandler);
45
46
 
@@ -73,12 +74,12 @@ internal class RefreshVersionUpdatePullRequestHandler : IUpdateHandler
73
74
 
74
75
  logger.Info($"Updating dependencies: {string.Join(", ", relevantUpdateOperationsToPerform.Select(g => g.Key).Distinct().OrderBy(d => d, StringComparer.OrdinalIgnoreCase))}");
75
76
 
76
- var tracker = new ModifiedFilesTracker(repoContentsPath);
77
+ var tracker = new ModifiedFilesTracker(originalRepoContentsPath, logger);
77
78
  await tracker.StartTrackingAsync(discoveryResult);
78
- foreach (var dependencyUpdatesToPeform in relevantUpdateOperationsToPerform)
79
+ foreach (var dependencyUpdatesToPerform in relevantUpdateOperationsToPerform)
79
80
  {
80
- var dependencyName = dependencyUpdatesToPeform.Key;
81
- var dependencyInfosToUpdate = dependencyUpdatesToPeform.Value
81
+ var dependencyName = dependencyUpdatesToPerform.Key;
82
+ var dependencyInfosToUpdate = dependencyUpdatesToPerform.Value
82
83
  .Where(o => !job.IsDependencyIgnoredByNameOnly(o.Dependency.Name))
83
84
  .Select(o => (o.ProjectPath, o.Dependency, RunWorker.GetDependencyInfo(job, o.Dependency)))
84
85
  .ToArray();
@@ -561,6 +561,16 @@ public class MiscellaneousTests
561
561
  Assert.Equal(expectedUpdateOperations, actualUpdateOperations);
562
562
  }
563
563
 
564
+ [Theory]
565
+ [InlineData("/src/project.csproj", "/src/project.csproj")] // correct casing
566
+ [InlineData("/src/project.csproj", "/SRC/PROJECT.csproj")] // incorrect casing
567
+ public async Task EnsureCorrectFileCasing(string filePathOnDisk, string candidatePath)
568
+ {
569
+ using var tempDir = await TemporaryDirectory.CreateWithContentsAsync((filePathOnDisk, "contents unimportant"));
570
+ var actualRepoRelativePath = RunWorker.EnsureCorrectFileCasing(candidatePath, tempDir.DirectoryPath, new TestLogger());
571
+ Assert.Equal(filePathOnDisk, actualRepoRelativePath);
572
+ }
573
+
564
574
  public static IEnumerable<object[]> GetUpdateOperationsData()
565
575
  {
566
576
  static ProjectDiscoveryResult GetProjectDiscovery(string filePath, params string[] dependencyNames)
@@ -3523,7 +3523,7 @@ public class RunWorkerTests
3523
3523
 
3524
3524
  var worker = new RunWorker(jobId, testApiHandler, discoveryWorker, analyzeWorker, updaterWorker, logger);
3525
3525
  var repoContentsPathDirectoryInfo = new DirectoryInfo(tempDirectory.DirectoryPath);
3526
- var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA", experimentsManager);
3526
+ var actualResult = await worker.RunAsync(job, repoContentsPathDirectoryInfo, repoContentsPathDirectoryInfo, "TEST-COMMIT-SHA", experimentsManager);
3527
3527
  var actualApiMessages = testApiHandler.ReceivedMessages
3528
3528
  .Select(m =>
3529
3529
  {
@@ -544,6 +544,141 @@ public class RefreshSecurityUpdatePullRequestHandlerTests : UpdateHandlersTestsB
544
544
  );
545
545
  }
546
546
 
547
+ [Fact]
548
+ public async Task GeneratesUpdatePullRequest_OneDependencyUpToDate_OneOtherVulnerable()
549
+ {
550
+ await TestAsync(
551
+ job: new Job()
552
+ {
553
+ Dependencies = ["Some.Dependency"],
554
+ ExistingPullRequests = [
555
+ new() { Dependencies = [new() { DependencyName = "Some.Dependency", DependencyVersion = NuGetVersion.Parse("2.0.0") }] }
556
+ ],
557
+ SecurityAdvisories = [
558
+ new() { DependencyName = "Some.Dependency", AffectedVersions = [Requirement.Parse(">= 1.0.0, < 2.0.0")] }
559
+ ],
560
+ SecurityUpdatesOnly = true,
561
+ Source = CreateJobSource("/src"),
562
+ UpdatingAPullRequest = true,
563
+ },
564
+ files: [
565
+ ("src/project1.csproj", "initial contents"),
566
+ ("src/project2.csproj", "initial contents")
567
+ ],
568
+ discoveryWorker: TestDiscoveryWorker.FromResults(
569
+ ("/src", new WorkspaceDiscoveryResult()
570
+ {
571
+ Path = "/src",
572
+ Projects = [
573
+ new()
574
+ {
575
+ FilePath = "project1.csproj",
576
+ Dependencies = [new("Some.Dependency", "2.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"])],
577
+ ImportedFiles = [],
578
+ AdditionalFiles = [],
579
+ },
580
+ new()
581
+ {
582
+ FilePath = "project2.csproj",
583
+ Dependencies = [new("Some.Dependency", "1.0.0", DependencyType.PackageReference, TargetFrameworks: ["net9.0"])],
584
+ ImportedFiles = [],
585
+ AdditionalFiles = [],
586
+ }
587
+ ]
588
+ })
589
+ ),
590
+ analyzeWorker: new TestAnalyzeWorker(input =>
591
+ {
592
+ var repoRoot = input.Item1;
593
+ var discovery = input.Item2;
594
+ var dependencyInfo = input.Item3;
595
+ if (dependencyInfo.Name != "Some.Dependency")
596
+ {
597
+ throw new NotImplementedException($"Test didn't expect to update dependency {dependencyInfo.Name}");
598
+ }
599
+
600
+ if (dependencyInfo.Version != "1.0.0")
601
+ {
602
+ throw new NotImplementedException($"Only expected to update version 1.0.0, but found {dependencyInfo.Version}");
603
+ }
604
+
605
+ return Task.FromResult(new AnalysisResult()
606
+ {
607
+ CanUpdate = true,
608
+ UpdatedVersion = "2.0.0",
609
+ UpdatedDependencies = [],
610
+ });
611
+ }),
612
+ updaterWorker: new TestUpdaterWorker(async input =>
613
+ {
614
+ var repoRoot = input.Item1;
615
+ var workspacePath = input.Item2;
616
+ var dependencyName = input.Item3;
617
+ var previousVersion = input.Item4;
618
+ var newVersion = input.Item5;
619
+ var isTransitive = input.Item6;
620
+
621
+ await File.WriteAllTextAsync(Path.Join(repoRoot, workspacePath), "updated contents");
622
+
623
+ return new UpdateOperationResult()
624
+ {
625
+ UpdateOperations = [new DirectUpdate() { DependencyName = "Some.Dependency", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/src/project2.csproj"] }],
626
+ };
627
+ }),
628
+ expectedUpdateHandler: RefreshSecurityUpdatePullRequestHandler.Instance,
629
+ expectedApiMessages: [
630
+ new UpdatedDependencyList()
631
+ {
632
+ Dependencies = [
633
+ new()
634
+ {
635
+ Name = "Some.Dependency",
636
+ Version = "2.0.0",
637
+ Requirements = [
638
+ new() { Requirement = "2.0.0", File = "/src/project1.csproj", Groups = ["dependencies"] },
639
+ ],
640
+ },
641
+ new()
642
+ {
643
+ Name = "Some.Dependency",
644
+ Version = "1.0.0",
645
+ Requirements = [
646
+ new() { Requirement = "1.0.0", File = "/src/project2.csproj", Groups = ["dependencies"] },
647
+ ],
648
+ },
649
+ ],
650
+ DependencyFiles = ["/src/project1.csproj", "/src/project2.csproj"],
651
+ },
652
+ new IncrementMetric()
653
+ {
654
+ Metric = "updater.started",
655
+ Tags = new()
656
+ {
657
+ ["operation"] = "update_security_pr",
658
+ }
659
+ },
660
+ new UpdatePullRequest()
661
+ {
662
+ DependencyNames = ["Some.Dependency"],
663
+ DependencyGroup = null,
664
+ UpdatedDependencyFiles = [
665
+ new()
666
+ {
667
+ Directory = "/src",
668
+ Name = "project2.csproj",
669
+ Content = "updated contents",
670
+ }
671
+ ],
672
+ BaseCommitSha = "TEST-COMMIT-SHA",
673
+ CommitMessage = RunWorkerTests.TestPullRequestCommitMessage,
674
+ PrTitle = RunWorkerTests.TestPullRequestTitle,
675
+ PrBody = RunWorkerTests.TestPullRequestBody,
676
+ },
677
+ new MarkAsProcessed("TEST-COMMIT-SHA"),
678
+ ]
679
+ );
680
+ }
681
+
547
682
  [Fact]
548
683
  public async Task GeneratesClosePullRequest_DependenciesRemoved()
549
684
  {
@@ -89,7 +89,7 @@ public class UpdatedDependencyListTests
89
89
  ]
90
90
  }
91
91
  };
92
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discovery);
92
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discovery, repoRoot: temp.DirectoryPath, new TestLogger());
93
93
  var expectedDependencyList = new UpdatedDependencyList()
94
94
  {
95
95
  Dependencies =
@@ -213,7 +213,7 @@ public class UpdatedDependencyListTests
213
213
  };
214
214
 
215
215
  // act
216
- var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discovery);
216
+ var updatedDependencyList = RunWorker.GetUpdatedDependencyListFromDiscovery(discovery, repoRoot: tempDir.DirectoryPath, new TestLogger());
217
217
  var expectedDependencyList = new UpdatedDependencyList()
218
218
  {
219
219
  Dependencies = [],
@@ -29,7 +29,13 @@ public sealed class TemporaryDirectory : IDisposable
29
29
  public void Dispose()
30
30
  {
31
31
  _environment.Dispose();
32
- Directory.Delete(_rootDirectory, true);
32
+ try
33
+ {
34
+ Directory.Delete(_rootDirectory, true);
35
+ }
36
+ catch
37
+ {
38
+ }
33
39
  }
34
40
 
35
41
  public async Task<TestFile[]> ReadFileContentsAsync(HashSet<string> filePaths)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-nuget
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.319.1
4
+ version: 0.320.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.319.1
18
+ version: 0.320.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.319.1
25
+ version: 0.320.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rubyzip
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -580,7 +580,7 @@ licenses:
580
580
  - MIT
581
581
  metadata:
582
582
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
583
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.319.1
583
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.320.0
584
584
  rdoc_options: []
585
585
  require_paths:
586
586
  - lib