dependabot-nuget 0.289.0 → 0.290.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 +4 -4
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +7 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +26 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +0 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +3 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/CompatabilityChecker.cs +24 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/NuGetContext.cs +0 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +17 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Advisory.cs +13 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/AllowedUpdate.cs +18 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Condition.cs +19 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyGroup.cs +8 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/GroupPullRequest.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/Job.cs +13 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PullRequest.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/RequirementsUpdateStrategy.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +24 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/VersionConverter.cs +19 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/BindingRedirectManager.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackagesConfigUpdater.cs +13 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/JsonHelper.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTestBase.cs +5 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.DotNetToolsJson.cs +45 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +35 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +0 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +85 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +7 -31
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +340 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TemporaryDirectory.cs +18 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackagesConfigUpdaterTests.cs +24 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +0 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DotNetTools.cs +84 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +66 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +55 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +0 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +557 -713
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/PathHelperTests.cs +2 -2
- data/lib/dependabot/nuget/analysis/analysis_json_reader.rb +1 -1
- data/lib/dependabot/nuget/analysis/dependency_analysis.rb +3 -3
- data/lib/dependabot/nuget/discovery/dependency_details.rb +10 -3
- data/lib/dependabot/nuget/discovery/dependency_file_discovery.rb +8 -12
- data/lib/dependabot/nuget/discovery/discovery_json_reader.rb +214 -29
- data/lib/dependabot/nuget/discovery/project_discovery.rb +41 -8
- data/lib/dependabot/nuget/discovery/workspace_discovery.rb +14 -19
- data/lib/dependabot/nuget/file_fetcher.rb +2 -3
- data/lib/dependabot/nuget/file_parser.rb +2 -3
- data/lib/dependabot/nuget/file_updater.rb +13 -13
- data/lib/dependabot/nuget/native_helpers.rb +14 -5
- data/lib/dependabot/nuget/update_checker/requirements_updater.rb +23 -27
- data/lib/dependabot/nuget/update_checker.rb +116 -190
- metadata +18 -29
- data/lib/dependabot/nuget/discovery/directory_packages_props_discovery.rb +0 -43
- data/lib/dependabot/nuget/http_response_helpers.rb +0 -19
- data/lib/dependabot/nuget/native_discovery/native_dependency_details.rb +0 -102
- data/lib/dependabot/nuget/native_discovery/native_dependency_file_discovery.rb +0 -122
- data/lib/dependabot/nuget/native_discovery/native_discovery_json_reader.rb +0 -277
- data/lib/dependabot/nuget/native_discovery/native_evaluation_details.rb +0 -63
- data/lib/dependabot/nuget/native_discovery/native_project_discovery.rb +0 -104
- data/lib/dependabot/nuget/native_discovery/native_property_details.rb +0 -43
- data/lib/dependabot/nuget/native_discovery/native_workspace_discovery.rb +0 -61
- data/lib/dependabot/nuget/native_update_checker/native_requirements_updater.rb +0 -105
- data/lib/dependabot/nuget/native_update_checker/native_update_checker.rb +0 -214
- data/lib/dependabot/nuget/nuget_client.rb +0 -223
- data/lib/dependabot/nuget/update_checker/compatibility_checker.rb +0 -116
- data/lib/dependabot/nuget/update_checker/dependency_finder.rb +0 -297
- data/lib/dependabot/nuget/update_checker/nupkg_fetcher.rb +0 -221
- data/lib/dependabot/nuget/update_checker/nuspec_fetcher.rb +0 -110
- data/lib/dependabot/nuget/update_checker/property_updater.rb +0 -196
- data/lib/dependabot/nuget/update_checker/repository_finder.rb +0 -466
- data/lib/dependabot/nuget/update_checker/tfm_comparer.rb +0 -34
- data/lib/dependabot/nuget/update_checker/tfm_finder.rb +0 -30
- data/lib/dependabot/nuget/update_checker/version_finder.rb +0 -449
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3ca35ae6f3d02ce8507984f89e7c929eb75cec515b39af94db530d6600f0caa
|
|
4
|
+
data.tar.gz: cbd548418a3e25163af5d8543109b520b6c9bd9e2bf5a5869421f8fe838128d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9395fb4eea720fbcba3b0cef278344b41a9ace7315ce62f5cb193bb05af2aa23553130dab3112cb900d39ad12cadd321e64291d72e4e21e4bbee2f2b7610626a
|
|
7
|
+
data.tar.gz: d74843dc18cab2fd6a58a31f1df2a4172cb308a3a2e452db7056727666e9f153b611046c25bd78f7c0679abe8be4eb57462886d87c8010ba21ac0a2ee316120e
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<PackageVersion Include="Microsoft.Build.Framework" Version="$(MSBuildPackageVersion)" />
|
|
17
17
|
<PackageVersion Include="Microsoft.Build.Tasks.Core" Version="$(MSBuildPackageVersion)" />
|
|
18
18
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="$(MSBuildPackageVersion)" />
|
|
19
|
-
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.
|
|
19
|
+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
|
|
20
20
|
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
|
|
21
21
|
<PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="9.0.0" />
|
|
22
22
|
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="9.0.0" />
|
|
@@ -7,6 +7,7 @@ namespace NuGetUpdater.Cli.Commands;
|
|
|
7
7
|
|
|
8
8
|
internal static class AnalyzeCommand
|
|
9
9
|
{
|
|
10
|
+
internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
|
|
10
11
|
internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root") { IsRequired = true };
|
|
11
12
|
internal static readonly Option<FileInfo> DependencyFilePathOption = new("--dependency-file-path") { IsRequired = true };
|
|
12
13
|
internal static readonly Option<FileInfo> DiscoveryFilePathOption = new("--discovery-file-path") { IsRequired = true };
|
|
@@ -16,6 +17,7 @@ internal static class AnalyzeCommand
|
|
|
16
17
|
{
|
|
17
18
|
Command command = new("analyze", "Determines how to update a dependency based on the workspace discovery information.")
|
|
18
19
|
{
|
|
20
|
+
JobPathOption,
|
|
19
21
|
RepoRootOption,
|
|
20
22
|
DependencyFilePathOption,
|
|
21
23
|
DiscoveryFilePathOption,
|
|
@@ -24,11 +26,13 @@ internal static class AnalyzeCommand
|
|
|
24
26
|
|
|
25
27
|
command.TreatUnmatchedTokensAsErrors = true;
|
|
26
28
|
|
|
27
|
-
command.SetHandler(async (repoRoot, discoveryPath, dependencyPath, analysisDirectory) =>
|
|
29
|
+
command.SetHandler(async (jobPath, repoRoot, discoveryPath, dependencyPath, analysisDirectory) =>
|
|
28
30
|
{
|
|
29
|
-
var
|
|
31
|
+
var logger = new ConsoleLogger();
|
|
32
|
+
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
|
|
33
|
+
var worker = new AnalyzeWorker(experimentsManager, logger);
|
|
30
34
|
await worker.RunAsync(repoRoot.FullName, discoveryPath.FullName, dependencyPath.FullName, analysisDirectory.FullName);
|
|
31
|
-
}, RepoRootOption, DiscoveryFilePathOption, DependencyFilePathOption, AnalysisFolderOption);
|
|
35
|
+
}, JobPathOption, RepoRootOption, DiscoveryFilePathOption, DependencyFilePathOption, AnalysisFolderOption);
|
|
32
36
|
|
|
33
37
|
return command;
|
|
34
38
|
}
|
|
@@ -36,7 +36,7 @@ internal static class RunCommand
|
|
|
36
36
|
var logger = new ConsoleLogger();
|
|
37
37
|
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
|
|
38
38
|
var discoverWorker = new DiscoveryWorker(experimentsManager, logger);
|
|
39
|
-
var analyzeWorker = new AnalyzeWorker(logger);
|
|
39
|
+
var analyzeWorker = new AnalyzeWorker(experimentsManager, logger);
|
|
40
40
|
var updateWorker = new UpdaterWorker(experimentsManager, logger);
|
|
41
41
|
var worker = new RunWorker(apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
|
|
42
42
|
await worker.RunAsync(jobPath, repoContentsPath, baseCommitSha, outputPath);
|
|
@@ -26,6 +26,8 @@ public partial class EntryPointTests
|
|
|
26
26
|
await RunAsync(path =>
|
|
27
27
|
[
|
|
28
28
|
"analyze",
|
|
29
|
+
"--job-path",
|
|
30
|
+
Path.Combine(path, "job.json"),
|
|
29
31
|
"--repo-root",
|
|
30
32
|
path,
|
|
31
33
|
"--discovery-file-path",
|
|
@@ -144,6 +146,8 @@ public partial class EntryPointTests
|
|
|
144
146
|
await RunAsync(path =>
|
|
145
147
|
[
|
|
146
148
|
"analyze",
|
|
149
|
+
"--job-path",
|
|
150
|
+
Path.Combine(path, "job.json"),
|
|
147
151
|
"--repo-root",
|
|
148
152
|
path,
|
|
149
153
|
"--discovery-file-path",
|
|
@@ -231,6 +235,8 @@ public partial class EntryPointTests
|
|
|
231
235
|
await RunAsync(path =>
|
|
232
236
|
[
|
|
233
237
|
"analyze",
|
|
238
|
+
"--job-path",
|
|
239
|
+
Path.Combine(path, "job.json"),
|
|
234
240
|
"--repo-root",
|
|
235
241
|
path,
|
|
236
242
|
"--discovery-file-path",
|
|
@@ -308,8 +314,16 @@ public partial class EntryPointTests
|
|
|
308
314
|
);
|
|
309
315
|
}
|
|
310
316
|
|
|
311
|
-
private static async Task RunAsync(
|
|
317
|
+
private static async Task RunAsync(
|
|
318
|
+
Func<string, string[]> getArgs,
|
|
319
|
+
string dependencyName,
|
|
320
|
+
TestFile[] initialFiles,
|
|
321
|
+
ExpectedAnalysisResult expectedResult,
|
|
322
|
+
MockNuGetPackage[]? packages = null,
|
|
323
|
+
ExperimentsManager? experimentsManager = null
|
|
324
|
+
)
|
|
312
325
|
{
|
|
326
|
+
experimentsManager ??= new ExperimentsManager();
|
|
313
327
|
var actualResult = await RunAnalyzerAsync(dependencyName, initialFiles, async path =>
|
|
314
328
|
{
|
|
315
329
|
var sb = new StringBuilder();
|
|
@@ -322,8 +336,19 @@ public partial class EntryPointTests
|
|
|
322
336
|
|
|
323
337
|
try
|
|
324
338
|
{
|
|
339
|
+
await UpdateWorkerTestBase.MockJobFileInDirectory(path, experimentsManager);
|
|
325
340
|
await UpdateWorkerTestBase.MockNuGetPackagesInDirectory(packages, path);
|
|
326
341
|
var args = getArgs(path);
|
|
342
|
+
|
|
343
|
+
// manually pull out the experiments manager for the validate step below
|
|
344
|
+
for (int i = 0; i < args.Length - 1; i++)
|
|
345
|
+
{
|
|
346
|
+
if (args[i] == "--job-path")
|
|
347
|
+
{
|
|
348
|
+
experimentsManager = await ExperimentsManager.FromJobFileAsync(args[i + 1], new TestLogger());
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
327
352
|
var result = await Program.Main(args);
|
|
328
353
|
if (result != 0)
|
|
329
354
|
{
|
|
@@ -393,7 +393,8 @@ public partial class EntryPointTests
|
|
|
393
393
|
TestFile[] initialFiles,
|
|
394
394
|
ExpectedWorkspaceDiscoveryResult expectedResult,
|
|
395
395
|
MockNuGetPackage[]? packages = null,
|
|
396
|
-
ExperimentsManager? experimentsManager = null
|
|
396
|
+
ExperimentsManager? experimentsManager = null
|
|
397
|
+
)
|
|
397
398
|
{
|
|
398
399
|
experimentsManager ??= new ExperimentsManager();
|
|
399
400
|
var actualResult = await RunDiscoveryAsync(initialFiles, async path =>
|
|
@@ -16,6 +16,7 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
|
16
16
|
{
|
|
17
17
|
public const string AnalysisDirectoryName = "./.dependabot/analysis";
|
|
18
18
|
|
|
19
|
+
private readonly ExperimentsManager _experimentsManager;
|
|
19
20
|
private readonly ILogger _logger;
|
|
20
21
|
|
|
21
22
|
internal static readonly JsonSerializerOptions SerializerOptions = new()
|
|
@@ -24,8 +25,9 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
|
24
25
|
Converters = { new JsonStringEnumConverter(), new RequirementArrayConverter() },
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
public AnalyzeWorker(ILogger logger)
|
|
28
|
+
public AnalyzeWorker(ExperimentsManager experimentsManager, ILogger logger)
|
|
28
29
|
{
|
|
30
|
+
_experimentsManager = experimentsManager;
|
|
29
31
|
_logger = logger;
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -80,9 +80,9 @@ internal static class CompatibilityChecker
|
|
|
80
80
|
NuGetContext nugetContext,
|
|
81
81
|
CancellationToken cancellationToken)
|
|
82
82
|
{
|
|
83
|
-
var
|
|
84
|
-
var readers = File.Exists(
|
|
85
|
-
? ReadPackage(
|
|
83
|
+
var packagePath = GetPackagePath(package, nugetContext);
|
|
84
|
+
var readers = File.Exists(packagePath)
|
|
85
|
+
? ReadPackage(packagePath)
|
|
86
86
|
: await DownloadPackageAsync(package, nugetContext, cancellationToken);
|
|
87
87
|
return readers;
|
|
88
88
|
}
|
|
@@ -134,10 +134,10 @@ internal static class CompatibilityChecker
|
|
|
134
134
|
return (isDevDependency, tfms.ToImmutableArray());
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
internal static PackageReaders ReadPackage(string
|
|
137
|
+
internal static PackageReaders ReadPackage(string packagePath)
|
|
138
138
|
{
|
|
139
139
|
var stream = new FileStream(
|
|
140
|
-
|
|
140
|
+
packagePath,
|
|
141
141
|
FileMode.Open,
|
|
142
142
|
FileAccess.Read,
|
|
143
143
|
FileShare.Read,
|
|
@@ -194,8 +194,8 @@ internal static class CompatibilityChecker
|
|
|
194
194
|
context.Logger,
|
|
195
195
|
cancellationToken);
|
|
196
196
|
|
|
197
|
-
var
|
|
198
|
-
var isDownloaded = await downloader.CopyNupkgFileToAsync(
|
|
197
|
+
var packagePath = GetPackagePath(package, context);
|
|
198
|
+
var isDownloaded = await downloader.CopyNupkgFileToAsync(packagePath, cancellationToken);
|
|
199
199
|
if (!isDownloaded)
|
|
200
200
|
{
|
|
201
201
|
continue;
|
|
@@ -207,6 +207,21 @@ internal static class CompatibilityChecker
|
|
|
207
207
|
return null;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
internal static string
|
|
211
|
-
|
|
210
|
+
internal static string GetPackagePath(PackageIdentity package, NuGetContext context)
|
|
211
|
+
{
|
|
212
|
+
// https://learn.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders
|
|
213
|
+
var nugetPackagesPath = Environment.GetEnvironmentVariable("NUGET_PACKAGES");
|
|
214
|
+
if (nugetPackagesPath is null)
|
|
215
|
+
{
|
|
216
|
+
// n.b., this path should never be hit during a unit test
|
|
217
|
+
nugetPackagesPath = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var normalizedName = package.Id.ToLowerInvariant();
|
|
221
|
+
var normalizedVersion = package.Version.ToNormalizedString().ToLowerInvariant();
|
|
222
|
+
var packageDirectory = Path.Join(nugetPackagesPath, normalizedName, normalizedVersion);
|
|
223
|
+
Directory.CreateDirectory(packageDirectory);
|
|
224
|
+
var packagePath = Path.Join(packageDirectory, $"{normalizedName}.{normalizedVersion}.nupkg");
|
|
225
|
+
return packagePath;
|
|
226
|
+
}
|
|
212
227
|
}
|
|
@@ -20,7 +20,6 @@ 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
|
-
public string TempPackageDirectory { get; }
|
|
24
23
|
|
|
25
24
|
public NuGetContext(string? currentDirectory = null, NuGet.Common.ILogger? logger = null)
|
|
26
25
|
{
|
|
@@ -37,23 +36,11 @@ internal record NuGetContext : IDisposable
|
|
|
37
36
|
.Where(p => p.IsEnabled)
|
|
38
37
|
.ToImmutableArray();
|
|
39
38
|
Logger = logger ?? NullLogger.Instance;
|
|
40
|
-
TempPackageDirectory = Path.Combine(Path.GetTempPath(), $"dependabot-packages_{Guid.NewGuid():d}");
|
|
41
|
-
Directory.CreateDirectory(TempPackageDirectory);
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
public void Dispose()
|
|
45
42
|
{
|
|
46
43
|
SourceCacheContext.Dispose();
|
|
47
|
-
if (Directory.Exists(TempPackageDirectory))
|
|
48
|
-
{
|
|
49
|
-
try
|
|
50
|
-
{
|
|
51
|
-
Directory.Delete(TempPackageDirectory, recursive: true);
|
|
52
|
-
}
|
|
53
|
-
catch
|
|
54
|
-
{
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
44
|
}
|
|
58
45
|
|
|
59
46
|
private readonly Dictionary<PackageIdentity, string?> _packageInfoUrlCache = new();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
using System.Text.Json;
|
|
2
|
+
using System.Text.Json.Serialization;
|
|
3
|
+
|
|
4
|
+
namespace NuGetUpdater.Core.Analyze;
|
|
5
|
+
|
|
6
|
+
public class RequirementConverter : JsonConverter<Requirement>
|
|
7
|
+
{
|
|
8
|
+
public override Requirement? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
9
|
+
{
|
|
10
|
+
return Requirement.Parse(reader.GetString()!);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public override void Write(Utf8JsonWriter writer, Requirement value, JsonSerializerOptions options)
|
|
14
|
+
{
|
|
15
|
+
writer.WriteStringValue(value.ToString());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
using System.Collections.Immutable;
|
|
2
|
+
|
|
3
|
+
using NuGetUpdater.Core.Analyze;
|
|
4
|
+
|
|
5
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
6
|
+
|
|
7
|
+
public record Advisory
|
|
8
|
+
{
|
|
9
|
+
public required string DependencyName { get; init; }
|
|
10
|
+
public ImmutableArray<Requirement>? AffectedVersions { get; init; } = null;
|
|
11
|
+
public ImmutableArray<Requirement>? PatchedVersions { get; init; } = null;
|
|
12
|
+
public ImmutableArray<Requirement>? UnaffectedVersions { get; init; } = null;
|
|
13
|
+
}
|
|
@@ -2,5 +2,22 @@ namespace NuGetUpdater.Core.Run.ApiModel;
|
|
|
2
2
|
|
|
3
3
|
public sealed record AllowedUpdate
|
|
4
4
|
{
|
|
5
|
-
public
|
|
5
|
+
public DependencyType DependencyType { get; init; } = DependencyType.All;
|
|
6
|
+
public string? DependencyName { get; init; } = null;
|
|
7
|
+
public UpdateType UpdateType { get; init; } = UpdateType.All;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public enum DependencyType
|
|
11
|
+
{
|
|
12
|
+
All,
|
|
13
|
+
Direct,
|
|
14
|
+
Indirect,
|
|
15
|
+
Development,
|
|
16
|
+
Production,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public enum UpdateType
|
|
20
|
+
{
|
|
21
|
+
All,
|
|
22
|
+
Security,
|
|
6
23
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
using System.Text.Json.Serialization;
|
|
2
|
+
|
|
3
|
+
using NuGetUpdater.Core.Analyze;
|
|
4
|
+
|
|
5
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
6
|
+
|
|
7
|
+
public sealed record Condition
|
|
8
|
+
{
|
|
9
|
+
[JsonPropertyName("dependency-name")]
|
|
10
|
+
public required string DependencyName { get; init; }
|
|
11
|
+
[JsonPropertyName("source")]
|
|
12
|
+
public string? Source { get; init; } = null;
|
|
13
|
+
[JsonPropertyName("update-types")]
|
|
14
|
+
public string[] UpdateTypes { get; init; } = [];
|
|
15
|
+
[JsonPropertyName("updated-at")]
|
|
16
|
+
public DateTime? UpdatedAt { get; init; } = null;
|
|
17
|
+
[JsonPropertyName("version-requirement")]
|
|
18
|
+
public Requirement? VersionRequirement { get; init; } = null;
|
|
19
|
+
}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
+
using System.Collections.Immutable;
|
|
1
2
|
using System.Text.Json;
|
|
2
3
|
using System.Text.Json.Serialization;
|
|
3
4
|
|
|
5
|
+
using NuGet.Credentials;
|
|
6
|
+
|
|
4
7
|
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
5
8
|
|
|
6
9
|
public sealed record Job
|
|
7
10
|
{
|
|
8
11
|
public string PackageManager { get; init; } = "nuget";
|
|
9
|
-
public AllowedUpdate
|
|
12
|
+
public ImmutableArray<AllowedUpdate> AllowedUpdates { get; init; } = [new AllowedUpdate()];
|
|
10
13
|
|
|
11
14
|
[JsonConverter(typeof(NullAsBoolConverter))]
|
|
12
15
|
public bool Debug { get; init; } = false;
|
|
13
|
-
public
|
|
14
|
-
public
|
|
16
|
+
public ImmutableArray<DependencyGroup> DependencyGroups { get; init; } = [];
|
|
17
|
+
public ImmutableArray<string>? Dependencies { get; init; } = null;
|
|
15
18
|
public string? DependencyGroupToRefresh { get; init; } = null;
|
|
16
|
-
public
|
|
17
|
-
public
|
|
19
|
+
public ImmutableArray<ImmutableArray<PullRequest>> ExistingPullRequests { get; init; } = [];
|
|
20
|
+
public ImmutableArray<GroupPullRequest> ExistingGroupPullRequests { get; init; } = [];
|
|
18
21
|
public Dictionary<string, object>? Experiments { get; init; } = null;
|
|
19
|
-
public
|
|
22
|
+
public Condition[] IgnoreConditions { get; init; } = [];
|
|
20
23
|
public bool LockfileOnly { get; init; } = false;
|
|
21
|
-
public
|
|
22
|
-
public
|
|
24
|
+
public RequirementsUpdateStrategy? RequirementsUpdateStrategy { get; init; } = null;
|
|
25
|
+
public ImmutableArray<Advisory> SecurityAdvisories { get; init; } = [];
|
|
23
26
|
public bool SecurityUpdatesOnly { get; init; } = false;
|
|
24
27
|
public required JobSource Source { get; init; }
|
|
25
28
|
public bool UpdateSubdependencies { get; init; } = false;
|
|
@@ -27,8 +30,8 @@ public sealed record Job
|
|
|
27
30
|
public bool VendorDependencies { get; init; } = false;
|
|
28
31
|
public bool RejectExternalCode { get; init; } = false;
|
|
29
32
|
public bool RepoPrivate { get; init; } = false;
|
|
30
|
-
public
|
|
31
|
-
public
|
|
33
|
+
public CommitOptions? CommitMessageOptions { get; init; } = null;
|
|
34
|
+
public ImmutableArray<Dictionary<string, string>>? CredentialsMetadata { get; init; } = null;
|
|
32
35
|
public int MaxUpdaterRunTime { get; init; } = 0;
|
|
33
36
|
|
|
34
37
|
public IEnumerable<string> GetAllDirectories()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
using NuGet.Versioning;
|
|
2
|
+
|
|
3
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
4
|
+
|
|
5
|
+
public record PullRequest
|
|
6
|
+
{
|
|
7
|
+
public required string DependencyName { get; init; }
|
|
8
|
+
public required NuGetVersion DependencyVersion { get; init; }
|
|
9
|
+
public bool DependencyRemoved { get; init; } = false;
|
|
10
|
+
public string? Directory { get; init; } = null;
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
using System.Text.Json.Serialization;
|
|
2
|
+
|
|
3
|
+
namespace NuGetUpdater.Core.Run.ApiModel;
|
|
4
|
+
|
|
5
|
+
public enum RequirementsUpdateStrategy
|
|
6
|
+
{
|
|
7
|
+
[JsonStringEnumMemberName("bump_versions")]
|
|
8
|
+
BumpVersions,
|
|
9
|
+
[JsonStringEnumMemberName("bump_versions_if_necessary")]
|
|
10
|
+
BumpVersionsIfNecessary,
|
|
11
|
+
[JsonStringEnumMemberName("lockfile_only")]
|
|
12
|
+
LockfileOnly,
|
|
13
|
+
[JsonStringEnumMemberName("widen_ranges")]
|
|
14
|
+
WidenRanges,
|
|
15
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
using System.Collections.Immutable;
|
|
1
2
|
using System.Net;
|
|
2
3
|
using System.Text;
|
|
3
4
|
using System.Text.Json;
|
|
@@ -21,7 +22,7 @@ public class RunWorker
|
|
|
21
22
|
{
|
|
22
23
|
PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower,
|
|
23
24
|
WriteIndented = true,
|
|
24
|
-
Converters = { new JsonStringEnumConverter() },
|
|
25
|
+
Converters = { new JsonStringEnumConverter(), new RequirementConverter(), new VersionConverter() },
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
public RunWorker(IApiHandler apiHandler, IDiscoveryWorker discoverWorker, IAnalyzeWorker analyzeWorker, IUpdaterWorker updateWorker, ILogger logger)
|
|
@@ -123,9 +124,8 @@ public class RunWorker
|
|
|
123
124
|
// TODO: pull out relevant dependencies, then check each for updates and track the changes
|
|
124
125
|
// TODO: for each top-level dependency, _or_ specific dependency (if security, use transitive)
|
|
125
126
|
var originalDependencyFileContents = new Dictionary<string, string>();
|
|
126
|
-
var allowedUpdates = job.AllowedUpdates ?? [];
|
|
127
127
|
var actualUpdatedDependencies = new List<ReportedDependency>();
|
|
128
|
-
if (
|
|
128
|
+
if (job.AllowedUpdates.Any(a => a.UpdateType == UpdateType.All))
|
|
129
129
|
{
|
|
130
130
|
await _apiHandler.IncrementMetric(new()
|
|
131
131
|
{
|
|
@@ -173,12 +173,13 @@ public class RunWorker
|
|
|
173
173
|
continue;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
var ignoredVersions = GetIgnoredRequirementsForDependency(job, dependency.Name);
|
|
176
177
|
var dependencyInfo = new DependencyInfo()
|
|
177
178
|
{
|
|
178
179
|
Name = dependency.Name,
|
|
179
180
|
Version = dependency.Version!,
|
|
180
181
|
IsVulnerable = false,
|
|
181
|
-
IgnoredVersions =
|
|
182
|
+
IgnoredVersions = ignoredVersions,
|
|
182
183
|
Vulnerabilities = [],
|
|
183
184
|
};
|
|
184
185
|
var analysisResult = await _analyzeWorker.RunAsync(repoContentsPath.FullName, discoveryResult, dependencyInfo);
|
|
@@ -303,6 +304,25 @@ public class RunWorker
|
|
|
303
304
|
return result;
|
|
304
305
|
}
|
|
305
306
|
|
|
307
|
+
internal static ImmutableArray<Requirement> GetIgnoredRequirementsForDependency(Job job, string dependencyName)
|
|
308
|
+
{
|
|
309
|
+
var ignoreConditions = job.IgnoreConditions
|
|
310
|
+
.Where(c => c.DependencyName.Equals(dependencyName, StringComparison.OrdinalIgnoreCase))
|
|
311
|
+
.ToArray();
|
|
312
|
+
if (ignoreConditions.Length == 1 && ignoreConditions[0].VersionRequirement is null)
|
|
313
|
+
{
|
|
314
|
+
// if only one match with no version requirement, ignore all versions
|
|
315
|
+
return [Requirement.Parse("> 0.0.0")];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
var ignoredVersions = ignoreConditions
|
|
319
|
+
.Select(c => c.VersionRequirement)
|
|
320
|
+
.Where(r => r is not null)
|
|
321
|
+
.Cast<Requirement>()
|
|
322
|
+
.ToImmutableArray();
|
|
323
|
+
return ignoredVersions;
|
|
324
|
+
}
|
|
325
|
+
|
|
306
326
|
internal static UpdatedDependencyList GetUpdatedDependencyListFromDiscovery(WorkspaceDiscoveryResult discoveryResult, string pathToContents)
|
|
307
327
|
{
|
|
308
328
|
string GetFullRepoPath(string path)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
using System.Text.Json;
|
|
2
|
+
using System.Text.Json.Serialization;
|
|
3
|
+
|
|
4
|
+
using NuGet.Versioning;
|
|
5
|
+
|
|
6
|
+
namespace NuGetUpdater.Core.Analyze;
|
|
7
|
+
|
|
8
|
+
public class VersionConverter : JsonConverter<NuGetVersion>
|
|
9
|
+
{
|
|
10
|
+
public override NuGetVersion? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
11
|
+
{
|
|
12
|
+
return NuGetVersion.Parse(reader.GetString()!);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public override void Write(Utf8JsonWriter writer, NuGetVersion value, JsonSerializerOptions options)
|
|
16
|
+
{
|
|
17
|
+
writer.WriteStringValue(value.ToString());
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -60,7 +60,8 @@ internal static class BindingRedirectManager
|
|
|
60
60
|
// finally we pull out the assembly `HintPath` values for _all_ references relative to the project file in a unix-style value
|
|
61
61
|
// e.g., ../packages/Some.Other.Package/4.5.6/lib/net45/Some.Other.Package.dll
|
|
62
62
|
// all of that is passed to `AddBindingRedirects()` so we can ensure binding redirects for the relevant assemblies
|
|
63
|
-
var
|
|
63
|
+
var packagesConfigPath = ProjectHelper.GetPackagesConfigPathFromProject(projectBuildFile.Path, ProjectHelper.PathFormat.Full);
|
|
64
|
+
var packagesDirectory = PackagesConfigUpdater.GetPathToPackagesDirectory(projectBuildFile, updatedPackageName, updatedPackageVersion, packagesConfigPath)!;
|
|
64
65
|
var assemblyPathPrefix = Path.Combine(packagesDirectory, $"{updatedPackageName}.{updatedPackageVersion}").NormalizePathToUnix().EnsureSuffix("/");
|
|
65
66
|
var assemblyPaths = references.Select(static x => x.HintPath).Select(x => Path.GetRelativePath(Path.GetDirectoryName(projectBuildFile.Path)!, x).NormalizePathToUnix()).ToList();
|
|
66
67
|
var bindingsAndAssemblyPaths = bindings.Zip(assemblyPaths);
|
|
@@ -23,7 +23,7 @@ namespace NuGetUpdater.Core;
|
|
|
23
23
|
/// See: https://learn.microsoft.com/en-us/nuget/reference/packages-config
|
|
24
24
|
/// https://learn.microsoft.com/en-us/nuget/resources/check-project-format
|
|
25
25
|
/// <remarks>
|
|
26
|
-
internal static class PackagesConfigUpdater
|
|
26
|
+
internal static partial class PackagesConfigUpdater
|
|
27
27
|
{
|
|
28
28
|
public static async Task UpdateDependencyAsync(
|
|
29
29
|
string repoRootPath,
|
|
@@ -215,7 +215,7 @@ internal static class PackagesConfigUpdater
|
|
|
215
215
|
var hintPathSubString = $"{dependencyName}.{dependencyVersion}";
|
|
216
216
|
|
|
217
217
|
string? partialPathMatch = null;
|
|
218
|
-
var specificHintPathNodes = projectBuildFile.Contents.Descendants().Where(e => e.IsHintPathNodeForDependency(dependencyName)).ToArray();
|
|
218
|
+
var specificHintPathNodes = projectBuildFile.Contents.Descendants().Where(e => e.IsHintPathNodeForDependency(dependencyName, dependencyVersion)).ToArray();
|
|
219
219
|
foreach (var hintPathNode in specificHintPathNodes)
|
|
220
220
|
{
|
|
221
221
|
var hintPath = hintPathNode.GetContentValue();
|
|
@@ -266,8 +266,7 @@ internal static class PackagesConfigUpdater
|
|
|
266
266
|
foreach (var hintPathNode in genericHintPathNodes)
|
|
267
267
|
{
|
|
268
268
|
var hintPath = hintPathNode.GetContentValue();
|
|
269
|
-
var match =
|
|
270
|
-
// e.g., ..\..\packages \ Some.Package.1.2.3 \ lib\ net45 \ Some.Package.dll
|
|
269
|
+
var match = PackageAssemblyHintPathPattern().Match(hintPath);
|
|
271
270
|
if (match.Success)
|
|
272
271
|
{
|
|
273
272
|
partialPathMatch = match.Groups["PackagesPath"].Value;
|
|
@@ -297,17 +296,15 @@ internal static class PackagesConfigUpdater
|
|
|
297
296
|
return false;
|
|
298
297
|
}
|
|
299
298
|
|
|
300
|
-
private static bool IsHintPathNodeForDependency(this IXmlElementSyntax element, string dependencyName)
|
|
299
|
+
private static bool IsHintPathNodeForDependency(this IXmlElementSyntax element, string dependencyName, string dependencyVersion)
|
|
301
300
|
{
|
|
302
301
|
if (element.IsHintPathNode())
|
|
303
302
|
{
|
|
304
|
-
// the
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (includeAttributeValue.Equals(dependencyName, StringComparison.OrdinalIgnoreCase) ||
|
|
310
|
-
includeAttributeValue.StartsWith($"{dependencyName},", StringComparison.OrdinalIgnoreCase))
|
|
303
|
+
// the hint path will look similar to this:
|
|
304
|
+
// ..\packages\Some.Package.1.2.3\lib\net45\Some.Package.dll
|
|
305
|
+
var assemblyPath = element.GetContentValue();
|
|
306
|
+
var match = PackageAssemblyHintPathPattern().Match(assemblyPath);
|
|
307
|
+
if (match.Success)
|
|
311
308
|
{
|
|
312
309
|
return true;
|
|
313
310
|
}
|
|
@@ -326,4 +323,8 @@ internal static class PackagesConfigUpdater
|
|
|
326
323
|
|
|
327
324
|
return subpath;
|
|
328
325
|
}
|
|
326
|
+
|
|
327
|
+
[GeneratedRegex(@"^(?<PackagesPath>.*)[/\\](?<PackageNameAndVersion>[^/\\]+)[/\\]lib[/\\](?<Tfm>[^/\\]+)[/\\](?<AssemblyName>[^/\\]+)$", RegexOptions.IgnoreCase)]
|
|
328
|
+
// e.g., ..\..\packages \ Some.Package.1.2.3 \ lib \ net45 \ Some.Package.dll
|
|
329
|
+
private static partial Regex PackageAssemblyHintPathPattern();
|
|
329
330
|
}
|
|
@@ -11,6 +11,7 @@ namespace NuGetUpdater.Core.Utilities
|
|
|
11
11
|
public static JsonDocumentOptions DocumentOptions { get; } = new JsonDocumentOptions
|
|
12
12
|
{
|
|
13
13
|
CommentHandling = JsonCommentHandling.Skip,
|
|
14
|
+
AllowTrailingCommas = true,
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
public static JsonNode? ParseNode(string content)
|
|
@@ -24,6 +25,7 @@ namespace NuGetUpdater.Core.Utilities
|
|
|
24
25
|
var readerOptions = new JsonReaderOptions
|
|
25
26
|
{
|
|
26
27
|
CommentHandling = JsonCommentHandling.Allow,
|
|
28
|
+
AllowTrailingCommas = true,
|
|
27
29
|
};
|
|
28
30
|
var bytes = Encoding.UTF8.GetBytes(json);
|
|
29
31
|
var reader = new Utf8JsonReader(bytes, readerOptions);
|
|
@@ -74,7 +74,7 @@ internal static class ProjectHelper
|
|
|
74
74
|
private static string? GetItemPathWithFileName(this ProjectRootElement projectRootElement, string itemFileName)
|
|
75
75
|
{
|
|
76
76
|
var projectDirectory = Path.GetDirectoryName(projectRootElement.FullPath)!;
|
|
77
|
-
var
|
|
77
|
+
var itemPath = projectRootElement.Items
|
|
78
78
|
.Where(i => i.ElementName.Equals("None", StringComparison.OrdinalIgnoreCase) ||
|
|
79
79
|
i.ElementName.Equals("Content", StringComparison.OrdinalIgnoreCase))
|
|
80
80
|
.Where(i => Path.GetFileName(i.Include).Equals(itemFileName, StringComparison.OrdinalIgnoreCase))
|
|
@@ -82,7 +82,7 @@ internal static class ProjectHelper
|
|
|
82
82
|
.Where(File.Exists)
|
|
83
83
|
.FirstOrDefault()
|
|
84
84
|
?.NormalizePathToUnix();
|
|
85
|
-
return
|
|
85
|
+
return itemPath;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
private static string? GetPathWithRegardsToProjectFile(string fullProjectPath, string fileName)
|