dependabot-nuget 0.254.0 → 0.255.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: c86cede5ca7a7c4b299c2ec8562eedac9a80f12b3d3087be4270b37f21a41861
4
- data.tar.gz: 8ea3c1c970f4606fed97261c70ebd493645037bdd635ab4368e38956ab1d17f9
3
+ metadata.gz: 1feb135ca2ebd58b0c7c96df96c8e3ad30b9f0dccd17b58c99d5670fb3ebf57b
4
+ data.tar.gz: 55e7d7d46b36738f198057ef6c83ea3f194d25623a65d6e719bf1fc5a6f44eb5
5
5
  SHA512:
6
- metadata.gz: 26ee476b689434e34f322153afc7f825e15555bf7c7061014e4b58bdb5962699226942ac64797d436d38b5aed780d4e57d818bd7ef64f6ed6e1961984129139e
7
- data.tar.gz: 28e0103dbcb88c4fabb9352a51891f0f69a0533959c7fe052c8b3396c00fcabfe33ae1d3cb28347ffc44f01464c8517397a11783c0c88a66e4bd04fd9f5b37e3
6
+ metadata.gz: 13a3eae5d94249eba9a08cbe55c4c36ca3116881550e76a518e789bc7fe7e8ee6d13fcf910a25de365a2e00af96ce586a7f169a52cc1a6b2fc5fbd594d4b8ba5
7
+ data.tar.gz: 318e0d0cb22917a6198cd0c0821dba4a2456c23a4378f9387d645c205886cac7078119983772806313427e3ceaf52ec72f64f11f134ddb010b2e59e0bf8a2a36
@@ -19,6 +19,11 @@
19
19
 
20
20
  <ItemGroup>
21
21
  <Compile Include="$(NuGetSourceLocation)\src\NuGet.Core\NuGet.Packaging\**\*.cs" />
22
+ <!--
23
+ The `PackageFolderReader.GetFiles()` method is case-sensitive which doesn't work for some scenarios so this
24
+ directory contains a copy of that file with that method with a case-insensitive patch.
25
+ -->
26
+ <Compile Remove="$(NuGetSourceLocation)\src\NuGet.Core\NuGet.Packaging\PackageFolderReader.cs" />
22
27
  </ItemGroup>
23
28
 
24
29
  <ItemGroup>
@@ -0,0 +1,270 @@
1
+ // Copyright (c) .NET Foundation. All rights reserved.
2
+ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
+
4
+ using System;
5
+ using System.Collections.Generic;
6
+ using System.Globalization;
7
+ using System.IO;
8
+ using System.Linq;
9
+ using System.Text;
10
+ using System.Threading;
11
+ using System.Threading.Tasks;
12
+
13
+ using NuGet.Common;
14
+ using NuGet.Frameworks;
15
+ using NuGet.Packaging.Core;
16
+ using NuGet.Packaging.Signing;
17
+
18
+ namespace NuGet.Packaging
19
+ {
20
+ /// <summary>
21
+ /// Reads an unzipped nupkg folder.
22
+ /// </summary>
23
+ public class PackageFolderReader : PackageReaderBase
24
+ {
25
+ private readonly DirectoryInfo _root;
26
+
27
+ /// <summary>
28
+ /// Package folder reader
29
+ /// </summary>
30
+ public PackageFolderReader(string folderPath)
31
+ : this(folderPath, DefaultFrameworkNameProvider.Instance, DefaultCompatibilityProvider.Instance)
32
+ {
33
+ }
34
+
35
+ /// <summary>
36
+ /// Package folder reader
37
+ /// </summary>
38
+ /// <param name="folder">root directory of an extracted nupkg</param>
39
+ public PackageFolderReader(DirectoryInfo folder)
40
+ : this(folder, DefaultFrameworkNameProvider.Instance, DefaultCompatibilityProvider.Instance)
41
+ {
42
+ }
43
+
44
+ /// <summary>
45
+ /// Package folder reader
46
+ /// </summary>
47
+ /// <param name="folderPath">root directory of an extracted nupkg</param>
48
+ /// <param name="frameworkProvider">framework mappings</param>
49
+ /// <param name="compatibilityProvider">framework compatibility provider</param>
50
+ public PackageFolderReader(string folderPath, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
51
+ : this(new DirectoryInfo(folderPath), frameworkProvider, compatibilityProvider)
52
+ {
53
+ }
54
+
55
+ /// <summary>
56
+ /// Package folder reader
57
+ /// </summary>
58
+ /// <param name="folder">root directory of an extracted nupkg</param>
59
+ /// <param name="frameworkProvider">framework mappings</param>
60
+ /// <param name="compatibilityProvider">framework compatibility provider</param>
61
+ public PackageFolderReader(DirectoryInfo folder, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
62
+ : base(frameworkProvider, compatibilityProvider)
63
+ {
64
+ _root = folder;
65
+ }
66
+
67
+ public override string GetNuspecFile()
68
+ {
69
+ // This needs to be explicitly case insensitive in order to work on XPlat, since GetFiles is normally case sensitive on non-Windows
70
+ var nuspecFiles = _root.GetFiles("*.*", SearchOption.TopDirectoryOnly).Where(f => f.Name.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase)).ToArray();
71
+
72
+ if (nuspecFiles.Length == 0)
73
+ {
74
+ var message = new StringBuilder();
75
+ message.Append(Strings.Error_MissingNuspecFile);
76
+ message.AppendFormat(CultureInfo.CurrentCulture, Strings.Message_Path, _root.FullName);
77
+ throw new PackagingException(NuGetLogCode.NU5037, message.ToString());
78
+ }
79
+ else if (nuspecFiles.Length > 1)
80
+ {
81
+ throw new PackagingException(Strings.MultipleNuspecFiles);
82
+ }
83
+
84
+ return nuspecFiles[0].FullName;
85
+ }
86
+
87
+ /// <summary>
88
+ /// Opens a local file in read only mode.
89
+ /// </summary>
90
+ public override Stream GetStream(string path)
91
+ {
92
+ return GetFile(path).OpenRead();
93
+ }
94
+
95
+ private FileInfo GetFile(string path)
96
+ {
97
+ var file = new FileInfo(Path.Combine(_root.FullName, path));
98
+
99
+ if (!file.FullName.StartsWith(_root.FullName, StringComparison.OrdinalIgnoreCase))
100
+ {
101
+ // the given path does not appear under the folder root
102
+ throw new FileNotFoundException(path);
103
+ }
104
+
105
+ return file;
106
+ }
107
+
108
+ public override IEnumerable<string> GetFiles()
109
+ {
110
+ // Read all files starting at the root.
111
+ return GetFiles(folder: null);
112
+ }
113
+
114
+ public override IEnumerable<string> GetFiles(string folder)
115
+ {
116
+ // Default to retrieve files and throwing if the root
117
+ // directory is not found.
118
+ var getFiles = true;
119
+ var searchFolder = new DirectoryInfo(_root.FullName);
120
+
121
+ if (!string.IsNullOrEmpty(folder))
122
+ {
123
+ // Search in the sub folder if one was specified
124
+ searchFolder = new DirectoryInfo(Path.Combine(_root.FullName, folder));
125
+
126
+ // For sub folders verify it exists
127
+ // The root is expected to exist and should throw if it does not
128
+ getFiles = searchFolder.Exists;
129
+
130
+ // try a case-insensitive search
131
+ if (!getFiles)
132
+ {
133
+ searchFolder = _root.GetDirectories().FirstOrDefault(d => d.Name.Equals(folder, StringComparison.OrdinalIgnoreCase));
134
+ getFiles = searchFolder?.Exists == true;
135
+ }
136
+ }
137
+
138
+ if (getFiles)
139
+ {
140
+ // Enumerate root folder filtering out nupkg files
141
+ foreach (var file in searchFolder.GetFiles("*", SearchOption.AllDirectories))
142
+ {
143
+ var path = GetRelativePath(_root, file);
144
+
145
+ // disallow nupkgs in the root
146
+ if (!IsFileInRoot(path) || !IsNupkg(path))
147
+ {
148
+ yield return path;
149
+ }
150
+ }
151
+ }
152
+
153
+ yield break;
154
+ }
155
+
156
+ /// <summary>
157
+ /// True if the path does not contain /
158
+ /// </summary>
159
+ private static bool IsFileInRoot(string path)
160
+ {
161
+ #if NETCOREAPP
162
+ return path.IndexOf('/', StringComparison.Ordinal) == -1;
163
+ #else
164
+ return path.IndexOf('/') == -1;
165
+ #endif
166
+ }
167
+
168
+ /// <summary>
169
+ /// True if the path ends with .nupkg
170
+ /// </summary>
171
+ private static bool IsNupkg(string path)
172
+ {
173
+ return path.EndsWith(PackagingCoreConstants.NupkgExtension, StringComparison.OrdinalIgnoreCase) == true;
174
+ }
175
+
176
+ /// <summary>
177
+ /// Build the relative path in the same format that ZipArchive uses
178
+ /// </summary>
179
+ private static string GetRelativePath(DirectoryInfo root, FileInfo file)
180
+ {
181
+ var parents = new Stack<DirectoryInfo>();
182
+
183
+ var parent = file.Directory;
184
+
185
+ while (parent != null
186
+ && !StringComparer.OrdinalIgnoreCase.Equals(parent.FullName, root.FullName))
187
+ {
188
+ parents.Push(parent);
189
+ parent = parent.Parent;
190
+ }
191
+
192
+ if (parent == null)
193
+ {
194
+ // the given file path does not appear under root
195
+ throw new FileNotFoundException(file.FullName);
196
+ }
197
+
198
+ var parts = parents.Select(d => d.Name).Concat(new string[] { file.Name });
199
+
200
+ return string.Join("/", parts);
201
+ }
202
+
203
+ public override IEnumerable<string> CopyFiles(
204
+ string destination,
205
+ IEnumerable<string> packageFiles,
206
+ ExtractPackageFileDelegate extractFile,
207
+ ILogger logger,
208
+ CancellationToken token)
209
+ {
210
+ var filesCopied = new List<string>();
211
+
212
+ foreach (var packageFile in packageFiles)
213
+ {
214
+ token.ThrowIfCancellationRequested();
215
+
216
+ var sourceFile = GetFile(packageFile);
217
+
218
+ var targetPath = Path.Combine(destination, packageFile);
219
+ Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
220
+
221
+ using (var fileStream = sourceFile.OpenRead())
222
+ {
223
+ targetPath = extractFile(sourceFile.FullName, targetPath, fileStream);
224
+ if (targetPath != null)
225
+ {
226
+ ZipArchiveExtensions.UpdateFileTime(targetPath, sourceFile.LastWriteTimeUtc);
227
+ filesCopied.Add(targetPath);
228
+ }
229
+ }
230
+ }
231
+
232
+ return filesCopied;
233
+ }
234
+
235
+ protected override void Dispose(bool disposing)
236
+ {
237
+ // do nothing here
238
+ }
239
+
240
+ public override Task<PrimarySignature> GetPrimarySignatureAsync(CancellationToken token)
241
+ {
242
+ return TaskResult.Null<PrimarySignature>();
243
+ }
244
+
245
+ public override Task<bool> IsSignedAsync(CancellationToken token)
246
+ {
247
+ return TaskResult.False;
248
+ }
249
+
250
+ public override Task ValidateIntegrityAsync(SignatureContent signatureContent, CancellationToken token)
251
+ {
252
+ throw new NotImplementedException();
253
+ }
254
+
255
+ public override Task<byte[]> GetArchiveHashAsync(HashAlgorithmName hashAlgorithm, CancellationToken token)
256
+ {
257
+ throw new NotImplementedException();
258
+ }
259
+
260
+ public override bool CanVerifySignedPackages(SignedPackageVerifierSettings verifierSettings)
261
+ {
262
+ return false;
263
+ }
264
+
265
+ public override string GetContentHash(CancellationToken token, Func<string> GetUnsignedPackageHash = null)
266
+ {
267
+ throw new NotImplementedException();
268
+ }
269
+ }
270
+ }
@@ -214,6 +214,77 @@ public partial class EntryPointTests
214
214
  });
215
215
  }
216
216
 
217
+ [Fact]
218
+ public async Task WithDuplicateDependenciesOfDifferentTypes()
219
+ {
220
+ var projectPath = "path/to/my.csproj";
221
+ var directoryBuildPropsPath = "path/Directory.Build.props";
222
+ await RunAsync(path =>
223
+ [
224
+ "discover",
225
+ "--repo-root",
226
+ path,
227
+ "--workspace",
228
+ path,
229
+ ],
230
+ new[]
231
+ {
232
+ (projectPath, """
233
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
234
+ <PropertyGroup>
235
+ <TargetFramework>net8.0</TargetFramework>
236
+ </PropertyGroup>
237
+ <ItemGroup>
238
+ <PackageReference Include="Newtonsoft.Json" Version="7.0.1" />
239
+ </ItemGroup>
240
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
241
+ </Project>
242
+ """),
243
+ (directoryBuildPropsPath, """
244
+ <Project>
245
+ <ItemGroup Condition="'$(ManagePackageVersionsCentrally)' == 'true'">
246
+ <GlobalPackageReference Include="System.Text.Json" Version="8.0.3" />
247
+ </ItemGroup>
248
+ <ItemGroup Condition="'$(ManagePackageVersionsCentrally)' != 'true'">
249
+ <PackageReference Include="System.Text.Json" Version="8.0.3" />
250
+ </ItemGroup>
251
+ </Project>
252
+ """)
253
+ },
254
+ expectedResult: new()
255
+ {
256
+ FilePath = "",
257
+ Projects = [
258
+ new()
259
+ {
260
+ FilePath = projectPath,
261
+ TargetFrameworks = ["net8.0"],
262
+ ReferencedProjectPaths = [],
263
+ ExpectedDependencyCount = 2,
264
+ Dependencies = [
265
+ new("Newtonsoft.Json", "7.0.1", DependencyType.PackageReference, TargetFrameworks: ["net8.0"], IsDirect: true),
266
+ // $(ManagePackageVersionsCentrally) evaluates false by default, we only get a PackageReference
267
+ new("System.Text.Json", "8.0.3", DependencyType.PackageReference, TargetFrameworks: ["net8.0"])
268
+ ],
269
+ Properties = [
270
+ new("TargetFramework", "net8.0", "path/to/my.csproj"),
271
+ ],
272
+ },
273
+ new()
274
+ {
275
+ FilePath = directoryBuildPropsPath,
276
+ ReferencedProjectPaths = [],
277
+ ExpectedDependencyCount = 2,
278
+ Dependencies = [
279
+ new("System.Text.Json", "8.0.3", DependencyType.PackageReference, IsDirect: true),
280
+ new("System.Text.Json", "8.0.3", DependencyType.GlobalPackageReference, IsDirect: true)
281
+ ],
282
+ Properties = [],
283
+ }
284
+ ]
285
+ });
286
+ }
287
+
217
288
  private static async Task RunAsync(
218
289
  Func<string, string[]> getArgs,
219
290
  TestFile[] initialFiles,
@@ -29,24 +29,25 @@ internal static class SdkProjectDiscovery
29
29
 
30
30
  // The build file dependencies have the correct DependencyType and the TopLevelDependencies have the evaluated version.
31
31
  // Combine them to have the set of dependencies that are directly referenced from the build file.
32
- var fileDependencies = BuildFile.GetDependencies(buildFile)
33
- .ToDictionary(d => d.Name, StringComparer.OrdinalIgnoreCase);
34
- var sdkDependencies = fileDependencies.Values
32
+ var fileDependencies = BuildFile.GetDependencies(buildFile).ToImmutableArray();
33
+ var fileDependencyLookup = fileDependencies
34
+ .ToLookup(d => d.Name, StringComparer.OrdinalIgnoreCase);
35
+ var sdkDependencies = fileDependencies
35
36
  .Where(d => d.Type == DependencyType.MSBuildSdk)
36
37
  .ToImmutableArray();
37
38
  var indirectDependencies = topLevelDependencies
38
- .Where(d => !fileDependencies.ContainsKey(d.Name))
39
+ .Where(d => !fileDependencyLookup.Contains(d.Name))
39
40
  .ToImmutableArray();
40
41
  var directDependencies = topLevelDependencies
41
- .Where(d => fileDependencies.ContainsKey(d.Name))
42
- .Select(d =>
42
+ .Where(d => fileDependencyLookup.Contains(d.Name))
43
+ .SelectMany(d =>
43
44
  {
44
- var dependency = fileDependencies[d.Name];
45
- return d with
45
+ var dependencies = fileDependencyLookup[d.Name];
46
+ return dependencies.Select(fileDependency => d with
46
47
  {
47
- Type = dependency.Type,
48
+ Type = fileDependency.Type,
48
49
  IsDirect = true
49
- };
50
+ });
50
51
  }).ToImmutableArray();
51
52
 
52
53
  if (buildFile.GetFileType() == ProjectBuildFileType.Project)
@@ -1,9 +1,6 @@
1
- using System;
2
- using System.Collections.Generic;
3
- using System.IO;
4
- using System.Linq;
5
1
  using System.Text;
6
- using System.Threading.Tasks;
2
+ using System.Xml.Linq;
3
+ using System.Xml.XPath;
7
4
 
8
5
  using Microsoft.Language.Xml;
9
6
 
@@ -23,7 +20,7 @@ internal static class PackagesConfigUpdater
23
20
  string dependencyName,
24
21
  string previousDependencyVersion,
25
22
  string newDependencyVersion,
26
- bool isTransitive,
23
+ string packagesConfigPath,
27
24
  Logger logger
28
25
  )
29
26
  {
@@ -33,7 +30,7 @@ internal static class PackagesConfigUpdater
33
30
 
34
31
  // ensure local packages directory exists
35
32
  var projectBuildFile = ProjectBuildFile.Open(repoRootPath, projectPath);
36
- var packagesSubDirectory = GetPathToPackagesDirectory(projectBuildFile, dependencyName, previousDependencyVersion);
33
+ var packagesSubDirectory = GetPathToPackagesDirectory(projectBuildFile, dependencyName, previousDependencyVersion, packagesConfigPath);
37
34
  if (packagesSubDirectory is null)
38
35
  {
39
36
  logger.Log($" Project [{projectPath}] does not reference this dependency.");
@@ -43,8 +40,6 @@ internal static class PackagesConfigUpdater
43
40
  logger.Log($" Using packages directory [{packagesSubDirectory}] for project [{projectPath}].");
44
41
 
45
42
  var projectDirectory = Path.GetDirectoryName(projectPath);
46
- var packagesConfigPath = PathHelper.JoinPath(projectDirectory, NuGetHelper.PackagesConfigFileName);
47
-
48
43
  var packagesDirectory = PathHelper.JoinPath(projectDirectory, packagesSubDirectory);
49
44
  Directory.CreateDirectory(packagesDirectory);
50
45
 
@@ -83,7 +78,7 @@ internal static class PackagesConfigUpdater
83
78
 
84
79
  using (new WebApplicationTargetsConditionPatcher(projectPath))
85
80
  {
86
- RunNuget(updateArgs, restoreArgs, packagesDirectory, logger);
81
+ RunNugetUpdate(updateArgs, restoreArgs, projectDirectory ?? packagesDirectory, logger);
87
82
  }
88
83
 
89
84
  projectBuildFile = ProjectBuildFile.Open(repoRootPath, projectPath);
@@ -96,7 +91,7 @@ internal static class PackagesConfigUpdater
96
91
  await projectBuildFile.SaveAsync();
97
92
  }
98
93
 
99
- private static void RunNuget(List<string> updateArgs, List<string> restoreArgs, string packagesDirectory, Logger logger)
94
+ private static void RunNugetUpdate(List<string> updateArgs, List<string> restoreArgs, string projectDirectory, Logger logger)
100
95
  {
101
96
  var outputBuilder = new StringBuilder();
102
97
  var writer = new StringWriter(outputBuilder);
@@ -110,7 +105,7 @@ internal static class PackagesConfigUpdater
110
105
  try
111
106
  {
112
107
 
113
- Environment.CurrentDirectory = packagesDirectory;
108
+ Environment.CurrentDirectory = projectDirectory;
114
109
  var retryingAfterRestore = false;
115
110
 
116
111
  doRestore:
@@ -122,13 +117,21 @@ internal static class PackagesConfigUpdater
122
117
  logger.Log($" Output:\n{fullOutput}");
123
118
  if (result != 0)
124
119
  {
125
- // If the `packages.config` file contains a delisted package, the initial `update` operation will fail
126
- // with the message listed below. The solution is to run `nuget.exe restore ...` and retry.
120
+ // The initial `update` command can fail for several reasons:
121
+ // 1. One possibility is that the `packages.config` file contains a delisted package. If that's the
122
+ // case, `update` will fail with the message "Existing packages must be restored before performing
123
+ // an install or update."
124
+ // 2. Another possibility is that the `update` command fails because the package contains no assemblies
125
+ // and doesn't appear in the cache. The message in this case will be "Could not install package
126
+ // '<name> <version>'...the package does not contain any assembly references or content files that
127
+ // are compatible with that framework.".
128
+ // The solution in all cases is to run `restore` then try the update again.
127
129
  if (!retryingAfterRestore &&
128
- fullOutput.Contains("Existing packages must be restored before performing an install or update."))
130
+ (fullOutput.Contains("Existing packages must be restored before performing an install or update.") ||
131
+ fullOutput.Contains("the package does not contain any assembly references or content files that are compatible with that framework.")))
129
132
  {
130
- logger.Log($" Running NuGet.exe with args: {string.Join(" ", restoreArgs)}");
131
133
  retryingAfterRestore = true;
134
+ logger.Log($" Running NuGet.exe with args: {string.Join(" ", restoreArgs)}");
132
135
  outputBuilder.Clear();
133
136
  var exitCodeAgain = Program.Main(restoreArgs.ToArray());
134
137
  var restoreOutput = outputBuilder.ToString();
@@ -157,7 +160,7 @@ internal static class PackagesConfigUpdater
157
160
  }
158
161
  }
159
162
 
160
- internal static string? GetPathToPackagesDirectory(ProjectBuildFile projectBuildFile, string dependencyName, string dependencyVersion)
163
+ internal static string? GetPathToPackagesDirectory(ProjectBuildFile projectBuildFile, string dependencyName, string dependencyVersion, string packagesConfigPath)
161
164
  {
162
165
  // the packages directory can be found from the hint path of the matching dependency, e.g., when given "Newtonsoft.Json", "7.0.1", and a project like this:
163
166
  // <Project>
@@ -203,6 +206,24 @@ internal static class PackagesConfigUpdater
203
206
  }
204
207
  }
205
208
 
209
+ if (partialPathMatch is null)
210
+ {
211
+ // if we got this far, we couldn't find the packages directory for the specified dependency and there are 2 possibilities:
212
+ // 1. the dependency doesn't actually exist in this project
213
+ // 2. the dependency exists, but doesn't have any assemblies, e.g., jQuery
214
+
215
+ // first let's check the packages.config file to see if we actually need it.
216
+ XDocument packagesDocument = XDocument.Load(packagesConfigPath);
217
+ var hasPackage = packagesDocument.XPathSelectElements("/packages/package")
218
+ .Where(e => e.Attribute("id")?.Value.Equals(dependencyName, StringComparison.OrdinalIgnoreCase) == true).Any();
219
+ if (hasPackage)
220
+ {
221
+ // the dependency exists in the packages.config file, so it must be the second case
222
+ // the vast majority of projects found in the wild use this, and since we have nothing to look for, we'll just have to hope
223
+ partialPathMatch = "../packages";
224
+ }
225
+ }
226
+
206
227
  return partialPathMatch;
207
228
  }
208
229
 
@@ -134,9 +134,9 @@ public class UpdaterWorker
134
134
 
135
135
  _logger.Log($"Updating project [{projectPath}]");
136
136
 
137
- if (NuGetHelper.TryGetPackagesConfigFile(projectPath, out _))
137
+ if (NuGetHelper.TryGetPackagesConfigFile(projectPath, out var packagesConfigPath))
138
138
  {
139
- await PackagesConfigUpdater.UpdateDependencyAsync(repoRootPath, projectPath, dependencyName, previousDependencyVersion, newDependencyVersion, isTransitive, _logger);
139
+ await PackagesConfigUpdater.UpdateDependencyAsync(repoRootPath, projectPath, dependencyName, previousDependencyVersion, newDependencyVersion, packagesConfigPath, _logger);
140
140
  }
141
141
 
142
142
  // Some repos use a mix of packages.config and PackageReference
@@ -91,7 +91,7 @@ public class DiscoveryWorkerTestBase
91
91
 
92
92
  foreach (var expectedDependency in expectedDependencies)
93
93
  {
94
- var actualDependency = actualDependencies.Single(d => d.Name == expectedDependency.Name);
94
+ var actualDependency = actualDependencies.Single(d => d.Name == expectedDependency.Name && d.Type == expectedDependency.Type);
95
95
  Assert.Equal(expectedDependency.Name, actualDependency.Name);
96
96
  Assert.Equal(expectedDependency.Version, actualDependency.Version);
97
97
  Assert.Equal(expectedDependency.Type, actualDependency.Type);
@@ -9,7 +9,7 @@ public class PackagesConfigUpdaterTests : TestBase
9
9
  public void PathToPackagesDirectoryCanBeDetermined(string projectContents, string dependencyName, string dependencyVersion, string expectedPackagesDirectoryPath)
10
10
  {
11
11
  var projectBuildFile = ProjectBuildFile.Parse("/", "project.csproj", projectContents);
12
- var actualPackagesDirectorypath = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, dependencyName, dependencyVersion);
12
+ var actualPackagesDirectorypath = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, dependencyName, dependencyVersion, "packages.config");
13
13
  Assert.Equal(expectedPackagesDirectoryPath, actualPackagesDirectorypath);
14
14
  }
15
15
 
@@ -1,6 +1,3 @@
1
- using System.Collections.Generic;
2
- using System.Threading.Tasks;
3
-
4
1
  using Xunit;
5
2
 
6
3
  namespace NuGetUpdater.Core.Test.Update;
@@ -121,6 +118,109 @@ public partial class UpdateWorkerTests
121
118
  """);
122
119
  }
123
120
 
121
+ [Fact]
122
+ public async Task UpdateSingleDependencyInPackagesConfig_SpecifiedDependencyHasNoPackagesPath()
123
+ {
124
+ // update jQuery from 1.6.4 to 3.7.1
125
+ await TestUpdateForProject("jQuery", "1.6.4", "3.7.1",
126
+ // existing
127
+ projectContents: """
128
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
129
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
130
+ <PropertyGroup>
131
+ <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
132
+ </PropertyGroup>
133
+ <ItemGroup>
134
+ <None Include="packages.config" />
135
+ </ItemGroup>
136
+ <ItemGroup>
137
+ <Reference Include="Newtonsoft.Json">
138
+ <HintPath>packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
139
+ <Private>True</Private>
140
+ </Reference>
141
+ </ItemGroup>
142
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
143
+ </Project>
144
+ """,
145
+ packagesConfigContents: """
146
+ <packages>
147
+ <package id="jQuery" version="1.6.4" targetFramework="net45" />
148
+ <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
149
+ </packages>
150
+ """,
151
+ // expected
152
+ expectedProjectContents: """
153
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
154
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
155
+ <PropertyGroup>
156
+ <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
157
+ </PropertyGroup>
158
+ <ItemGroup>
159
+ <None Include="packages.config" />
160
+ </ItemGroup>
161
+ <ItemGroup>
162
+ <Reference Include="Newtonsoft.Json">
163
+ <HintPath>packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
164
+ <Private>True</Private>
165
+ </Reference>
166
+ </ItemGroup>
167
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
168
+ </Project>
169
+ """,
170
+ expectedPackagesConfigContents: """
171
+ <?xml version="1.0" encoding="utf-8"?>
172
+ <packages>
173
+ <package id="jQuery" version="3.7.1" targetFramework="net46" />
174
+ <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
175
+ </packages>
176
+ """
177
+ );
178
+ }
179
+
180
+ [Fact]
181
+ public async Task UpdateSingleDependencyInPackagesConfig_NoPackagesPathCanBeFound()
182
+ {
183
+ // update jQuery from 3.7.0 to 3.7.1
184
+ await TestUpdateForProject("jQuery", "3.7.0", "3.7.1",
185
+ // existing
186
+ projectContents: """
187
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
188
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
189
+ <PropertyGroup>
190
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
191
+ </PropertyGroup>
192
+ <ItemGroup>
193
+ <None Include="packages.config" />
194
+ </ItemGroup>
195
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
196
+ </Project>
197
+ """,
198
+ packagesConfigContents: """
199
+ <packages>
200
+ <package id="jQuery" version="3.7.0" targetFramework="net45" />
201
+ </packages>
202
+ """,
203
+ // expected
204
+ expectedProjectContents: """
205
+ <Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
206
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
207
+ <PropertyGroup>
208
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
209
+ </PropertyGroup>
210
+ <ItemGroup>
211
+ <None Include="packages.config" />
212
+ </ItemGroup>
213
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
214
+ </Project>
215
+ """,
216
+ expectedPackagesConfigContents: """
217
+ <?xml version="1.0" encoding="utf-8"?>
218
+ <packages>
219
+ <package id="jQuery" version="3.7.1" targetFramework="net45" />
220
+ </packages>
221
+ """);
222
+ }
223
+
124
224
  [Fact]
125
225
  public async Task UpdateSingleDependencyInPackagesConfigButNotToLatest()
126
226
  {
@@ -2,7 +2,7 @@ using Xunit;
2
2
 
3
3
  namespace NuGetUpdater.Core.Test.Utilities
4
4
  {
5
- public class SdkPackageUpdaterHelperTests
5
+ public class SdkPackageUpdaterHelperTests : TestBase
6
6
  {
7
7
  [Fact]
8
8
  public async Task DirectoryBuildFilesAreOnlyPulledInFromParentDirectories()
@@ -21,6 +21,7 @@ module Dependabot
21
21
  def parse
22
22
  workspace_path = project_files.first&.directory
23
23
  return [] unless workspace_path
24
+ return [] unless repo_contents_path
24
25
 
25
26
  # `workspace_path` is the only unique value here so we use it as the cache key
26
27
  cache = T.let(CacheManager.cache("file_parser.parse"), T::Hash[String, T::Array[Dependabot::Dependency]])
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.254.0
4
+ version: 0.255.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-04-24 00:00:00.000000000 Z
11
+ date: 2024-05-03 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.254.0
19
+ version: 0.255.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.254.0
26
+ version: 0.255.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rubyzip
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -184,6 +184,20 @@ dependencies:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
186
  version: 0.8.1
187
+ - !ruby/object:Gem::Dependency
188
+ name: simplecov
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: 0.22.0
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: 0.22.0
187
201
  - !ruby/object:Gem::Dependency
188
202
  name: turbo_tests
189
203
  requirement: !ruby/object:Gem::Requirement
@@ -270,6 +284,7 @@ files:
270
284
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.LibraryModel/NuGet.LibraryModel.csproj
271
285
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.PackageManagement/NuGet.PackageManagement.csproj
272
286
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/NuGet.Packaging.csproj
287
+ - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/PackageFolderReader.cs
273
288
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.ProjectModel/NuGet.ProjectModel.csproj
274
289
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Protocol/NuGet.Protocol.csproj
275
290
  - helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Resolver/NuGet.Resolver.csproj
@@ -404,7 +419,7 @@ licenses:
404
419
  - Nonstandard
405
420
  metadata:
406
421
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
407
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.254.0
422
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.255.0
408
423
  post_install_message:
409
424
  rdoc_options: []
410
425
  require_paths:
@@ -420,7 +435,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
420
435
  - !ruby/object:Gem::Version
421
436
  version: 3.1.0
422
437
  requirements: []
423
- rubygems_version: 3.3.26
438
+ rubygems_version: 3.5.9
424
439
  signing_key:
425
440
  specification_version: 4
426
441
  summary: Provides Dependabot support for .NET (NuGet)