dependabot-nuget 0.321.3 → 0.322.1
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 +22 -22
- data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation.Cli/Program.cs +21 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/AnalyzeCommand.cs +19 -11
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/CloneCommand.cs +19 -9
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/DiscoverCommand.cs +21 -14
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/FrameworkCheckCommand.cs +8 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/RunCommand.cs +29 -16
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Commands/UpdateCommand.cs +20 -19
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli/Program.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Analyze.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Discover.cs +10 -23
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Run.cs +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Cli.Test/EntryPointTests.Update.cs +15 -232
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +1 -154
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/ExperimentsManager.cs +3 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Files/GlobalJsonBuildFile.cs +5 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/PrivateSourceTimedOutException.cs +12 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/JobErrorBase.cs +4 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/ApiModel/PrivateSourceTimedOut.cs +10 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/AzurePackageDetailFinder.cs +30 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGenerator.cs +237 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/GitHubPackageDetailFinder.cs +101 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/GitLabPackageDetailFinder.cs +107 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/HttpFetcher.cs +32 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IHttpFetcher.cs +30 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IPackageDetailFinder.cs +47 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/IPullRequestBodyGenerator.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestBodyGenerator/SimplePullRequestBodyGenerator.cs +15 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/PullRequestTextGenerator.cs +7 -3
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunWorker.cs +3 -525
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/GroupUpdateAllVersionsHandler.cs +4 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandler.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/FileWriterWorker.cs +85 -35
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +27 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/PackageReferenceUpdater.cs +1 -856
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdateOperationBase.cs +18 -7
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/UpdaterWorker.cs +16 -200
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +21 -556
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Analyze/AnalyzeWorkerTests.cs +9 -73
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/DependencySolver/MSBuildDependencySolverTests.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +1 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.GlobalJson.cs +0 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +3 -62
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +13 -563
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +20 -269
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Files/GlobalJsonBuildFileTests.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +131 -131
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/HttpApiHandlerTests.cs +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/JobErrorBaseTests.cs +7 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MessageReportTests.cs +11 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/MiscellaneousTests.cs +0 -203
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/DetailedPullRequestBodyGeneratorTests.cs +871 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/IPackageDetailFinderTests.cs +28 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestBodyGenerator/TestHttpFetcher.cs +23 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestTextTests.cs +24 -24
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/SerializationTests.cs +14 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/CreateSecurityUpdatePullRequestHandlerTests.cs +6 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/GroupUpdateAllVersionsHandlerTests.cs +18 -18
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshGroupUpdatePullRequestHandlerTests.cs +15 -15
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshSecurityUpdatePullRequestHandlerTests.cs +21 -21
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/RefreshVersionUpdatePullRequestHandlerTests.cs +15 -15
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlersTestsBase.cs +1 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterWorkerTests_MiscellaneousTests.cs +45 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +111 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/PackageReferenceUpdaterTests.cs +1 -159
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/MSBuildHelperTests.cs +26 -660
- data/helpers/lib/NuGetUpdater/global.json +1 -1
- metadata +18 -10
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/RunResult.cs +0 -13
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/PullRequestMessageTests.cs +0 -296
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/RunWorkerTests.cs +0 -3592
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatePermittedAndMessageTests.cs +0 -457
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/UpdateWorkerTests.DirsProj.cs +0 -378
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/SdkPackageUpdaterHelperTests.cs +0 -175
@@ -1,19 +1,11 @@
|
|
1
1
|
using System.Collections.Immutable;
|
2
2
|
using System.Diagnostics.CodeAnalysis;
|
3
3
|
using System.Reflection;
|
4
|
-
using System.Text;
|
5
|
-
using System.Text.Json;
|
6
4
|
using System.Text.Json.Nodes;
|
7
5
|
using System.Text.RegularExpressions;
|
8
|
-
using System.Xml;
|
9
6
|
using System.Xml.Linq;
|
10
7
|
|
11
|
-
using Microsoft.Build.Construction;
|
12
|
-
using Microsoft.Build.Definition;
|
13
|
-
using Microsoft.Build.Evaluation;
|
14
|
-
using Microsoft.Build.Exceptions;
|
15
8
|
using Microsoft.Build.Locator;
|
16
|
-
using Microsoft.Extensions.FileSystemGlobbing;
|
17
9
|
|
18
10
|
using NuGet.Configuration;
|
19
11
|
using NuGet.Frameworks;
|
@@ -104,260 +96,6 @@ internal static partial class MSBuildHelper
|
|
104
96
|
}
|
105
97
|
}
|
106
98
|
|
107
|
-
public static IEnumerable<string> GetProjectPathsFromSolution(string solutionPath)
|
108
|
-
{
|
109
|
-
var solution = SolutionFile.Parse(solutionPath);
|
110
|
-
return solution.ProjectsInOrder.Select(p => p.AbsolutePath);
|
111
|
-
}
|
112
|
-
|
113
|
-
public static IEnumerable<string> GetProjectPathsFromProject(string projFilePath)
|
114
|
-
{
|
115
|
-
var projectStack = new Stack<(string folderPath, ProjectRootElement)>();
|
116
|
-
var processedProjectFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
117
|
-
using var projectCollection = new ProjectCollection();
|
118
|
-
|
119
|
-
try
|
120
|
-
{
|
121
|
-
var projectRootElement = ProjectRootElement.Open(projFilePath, projectCollection);
|
122
|
-
projectStack.Push((Path.GetFullPath(Path.GetDirectoryName(projFilePath)!), projectRootElement));
|
123
|
-
}
|
124
|
-
catch (InvalidProjectFileException)
|
125
|
-
{
|
126
|
-
yield break; // Skip invalid project files
|
127
|
-
}
|
128
|
-
|
129
|
-
while (projectStack.Count > 0)
|
130
|
-
{
|
131
|
-
var (folderPath, tmpProject) = projectStack.Pop();
|
132
|
-
foreach (var projectReference in tmpProject.Items.Where(static x => x.ItemType == "ProjectReference" || x.ItemType == "ProjectFile"))
|
133
|
-
{
|
134
|
-
if (projectReference.Include is not { } projectPath)
|
135
|
-
{
|
136
|
-
continue;
|
137
|
-
}
|
138
|
-
|
139
|
-
Matcher matcher = new Matcher();
|
140
|
-
matcher.AddInclude(PathHelper.NormalizePathToUnix(projectReference.Include));
|
141
|
-
|
142
|
-
string searchDirectory = PathHelper.NormalizePathToUnix(folderPath);
|
143
|
-
|
144
|
-
IEnumerable<string> files = matcher.GetResultsInFullPath(searchDirectory);
|
145
|
-
|
146
|
-
foreach (var file in files)
|
147
|
-
{
|
148
|
-
// Check that we haven't already processed this file
|
149
|
-
if (processedProjectFiles.Contains(file))
|
150
|
-
{
|
151
|
-
continue;
|
152
|
-
}
|
153
|
-
|
154
|
-
var projectExtension = Path.GetExtension(file).ToLowerInvariant();
|
155
|
-
if (projectExtension == ".proj")
|
156
|
-
{
|
157
|
-
// If there is some MSBuild logic that needs to run to fully resolve the path skip the project
|
158
|
-
if (File.Exists(file))
|
159
|
-
{
|
160
|
-
var additionalProjectRootElement = ProjectRootElement.Open(file, projectCollection);
|
161
|
-
projectStack.Push((Path.GetFullPath(Path.GetDirectoryName(file)!), additionalProjectRootElement));
|
162
|
-
processedProjectFiles.Add(file);
|
163
|
-
}
|
164
|
-
}
|
165
|
-
else if (projectExtension == ".csproj" || projectExtension == ".vbproj" || projectExtension == ".fsproj")
|
166
|
-
{
|
167
|
-
yield return file;
|
168
|
-
}
|
169
|
-
}
|
170
|
-
}
|
171
|
-
}
|
172
|
-
}
|
173
|
-
|
174
|
-
public static IReadOnlyDictionary<string, Property> GetProperties(ImmutableArray<ProjectBuildFile> buildFiles)
|
175
|
-
{
|
176
|
-
Dictionary<string, Property> properties = new(StringComparer.OrdinalIgnoreCase);
|
177
|
-
|
178
|
-
foreach (var buildFile in buildFiles)
|
179
|
-
{
|
180
|
-
var projectRoot = CreateProjectRootElement(buildFile);
|
181
|
-
|
182
|
-
foreach (var property in projectRoot.Properties)
|
183
|
-
{
|
184
|
-
// Short of evaluating the entire project, there's no way to _really_ know what package version is
|
185
|
-
// going to be used, and even then we might not be able to update it. As a best guess, we'll simply
|
186
|
-
// skip any property that has a condition _or_ where the condition is checking for an empty string.
|
187
|
-
var hasEmptyCondition = string.IsNullOrEmpty(property.Condition);
|
188
|
-
var conditionIsCheckingForEmptyString = string.Equals(property.Condition, $"$({property.Name}) == ''", StringComparison.OrdinalIgnoreCase) ||
|
189
|
-
string.Equals(property.Condition, $"'$({property.Name})' == ''", StringComparison.OrdinalIgnoreCase);
|
190
|
-
if (hasEmptyCondition || conditionIsCheckingForEmptyString)
|
191
|
-
{
|
192
|
-
properties[property.Name] = new(property.Name, property.Value, PathHelper.NormalizePathToUnix(buildFile.RelativePath));
|
193
|
-
}
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
return properties;
|
198
|
-
}
|
199
|
-
|
200
|
-
public static IEnumerable<Dependency> GetTopLevelPackageDependencyInfos(ImmutableArray<ProjectBuildFile> buildFiles)
|
201
|
-
{
|
202
|
-
Dictionary<string, (string, bool, DependencyType)> packageInfo = new(StringComparer.OrdinalIgnoreCase);
|
203
|
-
Dictionary<string, string> packageVersionInfo = new(StringComparer.OrdinalIgnoreCase);
|
204
|
-
Dictionary<string, Property> propertyInfo = new(StringComparer.OrdinalIgnoreCase);
|
205
|
-
|
206
|
-
foreach (var buildFile in buildFiles)
|
207
|
-
{
|
208
|
-
var projectRoot = CreateProjectRootElement(buildFile);
|
209
|
-
|
210
|
-
foreach (var property in projectRoot.Properties)
|
211
|
-
{
|
212
|
-
// Short of evaluating the entire project, there's no way to _really_ know what package version is
|
213
|
-
// going to be used, and even then we might not be able to update it. As a best guess, we'll simply
|
214
|
-
// skip any property that has a condition _or_ where the condition is checking for an empty string.
|
215
|
-
var hasEmptyCondition = string.IsNullOrEmpty(property.Condition);
|
216
|
-
var conditionIsCheckingForEmptyString = string.Equals(property.Condition, $"$({property.Name}) == ''", StringComparison.OrdinalIgnoreCase) ||
|
217
|
-
string.Equals(property.Condition, $"'$({property.Name})' == ''", StringComparison.OrdinalIgnoreCase);
|
218
|
-
if (hasEmptyCondition || conditionIsCheckingForEmptyString)
|
219
|
-
{
|
220
|
-
propertyInfo[property.Name] = new(property.Name, property.Value, buildFile.RelativePath);
|
221
|
-
}
|
222
|
-
}
|
223
|
-
|
224
|
-
if (buildFile.IsOutsideBasePath)
|
225
|
-
{
|
226
|
-
continue;
|
227
|
-
}
|
228
|
-
|
229
|
-
foreach (var packageItem in projectRoot.Items
|
230
|
-
.Where(i => (i.ItemType == "PackageReference" || i.ItemType == "GlobalPackageReference")))
|
231
|
-
{
|
232
|
-
var dependencyType = packageItem.ItemType == "PackageReference" ? DependencyType.PackageReference : DependencyType.GlobalPackageReference;
|
233
|
-
var versionSpecification = packageItem.Metadata.FirstOrDefault(m => m.Name.Equals("Version", StringComparison.OrdinalIgnoreCase))?.Value
|
234
|
-
?? packageItem.Metadata.FirstOrDefault(m => m.Name.Equals("VersionOverride", StringComparison.OrdinalIgnoreCase))?.Value
|
235
|
-
?? string.Empty;
|
236
|
-
foreach (var rawAttributeValue in new[] { packageItem.Include, packageItem.Update })
|
237
|
-
{
|
238
|
-
var attributeValue = rawAttributeValue?.Trim();
|
239
|
-
if (!string.IsNullOrWhiteSpace(attributeValue))
|
240
|
-
{
|
241
|
-
if (packageInfo.TryGetValue(attributeValue, out var existingInfo))
|
242
|
-
{
|
243
|
-
var existingVersion = existingInfo.Item1;
|
244
|
-
var existingUpdate = existingInfo.Item2;
|
245
|
-
// Retain the version from the Update reference since the intention
|
246
|
-
// would be to override the version of the Include reference.
|
247
|
-
var vSpec = string.IsNullOrEmpty(versionSpecification) || existingUpdate ? existingVersion : versionSpecification;
|
248
|
-
|
249
|
-
var isUpdate = existingUpdate && string.IsNullOrEmpty(packageItem.Include);
|
250
|
-
packageInfo[attributeValue] = (vSpec, isUpdate, dependencyType);
|
251
|
-
}
|
252
|
-
else
|
253
|
-
{
|
254
|
-
var isUpdate = !string.IsNullOrEmpty(packageItem.Update);
|
255
|
-
packageInfo[attributeValue] = (versionSpecification, isUpdate, dependencyType);
|
256
|
-
}
|
257
|
-
}
|
258
|
-
}
|
259
|
-
}
|
260
|
-
|
261
|
-
foreach (var packageItem in projectRoot.Items
|
262
|
-
.Where(i => i.ItemType == "PackageVersion" && !string.IsNullOrEmpty(i.Include)))
|
263
|
-
{
|
264
|
-
packageVersionInfo[packageItem.Include] = packageItem.Metadata.FirstOrDefault(m => m.Name.Equals("Version", StringComparison.OrdinalIgnoreCase))?.Value
|
265
|
-
?? string.Empty;
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
|
-
foreach (var (name, info) in packageInfo)
|
270
|
-
{
|
271
|
-
var (version, isUpdate, dependencyType) = info;
|
272
|
-
if (version.Length != 0 || !packageVersionInfo.TryGetValue(name, out var packageVersion))
|
273
|
-
{
|
274
|
-
packageVersion = version;
|
275
|
-
}
|
276
|
-
|
277
|
-
// Walk the property replacements until we don't find another one.
|
278
|
-
var evaluationResult = GetEvaluatedValue(packageVersion, propertyInfo);
|
279
|
-
packageVersion = evaluationResult.ResultType == EvaluationResultType.Success
|
280
|
-
? evaluationResult.EvaluatedValue.TrimStart('[', '(').TrimEnd(']', ')')
|
281
|
-
: evaluationResult.EvaluatedValue;
|
282
|
-
|
283
|
-
// If at this point we have a semicolon in the name then split it and yield multiple dependencies.
|
284
|
-
foreach (var splitName in name.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
285
|
-
{
|
286
|
-
yield return new Dependency(splitName.Trim(), packageVersion, dependencyType, EvaluationResult: evaluationResult, IsUpdate: isUpdate);
|
287
|
-
}
|
288
|
-
}
|
289
|
-
}
|
290
|
-
|
291
|
-
/// <summary>
|
292
|
-
/// Given an MSBuild string and a set of properties, returns our best guess at the final value MSBuild will evaluate to.
|
293
|
-
/// </summary>
|
294
|
-
public static EvaluationResult GetEvaluatedValue(string msbuildString, IReadOnlyDictionary<string, Property> propertyInfo, params string[] propertiesToIgnore)
|
295
|
-
{
|
296
|
-
var ignoredProperties = new HashSet<string>(propertiesToIgnore, StringComparer.OrdinalIgnoreCase);
|
297
|
-
var seenProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
298
|
-
|
299
|
-
string originalValue = msbuildString;
|
300
|
-
string? rootPropertyName = null;
|
301
|
-
while (TryGetPropertyName(msbuildString, out var propertyName))
|
302
|
-
{
|
303
|
-
rootPropertyName = propertyName;
|
304
|
-
|
305
|
-
if (ignoredProperties.Contains(propertyName))
|
306
|
-
{
|
307
|
-
return new(EvaluationResultType.PropertyIgnored, originalValue, msbuildString, rootPropertyName, $"Property '{propertyName}' is ignored.");
|
308
|
-
}
|
309
|
-
|
310
|
-
if (!seenProperties.Add(propertyName))
|
311
|
-
{
|
312
|
-
return new(EvaluationResultType.CircularReference, originalValue, msbuildString, rootPropertyName, $"Property '{propertyName}' has a circular reference.");
|
313
|
-
}
|
314
|
-
|
315
|
-
if (!propertyInfo.TryGetValue(propertyName, out var property))
|
316
|
-
{
|
317
|
-
return new(EvaluationResultType.PropertyNotFound, originalValue, msbuildString, rootPropertyName, $"Property '{propertyName}' was not found.");
|
318
|
-
}
|
319
|
-
|
320
|
-
msbuildString = msbuildString.Replace($"$({propertyName})", property.Value);
|
321
|
-
}
|
322
|
-
|
323
|
-
return new(EvaluationResultType.Success, originalValue, msbuildString, rootPropertyName, null);
|
324
|
-
}
|
325
|
-
|
326
|
-
public static bool TryGetPropertyName(string versionContent, [NotNullWhen(true)] out string? propertyName)
|
327
|
-
{
|
328
|
-
var startIndex = versionContent.IndexOf("$(", StringComparison.Ordinal);
|
329
|
-
if (startIndex != -1)
|
330
|
-
{
|
331
|
-
var endIndex = versionContent.IndexOf(')', startIndex);
|
332
|
-
if (endIndex != -1)
|
333
|
-
{
|
334
|
-
propertyName = versionContent.Substring(startIndex + 2, endIndex - startIndex - 2);
|
335
|
-
return true;
|
336
|
-
}
|
337
|
-
}
|
338
|
-
|
339
|
-
propertyName = null;
|
340
|
-
return false;
|
341
|
-
}
|
342
|
-
|
343
|
-
internal static async Task<bool> DependenciesAreCoherentAsync(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> packages, ExperimentsManager experimentsManager, ILogger logger)
|
344
|
-
{
|
345
|
-
var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
|
346
|
-
try
|
347
|
-
{
|
348
|
-
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger);
|
349
|
-
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName, experimentsManager);
|
350
|
-
|
351
|
-
// NU1608: Detected package version outside of dependency constraint
|
352
|
-
|
353
|
-
return exitCode == 0 && !stdOut.Contains("NU1608");
|
354
|
-
}
|
355
|
-
finally
|
356
|
-
{
|
357
|
-
tempDirectory.Delete(recursive: true);
|
358
|
-
}
|
359
|
-
}
|
360
|
-
|
361
99
|
internal static async Task<ImmutableArray<Dependency>?> ResolveDependencyConflicts(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> packages, ImmutableArray<Dependency> update, ExperimentsManager experimentsManager, ILogger logger)
|
362
100
|
{
|
363
101
|
var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
|
@@ -524,136 +262,6 @@ internal static partial class MSBuildHelper
|
|
524
262
|
}
|
525
263
|
}
|
526
264
|
|
527
|
-
internal static async Task<ImmutableArray<Dependency>?> ResolveDependencyConflictsWithBruteForce(string repoRoot, string projectPath, string targetFramework, ImmutableArray<Dependency> packages, ExperimentsManager experimentsManager, ILogger logger)
|
528
|
-
{
|
529
|
-
var tempDirectory = Directory.CreateTempSubdirectory("package-dependency-coherence_");
|
530
|
-
try
|
531
|
-
{
|
532
|
-
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger);
|
533
|
-
var (exitCode, stdOut, stdErr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["restore", tempProjectPath], tempDirectory.FullName, experimentsManager);
|
534
|
-
ThrowOnUnauthenticatedFeed(stdOut);
|
535
|
-
|
536
|
-
// simple cases first
|
537
|
-
// if restore failed, nothing we can do
|
538
|
-
if (exitCode != 0)
|
539
|
-
{
|
540
|
-
return null;
|
541
|
-
}
|
542
|
-
|
543
|
-
// if no problems found, just return the current set
|
544
|
-
if (!stdOut.Contains("NU1608"))
|
545
|
-
{
|
546
|
-
return packages;
|
547
|
-
}
|
548
|
-
|
549
|
-
// now it gets complicated; look for the packages with issues
|
550
|
-
MatchCollection matches = PackageIncompatibilityWarningPattern().Matches(stdOut);
|
551
|
-
(string, NuGetVersion)[] badPackagesAndVersions = matches.Select(m => (m.Groups["PackageName"].Value, NuGetVersion.Parse(m.Groups["PackageVersion"].Value))).ToArray();
|
552
|
-
Dictionary<string, HashSet<NuGetVersion>> badPackagesAndCandidateVersionsDictionary = new(StringComparer.OrdinalIgnoreCase);
|
553
|
-
|
554
|
-
// and for each of those packages, find all versions greater than the one that's currently installed
|
555
|
-
foreach ((string PackageName, NuGetVersion packageVersion) in badPackagesAndVersions)
|
556
|
-
{
|
557
|
-
// this command dumps a JSON object with all versions of the specified package from all package sources
|
558
|
-
// not using the `dotnet` execution method because we want to force the latest MSBuild and SDK to be used
|
559
|
-
(exitCode, stdOut, stdErr) = await ProcessEx.RunAsync("dotnet", ["package", "search", PackageName, "--exact-match", "--format", "json"], workingDirectory: tempDirectory.FullName);
|
560
|
-
if (exitCode != 0)
|
561
|
-
{
|
562
|
-
continue;
|
563
|
-
}
|
564
|
-
|
565
|
-
// ensure collection exists
|
566
|
-
if (!badPackagesAndCandidateVersionsDictionary.ContainsKey(PackageName))
|
567
|
-
{
|
568
|
-
badPackagesAndCandidateVersionsDictionary.Add(PackageName, new HashSet<NuGetVersion>());
|
569
|
-
}
|
570
|
-
|
571
|
-
HashSet<NuGetVersion> foundVersions = badPackagesAndCandidateVersionsDictionary[PackageName];
|
572
|
-
|
573
|
-
var json = JsonHelper.ParseNode(stdOut);
|
574
|
-
if (json?["searchResult"] is JsonArray searchResults)
|
575
|
-
{
|
576
|
-
foreach (var searchResult in searchResults)
|
577
|
-
{
|
578
|
-
if (searchResult?["packages"] is JsonArray packagesArray)
|
579
|
-
{
|
580
|
-
foreach (var package in packagesArray)
|
581
|
-
{
|
582
|
-
// in 8.0.xxx SDKs, the package version is in the `latestVersion` property, but in 9.0.xxx, it's `version`
|
583
|
-
var packageVersionProperty = package?["version"] ?? package?["latestVersion"];
|
584
|
-
if (packageVersionProperty is JsonValue latestVersion &&
|
585
|
-
latestVersion.GetValueKind() == JsonValueKind.String &&
|
586
|
-
NuGetVersion.TryParse(latestVersion.ToString(), out var nugetVersion) &&
|
587
|
-
nugetVersion > packageVersion)
|
588
|
-
{
|
589
|
-
foundVersions.Add(nugetVersion);
|
590
|
-
}
|
591
|
-
}
|
592
|
-
}
|
593
|
-
}
|
594
|
-
}
|
595
|
-
}
|
596
|
-
|
597
|
-
// generate all possible combinations
|
598
|
-
(string Key, NuGetVersion v)[][] expandedLists = badPackagesAndCandidateVersionsDictionary.Select(kvp => kvp.Value.Order().Select(v => (kvp.Key, v)).ToArray()).ToArray();
|
599
|
-
IEnumerable<(string PackageName, NuGetVersion PackageVersion)>[] product = expandedLists.CartesianProduct().ToArray();
|
600
|
-
|
601
|
-
// FUTURE WORK: pre-filter individual known package incompatibilities to reduce the number of combinations, e.g., if Package.A v1.0.0
|
602
|
-
// is incompatible with Package.B v2.0.0, then remove _all_ combinations with that pair
|
603
|
-
|
604
|
-
// this is the slow part
|
605
|
-
foreach (IEnumerable<(string PackageName, NuGetVersion PackageVersion)> candidateSet in product)
|
606
|
-
{
|
607
|
-
// rebuild candidate dependency list with the relevant versions
|
608
|
-
Dictionary<string, NuGetVersion> packageVersions = candidateSet.ToDictionary(candidateSet => candidateSet.PackageName, candidateSet => candidateSet.PackageVersion);
|
609
|
-
var candidatePackages = packages.Select(p =>
|
610
|
-
{
|
611
|
-
if (packageVersions.TryGetValue(p.Name, out var version))
|
612
|
-
{
|
613
|
-
// create a new dependency with the updated version
|
614
|
-
return new Dependency(p.Name, version.ToString(), p.Type, IsDevDependency: p.IsDevDependency, IsOverride: p.IsOverride, IsUpdate: p.IsUpdate);
|
615
|
-
}
|
616
|
-
|
617
|
-
// not the dependency we're looking for, use whatever it already was in this set
|
618
|
-
return p;
|
619
|
-
}).ToImmutableArray();
|
620
|
-
|
621
|
-
if (await DependenciesAreCoherentAsync(repoRoot, projectPath, targetFramework, candidatePackages, experimentsManager, logger))
|
622
|
-
{
|
623
|
-
// return as soon as we find a coherent set
|
624
|
-
return candidatePackages;
|
625
|
-
}
|
626
|
-
}
|
627
|
-
|
628
|
-
// no package resolution set found
|
629
|
-
return null;
|
630
|
-
}
|
631
|
-
finally
|
632
|
-
{
|
633
|
-
tempDirectory.Delete(recursive: true);
|
634
|
-
}
|
635
|
-
}
|
636
|
-
|
637
|
-
// fully expand all possible combinations using the algorithm from here:
|
638
|
-
// https://ericlippert.com/2010/06/28/computing-a-cartesian-product-with-linq/
|
639
|
-
private static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
|
640
|
-
{
|
641
|
-
IEnumerable<IEnumerable<T>> emptyProduct = [[]];
|
642
|
-
return sequences.Aggregate(emptyProduct, (accumulator, sequence) => from accseq in accumulator
|
643
|
-
from item in sequence
|
644
|
-
select accseq.Concat([item]));
|
645
|
-
}
|
646
|
-
|
647
|
-
private static ProjectRootElement CreateProjectRootElement(ProjectBuildFile buildFile)
|
648
|
-
{
|
649
|
-
var xmlString = buildFile.Contents.ToFullString();
|
650
|
-
using var xmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
|
651
|
-
using var xmlReader = XmlReader.Create(xmlStream);
|
652
|
-
var projectRoot = ProjectRootElement.Create(xmlReader);
|
653
|
-
|
654
|
-
return projectRoot;
|
655
|
-
}
|
656
|
-
|
657
265
|
private static IEnumerable<PackageSource>? LoadPackageSources(string nugetConfigPath, ILogger logger)
|
658
266
|
{
|
659
267
|
try
|
@@ -900,44 +508,13 @@ internal static partial class MSBuildHelper
|
|
900
508
|
try
|
901
509
|
{
|
902
510
|
var topLevelPackagesNames = packages.Select(p => p.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
903
|
-
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger, importDependencyTargets:
|
511
|
+
var tempProjectPath = await CreateTempProjectAsync(tempDirectory, repoRoot, projectPath, targetFramework, packages, experimentsManager, logger, importDependencyTargets: false);
|
904
512
|
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
.Where(p => p.FilePath == Path.GetFileName(tempProjectPath))
|
911
|
-
.FirstOrDefault()
|
912
|
-
?.Dependencies.ToImmutableArray() ?? [];
|
913
|
-
}
|
914
|
-
else
|
915
|
-
{
|
916
|
-
var (exitCode, stdout, stderr) = await ProcessEx.RunDotnetWithoutMSBuildEnvironmentVariablesAsync(["build", tempProjectPath, "/t:_ReportDependencies"], tempDirectory.FullName, experimentsManager);
|
917
|
-
ThrowOnUnauthenticatedFeed(stdout);
|
918
|
-
|
919
|
-
if (exitCode == 0)
|
920
|
-
{
|
921
|
-
ImmutableArray<string> tfms = [targetFramework];
|
922
|
-
var lines = stdout.Split('\n').Select(line => line.Trim());
|
923
|
-
var pattern = PackagePattern();
|
924
|
-
allDependencies = lines
|
925
|
-
.Select(line => pattern.Match(line))
|
926
|
-
.Where(match => match.Success)
|
927
|
-
.Select(match =>
|
928
|
-
{
|
929
|
-
var PackageName = match.Groups["PackageName"].Value;
|
930
|
-
var isTransitive = !topLevelPackagesNames.Contains(PackageName);
|
931
|
-
return new Dependency(PackageName, match.Groups["PackageVersion"].Value, DependencyType.Unknown, TargetFrameworks: tfms, IsTransitive: isTransitive);
|
932
|
-
})
|
933
|
-
.ToImmutableArray();
|
934
|
-
}
|
935
|
-
else
|
936
|
-
{
|
937
|
-
logger?.Warn($"dotnet build in {nameof(GetAllPackageDependenciesAsync)} failed. STDOUT: {stdout} STDERR: {stderr}");
|
938
|
-
allDependencies = [];
|
939
|
-
}
|
940
|
-
}
|
513
|
+
var projectDiscovery = await SdkProjectDiscovery.DiscoverAsync(repoRoot, tempDirectory.FullName, tempProjectPath, experimentsManager, logger);
|
514
|
+
var allDependencies = projectDiscovery
|
515
|
+
.Where(p => p.FilePath == Path.GetFileName(tempProjectPath))
|
516
|
+
.FirstOrDefault()
|
517
|
+
?.Dependencies.ToImmutableArray() ?? [];
|
941
518
|
|
942
519
|
return allDependencies;
|
943
520
|
}
|
@@ -976,6 +553,7 @@ internal static partial class MSBuildHelper
|
|
976
553
|
ThrowOnMissingPackages(output);
|
977
554
|
ThrowOnUpdateNotPossible(output);
|
978
555
|
ThrowOnRateLimitExceeded(output);
|
556
|
+
ThrowOnTimeout(output);
|
979
557
|
ThrowOnBadResponse(output);
|
980
558
|
ThrowOnUnparseableFile(output);
|
981
559
|
}
|
@@ -1009,6 +587,19 @@ internal static partial class MSBuildHelper
|
|
1009
587
|
}
|
1010
588
|
}
|
1011
589
|
|
590
|
+
private static void ThrowOnTimeout(string stdout)
|
591
|
+
{
|
592
|
+
var patterns = new[]
|
593
|
+
{
|
594
|
+
new Regex(@"The HTTP request to 'GET (?<Source>[^']+)' has timed out after \d+ms"),
|
595
|
+
};
|
596
|
+
var match = patterns.Select(p => p.Match(stdout)).Where(m => m.Success).FirstOrDefault();
|
597
|
+
if (match is not null)
|
598
|
+
{
|
599
|
+
throw new PrivateSourceTimedOutException(match.Groups["Source"].Value);
|
600
|
+
}
|
601
|
+
}
|
602
|
+
|
1012
603
|
private static void ThrowOnBadResponse(string stdout)
|
1013
604
|
{
|
1014
605
|
var patterns = new[]
|
@@ -1043,6 +634,7 @@ internal static partial class MSBuildHelper
|
|
1043
634
|
new Regex(@"Unable to find package (?<PackageName>[^ ]+)\. No packages exist with this id in source\(s\): (?<PackageSource>.*)$", RegexOptions.Multiline),
|
1044
635
|
new Regex(@"Unable to find package (?<PackageName>[^ ]+) with version \((?<PackageVersion>[^)]+)\)"),
|
1045
636
|
new Regex(@"Unable to find package '(?<PackageName>[^ ]+)'\."),
|
637
|
+
new Regex(@"Unable to resolve dependency '(?<PackageName>[^']+)'\. Source\(s\) used"),
|
1046
638
|
new Regex(@"Could not resolve SDK ""(?<PackageName>[^ ]+)""\."),
|
1047
639
|
new Regex(@"Failed to fetch results from V2 feed at '.*FindPackagesById\(\)\?id='(?<PackageName>[^']+)'&semVerLevel=2\.0\.0' with following message : Response status code does not indicate success: 404\."),
|
1048
640
|
};
|
@@ -1108,131 +700,4 @@ internal static partial class MSBuildHelper
|
|
1108
700
|
dotnetToolsJsonJsonPath = PathHelper.GetFileInDirectoryOrParent(workspacePath, repoRootPath, "./.config/dotnet-tools.json", caseSensitive: false);
|
1109
701
|
return dotnetToolsJsonJsonPath is not null;
|
1110
702
|
}
|
1111
|
-
|
1112
|
-
internal static bool TryGetDirectoryPackagesPropsPath(string repoRootPath, string workspacePath, [NotNullWhen(returnValue: true)] out string? directoryPackagesPropsPath)
|
1113
|
-
{
|
1114
|
-
directoryPackagesPropsPath = PathHelper.GetFileInDirectoryOrParent(workspacePath, repoRootPath, "./Directory.Packages.props", caseSensitive: false);
|
1115
|
-
return directoryPackagesPropsPath is not null;
|
1116
|
-
}
|
1117
|
-
|
1118
|
-
internal static async Task<(ImmutableArray<ProjectBuildFile> ProjectBuildFiles, string[] TargetFrameworks)> LoadBuildFilesAndTargetFrameworksAsync(string repoRootPath, string projectPath)
|
1119
|
-
{
|
1120
|
-
var buildFileList = new List<string>
|
1121
|
-
{
|
1122
|
-
projectPath.NormalizePathToUnix() // always include the starting project
|
1123
|
-
};
|
1124
|
-
|
1125
|
-
// a global.json file might cause problems with the dotnet msbuild command; create a safe version temporarily
|
1126
|
-
TryGetGlobalJsonPath(repoRootPath, projectPath, out var globalJsonPath);
|
1127
|
-
var safeGlobalJsonName = $"{globalJsonPath}{Guid.NewGuid()}";
|
1128
|
-
HashSet<string> targetFrameworks = new(StringComparer.OrdinalIgnoreCase);
|
1129
|
-
var repoRootDirectoryInfo = new DirectoryInfo(repoRootPath);
|
1130
|
-
|
1131
|
-
try
|
1132
|
-
{
|
1133
|
-
// move the original
|
1134
|
-
if (globalJsonPath is not null)
|
1135
|
-
{
|
1136
|
-
File.Move(globalJsonPath, safeGlobalJsonName);
|
1137
|
-
|
1138
|
-
// create a safe version with only certain top-level keys
|
1139
|
-
var globalJsonContent = await File.ReadAllTextAsync(safeGlobalJsonName);
|
1140
|
-
var json = JsonHelper.ParseNode(globalJsonContent);
|
1141
|
-
var sdks = json?["msbuild-sdks"];
|
1142
|
-
if (sdks is not null)
|
1143
|
-
{
|
1144
|
-
var newObject = new Dictionary<string, object>()
|
1145
|
-
{
|
1146
|
-
["msbuild-sdks"] = sdks,
|
1147
|
-
};
|
1148
|
-
var newContent = JsonSerializer.Serialize(newObject);
|
1149
|
-
await File.WriteAllTextAsync(globalJsonPath, newContent);
|
1150
|
-
}
|
1151
|
-
}
|
1152
|
-
|
1153
|
-
// This is equivalent to running the command `dotnet msbuild <projectPath> /pp` to preprocess the file.
|
1154
|
-
// The only difference is that we're specifying the `IgnoreMissingImports` flag which will allow us to
|
1155
|
-
// load the project even if it imports a file that doesn't exist (e.g. a file that's generated at restore
|
1156
|
-
// or build time).
|
1157
|
-
using var projectCollection = new ProjectCollection(); // do this in a one-off instance and don't pollute the global collection
|
1158
|
-
var project = Project.FromFile(projectPath, new ProjectOptions
|
1159
|
-
{
|
1160
|
-
LoadSettings = ProjectLoadSettings.IgnoreMissingImports,
|
1161
|
-
ProjectCollection = projectCollection,
|
1162
|
-
});
|
1163
|
-
var allImportedPaths = project.Imports.Select(i => i.ImportedProject.FullPath.NormalizePathToUnix()).ToArray();
|
1164
|
-
var importedPathsInRepo = allImportedPaths.Where(p => PathHelper.IsFileUnderDirectory(repoRootDirectoryInfo, new FileInfo(p))).ToArray();
|
1165
|
-
var projectDir = Path.GetDirectoryName(projectPath)!;
|
1166
|
-
var intermediateDir = new DirectoryInfo(Path.Combine(projectDir, project.GetPropertyValue("BaseIntermediateOutputPath")));
|
1167
|
-
var outputDir = new DirectoryInfo(Path.Combine(projectDir, project.GetPropertyValue("BaseOutputPath")));
|
1168
|
-
var nonTransitivePathsInRepo = importedPathsInRepo.Where(p =>
|
1169
|
-
{
|
1170
|
-
var fi = new FileInfo(p);
|
1171
|
-
return !PathHelper.IsFileUnderDirectory(intermediateDir, fi)
|
1172
|
-
&& !PathHelper.IsFileUnderDirectory(outputDir, fi);
|
1173
|
-
}).ToArray();
|
1174
|
-
buildFileList.AddRange(nonTransitivePathsInRepo.Select(p => p.NormalizePathToUnix()));
|
1175
|
-
|
1176
|
-
// use the MSBuild-evaluated value so we don't have to try to manually parse XML
|
1177
|
-
IEnumerable<ProjectProperty> targetFrameworkProperties = project.Properties.Where(p => p.Name.Equals("TargetFramework", StringComparison.OrdinalIgnoreCase)).ToList();
|
1178
|
-
IEnumerable<ProjectProperty> targetFrameworksProperties = project.Properties.Where(p => p.Name.Equals("TargetFrameworks", StringComparison.OrdinalIgnoreCase)).ToList();
|
1179
|
-
IEnumerable<ProjectProperty> targetFrameworkVersionProperties = project.Properties.Where(p => p.Name.Equals("TargetFrameworkVersion", StringComparison.OrdinalIgnoreCase)).ToList();
|
1180
|
-
foreach (ProjectProperty tfm in targetFrameworkProperties)
|
1181
|
-
{
|
1182
|
-
if (!string.IsNullOrWhiteSpace(tfm.EvaluatedValue))
|
1183
|
-
{
|
1184
|
-
targetFrameworks.Add(tfm.EvaluatedValue);
|
1185
|
-
}
|
1186
|
-
}
|
1187
|
-
|
1188
|
-
foreach (ProjectProperty tfms in targetFrameworksProperties)
|
1189
|
-
{
|
1190
|
-
foreach (string tfmValue in tfms.EvaluatedValue.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
1191
|
-
{
|
1192
|
-
targetFrameworks.Add(tfmValue);
|
1193
|
-
}
|
1194
|
-
}
|
1195
|
-
|
1196
|
-
if (targetFrameworks.Count == 0)
|
1197
|
-
{
|
1198
|
-
// Only try this if we haven't been able to resolve anything yet. This is because deep in the SDK, a
|
1199
|
-
// `TargetFramework` of `netstandard2.0` (eventually) gets turned into `v2.0` and we don't want to
|
1200
|
-
// interpret that as a .NET Framework 2.0 project.
|
1201
|
-
foreach (ProjectProperty tfvm in targetFrameworkVersionProperties)
|
1202
|
-
{
|
1203
|
-
// `v0.0` is an error case where no TFM could be evaluated
|
1204
|
-
if (tfvm.EvaluatedValue != "v0.0")
|
1205
|
-
{
|
1206
|
-
targetFrameworks.Add($"net{tfvm.EvaluatedValue.TrimStart('v').Replace(".", "")}");
|
1207
|
-
}
|
1208
|
-
}
|
1209
|
-
}
|
1210
|
-
}
|
1211
|
-
catch (InvalidProjectFileException)
|
1212
|
-
{
|
1213
|
-
return ([], []);
|
1214
|
-
}
|
1215
|
-
finally
|
1216
|
-
{
|
1217
|
-
if (globalJsonPath is not null)
|
1218
|
-
{
|
1219
|
-
File.Move(safeGlobalJsonName, globalJsonPath, overwrite: true);
|
1220
|
-
}
|
1221
|
-
}
|
1222
|
-
|
1223
|
-
var result = buildFileList
|
1224
|
-
.Where(File.Exists)
|
1225
|
-
.Select(path => ProjectBuildFile.Open(repoRootPath, path))
|
1226
|
-
.ToImmutableArray();
|
1227
|
-
return (result, targetFrameworks.ToArray());
|
1228
|
-
}
|
1229
|
-
|
1230
|
-
[GeneratedRegex("^\\s*NuGetData::Package=(?<PackageName>[^,]+), Version=(?<PackageVersion>.+)$")]
|
1231
|
-
private static partial Regex PackagePattern();
|
1232
|
-
|
1233
|
-
// Example output:
|
1234
|
-
// NU1608: Detected package version outside of dependency constraint: SpecFlow.Tools.MsBuild.Generation 3.3.30 requires SpecFlow(= 3.3.30) but version SpecFlow 3.9.74 was resolved.
|
1235
|
-
// PackageName-|+++++++++++++++++++++++++++++++| |++++|-PackageVersion
|
1236
|
-
[GeneratedRegex("NU1608: [^:]+: (?<PackageName>[^ ]+) (?<PackageVersion>[^ ]+)")]
|
1237
|
-
private static partial Regex PackageIncompatibilityWarningPattern();
|
1238
703
|
}
|