dependabot-nuget 0.254.0 → 0.255.0

Sign up to get free protection for your applications and to get access to all the features.
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)