dependabot-nuget 0.290.0 → 0.292.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/.editorconfig +1 -0
- data/helpers/lib/NuGetUpdater/Directory.Build.props +1 -0
- data/helpers/lib/NuGetUpdater/Directory.Packages.props +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +15 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +87 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/AnalyzeWorker.cs +14 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/DependencyFinder.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Analyze/RequirementConverter.cs +19 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/BadRequirementException.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Clone/CloneWorker.cs +39 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +111 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/PackagesConfigDiscovery.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +19 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ErrorType.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +31 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/BadRequirement.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/CommitOptions.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/DependencyFileNotFound.cs +3 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobRepoNotFound.cs +1 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceAuthenticationFailure.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UnknownError.cs +6 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/UpdateNotPossible.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +9 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/LockFileUpdater.cs +3 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +43 -18
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/WebApplicationTargetsConditionPatcher.cs +12 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +0 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +48 -17
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/NuGetHelper.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProcessExtensions.cs +45 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/ProjectHelper.cs +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +60 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +10 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +56 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +41 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +2 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/MockNuGetPackage.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +76 -40
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTestBase.cs +20 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.GlobalJson.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.LockFile.cs +251 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackageReference.cs +6 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.PackagesConfig.cs +63 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +277 -73
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/ProjectHelperTests.cs +65 -0
- data/helpers/lib/NuGetUpdater/global.json +1 -1
- data/lib/dependabot/nuget/file_fetcher.rb +1 -0
- data/lib/dependabot/nuget/file_parser.rb +90 -0
- data/lib/dependabot/nuget/language.rb +98 -0
- data/lib/dependabot/nuget/native_helpers.rb +25 -0
- data/lib/dependabot/nuget/package_manager.rb +51 -0
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc0cf2e8a7f769337787f983af710cd8a4c30c464b1118f22589c522b3ed107a
|
4
|
+
data.tar.gz: b1e2fb7957b3cd3daf6331e199ebce5b0f94d84f42033de6e6f0e39bef4295b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c66ad9bb9ce3d932d0965f18fc4a6dde14ae022413343689a7c92f1e9439cca523447c20719f579bbc6c5fe6caeadab1dde0056f0a99e4a1afd09c7a5a79266
|
7
|
+
data.tar.gz: eb4601daef366ea15b011fb20a3efce1b976da73a4c4ba14c991a1aa9910a01d220b2cc46a086e47e7336432597b01f431d65ad4d40b431b1545996e1af613dd
|
@@ -4,6 +4,7 @@
|
|
4
4
|
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
5
5
|
<NoWarn>$(NoWarn);NU1701</NoWarn>
|
6
6
|
<Nullable>enable</Nullable>
|
7
|
+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
7
8
|
</PropertyGroup>
|
8
9
|
|
9
10
|
<Import Project="Directory.Common.props" />
|
@@ -36,7 +36,7 @@
|
|
36
36
|
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
37
37
|
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.0" />
|
38
38
|
<PackageVersion Include="xunit" Version="2.9.2" />
|
39
|
-
<PackageVersion Include="xunit.runner.visualstudio" Version="
|
39
|
+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
|
40
40
|
</ItemGroup>
|
41
41
|
|
42
42
|
</Project>
|
@@ -29,7 +29,7 @@ internal static class AnalyzeCommand
|
|
29
29
|
command.SetHandler(async (jobPath, repoRoot, discoveryPath, dependencyPath, analysisDirectory) =>
|
30
30
|
{
|
31
31
|
var logger = new ConsoleLogger();
|
32
|
-
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName
|
32
|
+
var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobPath.FullName);
|
33
33
|
var worker = new AnalyzeWorker(experimentsManager, logger);
|
34
34
|
await worker.RunAsync(repoRoot.FullName, discoveryPath.FullName, dependencyPath.FullName, analysisDirectory.FullName);
|
35
35
|
}, JobPathOption, RepoRootOption, DiscoveryFilePathOption, DependencyFilePathOption, AnalysisFolderOption);
|
@@ -30,7 +30,7 @@ internal static class CloneCommand
|
|
30
30
|
var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
|
31
31
|
var logger = new ConsoleLogger();
|
32
32
|
var gitCommandHandler = new ShellGitCommandHandler(logger);
|
33
|
-
var worker = new CloneWorker(apiHandler, gitCommandHandler
|
33
|
+
var worker = new CloneWorker(jobId, apiHandler, gitCommandHandler);
|
34
34
|
var exitCode = await worker.RunAsync(jobPath, repoContentsPath);
|
35
35
|
setExitCode(exitCode);
|
36
36
|
}, JobPathOption, RepoContentsPathOption, ApiUrlOption, JobIdOption);
|
@@ -26,8 +26,22 @@ internal static class DiscoverCommand
|
|
26
26
|
|
27
27
|
command.SetHandler(async (jobPath, repoRoot, workspace, outputPath) =>
|
28
28
|
{
|
29
|
+
var (experimentsManager, errorResult) = await ExperimentsManager.FromJobFileAsync(jobPath.FullName);
|
30
|
+
if (errorResult is not null)
|
31
|
+
{
|
32
|
+
// to make testing easier, this should be a `WorkspaceDiscoveryResult` object
|
33
|
+
var discoveryErrorResult = new WorkspaceDiscoveryResult
|
34
|
+
{
|
35
|
+
Path = workspace,
|
36
|
+
Projects = [],
|
37
|
+
ErrorType = errorResult.ErrorType,
|
38
|
+
ErrorDetails = errorResult.ErrorDetails,
|
39
|
+
};
|
40
|
+
await DiscoveryWorker.WriteResultsAsync(repoRoot.FullName, outputPath.FullName, discoveryErrorResult);
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
|
29
44
|
var logger = new ConsoleLogger();
|
30
|
-
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
|
31
45
|
var worker = new DiscoveryWorker(experimentsManager, logger);
|
32
46
|
await worker.RunAsync(repoRoot.FullName, workspace, outputPath.FullName);
|
33
47
|
}, JobPathOption, RepoRootOption, WorkspaceOption, OutputOption);
|
@@ -33,12 +33,12 @@ internal static class RunCommand
|
|
33
33
|
command.SetHandler(async (jobPath, repoContentsPath, apiUrl, jobId, outputPath, baseCommitSha) =>
|
34
34
|
{
|
35
35
|
var apiHandler = new HttpApiHandler(apiUrl.ToString(), jobId);
|
36
|
+
var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobPath.FullName);
|
36
37
|
var logger = new ConsoleLogger();
|
37
|
-
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
|
38
38
|
var discoverWorker = new DiscoveryWorker(experimentsManager, logger);
|
39
39
|
var analyzeWorker = new AnalyzeWorker(experimentsManager, logger);
|
40
40
|
var updateWorker = new UpdaterWorker(experimentsManager, logger);
|
41
|
-
var worker = new RunWorker(apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
|
41
|
+
var worker = new RunWorker(jobId, apiHandler, discoverWorker, analyzeWorker, updateWorker, logger);
|
42
42
|
await worker.RunAsync(jobPath, repoContentsPath, baseCommitSha, outputPath);
|
43
43
|
}, JobPathOption, RepoContentsPathOption, ApiUrlOption, JobIdOption, OutputPathOption, BaseCommitShaOption);
|
44
44
|
|
@@ -33,8 +33,8 @@ internal static class UpdateCommand
|
|
33
33
|
|
34
34
|
command.SetHandler(async (jobPath, repoRoot, solutionOrProjectFile, dependencyName, newVersion, previousVersion, isTransitive, resultOutputPath) =>
|
35
35
|
{
|
36
|
+
var (experimentsManager, _errorResult) = await ExperimentsManager.FromJobFileAsync(jobPath.FullName);
|
36
37
|
var logger = new ConsoleLogger();
|
37
|
-
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName, logger);
|
38
38
|
var worker = new UpdaterWorker(experimentsManager, logger);
|
39
39
|
await worker.RunAsync(repoRoot.FullName, solutionOrProjectFile.FullName, dependencyName, previousVersion, newVersion, isTransitive, resultOutputPath);
|
40
40
|
setExitCode(0);
|
@@ -345,7 +345,8 @@ public partial class EntryPointTests
|
|
345
345
|
{
|
346
346
|
if (args[i] == "--job-path")
|
347
347
|
{
|
348
|
-
|
348
|
+
var experimentsResult = await ExperimentsManager.FromJobFileAsync(args[i + 1]);
|
349
|
+
experimentsManager = experimentsResult.ExperimentsManager;
|
349
350
|
}
|
350
351
|
}
|
351
352
|
|
@@ -388,6 +388,83 @@ public partial class EntryPointTests
|
|
388
388
|
);
|
389
389
|
}
|
390
390
|
|
391
|
+
[Fact]
|
392
|
+
public async Task JobFileParseErrorIsReported_InvalidJson()
|
393
|
+
{
|
394
|
+
using var testDirectory = new TemporaryDirectory();
|
395
|
+
var jobFilePath = Path.Combine(testDirectory.DirectoryPath, "job.json");
|
396
|
+
var resultFilePath = Path.Combine(testDirectory.DirectoryPath, DiscoveryWorker.DiscoveryResultFileName);
|
397
|
+
await File.WriteAllTextAsync(jobFilePath, "not json");
|
398
|
+
await RunAsync(path =>
|
399
|
+
[
|
400
|
+
"discover",
|
401
|
+
"--job-path",
|
402
|
+
jobFilePath,
|
403
|
+
"--repo-root",
|
404
|
+
path,
|
405
|
+
"--workspace",
|
406
|
+
"/",
|
407
|
+
"--output",
|
408
|
+
resultFilePath
|
409
|
+
],
|
410
|
+
initialFiles: [],
|
411
|
+
expectedResult: new()
|
412
|
+
{
|
413
|
+
Path = "/",
|
414
|
+
Projects = [],
|
415
|
+
ErrorType = ErrorType.Unknown,
|
416
|
+
ErrorDetailsPattern = "JsonException",
|
417
|
+
}
|
418
|
+
);
|
419
|
+
}
|
420
|
+
|
421
|
+
[Fact]
|
422
|
+
public async Task JobFileParseErrorIsReported_BadRequirement()
|
423
|
+
{
|
424
|
+
using var testDirectory = new TemporaryDirectory();
|
425
|
+
var jobFilePath = Path.Combine(testDirectory.DirectoryPath, "job.json");
|
426
|
+
var resultFilePath = Path.Combine(testDirectory.DirectoryPath, DiscoveryWorker.DiscoveryResultFileName);
|
427
|
+
|
428
|
+
// write a job file with a valid shape, but invalid requirement
|
429
|
+
await File.WriteAllTextAsync(jobFilePath, """
|
430
|
+
{
|
431
|
+
"job": {
|
432
|
+
"source": {
|
433
|
+
"provider": "github",
|
434
|
+
"repo": "test/repo"
|
435
|
+
},
|
436
|
+
"security-advisories": [
|
437
|
+
{
|
438
|
+
"dependency-name": "Some.Dependency",
|
439
|
+
"affected-versions": ["not a valid requirement"]
|
440
|
+
}
|
441
|
+
]
|
442
|
+
}
|
443
|
+
}
|
444
|
+
""");
|
445
|
+
await RunAsync(path =>
|
446
|
+
[
|
447
|
+
"discover",
|
448
|
+
"--job-path",
|
449
|
+
jobFilePath,
|
450
|
+
"--repo-root",
|
451
|
+
path,
|
452
|
+
"--workspace",
|
453
|
+
"/",
|
454
|
+
"--output",
|
455
|
+
resultFilePath
|
456
|
+
],
|
457
|
+
initialFiles: [],
|
458
|
+
expectedResult: new()
|
459
|
+
{
|
460
|
+
Path = "/",
|
461
|
+
Projects = [],
|
462
|
+
ErrorType = ErrorType.BadRequirement,
|
463
|
+
ErrorDetailsPattern = "not a valid requirement",
|
464
|
+
}
|
465
|
+
);
|
466
|
+
}
|
467
|
+
|
391
468
|
private static async Task RunAsync(
|
392
469
|
Func<string, string[]> getArgs,
|
393
470
|
TestFile[] initialFiles,
|
@@ -406,6 +483,7 @@ public partial class EntryPointTests
|
|
406
483
|
var originalErr = Console.Error;
|
407
484
|
Console.SetOut(writer);
|
408
485
|
Console.SetError(writer);
|
486
|
+
string? resultPath = null;
|
409
487
|
|
410
488
|
try
|
411
489
|
{
|
@@ -416,9 +494,15 @@ public partial class EntryPointTests
|
|
416
494
|
// manually pull out the experiments manager for the validate step below
|
417
495
|
for (int i = 0; i < args.Length - 1; i++)
|
418
496
|
{
|
419
|
-
|
497
|
+
switch (args[i])
|
420
498
|
{
|
421
|
-
|
499
|
+
case "--job-path":
|
500
|
+
var experimentsResult = await ExperimentsManager.FromJobFileAsync(args[i + 1]);
|
501
|
+
experimentsManager = experimentsResult.ExperimentsManager;
|
502
|
+
break;
|
503
|
+
case "--output":
|
504
|
+
resultPath = args[i + 1];
|
505
|
+
break;
|
422
506
|
}
|
423
507
|
}
|
424
508
|
|
@@ -434,7 +518,7 @@ public partial class EntryPointTests
|
|
434
518
|
Console.SetError(originalErr);
|
435
519
|
}
|
436
520
|
|
437
|
-
|
521
|
+
resultPath ??= Path.Join(path, DiscoveryWorker.DiscoveryResultFileName);
|
438
522
|
var resultJson = await File.ReadAllTextAsync(resultPath);
|
439
523
|
var resultObject = JsonSerializer.Deserialize<WorkspaceDiscoveryResult>(resultJson, DiscoveryWorker.SerializerOptions);
|
440
524
|
return resultObject!;
|
@@ -382,7 +382,7 @@ public partial class EntryPointTests
|
|
382
382
|
workingDirectory = Path.Join(workingDirectory, workingDirectoryPath);
|
383
383
|
}
|
384
384
|
|
385
|
-
var (exitCode, output, error) = await ProcessEx.
|
385
|
+
var (exitCode, output, error) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(executableArgs, workingDirectory, new ExperimentsManager() { InstallDotnetSdks = false });
|
386
386
|
Assert.True(exitCode == 0, $"Error running update on unsupported SDK.\nSTDOUT:\n{output}\nSTDERR:\n{error}");
|
387
387
|
|
388
388
|
// verify project update
|
@@ -62,6 +62,17 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
62
62
|
UpdatedDependencies = [],
|
63
63
|
};
|
64
64
|
}
|
65
|
+
catch (Exception ex)
|
66
|
+
{
|
67
|
+
analysisResult = new AnalysisResult
|
68
|
+
{
|
69
|
+
ErrorType = ErrorType.Unknown,
|
70
|
+
ErrorDetails = ex.ToString(),
|
71
|
+
UpdatedVersion = string.Empty,
|
72
|
+
CanUpdate = false,
|
73
|
+
UpdatedDependencies = [],
|
74
|
+
};
|
75
|
+
}
|
65
76
|
|
66
77
|
return analysisResult;
|
67
78
|
}
|
@@ -142,6 +153,7 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
142
153
|
dependenciesToUpdate,
|
143
154
|
updatedVersion,
|
144
155
|
nugetContext,
|
156
|
+
_experimentsManager,
|
145
157
|
_logger,
|
146
158
|
CancellationToken.None);
|
147
159
|
}
|
@@ -393,6 +405,7 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
393
405
|
ImmutableHashSet<string> packageIds,
|
394
406
|
NuGetVersion updatedVersion,
|
395
407
|
NuGetContext nugetContext,
|
408
|
+
ExperimentsManager experimentsManager,
|
396
409
|
ILogger logger,
|
397
410
|
CancellationToken cancellationToken)
|
398
411
|
{
|
@@ -432,6 +445,7 @@ public partial class AnalyzeWorker : IAnalyzeWorker
|
|
432
445
|
packageIds,
|
433
446
|
updatedVersion,
|
434
447
|
nugetContext,
|
448
|
+
experimentsManager,
|
435
449
|
logger,
|
436
450
|
cancellationToken);
|
437
451
|
|
@@ -14,6 +14,7 @@ internal static class DependencyFinder
|
|
14
14
|
ImmutableHashSet<string> packageIds,
|
15
15
|
NuGetVersion version,
|
16
16
|
NuGetContext nugetContext,
|
17
|
+
ExperimentsManager experimentsManager,
|
17
18
|
ILogger logger,
|
18
19
|
CancellationToken cancellationToken)
|
19
20
|
{
|
@@ -30,6 +31,7 @@ internal static class DependencyFinder
|
|
30
31
|
projectPath,
|
31
32
|
framework.ToString(),
|
32
33
|
packages,
|
34
|
+
experimentsManager,
|
33
35
|
logger);
|
34
36
|
var updatedDependencies = new List<Dependency>();
|
35
37
|
foreach (var dependency in dependencies)
|
@@ -7,7 +7,25 @@ public class RequirementConverter : JsonConverter<Requirement>
|
|
7
7
|
{
|
8
8
|
public override Requirement? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
9
9
|
{
|
10
|
-
|
10
|
+
if (reader.TokenType != JsonTokenType.String)
|
11
|
+
{
|
12
|
+
throw new BadRequirementException($"Expected token type {nameof(JsonTokenType.String)}, but found {reader.TokenType}.");
|
13
|
+
}
|
14
|
+
|
15
|
+
var text = reader.GetString();
|
16
|
+
if (text is null)
|
17
|
+
{
|
18
|
+
throw new BadRequirementException("Unexpected null token.");
|
19
|
+
}
|
20
|
+
|
21
|
+
try
|
22
|
+
{
|
23
|
+
return Requirement.Parse(text);
|
24
|
+
}
|
25
|
+
catch
|
26
|
+
{
|
27
|
+
throw new BadRequirementException(text);
|
28
|
+
}
|
11
29
|
}
|
12
30
|
|
13
31
|
public override void Write(Utf8JsonWriter writer, Requirement value, JsonSerializerOptions options)
|
@@ -9,23 +9,49 @@ namespace NuGetUpdater.Core.Clone;
|
|
9
9
|
|
10
10
|
public class CloneWorker
|
11
11
|
{
|
12
|
+
private readonly string _jobId;
|
12
13
|
private readonly IApiHandler _apiHandler;
|
13
14
|
private readonly IGitCommandHandler _gitCommandHandler;
|
14
|
-
private readonly ILogger _logger;
|
15
15
|
|
16
|
-
public CloneWorker(IApiHandler apiHandler, IGitCommandHandler gitCommandHandler
|
16
|
+
public CloneWorker(string jobId, IApiHandler apiHandler, IGitCommandHandler gitCommandHandler)
|
17
17
|
{
|
18
|
+
_jobId = jobId;
|
18
19
|
_apiHandler = apiHandler;
|
19
20
|
_gitCommandHandler = gitCommandHandler;
|
20
|
-
_logger = logger;
|
21
21
|
}
|
22
22
|
|
23
23
|
// entrypoint for cli
|
24
24
|
public async Task<int> RunAsync(FileInfo jobFilePath, DirectoryInfo repoContentsPath)
|
25
25
|
{
|
26
26
|
var jobFileContent = await File.ReadAllTextAsync(jobFilePath.FullName);
|
27
|
-
|
28
|
-
|
27
|
+
|
28
|
+
// only a limited set of errors can occur here
|
29
|
+
JobFile? jobFile = null;
|
30
|
+
JobErrorBase? parseError = null;
|
31
|
+
try
|
32
|
+
{
|
33
|
+
jobFile = RunWorker.Deserialize(jobFileContent);
|
34
|
+
if (jobFile is null)
|
35
|
+
{
|
36
|
+
parseError = new UnknownError(new Exception("Job file could not be deserialized"), _jobId);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
catch (BadRequirementException ex)
|
40
|
+
{
|
41
|
+
parseError = new BadRequirement(ex.Message);
|
42
|
+
}
|
43
|
+
catch (Exception ex)
|
44
|
+
{
|
45
|
+
parseError = new UnknownError(ex, _jobId);
|
46
|
+
}
|
47
|
+
|
48
|
+
if (parseError is not null)
|
49
|
+
{
|
50
|
+
await ReportError(parseError);
|
51
|
+
return 1;
|
52
|
+
}
|
53
|
+
|
54
|
+
var result = await RunAsync(jobFile!.Job, repoContentsPath.FullName);
|
29
55
|
return result;
|
30
56
|
}
|
31
57
|
|
@@ -48,19 +74,24 @@ public class CloneWorker
|
|
48
74
|
}
|
49
75
|
catch (Exception ex)
|
50
76
|
{
|
51
|
-
error = new UnknownError(ex
|
77
|
+
error = new UnknownError(ex, _jobId);
|
52
78
|
}
|
53
79
|
|
54
80
|
if (error is not null)
|
55
81
|
{
|
56
|
-
await
|
57
|
-
await _apiHandler.MarkAsProcessed(new("unknown"));
|
82
|
+
await ReportError(error);
|
58
83
|
return 1;
|
59
84
|
}
|
60
85
|
|
61
86
|
return 0;
|
62
87
|
}
|
63
88
|
|
89
|
+
private async Task ReportError(JobErrorBase error)
|
90
|
+
{
|
91
|
+
await _apiHandler.RecordUpdateJobError(error);
|
92
|
+
await _apiHandler.MarkAsProcessed(new("unknown"));
|
93
|
+
}
|
94
|
+
|
64
95
|
internal static CommandArguments[] GetAllCommandArgs(Job job, string repoContentsPath)
|
65
96
|
{
|
66
97
|
var commandArgs = new List<CommandArguments>()
|
@@ -6,6 +6,9 @@ using System.Text.Json.Serialization;
|
|
6
6
|
using Microsoft.Build.Construction;
|
7
7
|
using Microsoft.Build.Definition;
|
8
8
|
using Microsoft.Build.Evaluation;
|
9
|
+
using Microsoft.Build.Exceptions;
|
10
|
+
|
11
|
+
using NuGet.Frameworks;
|
9
12
|
|
10
13
|
using NuGetUpdater.Core.Analyze;
|
11
14
|
using NuGetUpdater.Core.Utilities;
|
@@ -56,6 +59,16 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
56
59
|
Projects = [],
|
57
60
|
};
|
58
61
|
}
|
62
|
+
catch (Exception ex)
|
63
|
+
{
|
64
|
+
result = new WorkspaceDiscoveryResult
|
65
|
+
{
|
66
|
+
ErrorType = ErrorType.Unknown,
|
67
|
+
ErrorDetails = ex.ToString(),
|
68
|
+
Path = workspacePath,
|
69
|
+
Projects = [],
|
70
|
+
};
|
71
|
+
}
|
59
72
|
|
60
73
|
return result;
|
61
74
|
}
|
@@ -93,13 +106,31 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
93
106
|
}
|
94
107
|
|
95
108
|
// this next line should throw or something
|
96
|
-
projectResults = await
|
109
|
+
projectResults = await RunForDirectoryAsync(repoRootPath, workspacePath);
|
97
110
|
}
|
98
111
|
else
|
99
112
|
{
|
100
113
|
_logger.Info($"Workspace path [{workspacePath}] does not exist.");
|
101
114
|
}
|
102
115
|
|
116
|
+
//if any projectResults are not successful, return a failed result
|
117
|
+
if (projectResults.Any(p => p.IsSuccess == false))
|
118
|
+
{
|
119
|
+
var failedProjectResult = projectResults.Where(p => p.IsSuccess == false).First();
|
120
|
+
var failedDiscoveryResult = new WorkspaceDiscoveryResult
|
121
|
+
{
|
122
|
+
Path = initialWorkspacePath,
|
123
|
+
DotNetToolsJson = null,
|
124
|
+
GlobalJson = null,
|
125
|
+
Projects = projectResults.Where(p => p.IsSuccess).OrderBy(p => p.FilePath).ToImmutableArray(),
|
126
|
+
ErrorType = failedProjectResult.ErrorType,
|
127
|
+
ErrorDetails = failedProjectResult.FilePath,
|
128
|
+
IsSuccess = false,
|
129
|
+
};
|
130
|
+
|
131
|
+
return failedDiscoveryResult;
|
132
|
+
}
|
133
|
+
|
103
134
|
result = new WorkspaceDiscoveryResult
|
104
135
|
{
|
105
136
|
Path = initialWorkspacePath,
|
@@ -137,14 +168,34 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
137
168
|
|
138
169
|
_logger.Info($" Restoring MSBuild SDKs: {string.Join(", ", keys)}");
|
139
170
|
|
140
|
-
return await NuGetHelper.DownloadNuGetPackagesAsync(repoRootPath, workspacePath, msbuildSdks, logger);
|
171
|
+
return await NuGetHelper.DownloadNuGetPackagesAsync(repoRootPath, workspacePath, msbuildSdks, _experimentsManager, logger);
|
141
172
|
}
|
142
173
|
|
143
|
-
private async Task<ImmutableArray<ProjectDiscoveryResult>>
|
174
|
+
private async Task<ImmutableArray<ProjectDiscoveryResult>> RunForDirectoryAsync(string repoRootPath, string workspacePath)
|
144
175
|
{
|
145
176
|
_logger.Info($" Discovering projects beneath [{Path.GetRelativePath(repoRootPath, workspacePath)}].");
|
146
177
|
var entryPoints = FindEntryPoints(workspacePath);
|
147
|
-
|
178
|
+
ImmutableArray<string> projects;
|
179
|
+
try
|
180
|
+
{
|
181
|
+
projects = ExpandEntryPointsIntoProjects(entryPoints);
|
182
|
+
}
|
183
|
+
catch (InvalidProjectFileException e)
|
184
|
+
{
|
185
|
+
var invalidProjectFile = Path.GetRelativePath(workspacePath, e.ProjectFile).NormalizePathToUnix();
|
186
|
+
|
187
|
+
_logger.Info("Error encountered during discovery: " + e.Message);
|
188
|
+
return [new ProjectDiscoveryResult
|
189
|
+
{
|
190
|
+
FilePath = invalidProjectFile,
|
191
|
+
Dependencies = ImmutableArray<Dependency>.Empty,
|
192
|
+
ImportedFiles = ImmutableArray<string>.Empty,
|
193
|
+
AdditionalFiles = ImmutableArray<string>.Empty,
|
194
|
+
IsSuccess = false,
|
195
|
+
ErrorType = ErrorType.DependencyFileNotParseable,
|
196
|
+
ErrorDetails = "Failed to parse project file found at " + invalidProjectFile,
|
197
|
+
}];
|
198
|
+
}
|
148
199
|
if (projects.IsEmpty)
|
149
200
|
{
|
150
201
|
_logger.Info(" No project files found.");
|
@@ -286,7 +337,7 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
286
337
|
_processedProjectPaths.Add(actualProjectPath);
|
287
338
|
|
288
339
|
var relativeProjectPath = Path.GetRelativePath(workspacePath, actualProjectPath).NormalizePathToUnix();
|
289
|
-
var packagesConfigResult = await PackagesConfigDiscovery.Discover(repoRootPath, workspacePath, actualProjectPath, _logger);
|
340
|
+
var packagesConfigResult = await PackagesConfigDiscovery.Discover(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
|
290
341
|
var projectResults = await SdkProjectDiscovery.DiscoverAsync(repoRootPath, workspacePath, actualProjectPath, _experimentsManager, _logger);
|
291
342
|
|
292
343
|
// Determine if there were unrestored MSBuildSdks
|
@@ -325,19 +376,62 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
325
376
|
}
|
326
377
|
}
|
327
378
|
|
328
|
-
if (
|
329
|
-
packagesConfigResult is not null &&
|
330
|
-
packagesConfigResult.Dependencies.Length > 0)
|
379
|
+
if (packagesConfigResult is not null)
|
331
380
|
{
|
332
|
-
//
|
333
|
-
results
|
381
|
+
// we might have to merge this dependency with some others
|
382
|
+
if (results.TryGetValue(relativeProjectPath, out var existingProjectDiscovery))
|
383
|
+
{
|
384
|
+
// merge SDK and packages.config results
|
385
|
+
var mergedDependencies = existingProjectDiscovery.Dependencies.Concat(packagesConfigResult.Dependencies)
|
386
|
+
.DistinctBy(d => d.Name, StringComparer.OrdinalIgnoreCase)
|
387
|
+
.OrderBy(d => d.Name)
|
388
|
+
.ToImmutableArray();
|
389
|
+
var mergedTargetFrameworks = existingProjectDiscovery.TargetFrameworks.Concat(packagesConfigResult.TargetFrameworks)
|
390
|
+
.Select(t =>
|
391
|
+
{
|
392
|
+
try
|
393
|
+
{
|
394
|
+
var tfm = NuGetFramework.Parse(t);
|
395
|
+
return tfm.GetShortFolderName();
|
396
|
+
}
|
397
|
+
catch
|
398
|
+
{
|
399
|
+
return string.Empty;
|
400
|
+
}
|
401
|
+
})
|
402
|
+
.Where(tfm => !string.IsNullOrEmpty(tfm))
|
403
|
+
.Distinct()
|
404
|
+
.OrderBy(tfm => tfm)
|
405
|
+
.ToImmutableArray();
|
406
|
+
var mergedProperties = existingProjectDiscovery.Properties; // packages.config discovery doesn't produce properties
|
407
|
+
var mergedImportedFiles = existingProjectDiscovery.ImportedFiles; // packages.config discovery doesn't produce imported files
|
408
|
+
var mergedAdditionalFiles = existingProjectDiscovery.AdditionalFiles.Concat(packagesConfigResult.AdditionalFiles)
|
409
|
+
.Distinct(StringComparer.OrdinalIgnoreCase)
|
410
|
+
.OrderBy(f => f)
|
411
|
+
.ToImmutableArray();
|
412
|
+
var mergedResult = new ProjectDiscoveryResult()
|
413
|
+
{
|
414
|
+
FilePath = existingProjectDiscovery.FilePath,
|
415
|
+
Dependencies = mergedDependencies,
|
416
|
+
TargetFrameworks = mergedTargetFrameworks,
|
417
|
+
Properties = mergedProperties,
|
418
|
+
ImportedFiles = mergedImportedFiles,
|
419
|
+
AdditionalFiles = mergedAdditionalFiles,
|
420
|
+
};
|
421
|
+
results[relativeProjectPath] = mergedResult;
|
422
|
+
}
|
423
|
+
else
|
334
424
|
{
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
425
|
+
// add packages.config results
|
426
|
+
results[relativeProjectPath] = new ProjectDiscoveryResult()
|
427
|
+
{
|
428
|
+
FilePath = relativeProjectPath,
|
429
|
+
Dependencies = packagesConfigResult.Dependencies,
|
430
|
+
TargetFrameworks = packagesConfigResult.TargetFrameworks,
|
431
|
+
ImportedFiles = [], // no imported files resolved for packages.config scenarios
|
432
|
+
AdditionalFiles = packagesConfigResult.AdditionalFiles,
|
433
|
+
};
|
434
|
+
}
|
341
435
|
}
|
342
436
|
}
|
343
437
|
}
|
@@ -358,6 +452,6 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
358
452
|
}
|
359
453
|
|
360
454
|
var resultJson = JsonSerializer.Serialize(result, SerializerOptions);
|
361
|
-
await File.WriteAllTextAsync(
|
455
|
+
await File.WriteAllTextAsync(resultPath, resultJson);
|
362
456
|
}
|
363
457
|
}
|
@@ -6,7 +6,7 @@ namespace NuGetUpdater.Core.Discover;
|
|
6
6
|
|
7
7
|
internal static class PackagesConfigDiscovery
|
8
8
|
{
|
9
|
-
public static async Task<PackagesConfigDiscoveryResult?> Discover(string repoRootPath, string workspacePath, string projectPath, ILogger logger)
|
9
|
+
public static async Task<PackagesConfigDiscoveryResult?> Discover(string repoRootPath, string workspacePath, string projectPath, ExperimentsManager experimentsManager, ILogger logger)
|
10
10
|
{
|
11
11
|
var projectDirectory = Path.GetDirectoryName(projectPath)!;
|
12
12
|
var additionalFiles = ProjectHelper.GetAllAdditionalFilesFromProject(projectPath, ProjectHelper.PathFormat.Full);
|
@@ -27,7 +27,7 @@ internal static class PackagesConfigDiscovery
|
|
27
27
|
.ToImmutableArray();
|
28
28
|
|
29
29
|
// generate `$(TargetFramework)` via MSBuild
|
30
|
-
var tfms = await MSBuildHelper.GetTargetFrameworkValuesFromProject(repoRootPath, projectPath, logger);
|
30
|
+
var tfms = await MSBuildHelper.GetTargetFrameworkValuesFromProject(repoRootPath, projectPath, experimentsManager, logger);
|
31
31
|
|
32
32
|
var additionalFilesRelative = additionalFiles.Select(p => Path.GetRelativePath(projectDirectory, p).NormalizePathToUnix()).ToImmutableArray();
|
33
33
|
return new()
|
@@ -8,6 +8,8 @@ public record ProjectDiscoveryResult : IDiscoveryResultWithDependencies
|
|
8
8
|
public required string FilePath { get; init; }
|
9
9
|
public required ImmutableArray<Dependency> Dependencies { get; init; }
|
10
10
|
public bool IsSuccess { get; init; } = true;
|
11
|
+
public string? ErrorDetails { get; init; }
|
12
|
+
public ErrorType? ErrorType { get; init; }
|
11
13
|
public ImmutableArray<Property> Properties { get; init; } = [];
|
12
14
|
public ImmutableArray<string> TargetFrameworks { get; init; } = [];
|
13
15
|
public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
|