dependabot-nuget 0.393.0 → 0.394.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/helpers/lib/NuGetUpdater/Directory.Build.targets +1 -0
  3. data/helpers/lib/NuGetUpdater/Directory.Packages.props +17 -15
  4. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Build.props +9 -1
  5. data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Build.targets +57 -1
  6. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.CommandLine/Commands/ProjectFactory.cs +9 -1
  7. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.CommandLine/Commands/UpdateCommand.cs +6 -1
  8. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Packaging/PackageFolderReader.cs +2 -2
  9. data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Protocol/NuGet.Protocol.csproj +1 -0
  10. data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTestHelper.cs +2 -0
  11. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +21 -13
  12. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/PackagesConfigBuildFile.cs +3 -1
  13. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/ProjectBuildFile.cs +13 -6
  14. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CreatePullRequest.cs +1 -1
  15. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +16 -7
  16. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ReportedDependency.cs +1 -1
  17. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/ReportedDependencyWithDirectory.cs +19 -0
  18. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/GitEOLMetadataProvider.cs +64 -0
  19. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/IEOLMetadataProvider.cs +10 -0
  20. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ModifiedFilesTracker.cs +70 -5
  21. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +3 -2
  22. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +6 -4
  23. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +5 -3
  24. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +4 -3
  25. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +4 -3
  26. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +1 -1
  27. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +28 -16
  28. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +6 -7
  29. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +5 -0
  30. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/PathHelper.cs +1 -1
  31. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +133 -0
  32. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/ProjectBuildFileTests.cs +14 -0
  33. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/GitTestHelper.cs +23 -0
  34. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.InsecureHttpFeed.cs +2 -0
  35. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +20 -0
  36. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/GitEOLMetadataProviderTests.cs +58 -0
  37. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +2 -0
  38. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +51 -1
  39. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/ModifiedFilesTrackerTests.cs +182 -2
  40. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +2 -2
  41. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +3 -0
  42. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +14 -0
  43. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandlerTests.cs +3 -0
  44. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandlerTests.cs +2 -0
  45. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandlerTests.cs +2 -0
  46. data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +29 -5
  47. metadata +11 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9a1c5805c694589281a1cc0397c9059d82152c07f92a1f92dc5cb8d4784f766
4
- data.tar.gz: 7c3111d367c94ce6169ffa1001578477e972565c54d5c0233a4ae562cf72c692
3
+ metadata.gz: 4f87265e6a1903fa2d9a3ebf527ce5a2011050a3166b4dc38e0e5ed973047ed3
4
+ data.tar.gz: a34d83e590e6a578617e53ac28407412492c01c62c198f910929246c3af3b405
5
5
  SHA512:
6
- metadata.gz: 5907f25c11a733215444381da841f4cebcd6090480a303fb8b560eea34ff3e1222cc7164d08bd0dfbd1466dadde76d2ee908170cdb645a3efe1e63c621cd41e9
7
- data.tar.gz: 0067f9a4057bf56bf4d64396377565c3ae2a055ac68bc1ff90962877bd015d3b6bea96aab2893dbd00c56fd7cc9b03a2b22d88a4715cfc622f6e6010572467f4
6
+ metadata.gz: d3d30fb0420935c01ec7fa4d8d08538994cd51bc4c4e4875b717f85ede40bcbec970b0e127bc9d830c6bdc9de8ef3048340d49bc36efcd307c4d2c57a5e82e4c
7
+ data.tar.gz: 54406d1b180a7da9baf7fd61f9aba249d8eae142eda7404f96c6f9c364184f600d49b3ea61daa756f86f7ad005026560623522003712801a149a176c8863ec4b
@@ -13,5 +13,6 @@
13
13
  <PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" PrivateAssets="all" />
14
14
  <PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" PrivateAssets="all" />
15
15
  <PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" PrivateAssets="all" />
16
+ <PackageReference Include="Microsoft.NET.StringTools" ExcludeAssets="runtime" PrivateAssets="all" />
16
17
  </ItemGroup>
17
18
  </Project>
@@ -3,38 +3,40 @@
3
3
  <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4
4
  </PropertyGroup>
5
5
  <PropertyGroup>
6
- <MSBuildPackageVersion>18.3.3</MSBuildPackageVersion>
6
+ <!-- Match the MSBuild assemblies supplied by the SDK selected in global.json. -->
7
+ <MSBuildPackageVersion>18.9.6</MSBuildPackageVersion>
7
8
  </PropertyGroup>
8
9
  <ItemGroup>
9
10
  <PackageVersion Include="DiffPlex" Version="1.9.0" />
10
- <PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.93" />
11
- <PackageVersion Include="Microsoft.Build.Locator" Version="1.9.1" />
11
+ <PackageVersion Include="GuiLabs.Language.Xml" Version="1.2.120" />
12
+ <PackageVersion Include="Microsoft.Build.Locator" Version="1.11.2" />
12
13
  <PackageVersion Include="Microsoft.Build" Version="$(MSBuildPackageVersion)" />
13
14
  <PackageVersion Include="Microsoft.Build.Framework" Version="$(MSBuildPackageVersion)" />
14
15
  <PackageVersion Include="Microsoft.Build.Tasks.Core" Version="$(MSBuildPackageVersion)" />
15
16
  <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MSBuildPackageVersion)" />
16
- <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
17
+ <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.9.0" />
17
18
  <PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
18
- <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.3" />
19
- <PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="10.0.3" />
20
- <PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.3" />
21
- <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
19
+ <PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.11" />
20
+ <PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="10.0.11" />
21
+ <PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.11" />
22
+ <PackageVersion Include="Microsoft.NET.StringTools" Version="$(MSBuildPackageVersion)" />
23
+ <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
22
24
  <PackageVersion Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Version="3.14.2075" />
23
25
  <PackageVersion Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.52" />
24
- <PackageVersion Include="Microsoft.Web.Xdt" Version="3.2.3" />
25
- <PackageVersion Include="MSBuild.StructuredLogger" Version="2.3.17" />
26
+ <PackageVersion Include="Microsoft.Web.Xdt" Version="3.2.11" />
27
+ <PackageVersion Include="MSBuild.StructuredLogger" Version="2.3.246" />
26
28
  <PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
27
- <PackageVersion Include="OpenTelemetry" Version="1.15.3" />
29
+ <PackageVersion Include="OpenTelemetry" Version="1.18.0" />
28
30
  <PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.15.3" />
29
- <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
30
- <PackageVersion Include="packageurl-dotnet" Version="2.0.0" />
31
+ <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.18.0" />
32
+ <PackageVersion Include="packageurl-dotnet" Version="2.0.1" />
31
33
  <PackageVersion Include="Semver" Version="3.0.0" />
32
34
  <PackageVersion Include="System.CommandLine" Version="2.0.3" />
33
35
  <PackageVersion Include="System.ComponentModel.Composition" Version="10.0.3" />
34
36
  <PackageVersion Include="System.Net.Http" Version="4.3.4" />
35
37
  <PackageVersion Include="System.Formats.Asn1" Version="10.0.3" />
36
- <PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.3" />
37
- <PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="9.0.11" />
38
+ <PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.10" />
39
+ <PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="10.0.8" />
38
40
  <PackageVersion Include="System.Text.Json" Version="10.0.3" />
39
41
  <PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
40
42
  <PackageVersion Include="System.Threading.Tasks.Dataflow" Version="10.0.3" />
@@ -11,7 +11,15 @@
11
11
  <SharedDirectory>$(NuGetSourceLocation)\build\Shared</SharedDirectory>
12
12
  <NoWarn>$(NoWarn);CA1416</NoWarn><!-- platform compatibility in vendored NuGet.Client code -->
13
13
  <NoWarn>$(NoWarn);CS0436</NoWarn><!-- type conflicts with imported types in vendored NuGet.Client code -->
14
- <Version>6.8.0</Version>
14
+ <!--
15
+ These assemblies share the default load context with the copies bundled in the selected .NET SDK.
16
+ Keep this version aligned with both NuGet.Client/build/config.props and the SDK in ../global.json.
17
+ -->
18
+ <Version>7.9.0</Version>
19
+ <SignAssembly>true</SignAssembly>
20
+ <PublicSign>true</PublicSign>
21
+ <!-- NuGet.Core assemblies use Microsoft's public key, as do the copies bundled with the SDK. -->
22
+ <AssemblyOriginatorKeyFile>$(NuGetSourceLocation)\keys\35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
15
23
  </PropertyGroup>
16
24
 
17
25
  <Import Project="..\Directory.Common.props" />
@@ -1,7 +1,63 @@
1
1
  <Project>
2
2
 
3
3
  <ItemGroup>
4
- <Compile Include="$(SharedDirectory)\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
4
+ <!-- NuGetFeatureFlags depends on NuGet.Common and is included only by projects that use it upstream. -->
5
+ <Compile Include="$(SharedDirectory)\*.cs"
6
+ Exclude="bin\**;obj\**;**\*.xproj;packages\**;$(SharedDirectory)\NuGetFeatureFlags.cs" />
5
7
  </ItemGroup>
6
8
 
9
+ <!--
10
+ MSBuild and the updater load NuGet assemblies into the same process. Fail the build before a
11
+ mismatched assembly identity can become a runtime FileNotFoundException.
12
+ -->
13
+ <Target Name="ValidateNuGetAssemblyVersion"
14
+ BeforeTargets="CoreCompile"
15
+ Condition="'$(MSBuildProjectName)' == 'NuGet.Frameworks'">
16
+ <XmlPeek XmlInputPath="$(NuGetSourceLocation)\build\config.props"
17
+ Query="/Project/PropertyGroup/MajorNuGetVersion/text()">
18
+ <Output TaskParameter="Result" PropertyName="_VendoredNuGetMajorVersion" />
19
+ </XmlPeek>
20
+ <XmlPeek XmlInputPath="$(NuGetSourceLocation)\build\config.props"
21
+ Query="/Project/PropertyGroup/MinorNuGetVersion/text()">
22
+ <Output TaskParameter="Result" PropertyName="_VendoredNuGetMinorVersion" />
23
+ </XmlPeek>
24
+ <XmlPeek XmlInputPath="$(NuGetSourceLocation)\build\config.props"
25
+ Query="/Project/PropertyGroup/PatchNuGetVersion/text()">
26
+ <Output TaskParameter="Result" PropertyName="_VendoredNuGetPatchVersion" />
27
+ </XmlPeek>
28
+
29
+ <PropertyGroup>
30
+ <_VendoredNuGetVersion>$(_VendoredNuGetMajorVersion).$(_VendoredNuGetMinorVersion).$(_VendoredNuGetPatchVersion)</_VendoredNuGetVersion>
31
+ <_SdkNuGetFrameworksPath>$(MSBuildSDKsPath)\..\NuGet.Frameworks.dll</_SdkNuGetFrameworksPath>
32
+ </PropertyGroup>
33
+
34
+ <Error Condition="'$(_VendoredNuGetVersion)' != '$(Version)'"
35
+ Text="The NuGetProjects version ($(Version)) must match the vendored NuGet.Client version ($(_VendoredNuGetVersion)). Update the submodule and Directory.Build.props together." />
36
+ <Error Condition="!Exists('$(_SdkNuGetFrameworksPath)')"
37
+ Text="NuGet.Frameworks.dll was not found beside the selected SDK at '$(_SdkNuGetFrameworksPath)'." />
38
+
39
+ <GetAssemblyIdentity AssemblyFiles="$(_SdkNuGetFrameworksPath)"
40
+ Condition="Exists('$(_SdkNuGetFrameworksPath)')">
41
+ <Output TaskParameter="Assemblies" ItemName="_SdkNuGetFrameworksAssembly" />
42
+ </GetAssemblyIdentity>
43
+
44
+ <Error Condition="'%(_SdkNuGetFrameworksAssembly.Version)' != '$(Version).0'"
45
+ Text="The selected SDK contains NuGet.Frameworks version %(_SdkNuGetFrameworksAssembly.Version), but NuGetProjects builds version $(Version).0. Keep global.json, the NuGet.Client submodule, and Directory.Build.props aligned." />
46
+ </Target>
47
+
48
+ <Target Name="ValidateNuGetAssemblyIdentity"
49
+ AfterTargets="CopyFilesToOutputDirectory"
50
+ DependsOnTargets="ValidateNuGetAssemblyVersion"
51
+ Condition="'$(MSBuildProjectName)' == 'NuGet.Frameworks'">
52
+ <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
53
+ <Output TaskParameter="Assemblies" ItemName="_BuiltNuGetFrameworksAssembly" />
54
+ </GetAssemblyIdentity>
55
+ <GetAssemblyIdentity AssemblyFiles="$(_SdkNuGetFrameworksPath)">
56
+ <Output TaskParameter="Assemblies" ItemName="_SdkNuGetFrameworksAssemblyForIdentity" />
57
+ </GetAssemblyIdentity>
58
+
59
+ <Error Condition="'@(_BuiltNuGetFrameworksAssembly)' != '@(_SdkNuGetFrameworksAssemblyForIdentity)'"
60
+ Text="The built NuGet.Frameworks identity '@(_BuiltNuGetFrameworksAssembly)' must match the selected SDK copy '@(_SdkNuGetFrameworksAssemblyForIdentity)'." />
61
+ </Target>
62
+
7
63
  </Project>
@@ -38,6 +38,9 @@ namespace NuGet.CommandLine
38
38
 
39
39
  private IEnvironmentVariableReader _environmentVariableReader;
40
40
 
41
+ private bool _deterministic;
42
+ private string _deterministicTimestamp;
43
+
41
44
  // Files we want to always exclude from the resulting package
42
45
  private static readonly HashSet<string> ExcludeFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
43
46
  NuGetConstants.PackageReferenceFile,
@@ -71,6 +74,8 @@ namespace NuGet.CommandLine
71
74
  {
72
75
  return new ProjectFactory(packArgs.MsBuildDirectory.Value, path, packArgs.Properties)
73
76
  {
77
+ _deterministic = packArgs.Deterministic,
78
+ _deterministicTimestamp = packArgs.DeterministicTimestamp,
74
79
  IsTool = packArgs.Tool,
75
80
  LogLevel = packArgs.LogLevel,
76
81
  Logger = packArgs.Logger,
@@ -234,7 +239,10 @@ namespace NuGet.CommandLine
234
239
  }
235
240
  }
236
241
 
237
- builder = new PackageBuilder(false, Logger);
242
+ builder = new PackageBuilder(_deterministic, Logger)
243
+ {
244
+ DeterministicTimestamp = _deterministicTimestamp,
245
+ };
238
246
 
239
247
  try
240
248
  {
@@ -84,7 +84,12 @@ namespace NuGet.CommandLine
84
84
  throw new CommandException(NuGetResources.InvalidFile);
85
85
  }
86
86
 
87
- _msbuildDirectory = MsBuildUtility.GetMsBuildDirectoryFromMsBuildPath(MSBuildPath, MSBuildVersion, Console).Value.Path;
87
+ // Upstream rejects SDK MSBuild paths because standalone NuGet.exe runs on .NET Framework and cannot load
88
+ // .NET SDK assemblies. Dependabot embeds this command in .NET and pre-registers the matching SDK with
89
+ // MSBuildLocator, so the supplied SDK path is both supported and required on Linux.
90
+ _msbuildDirectory = string.IsNullOrEmpty(MSBuildPath)
91
+ ? MsBuildUtility.GetMsBuildDirectoryFromMsBuildPath(MSBuildPath, MSBuildVersion, Console).Value.Path
92
+ : MSBuildPath;
88
93
  var context = new UpdateConsoleProjectContext(Console, FileConflictAction);
89
94
 
90
95
  var logger = new LoggerAdapter(context);
@@ -237,7 +237,7 @@ namespace NuGet.Packaging
237
237
  // do nothing here
238
238
  }
239
239
 
240
- public override Task<PrimarySignature> GetPrimarySignatureAsync(CancellationToken token)
240
+ public override Task<PrimarySignature?> GetPrimarySignatureAsync(CancellationToken token)
241
241
  {
242
242
  return TaskResult.Null<PrimarySignature>();
243
243
  }
@@ -262,7 +262,7 @@ namespace NuGet.Packaging
262
262
  return false;
263
263
  }
264
264
 
265
- public override string GetContentHash(CancellationToken token, Func<string> GetUnsignedPackageHash = null)
265
+ public override string GetContentHash(CancellationToken token, Func<string>? GetUnsignedPackageHash = null)
266
266
  {
267
267
  throw new NotImplementedException();
268
268
  }
@@ -12,6 +12,7 @@
12
12
 
13
13
  <ItemGroup>
14
14
  <Compile Include="$(NuGetSourceLocation)\src\NuGet.Core\NuGet.Protocol\**\*.cs" />
15
+ <Compile Include="$(SharedDirectory)\NuGetFeatureFlags.cs" />
15
16
  </ItemGroup>
16
17
 
17
18
  <ItemGroup>
@@ -41,6 +41,8 @@ internal static class EntryPointTestHelper
41
41
  // save packages
42
42
  await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, tempDirectory.DirectoryPath);
43
43
 
44
+ await GitTestHelper.InitializeRepositoryAsync(tempDirectory.DirectoryPath, files.Select(file => file.Path));
45
+
44
46
  var actualUrls = new List<string>();
45
47
  using var http = TestHttpServer.CreateTestStringServer((method, url) =>
46
48
  {
@@ -20,8 +20,12 @@ internal record NuGetContext : IDisposable
20
20
  public IMachineWideSettings MachineWideSettings { get; }
21
21
  public ImmutableArray<PackageSource> PackageSources { get; }
22
22
  public NuGet.Common.ILogger Logger { get; }
23
+ private readonly Func<PackageSource, SourceRepository> _sourceRepositoryFactory;
23
24
 
24
- public NuGetContext(string? currentDirectory = null, NuGet.Common.ILogger? logger = null)
25
+ public NuGetContext(
26
+ string? currentDirectory = null,
27
+ NuGet.Common.ILogger? logger = null,
28
+ Func<PackageSource, SourceRepository>? sourceRepositoryFactory = null)
25
29
  {
26
30
  SourceCacheContext = new SourceCacheContext();
27
31
  PackageDownloadContext = new PackageDownloadContext(SourceCacheContext);
@@ -36,6 +40,7 @@ internal record NuGetContext : IDisposable
36
40
  .Where(p => p.IsEnabled)
37
41
  .ToImmutableArray();
38
42
  Logger = logger ?? NullLogger.Instance;
43
+ _sourceRepositoryFactory = sourceRepositoryFactory ?? Repository.Factory.GetCoreV3;
39
44
  }
40
45
 
41
46
  public void Dispose()
@@ -83,7 +88,7 @@ internal record NuGetContext : IDisposable
83
88
  foreach (var source in sources)
84
89
  {
85
90
  message.AppendLine($" checking {source.Name}");
86
- var sourceRepository = Repository.Factory.GetCoreV3(source);
91
+ var sourceRepository = _sourceRepositoryFactory(source);
87
92
  var feed = await sourceRepository.GetResourceAsync<MetadataResource>(cancellationToken);
88
93
  if (feed is null)
89
94
  {
@@ -118,21 +123,24 @@ internal record NuGetContext : IDisposable
118
123
  }
119
124
 
120
125
  var downloadResource = await sourceRepository.GetResourceAsync<DownloadResource>(cancellationToken);
121
- using var downloadResult = await downloadResource.GetDownloadResourceResultAsync(packageIdentity, PackageDownloadContext, globalPackagesFolder, Logger, cancellationToken);
122
- if (downloadResult.Status == DownloadResourceResultStatus.Available)
126
+ if (downloadResource is not null)
123
127
  {
124
- var repositoryMetadata = downloadResult.PackageReader.NuspecReader.GetRepositoryMetadata();
125
- message.AppendLine($" repometadata: type=[{repositoryMetadata.Type}], url=[{repositoryMetadata.Url}], branch=[{repositoryMetadata.Branch}], commit=[{repositoryMetadata.Commit}]");
126
- if (!string.IsNullOrEmpty(repositoryMetadata.Url))
128
+ using var downloadResult = await downloadResource.GetDownloadResourceResultAsync(packageIdentity, PackageDownloadContext, globalPackagesFolder, Logger, cancellationToken);
129
+ if (downloadResult.Status == DownloadResourceResultStatus.Available &&
130
+ downloadResult.PackageReader is not null)
127
131
  {
128
- return repositoryMetadata.Url;
132
+ var repositoryMetadata = downloadResult.PackageReader.NuspecReader.GetRepositoryMetadata();
133
+ message.AppendLine($" repometadata: type=[{repositoryMetadata.Type}], url=[{repositoryMetadata.Url}], branch=[{repositoryMetadata.Branch}], commit=[{repositoryMetadata.Commit}]");
134
+ if (!string.IsNullOrEmpty(repositoryMetadata.Url))
135
+ {
136
+ return repositoryMetadata.Url;
137
+ }
138
+ }
139
+ else
140
+ {
141
+ message.AppendLine($" download result status: {downloadResult.Status}");
129
142
  }
130
143
  }
131
- else
132
- {
133
- message.AppendLine($" download result status: {downloadResult.Status}");
134
- }
135
-
136
144
  var metadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>(cancellationToken);
137
145
  if (metadataResource is not null)
138
146
  {
@@ -20,7 +20,9 @@ internal sealed class PackagesConfigBuildFile : XmlBuildFile
20
20
  }
21
21
  }
22
22
 
23
- public IEnumerable<IXmlElementSyntax> Packages => Contents.RootSyntax.GetElements("package", StringComparison.OrdinalIgnoreCase);
23
+ public IEnumerable<IXmlElementSyntax> Packages => (Contents.RootSyntax
24
+ ?? throw new UnparseableFileException("packages.config does not contain a root element", Path))
25
+ .GetElements("package", StringComparison.OrdinalIgnoreCase);
24
26
 
25
27
  public IEnumerable<Dependency> GetDependencies() => Packages
26
28
  .Select(p => new Dependency(
@@ -17,7 +17,8 @@ internal sealed class ProjectBuildFile : XmlBuildFile
17
17
 
18
18
  public static XmlDocumentSyntax Parse(string contents) => Parser.ParseText(contents);
19
19
 
20
- public IXmlElementSyntax ProjectNode => Contents.RootSyntax;
20
+ public IXmlElementSyntax ProjectNode => Contents.RootSyntax
21
+ ?? throw new UnparseableFileException("Project file does not contain a root element", Path);
21
22
 
22
23
  public IEnumerable<IXmlElementSyntax> SdkNodes => ProjectNode
23
24
  .GetElements("Sdk", StringComparison.OrdinalIgnoreCase);
@@ -142,7 +143,9 @@ internal sealed class ProjectBuildFile : XmlBuildFile
142
143
  .Where(e =>
143
144
  e.Name.Equals("ProjectReference", StringComparison.OrdinalIgnoreCase) ||
144
145
  e.Name.Equals("ProjectFile", StringComparison.OrdinalIgnoreCase))
145
- .Select(e => PathHelper.GetFullPathFromRelative(System.IO.Path.GetDirectoryName(Path)!, e.GetAttribute("Include").Value));
146
+ .Select(e => e.GetAttributeValueCaseInsensitive("Include")
147
+ ?? throw new UnparseableFileException($"`{e.Name}` element missing `Include` attribute", Path))
148
+ .Select(include => PathHelper.GetFullPathFromRelative(System.IO.Path.GetDirectoryName(Path)!, include));
146
149
 
147
150
  public void NormalizeDirectorySeparatorsInProject()
148
151
  {
@@ -169,11 +172,13 @@ internal sealed class ProjectBuildFile : XmlBuildFile
169
172
  updatedXml = Contents.ReplaceNodes(errorsWithConditions,
170
173
  (_, n) =>
171
174
  {
172
- var conditionAttr = n.GetAttribute("Condition");
175
+ var conditionAttr = n.GetAttribute("Condition")
176
+ ?? throw new InvalidOperationException("Expected Error element to have a Condition attribute");
173
177
  var newConditionAttr = conditionAttr.WithValue(conditionAttr.Value.Replace("/", "\\"));
174
178
  n = (XmlEmptyElementSyntax)n.ReplaceAttribute(conditionAttr, newConditionAttr).AsNode;
175
179
 
176
- var textAttr = n.GetAttribute("Text");
180
+ var textAttr = n.GetAttribute("Text")
181
+ ?? throw new InvalidOperationException("Expected Error element to have a Text attribute");
177
182
  var newTextAttr = textAttr.WithValue(textAttr.Value.Replace("/", "\\"));
178
183
  return n.ReplaceAttribute(textAttr, newTextAttr).AsNode;
179
184
  });
@@ -191,11 +196,13 @@ internal sealed class ProjectBuildFile : XmlBuildFile
191
196
  updatedXml = Contents.ReplaceNodes(importsWithConditions,
192
197
  (_, n) =>
193
198
  {
194
- var projectAttr = n.GetAttribute("Project");
199
+ var projectAttr = n.GetAttribute("Project")
200
+ ?? throw new InvalidOperationException("Expected Import element to have a Project attribute");
195
201
  var newProjectAttr = projectAttr.WithValue(projectAttr.Value.Replace("/", "\\"));
196
202
  n = (XmlEmptyElementSyntax)n.ReplaceAttribute(projectAttr, newProjectAttr).AsNode;
197
203
 
198
- var conditionAttr = n.GetAttribute("Condition");
204
+ var conditionAttr = n.GetAttribute("Condition")
205
+ ?? throw new InvalidOperationException("Expected Import element to have a Condition attribute");
199
206
  var newConditionAttr = conditionAttr.WithValue(conditionAttr.Value.Replace("/", "\\"));
200
207
  return n.ReplaceAttribute(conditionAttr, newConditionAttr).AsNode;
201
208
  });
@@ -8,7 +8,7 @@ namespace NuGetUpdater.Core.Run.ApiModel;
8
8
 
9
9
  public sealed record CreatePullRequest : MessageBase
10
10
  {
11
- public required ReportedDependency[] Dependencies { get; init; }
11
+ public required ReportedDependencyWithDirectory[] Dependencies { get; init; }
12
12
 
13
13
  [JsonPropertyName("updated-dependency-files")]
14
14
  public required DependencyFile[] UpdatedDependencyFiles { get; init; }
@@ -102,25 +102,34 @@ public sealed record Job
102
102
  return existingPullRequests;
103
103
  }
104
104
 
105
- public Tuple<string?, ImmutableArray<PullRequestDependency>>? GetExistingPullRequestForDependencies(IEnumerable<Dependency> dependencies, bool considerVersions)
105
+ public Tuple<string?, ImmutableArray<PullRequestDependency>>? GetExistingPullRequestForDependencies(IEnumerable<ReportedDependencyWithDirectory> dependencies, bool considerVersions)
106
106
  {
107
- if (dependencies.Any(d => d.Version is null))
107
+ var desiredDependencies = dependencies.ToArray();
108
+ if (desiredDependencies.Any(d => d.Version is null))
108
109
  {
109
110
  return null;
110
111
  }
111
112
 
112
- string CreateIdentifier(string dependencyName, string dependencyVersion)
113
+ bool NamesAndVersionsMatch(ReportedDependencyWithDirectory desiredDependency, PullRequestDependency existingDependency)
113
114
  {
114
- return $"{dependencyName}/{(considerVersions ? dependencyVersion : null)}";
115
+ return desiredDependency.Name.Equals(existingDependency.DependencyName, StringComparison.OrdinalIgnoreCase) &&
116
+ (!considerVersions ||
117
+ desiredDependency.Version!.Equals(existingDependency.DependencyVersion.ToString(), StringComparison.OrdinalIgnoreCase));
118
+ }
119
+
120
+ bool DependenciesMatch(ReportedDependencyWithDirectory desiredDependency, PullRequestDependency existingDependency)
121
+ {
122
+ return NamesAndVersionsMatch(desiredDependency, existingDependency) &&
123
+ (existingDependency.Directory is null ||
124
+ desiredDependency.Directory.Equals(existingDependency.Directory, StringComparison.Ordinal));
115
125
  }
116
126
 
117
- var desiredDependencySet = dependencies.Select(d => CreateIdentifier(d.Name, d.Version!)).ToHashSet(StringComparer.OrdinalIgnoreCase);
118
127
  var existingPullRequests = GetAllExistingPullRequests();
119
128
  var existingPullRequest = existingPullRequests
120
129
  .FirstOrDefault(pr =>
121
130
  {
122
- var prDependencySet = pr.Item2.Select(d => CreateIdentifier(d.DependencyName, d.DependencyVersion.ToString())).ToHashSet(StringComparer.OrdinalIgnoreCase);
123
- return prDependencySet.SetEquals(desiredDependencySet);
131
+ return desiredDependencies.All(desired => pr.Item2.Any(existing => DependenciesMatch(desired, existing))) &&
132
+ pr.Item2.All(existing => desiredDependencies.Any(desired => DependenciesMatch(desired, existing)));
124
133
  });
125
134
  return existingPullRequest;
126
135
  }
@@ -2,7 +2,7 @@ using System.Text.Json.Serialization;
2
2
 
3
3
  namespace NuGetUpdater.Core.Run.ApiModel;
4
4
 
5
- public sealed record ReportedDependency
5
+ public record ReportedDependency
6
6
  {
7
7
  public required string Name { get; init; }
8
8
  public required string? Version { get; init; }
@@ -0,0 +1,19 @@
1
+ namespace NuGetUpdater.Core.Run.ApiModel;
2
+
3
+ public sealed record ReportedDependencyWithDirectory : ReportedDependency
4
+ {
5
+ public required string Directory { get; init; }
6
+
7
+ public static ReportedDependencyWithDirectory From(ReportedDependency dependency, string directory)
8
+ {
9
+ return new ReportedDependencyWithDirectory()
10
+ {
11
+ Name = dependency.Name,
12
+ Version = dependency.Version,
13
+ Requirements = dependency.Requirements,
14
+ PreviousVersion = dependency.PreviousVersion,
15
+ PreviousRequirements = dependency.PreviousRequirements,
16
+ Directory = directory,
17
+ };
18
+ }
19
+ }
@@ -0,0 +1,64 @@
1
+ using static NuGetUpdater.Core.Utilities.EOLHandling;
2
+
3
+ namespace NuGetUpdater.Core.Run;
4
+
5
+ internal sealed class GitEOLMetadataProvider : IEOLMetadataProvider
6
+ {
7
+ public async Task<Dictionary<string, EOLType>> GetIndexEOLsAsync(
8
+ DirectoryInfo repoContentsPath,
9
+ IReadOnlyCollection<string> repoRelativePaths)
10
+ {
11
+ if (repoRelativePaths.Count == 0)
12
+ {
13
+ return new Dictionary<string, EOLType>(StringComparer.Ordinal);
14
+ }
15
+
16
+ var arguments = new List<string>
17
+ {
18
+ "--literal-pathspecs",
19
+ "ls-files",
20
+ "--eol",
21
+ "-z",
22
+ "--",
23
+ };
24
+ arguments.AddRange(repoRelativePaths);
25
+
26
+ var (exitCode, stdout, stderr) = await ProcessEx.RunAsync("git", arguments, repoContentsPath.FullName);
27
+ if (exitCode != 0)
28
+ {
29
+ throw new InvalidOperationException($"Unable to determine Git index line endings:\n{stderr}");
30
+ }
31
+
32
+ return ParseOutput(stdout);
33
+ }
34
+
35
+ internal static Dictionary<string, EOLType> ParseOutput(string output)
36
+ {
37
+ var result = new Dictionary<string, EOLType>(StringComparer.Ordinal);
38
+ foreach (var record in output.Split('\0', StringSplitOptions.RemoveEmptyEntries))
39
+ {
40
+ var separatorIndex = record.IndexOf('\t');
41
+ if (separatorIndex < 0)
42
+ {
43
+ continue;
44
+ }
45
+
46
+ var metadata = record[..separatorIndex];
47
+ var path = record[(separatorIndex + 1)..].NormalizePathToUnix();
48
+ var indexMetadata = metadata.Split(' ', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
49
+ var eol = indexMetadata switch
50
+ {
51
+ "i/lf" => EOLType.LF,
52
+ "i/crlf" => EOLType.CRLF,
53
+ _ => (EOLType?)null,
54
+ };
55
+
56
+ if (eol is not null)
57
+ {
58
+ result[path] = eol.Value;
59
+ }
60
+ }
61
+
62
+ return result;
63
+ }
64
+ }
@@ -0,0 +1,10 @@
1
+ using static NuGetUpdater.Core.Utilities.EOLHandling;
2
+
3
+ namespace NuGetUpdater.Core.Run;
4
+
5
+ internal interface IEOLMetadataProvider
6
+ {
7
+ Task<Dictionary<string, EOLType>> GetIndexEOLsAsync(
8
+ DirectoryInfo repoContentsPath,
9
+ IReadOnlyCollection<string> repoRelativePaths);
10
+ }