dependabot-nuget 0.330.0 → 0.331.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: f873f613d2174dfdf82367b571a8f389e332d02f2dfb0f3e37e7db656bcb0442
4
- data.tar.gz: fa66bffbadf7e9e8d51dd2d7fabfa60562504315b2c03fe5722aad203e582982
3
+ metadata.gz: ccdc340808fa9270ad530b71725c46f34208a49a2548adc2cb7fe3ffe7a1bd2b
4
+ data.tar.gz: d031c05ffd08ab81b2718757e7071940f70d2248b76ac473009a66f83aca3d22
5
5
  SHA512:
6
- metadata.gz: b45f0eb1a0fc68119d181985244952bd0527d344ef54265bc3d8810e30083f3f6aff61225e4d813d195a723905b77e9fd76f18b0a7c99c06978a028d8d56b82c
7
- data.tar.gz: 68f201f704f413c26db73bb7a6fa6235013761189153585adf6822cdc6cca93a0ce6bd88c89997b3f34a0502df1636a36f7e23be216b648273ec5caef692c919
6
+ metadata.gz: 96afb97242edf3a29a84e0f76854f08cbcda2f33c270e9ea98e319446c717317be0e816c09afbc149857f69f95a1ddae032e5926af3187ea86a289303881cdbf
7
+ data.tar.gz: f04a2e9d50460056ae64df2bc73cae5f80bc32ba328f0f88367eb88fb640405261c916e4a9d636ad2c7fb7980dfae0257d642b799963ec378bb8d0be00412b99
@@ -149,14 +149,60 @@ internal sealed class ProjectBuildFile : XmlBuildFile
149
149
 
150
150
  public void NormalizeDirectorySeparatorsInProject()
151
151
  {
152
+ // `//Reference/HintPath`
152
153
  var hintPathNodes = Contents.Descendants()
153
154
  .Where(e =>
154
155
  e.Name.Equals("HintPath", StringComparison.OrdinalIgnoreCase) &&
155
- e.Parent.Name.Equals("Reference", StringComparison.OrdinalIgnoreCase))
156
- .Select(e => (XmlElementSyntax)e.AsNode);
156
+ (e.Parent?.Name ?? "").Equals("Reference", StringComparison.OrdinalIgnoreCase))
157
+ .Select(e => e.AsNode)
158
+ .OfType<XmlElementSyntax>();
157
159
  var updatedXml = Contents.ReplaceNodes(hintPathNodes,
158
160
  (_, n) => n.WithContent(n.GetContentValue().Replace("/", "\\")).AsNode);
159
161
  Update(updatedXml);
162
+
163
+ // `//Target/Error[starts-with(@Condition, '!Exists(' and Text)]`
164
+ var errorsWithConditions = Contents.Descendants()
165
+ .Where(e =>
166
+ e.Name.Equals("Error", StringComparison.OrdinalIgnoreCase) &&
167
+ (e.Parent?.Name ?? "").Equals("Target", StringComparison.OrdinalIgnoreCase) &&
168
+ e.GetAttributeValue("Condition")?.StartsWith("!Exists(") == true &&
169
+ e.GetAttribute("Text") is not null)
170
+ .Select(e => e.AsNode)
171
+ .OfType<XmlEmptyElementSyntax>();
172
+ updatedXml = Contents.ReplaceNodes(errorsWithConditions,
173
+ (_, n) =>
174
+ {
175
+ var conditionAttr = n.GetAttribute("Condition");
176
+ var newConditionAttr = conditionAttr.WithValue(conditionAttr.Value.Replace("/", "\\"));
177
+ n = (XmlEmptyElementSyntax)n.ReplaceAttribute(conditionAttr, newConditionAttr).AsNode;
178
+
179
+ var textAttr = n.GetAttribute("Text");
180
+ var newTextAttr = textAttr.WithValue(textAttr.Value.Replace("/", "\\"));
181
+ return n.ReplaceAttribute(textAttr, newTextAttr).AsNode;
182
+ });
183
+ Update(updatedXml);
184
+
185
+ // `/Project/Import[starts-with(@Condition, 'Exists(') and Project]`
186
+ var importsWithConditions = Contents.Descendants()
187
+ .Where(e =>
188
+ e.Name.Equals("Import", StringComparison.OrdinalIgnoreCase) &&
189
+ (e.Parent?.Name ?? "").Equals("Project", StringComparison.OrdinalIgnoreCase) &&
190
+ e.GetAttributeValue("Condition")?.StartsWith("Exists(") == true &&
191
+ e.GetAttribute("Project") is not null)
192
+ .Select(e => e.AsNode)
193
+ .OfType<XmlEmptyElementSyntax>();
194
+ updatedXml = Contents.ReplaceNodes(importsWithConditions,
195
+ (_, n) =>
196
+ {
197
+ var projectAttr = n.GetAttribute("Project");
198
+ var newProjectAttr = projectAttr.WithValue(projectAttr.Value.Replace("/", "\\"));
199
+ n = (XmlEmptyElementSyntax)n.ReplaceAttribute(projectAttr, newProjectAttr).AsNode;
200
+
201
+ var conditionAttr = n.GetAttribute("Condition");
202
+ var newConditionAttr = conditionAttr.WithValue(conditionAttr.Value.Replace("/", "\\"));
203
+ return n.ReplaceAttribute(conditionAttr, newConditionAttr).AsNode;
204
+ });
205
+ Update(updatedXml);
160
206
  }
161
207
 
162
208
  public ProjectBuildFileType GetFileType()
@@ -54,6 +54,15 @@ internal static partial class PackagesConfigUpdater
54
54
  var packagesDirectory = PathHelper.JoinPath(projectDirectory, packagesSubDirectory);
55
55
  Directory.CreateDirectory(packagesDirectory);
56
56
 
57
+ var restoreArgs = new List<string>
58
+ {
59
+ "restore",
60
+ projectPath,
61
+ "-PackagesDirectory",
62
+ packagesDirectory,
63
+ "-NonInteractive",
64
+ };
65
+
57
66
  var updateArgs = new List<string>
58
67
  {
59
68
  "update",
@@ -67,20 +76,11 @@ internal static partial class PackagesConfigUpdater
67
76
  "-NonInteractive",
68
77
  };
69
78
 
70
- var restoreArgs = new List<string>
71
- {
72
- "restore",
73
- projectPath,
74
- "-PackagesDirectory",
75
- packagesDirectory,
76
- "-NonInteractive",
77
- };
78
-
79
79
  logger.Info(" Finding MSBuild...");
80
80
  var msbuildDirectory = MSBuildHelper.MSBuildPath;
81
81
  if (msbuildDirectory is not null)
82
82
  {
83
- foreach (var args in new[] { updateArgs, restoreArgs })
83
+ foreach (var args in new[] { restoreArgs, updateArgs })
84
84
  {
85
85
  args.Add("-MSBuildPath");
86
86
  args.Add(msbuildDirectory); // e.g., /usr/share/dotnet/sdk/7.0.203
@@ -89,7 +89,7 @@ internal static partial class PackagesConfigUpdater
89
89
 
90
90
  using (new SpecialImportsConditionPatcher(projectPath))
91
91
  {
92
- RunNugetUpdate(updateArgs, restoreArgs, projectDirectory ?? packagesDirectory, logger);
92
+ RunNugetUpdate([.. restoreArgs], [.. updateArgs], projectDirectory ?? packagesDirectory, logger);
93
93
  }
94
94
 
95
95
  projectBuildFile = ProjectBuildFile.Open(repoRootPath, projectPath);
@@ -110,7 +110,7 @@ internal static partial class PackagesConfigUpdater
110
110
  return [updateResult];
111
111
  }
112
112
 
113
- private static void RunNugetUpdate(List<string> updateArgs, List<string> restoreArgs, string projectDirectory, ILogger logger)
113
+ private static void RunNugetUpdate(string[] restoreArgs, string[] updateArgs, string projectDirectory, ILogger logger)
114
114
  {
115
115
  var outputBuilder = new StringBuilder();
116
116
  var writer = new StringWriter(outputBuilder);
@@ -122,53 +122,26 @@ internal static partial class PackagesConfigUpdater
122
122
 
123
123
  var currentDir = Environment.CurrentDirectory;
124
124
  var existingSpawnedProcesses = GetLikelyNuGetSpawnedProcesses();
125
- try
126
- {
127
- Environment.CurrentDirectory = projectDirectory;
128
- var retryingAfterRestore = false;
129
125
 
130
- doRestore:
131
- logger.Info($" Running NuGet.exe with args: {string.Join(" ", updateArgs)}");
126
+ void RunNuGetWithArguments(string[] args)
127
+ {
128
+ logger.Info($" Running NuGet.exe with args: {string.Join(" ", args)}");
132
129
  outputBuilder.Clear();
133
- var result = Program.Main(updateArgs.ToArray());
130
+ var exitCode = Program.Main(args);
134
131
  var fullOutput = outputBuilder.ToString();
135
- logger.Info($" Result: {result}");
136
- logger.Info($" Output:\n{fullOutput}");
137
- if (result != 0)
132
+ if (exitCode != 0)
138
133
  {
139
- // The initial `update` command can fail for several reasons:
140
- // 1. One possibility is that the `packages.config` file contains a delisted package. If that's the
141
- // case, `update` will fail with the message "Existing packages must be restored before performing
142
- // an install or update."
143
- // 2. Another possibility is that the `update` command fails because the package contains no assemblies
144
- // and doesn't appear in the cache. The message in this case will be "Could not install package
145
- // '<name> <version>'...the package does not contain any assembly references or content files that
146
- // are compatible with that framework.".
147
- // 3. Yet another possibility is that the project explicitly imports a targets file without a condition
148
- // of `Exists(...)`.
149
- // The solution in all cases is to run `restore` then try the update again.
150
- if (!retryingAfterRestore && OutputIndicatesRestoreIsRequired(fullOutput))
151
- {
152
- retryingAfterRestore = true;
153
- logger.Info($" Running NuGet.exe with args: {string.Join(" ", restoreArgs)}");
154
- outputBuilder.Clear();
155
- var exitCodeAgain = Program.Main(restoreArgs.ToArray());
156
- var restoreOutput = outputBuilder.ToString();
157
-
158
- if (exitCodeAgain != 0)
159
- {
160
- MSBuildHelper.ThrowOnError(fullOutput);
161
- MSBuildHelper.ThrowOnError(restoreOutput);
162
- throw new Exception($"Unable to restore.\nOutput:\n${restoreOutput}\n");
163
- }
164
-
165
- goto doRestore;
166
- }
167
-
168
134
  MSBuildHelper.ThrowOnError(fullOutput);
169
- throw new Exception(fullOutput);
135
+ throw new Exception($"Unable to run NuGet.exe with args: {string.Join(" ", args)}\nOutput:\n{fullOutput}\n");
170
136
  }
171
137
  }
138
+
139
+ try
140
+ {
141
+ Environment.CurrentDirectory = projectDirectory;
142
+ RunNuGetWithArguments(restoreArgs);
143
+ RunNuGetWithArguments(updateArgs);
144
+ }
172
145
  catch (Exception e)
173
146
  {
174
147
  logger.Info($"Error: {e}");
@@ -191,13 +164,6 @@ internal static partial class PackagesConfigUpdater
191
164
  }
192
165
  }
193
166
 
194
- private static bool OutputIndicatesRestoreIsRequired(string output)
195
- {
196
- return output.Contains("Existing packages must be restored before performing an install or update.")
197
- || output.Contains("the package does not contain any assembly references or content files that are compatible with that framework.")
198
- || MSBuildHelper.GetMissingFile(output) is not null;
199
- }
200
-
201
167
  private static Process[] GetLikelyNuGetSpawnedProcesses()
202
168
  {
203
169
  var processes = Process.GetProcesses().Where(p => p.ProcessName.StartsWith("CredentialProvider", StringComparison.OrdinalIgnoreCase) == true).ToArray();
@@ -161,4 +161,32 @@ public class ProjectBuildFileTests
161
161
  buildFile.NormalizeDirectorySeparatorsInProject();
162
162
  Assert.Equal(expectedXml, buildFile.Contents.ToFullString());
163
163
  }
164
+
165
+ [Theory]
166
+ [InlineData(
167
+ // language=xml
168
+ """
169
+ <Project>
170
+ <Target>
171
+ <Error Condition="!Exists('../packages/Some.Package.1.0.0/build/Some.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '../packages/Some.Package.1.0.0/build/Some.Package.targets'))" />
172
+ </Target>
173
+ <Import Project="../packages/Some.Package.1.0.0/build/Some.Package.targets" Condition="Exists('../packages/Some.Package.1.0.0/build/Some.Package.targets')" />
174
+ </Project>
175
+ """,
176
+ // language=xml
177
+ """
178
+ <Project>
179
+ <Target>
180
+ <Error Condition="!Exists('..\packages\Some.Package.1.0.0\build\Some.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Some.Package.1.0.0\build\Some.Package.targets'))" />
181
+ </Target>
182
+ <Import Project="..\packages\Some.Package.1.0.0\build\Some.Package.targets" Condition="Exists('..\packages\Some.Package.1.0.0\build\Some.Package.targets')" />
183
+ </Project>
184
+ """
185
+ )]
186
+ public void ImportPathsCanBeNormalized(string originalXml, string expectedXml)
187
+ {
188
+ var buildFile = GetBuildFile(originalXml, "project.csproj");
189
+ buildFile.NormalizeDirectorySeparatorsInProject();
190
+ Assert.Equal(expectedXml, buildFile.Contents.ToFullString());
191
+ }
164
192
  }
@@ -1,3 +1,4 @@
1
+ using System.Text;
1
2
  using System.Text.Json;
2
3
 
3
4
  using NuGet.Versioning;
@@ -352,7 +353,7 @@ public class FileWriterWorkerTests : TestBase
352
353
  {
353
354
  // project is directly changed
354
355
  await TestAsync(
355
- dependencyName: "Some.Dependency",
356
+ dependencyName: "Some.Package",
356
357
  oldDependencyVersion: "1.0.0",
357
358
  newDependencyVersion: "2.0.0",
358
359
  projectContents: """
@@ -365,25 +366,46 @@ public class FileWriterWorkerTests : TestBase
365
366
  <None Include="packages.config" />
366
367
  </ItemGroup>
367
368
  <ItemGroup>
368
- <Reference Include="Some.Dependency">
369
- <HintPath>packages\Some.Dependency.1.0.0\lib\net45\Some.Dependency.dll</HintPath>
369
+ <Reference Include="Some.Other.Package">
370
+ <HintPath>..\packages\Some.Other.Package.3.0.0\lib\net45\Some.Other.Package.dll</HintPath>
371
+ <Private>True</Private>
372
+ </Reference>
373
+ <Reference Include="Some.Package">
374
+ <HintPath>..\packages\Some.Package.1.0.0\lib\net45\Some.Package.dll</HintPath>
370
375
  <Private>True</Private>
371
376
  </Reference>
372
377
  </ItemGroup>
378
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
379
+ <Error Condition="!Exists('..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets'))" />
380
+ <Error Condition="!Exists('..\packages\Some.Package.1.0.0\build\Some.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Some.Package.1.0.0\build\Some.Package.targets'))" />
381
+ </Target>
373
382
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
383
+ <Import Project="..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets" Condition="Exists('..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets')" />
384
+ <Import Project="..\packages\Some.Package.1.0.0\build\Some.Package.targets" Condition="Exists('..\packages\Some.Package.1.0.0\build\Some.Package.targets')" />
374
385
  </Project>
375
386
  """,
376
387
  additionalFiles: [
377
388
  ("packages.config", """
378
389
  <?xml version="1.0" encoding="utf-8"?>
379
390
  <packages>
380
- <package id="Some.Dependency" version="1.0.0" targetFramework="net45" />
391
+ <package id="Some.Other.Package" version="3.0.0" targetFramework="net45" />
392
+ <package id="Some.Package" version="1.0.0" targetFramework="net45" />
381
393
  </packages>
382
394
  """)
383
395
  ],
384
396
  packages: [
385
- MockNuGetPackage.CreateSimplePackage("Some.Dependency", "1.0.0", "net45"),
386
- MockNuGetPackage.CreateSimplePackage("Some.Dependency", "2.0.0", "net45"),
397
+ new MockNuGetPackage("Some.Package", "1.0.0", Files: [
398
+ ("lib/net45/Some.Package.dll", Array.Empty<byte>()),
399
+ ("build/Some.Package.targets", Encoding.UTF8.GetBytes("<Project />"))
400
+ ]),
401
+ new MockNuGetPackage("Some.Package", "2.0.0", Files: [
402
+ ("lib/net45/Some.Package.dll", Array.Empty<byte>()),
403
+ ("build/Some.Package.targets", Encoding.UTF8.GetBytes("<Project />"))
404
+ ]),
405
+ new MockNuGetPackage("Some.Other.Package", "3.0.0", Files: [
406
+ ("lib/net45/Some.Other.Package.dll", Array.Empty<byte>()),
407
+ ("build/Some.Other.Package.targets", Encoding.UTF8.GetBytes("<Project />"))
408
+ ]),
387
409
  ],
388
410
  discoveryWorker: null, // use real worker
389
411
  dependencySolver: null, // use real worker
@@ -398,24 +420,35 @@ public class FileWriterWorkerTests : TestBase
398
420
  <None Include="packages.config" />
399
421
  </ItemGroup>
400
422
  <ItemGroup>
401
- <Reference Include="Some.Dependency">
402
- <HintPath>packages\Some.Dependency.2.0.0\lib\net45\Some.Dependency.dll</HintPath>
423
+ <Reference Include="Some.Other.Package">
424
+ <HintPath>..\packages\Some.Other.Package.3.0.0\lib\net45\Some.Other.Package.dll</HintPath>
425
+ <Private>True</Private>
426
+ </Reference>
427
+ <Reference Include="Some.Package">
428
+ <HintPath>..\packages\Some.Package.2.0.0\lib\net45\Some.Package.dll</HintPath>
403
429
  <Private>True</Private>
404
430
  </Reference>
405
431
  </ItemGroup>
432
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
433
+ <Error Condition="!Exists('..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets'))" />
434
+ <Error Condition="!Exists('..\packages\Some.Package.2.0.0\build\Some.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Some.Package.2.0.0\build\Some.Package.targets'))" />
435
+ </Target>
406
436
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
437
+ <Import Project="..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets" Condition="Exists('..\packages\Some.Other.Package.3.0.0\build\Some.Other.Package.targets')" />
438
+ <Import Project="..\packages\Some.Package.2.0.0\build\Some.Package.targets" Condition="Exists('..\packages\Some.Package.2.0.0\build\Some.Package.targets')" />
407
439
  </Project>
408
440
  """,
409
441
  expectedAdditionalFiles: [
410
442
  ("packages.config", """
411
443
  <?xml version="1.0" encoding="utf-8"?>
412
444
  <packages>
413
- <package id="Some.Dependency" version="2.0.0" targetFramework="net45" />
445
+ <package id="Some.Other.Package" version="3.0.0" targetFramework="net45" />
446
+ <package id="Some.Package" version="2.0.0" targetFramework="net45" />
414
447
  </packages>
415
448
  """)
416
449
  ],
417
450
  expectedOperations: [
418
- new DirectUpdate() { DependencyName = "Some.Dependency", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/packages.config", "/project.csproj"] }
451
+ new DirectUpdate() { DependencyName = "Some.Package", NewVersion = NuGetVersion.Parse("2.0.0"), UpdatedFiles = ["/packages.config", "/project.csproj"] }
419
452
  ]
420
453
  );
421
454
  }
@@ -1868,7 +1868,7 @@ public class PackagesConfigUpdaterTests : TestBase
1868
1868
  var error = JobErrorBase.ErrorFromException(notFoundException, "TEST-JOB-ID", temporaryDirectory.DirectoryPath);
1869
1869
  var notFound = Assert.IsType<DependencyNotFound>(error);
1870
1870
  var depName = Assert.IsType<string>(notFound.Details["source"]);
1871
- Assert.Equal("Unrelated.Package", depName);
1871
+ Assert.Equal("Unrelated.Package.1.0.0", depName);
1872
1872
  }
1873
1873
 
1874
1874
  [Theory]
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.330.0
4
+ version: 0.331.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.330.0
18
+ version: 0.331.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.330.0
25
+ version: 0.331.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -551,7 +551,7 @@ licenses:
551
551
  - MIT
552
552
  metadata:
553
553
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
554
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.330.0
554
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.331.0
555
555
  rdoc_options: []
556
556
  require_paths:
557
557
  - lib