dependabot-nuget 0.370.0 → 0.372.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.Build.props +1 -0
- data/helpers/lib/NuGetUpdater/DotNetPackageCorrelation/DotNetPackageCorrelation.csproj +1 -0
- data/helpers/lib/NuGetUpdater/NuGetProjects/Directory.Build.props +2 -0
- data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.Build.Tasks/NuGet.Build.Tasks.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetProjects/NuGet.PackageManagement/NuGet.PackageManagement.csproj +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/DiscoveryWorker.cs +14 -6
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/ProjectDiscoveryResult.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Discover/SdkProjectDiscovery.cs +31 -16
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/GetProperty.targets +9 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/NuGetUpdater.Core.csproj +1 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Run/CommitOptions_IncludeScopeConverter.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Updater/FileWriters/XmlFileWriter.cs +41 -14
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/DependencyConflictResolver.cs +55 -51
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Utilities/MSBuildHelper.cs +62 -12
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Clone/CloneWorkerTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTestBase.cs +0 -20
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.PackagesConfig.cs +96 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Proj.cs +0 -8
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.Project.cs +2 -49
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/DiscoveryWorkerTests.cs +0 -77
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/ExpectedDiscoveryResults.cs +0 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Discover/SdkProjectDiscoveryTests.cs +0 -58
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/EndToEndTests.cs +1 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlerSelectionTests.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdateHandlers/UpdateHandlersTestsBase.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Run/UpdatedDependencyListTests.cs +1 -4
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestBase.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/TestHttpServer.cs +2 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/FileWriterTestsBase.cs +1 -1
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests.cs +64 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/FileWriters/XmlFileWriterTests_GetDocumentIndentationCharactersTests.cs +120 -0
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Update/SpecialFilePatcherTests.cs +2 -2
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core.Test/Utilities/LinuxOnlyAttribute.cs +6 -1
- metadata +6 -5
- data/helpers/lib/NuGetUpdater/NuGetUpdater.Core/Property.cs +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a058182c9ce909abc8398d444a3cba984f43528a7655fd5ee96cc8c607bbfd76
|
|
4
|
+
data.tar.gz: ffd8f02946da91739938e89ca13e3beb4e6b3ef157bb23083251df98cf45930f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d9d90b837aa4ebd014a46c1dc0a89ae29689f30bbe84fc49c16deec4c260625e263aa731f100d0ef909ad2da00a48c131e9086393866f54e83e48e6678a77f8
|
|
7
|
+
data.tar.gz: d8c27b9ff9c1837c191ce89ae005e3071f5fc5cd09d76d8c1e0ecc3ea1bd511ed1cd544bac6bdd0ea17aef43dc49747b2c87cc8cbe0f3e3645f6977582ec3394
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
|
5
5
|
<NoWarn>$(NoWarn);NU1701</NoWarn>
|
|
6
6
|
<Nullable>enable</Nullable>
|
|
7
|
+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
7
8
|
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
|
8
9
|
</PropertyGroup>
|
|
9
10
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
<NoWarn>$(NoWarn);SYSLIB0014</NoWarn><!-- obsolete -->
|
|
11
11
|
<NuGetSourceLocation>$(MSBuildThisFileDirectory)..\..\NuGet.Client</NuGetSourceLocation>
|
|
12
12
|
<SharedDirectory>$(NuGetSourceLocation)\build\Shared</SharedDirectory>
|
|
13
|
+
<NoWarn>$(NoWarn);CA1416</NoWarn><!-- platform compatibility in vendored NuGet.Client code -->
|
|
14
|
+
<NoWarn>$(NoWarn);CS0436</NoWarn><!-- type conflicts with imported types in vendored NuGet.Client code -->
|
|
13
15
|
<Version>6.8.0</Version>
|
|
14
16
|
</PropertyGroup>
|
|
15
17
|
|
|
@@ -318,7 +318,20 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
|
318
318
|
private async Task<ImmutableArray<ProjectDiscoveryResult>> RunForProjectPathsAsync(string repoRootPath, string workspacePath, IEnumerable<string> projectPaths)
|
|
319
319
|
{
|
|
320
320
|
var normalizedProjectPaths = projectPaths.SelectMany(p => PathHelper.ResolveCaseInsensitivePathsInsideRepoRoot(p, repoRootPath) ?? []).Distinct().ToImmutableArray();
|
|
321
|
-
|
|
321
|
+
|
|
322
|
+
// Find all MSBuild files that may contain special imports
|
|
323
|
+
var enumerationOptions = new EnumerationOptions()
|
|
324
|
+
{
|
|
325
|
+
RecurseSubdirectories = true,
|
|
326
|
+
IgnoreInaccessible = true,
|
|
327
|
+
AttributesToSkip = FileAttributes.ReparsePoint,
|
|
328
|
+
};
|
|
329
|
+
var msbuildExtensions = new[] { ".props", ".targets", ".proj", ".csproj", ".vbproj", ".fsproj" };
|
|
330
|
+
var filesToPatch = Directory.GetFiles(repoRootPath, "*.*", enumerationOptions)
|
|
331
|
+
.Where(f => msbuildExtensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase))
|
|
332
|
+
.ToImmutableArray();
|
|
333
|
+
|
|
334
|
+
var disposables = filesToPatch.Select(p => new SpecialImportsConditionPatcher(p)).ToImmutableArray();
|
|
322
335
|
var results = new Dictionary<string, ProjectDiscoveryResult>(StringComparer.Ordinal);
|
|
323
336
|
|
|
324
337
|
try
|
|
@@ -411,10 +424,6 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
|
411
424
|
var mergedDependencies = mergedDependenciesSet.Values
|
|
412
425
|
.OrderBy(d => d.Name, StringComparer.OrdinalIgnoreCase)
|
|
413
426
|
.ToImmutableArray();
|
|
414
|
-
var mergedProperties = result1.Properties.Concat(result2.Properties)
|
|
415
|
-
.DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
|
|
416
|
-
.OrderBy(p => p.Name)
|
|
417
|
-
.ToImmutableArray();
|
|
418
427
|
var mergedTargetFrameworks = result1.TargetFrameworks.Concat(result2.TargetFrameworks)
|
|
419
428
|
.Select(t =>
|
|
420
429
|
{
|
|
@@ -450,7 +459,6 @@ public partial class DiscoveryWorker : IDiscoveryWorker
|
|
|
450
459
|
Dependencies = mergedDependencies,
|
|
451
460
|
IsSuccess = result1.IsSuccess && result2.IsSuccess,
|
|
452
461
|
Error = result1.Error ?? result2.Error,
|
|
453
|
-
Properties = mergedProperties,
|
|
454
462
|
TargetFrameworks = mergedTargetFrameworks,
|
|
455
463
|
ReferencedProjectPaths = mergedReferencedProjects,
|
|
456
464
|
ImportedFiles = mergedImportedFiles,
|
|
@@ -10,7 +10,6 @@ public record ProjectDiscoveryResult : IDiscoveryResultWithDependencies
|
|
|
10
10
|
public required ImmutableArray<Dependency> Dependencies { get; init; }
|
|
11
11
|
public bool IsSuccess { get; init; } = true;
|
|
12
12
|
public JobErrorBase? Error { get; init; } = null;
|
|
13
|
-
public ImmutableArray<Property> Properties { get; init; } = [];
|
|
14
13
|
public ImmutableArray<string> TargetFrameworks { get; init; } = [];
|
|
15
14
|
public ImmutableArray<string> ReferencedProjectPaths { get; init; } = [];
|
|
16
15
|
public required ImmutableArray<string> ImportedFiles { get; init; }
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
using System.Collections.Immutable;
|
|
2
2
|
using System.Text.Json;
|
|
3
3
|
using System.Xml.Linq;
|
|
4
|
-
using System.Xml.XPath;
|
|
5
4
|
|
|
6
5
|
using Microsoft.Build.Logging.StructuredLogger;
|
|
7
6
|
|
|
@@ -63,6 +62,12 @@ internal static class SdkProjectDiscovery
|
|
|
63
62
|
"GenerateBuildDependencyFile"
|
|
64
63
|
];
|
|
65
64
|
|
|
65
|
+
// these targets are required to evaluate a legacy project with a single operation
|
|
66
|
+
private static readonly ImmutableArray<string> LegacyProjectSingleRestoreTargetNames = ["ResolveProjectReferences"];
|
|
67
|
+
|
|
68
|
+
// this property evaluates to a version number in an SDK-style project and is unset or empty otherwise
|
|
69
|
+
private const string NETCoreSdkVersionPropertyName = "NETCoreSdkVersion";
|
|
70
|
+
|
|
66
71
|
// this seems to be the maximum number of TFMs that can be restored in parallel without running into race conditions
|
|
67
72
|
private const int MaximumParallelTargetFrameworkRestores = 2;
|
|
68
73
|
|
|
@@ -138,20 +143,39 @@ internal static class SdkProjectDiscovery
|
|
|
138
143
|
var binLogPath = Path.Combine(Path.GetTempPath(), $"msbuild_{Guid.NewGuid():d}.binlog");
|
|
139
144
|
try
|
|
140
145
|
{
|
|
141
|
-
// when using single restore, we can directly invoke the relevant targets
|
|
146
|
+
// when using single restore, we can directly invoke the relevant targets...
|
|
142
147
|
var args = new List<string>() { "msbuild", startingProjectPath };
|
|
143
|
-
|
|
144
|
-
|
|
148
|
+
|
|
149
|
+
// ...but determining what the relevant targets are can be complicated
|
|
150
|
+
|
|
151
|
+
// For SDK-style projects the targets `Restore`, `ResolveProjectReferences`, and `GenerateBuildDependencyFile`
|
|
152
|
+
// are necessary. If the project has a single target framework, those magic targets will all be present and can
|
|
153
|
+
// be directly invoked, but if the project has multiple target frameworks, those targets will _NOT_ be directly
|
|
154
|
+
// present and we instead have to invoke the `Build` target and specify the three magic values as `InnerTargets`.
|
|
155
|
+
|
|
156
|
+
// If the project is legacy then those three magic targets will not be present, but we shouldn't use the `Build`
|
|
157
|
+
// and `InnerTargets` trick because that's an SDK-only mechanism, so we instead only need to invoke
|
|
158
|
+
// `ResolveProjectReferences` to gather all `PackageReference` items and further down we re-build the transitive
|
|
159
|
+
// dependency set. Without the legacy project check, we could incorrectly invoke `Build` which eventually tries
|
|
160
|
+
// to call `csc.exe` which is unnecessary and can be slow.
|
|
161
|
+
var netCoreSdkVersionValue = await MSBuildHelper.GetProjectPropertyAsync(startingProjectPath, NETCoreSdkVersionPropertyName, logger);
|
|
162
|
+
var isLegacyProject = string.IsNullOrEmpty(netCoreSdkVersionValue);
|
|
163
|
+
var requiredTargets = isLegacyProject
|
|
164
|
+
? LegacyProjectSingleRestoreTargetNames
|
|
165
|
+
: SingleRestoreTargetNames;
|
|
166
|
+
|
|
167
|
+
var actualTargets = await MSBuildHelper.GetProjectTargetsAsync(startingProjectPath, logger);
|
|
168
|
+
var useDirectRestore = requiredTargets.All(actualTargets.Contains);
|
|
145
169
|
if (useDirectRestore || isIndividualTfmRestore)
|
|
146
170
|
{
|
|
147
171
|
// directly call the required targets
|
|
148
|
-
args.Add($"/t:{string.Join(",",
|
|
172
|
+
args.Add($"/t:{string.Join(",", requiredTargets)}");
|
|
149
173
|
}
|
|
150
174
|
else
|
|
151
175
|
{
|
|
152
176
|
// delegate to the inner build and call those targets
|
|
153
177
|
args.Add("/t:Build");
|
|
154
|
-
args.Add($"/p:InnerTargets=\"{string.Join(";",
|
|
178
|
+
args.Add($"/p:InnerTargets=\"{string.Join(";", requiredTargets)}\"");
|
|
155
179
|
}
|
|
156
180
|
|
|
157
181
|
// inject various props and targets to help with discovery
|
|
@@ -385,7 +409,7 @@ internal static class SdkProjectDiscovery
|
|
|
385
409
|
foreach (var projectPath in resolvedProperties.Keys)
|
|
386
410
|
{
|
|
387
411
|
var projectProperties = resolvedProperties[projectPath];
|
|
388
|
-
var isProjectLegacy = !projectProperties.ContainsKey(
|
|
412
|
+
var isProjectLegacy = !projectProperties.ContainsKey(NETCoreSdkVersionPropertyName); // legacy projects don't contain this property
|
|
389
413
|
if (isProjectLegacy)
|
|
390
414
|
{
|
|
391
415
|
logger.Info($"Project {projectPath} is legacy");
|
|
@@ -482,9 +506,6 @@ internal static class SdkProjectDiscovery
|
|
|
482
506
|
}
|
|
483
507
|
|
|
484
508
|
var projectFullDirectory = Path.GetDirectoryName(projectPath)!;
|
|
485
|
-
var doc = XDocument.Load(projectPath);
|
|
486
|
-
var localPropertyDefinitionElements = doc.Root!.XPathSelectElements("/Project/PropertyGroup/*");
|
|
487
|
-
var projectPropertyNames = localPropertyDefinitionElements.Select(e => e.Name.LocalName).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
488
509
|
var projectRelativePath = Path.GetRelativePath(workspacePath, projectPath);
|
|
489
510
|
|
|
490
511
|
var propertiesForProject = resolvedProperties.GetOrAdd(projectPath, () => new(StringComparer.OrdinalIgnoreCase));
|
|
@@ -611,11 +632,6 @@ internal static class SdkProjectDiscovery
|
|
|
611
632
|
|
|
612
633
|
// others
|
|
613
634
|
var projectProperties = resolvedProperties[projectPath];
|
|
614
|
-
var properties = projectProperties
|
|
615
|
-
.Where(pkvp => projectPropertyNames.Contains(pkvp.Key))
|
|
616
|
-
.Select(pkvp => new Property(pkvp.Key, pkvp.Value, Path.GetRelativePath(repoRootPath, projectPath).NormalizePathToUnix()))
|
|
617
|
-
.OrderBy(p => p.Name)
|
|
618
|
-
.ToImmutableArray();
|
|
619
635
|
var referenced = referencedProjects.GetOrAdd(projectPath, () => new(PathComparer.Instance))
|
|
620
636
|
.Select(p => Path.GetRelativePath(projectFullDirectory, p).NormalizePathToUnix())
|
|
621
637
|
.OrderBy(p => p)
|
|
@@ -640,7 +656,6 @@ internal static class SdkProjectDiscovery
|
|
|
640
656
|
FilePath = projectRelativePath,
|
|
641
657
|
Dependencies = dependencies,
|
|
642
658
|
TargetFrameworks = tfms,
|
|
643
|
-
Properties = properties,
|
|
644
659
|
ReferencedProjectPaths = referenced,
|
|
645
660
|
ImportedFiles = imported,
|
|
646
661
|
AdditionalFiles = additional,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<Project>
|
|
2
|
+
<Target Name="_Dependabot_GetProperty">
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<!-- the following value will get copied and replaced at runtime -->
|
|
5
|
+
<_DependabotPropertyValue>%RequestedPropertyName%</_DependabotPropertyValue>
|
|
6
|
+
</PropertyGroup>
|
|
7
|
+
<Message Importance="High" Text="__PROPERTY_VALUE:$(_DependabotPropertyValue)" />
|
|
8
|
+
</Target>
|
|
9
|
+
</Project>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<None Include="DependencyDiscovery.props" CopyToOutputDirectory="PreserveNewest" />
|
|
12
12
|
<None Include="DependencyDiscoveryTargetingPacks.props" CopyToOutputDirectory="PreserveNewest" />
|
|
13
13
|
<None Include="DependencyDiscovery.targets" CopyToOutputDirectory="PreserveNewest" />
|
|
14
|
+
<None Include="GetProperty.targets" CopyToOutputDirectory="PreserveNewest" />
|
|
14
15
|
<None Include="TargetFrameworkReporter.targets" CopyToOutputDirectory="PreserveNewest" />
|
|
15
16
|
</ItemGroup>
|
|
16
17
|
|
|
@@ -150,29 +150,35 @@ public class XmlFileWriter : IFileWriter
|
|
|
150
150
|
// find last `<ItemGroup>` in the project...
|
|
151
151
|
Action addItemGroup = () => { }; // adding an ItemGroup to the project isn't always necessary, but it's much easier to prepare for it here
|
|
152
152
|
var projectDocument = filesAndContents[projectRelativePath];
|
|
153
|
-
var
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
var indentation = GetDocumentIndentationCharacters(projectDocument);
|
|
154
|
+
var itemGroups = projectDocument.RootSyntax.Elements
|
|
155
|
+
.Where(e => e.Name.Equals(ItemGroupElementName, StringComparison.OrdinalIgnoreCase))
|
|
156
|
+
.ToArray();
|
|
157
|
+
var itemGroupsWithPackageReferences = itemGroups
|
|
158
|
+
.Where(e => e.Elements.Any(c => c.Name.Equals(PackageReferenceElementName, StringComparison.OrdinalIgnoreCase)))
|
|
159
|
+
.ToArray();
|
|
160
|
+
var itemGroupForInsertion = itemGroupsWithPackageReferences.LastOrDefault() ?? itemGroups.LastOrDefault();
|
|
161
|
+
if (itemGroupForInsertion is null)
|
|
156
162
|
{
|
|
157
163
|
_logger.Info($"No `<{ItemGroupElementName}>` element found in project; adding one.");
|
|
158
|
-
|
|
159
|
-
new SyntaxList<SyntaxNode>([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(
|
|
164
|
+
itemGroupForInsertion = XmlExtensions.CreateOpenCloseXmlElementSyntax(ItemGroupElementName,
|
|
165
|
+
new SyntaxList<SyntaxNode>([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(indentation)]),
|
|
160
166
|
insertIntermediateNewline: false);
|
|
161
167
|
addItemGroup = () =>
|
|
162
168
|
{
|
|
163
169
|
// add the new element
|
|
164
|
-
var updatedRootSyntax = projectDocument.RootSyntax.AddChild(
|
|
170
|
+
var updatedRootSyntax = projectDocument.RootSyntax.AddChild(itemGroupForInsertion);
|
|
165
171
|
var updatedProjectDocument = projectDocument.ReplaceNode(projectDocument.RootSyntax.AsNode, updatedRootSyntax.AsNode);
|
|
166
172
|
|
|
167
173
|
// reset well-known variables
|
|
168
174
|
projectDocument = updatedProjectDocument;
|
|
169
175
|
filesAndContents[projectRelativePath] = updatedProjectDocument;
|
|
170
|
-
|
|
176
|
+
itemGroupForInsertion = updatedProjectDocument.RootSyntax.Elements.Last(e => e.Name.Equals(ItemGroupElementName, StringComparison.OrdinalIgnoreCase));
|
|
171
177
|
};
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
// ...find where the new item should go...
|
|
175
|
-
var elementsBeforeNew = GetOrderedElementsBeforeSpecified(
|
|
181
|
+
var elementsBeforeNew = GetOrderedElementsBeforeSpecified(itemGroupForInsertion, PackageReferenceElementName, [IncludeAttributeName, UpdateAttributeName], requiredPackageVersion.Name);
|
|
176
182
|
|
|
177
183
|
// ...prepare a new `<PackageReference>` element...
|
|
178
184
|
var newElement = XmlExtensions.CreateSingleLineXmlElementSyntax(PackageReferenceElementName, leadingTrivia: new SyntaxList<SyntaxNode>())
|
|
@@ -221,18 +227,18 @@ public class XmlFileWriter : IFileWriter
|
|
|
221
227
|
else
|
|
222
228
|
{
|
|
223
229
|
// no prior package references; add to the front
|
|
224
|
-
var itemGroupTrivia =
|
|
230
|
+
var itemGroupTrivia = itemGroupForInsertion.AsNode.GetLeadingTrivia().ToList();
|
|
225
231
|
var priorEolIndex = itemGroupTrivia.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
|
|
226
232
|
var indentTrivia = itemGroupTrivia
|
|
227
233
|
.Skip(priorEolIndex + 1)
|
|
228
234
|
.Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
|
|
229
235
|
.ToArray();
|
|
230
|
-
var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(
|
|
236
|
+
var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(indentation), .. indentTrivia]);
|
|
231
237
|
newElement = (IXmlElementSyntax)newElement.AsNode.WithLeadingTrivia(newTrivia);
|
|
232
238
|
var updatedItemGroup = (IXmlElementSyntax)ReplaceNode(
|
|
233
239
|
projectRelativePath,
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
itemGroupForInsertion.AsNode,
|
|
241
|
+
itemGroupForInsertion.InsertChild(newElement, 0).AsNode
|
|
236
242
|
);
|
|
237
243
|
newElement = (IXmlElementSyntax)updatedItemGroup.Content[0];
|
|
238
244
|
}
|
|
@@ -353,7 +359,9 @@ public class XmlFileWriter : IFileWriter
|
|
|
353
359
|
.Skip(priorEolIndex + 1)
|
|
354
360
|
.Select(t => SyntaxFactory.WhitespaceTrivia(t.ToFullString()))
|
|
355
361
|
.ToArray();
|
|
356
|
-
var
|
|
362
|
+
var packageVersionDocument = filesAndContents[filePath];
|
|
363
|
+
var packageVersionIndentation = GetDocumentIndentationCharacters(packageVersionDocument);
|
|
364
|
+
var newTrivia = new SyntaxTriviaList([SyntaxFactory.EndOfLineTrivia("\n"), SyntaxFactory.WhitespaceTrivia(packageVersionIndentation), .. indentTrivia]);
|
|
357
365
|
newVersionElement = (IXmlElementSyntax)newVersionElement.AsNode.WithLeadingTrivia(newTrivia).WithoutTrailingTrivia();
|
|
358
366
|
var insertionIndex = 0;
|
|
359
367
|
var replacementPackageVersionGroup = packageVersionGroup
|
|
@@ -581,7 +589,7 @@ public class XmlFileWriter : IFileWriter
|
|
|
581
589
|
return elementsBeforeNew;
|
|
582
590
|
}
|
|
583
591
|
|
|
584
|
-
|
|
592
|
+
internal static async Task<XmlDocumentSyntax> ReadFileContentsAsync(DirectoryInfo repoContentsPath, string path)
|
|
585
593
|
{
|
|
586
594
|
var fullPath = Path.Join(repoContentsPath.FullName, path);
|
|
587
595
|
var contents = await File.ReadAllTextAsync(fullPath);
|
|
@@ -696,4 +704,23 @@ public class XmlFileWriter : IFileWriter
|
|
|
696
704
|
|
|
697
705
|
return newRange.ToString();
|
|
698
706
|
}
|
|
707
|
+
|
|
708
|
+
public static string GetDocumentIndentationCharacters(XmlDocumentSyntax document)
|
|
709
|
+
{
|
|
710
|
+
// find the first element with leading whitespace and assume that's the document indentation
|
|
711
|
+
var nodeLeadingLineTrivias = document.DescendantNodes()
|
|
712
|
+
.Select(n => n.GetLeadingTrivia().ToList())
|
|
713
|
+
.Select(l =>
|
|
714
|
+
{
|
|
715
|
+
var priorEolIndex = l.FindLastIndex(t => t.Kind == SyntaxKind.EndOfLineTrivia);
|
|
716
|
+
var leadingTriviaParts = l.Skip(priorEolIndex + 1)
|
|
717
|
+
.Select(t => t.ToFullString());
|
|
718
|
+
var leadingTrivia = string.Concat(leadingTriviaParts);
|
|
719
|
+
return leadingTrivia;
|
|
720
|
+
})
|
|
721
|
+
.ToArray();
|
|
722
|
+
var nodeLeadingLineTrivia = nodeLeadingLineTrivias
|
|
723
|
+
.FirstOrDefault(t => !string.IsNullOrEmpty(t));
|
|
724
|
+
return nodeLeadingLineTrivia ?? " ";
|
|
725
|
+
}
|
|
699
726
|
}
|