diff --git a/src/Microsoft.DotNet.VersionTools.Tests/BuildManifest/ManifestModelTests.cs b/src/Microsoft.DotNet.VersionTools.Tests/BuildManifest/ManifestModelTests.cs index fefed0e586..d5b5fad593 100644 --- a/src/Microsoft.DotNet.VersionTools.Tests/BuildManifest/ManifestModelTests.cs +++ b/src/Microsoft.DotNet.VersionTools.Tests/BuildManifest/ManifestModelTests.cs @@ -72,11 +72,11 @@ public void TestMergeBuildManifests() - - - + + + @@ -110,12 +110,12 @@ private BuildModel CreatePackageOnlyBuildManifestModel() Branch=""master"" Commit=""defb6d52047cc3d6b5f5d0853b0afdb1512dfbf4""> - + - - + + "; @@ -132,17 +132,17 @@ private BuildModel CreatePackageOnlyBuildManifestModel() - + - + - + diff --git a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/ArtifactSet.cs b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/ArtifactSet.cs index a1e53b6091..4d155cf395 100644 --- a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/ArtifactSet.cs +++ b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/ArtifactSet.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; @@ -21,8 +22,13 @@ public void Add(ArtifactSet source) } public IEnumerable ToXml() => Enumerable.Concat( - Packages.Select(p => p.ToXml()), - Blobs.Select(b => b.ToXml())); + Packages + .OrderBy(p => p.Id, StringComparer.OrdinalIgnoreCase) + .ThenBy(p => p.Version, StringComparer.OrdinalIgnoreCase) + .Select(p => p.ToXml()), + Blobs + .OrderBy(b => b.Id, StringComparer.OrdinalIgnoreCase) + .Select(b => b.ToXml())); public static ArtifactSet Parse(XElement xml) => new ArtifactSet { diff --git a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/BlobArtifactModel.cs b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/BlobArtifactModel.cs index b16e944698..871595f1d1 100644 --- a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/BlobArtifactModel.cs +++ b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/BlobArtifactModel.cs @@ -9,6 +9,11 @@ namespace Microsoft.DotNet.VersionTools.BuildManifest.Model { public class BlobArtifactModel { + private static readonly string[] AttributeOrder = + { + nameof(Id) + }; + public Dictionary Attributes { get; set; } = new Dictionary(); public string Id @@ -21,7 +26,7 @@ public string Id public XElement ToXml() => new XElement( "Blob", - Attributes.CreateXmlAttributes()); + Attributes.CreateXmlAttributes(AttributeOrder)); public static BlobArtifactModel Parse(XElement xml) => new BlobArtifactModel { diff --git a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/EndpointModel.cs b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/EndpointModel.cs index a1f2b45140..aac54c9a27 100644 --- a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/EndpointModel.cs +++ b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/EndpointModel.cs @@ -9,6 +9,13 @@ namespace Microsoft.DotNet.VersionTools.BuildManifest.Model { public class EndpointModel { + private static readonly string[] AttributeOrder = + { + nameof(Id), + nameof(Type), + nameof(Url) + }; + public const string BlobFeedType = "BlobFeed"; public const string OrchestratedBlobFeedId = "Orchestrated"; @@ -41,7 +48,7 @@ public string Url public XElement ToXml() => new XElement( "Endpoint", - Attributes.CreateXmlAttributes(), + Attributes.CreateXmlAttributes(AttributeOrder), Artifacts?.ToXml()); public static EndpointModel Parse(XElement xml) => new EndpointModel diff --git a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/PackageArtifactModel.cs b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/PackageArtifactModel.cs index ac051a4754..9aa2079093 100644 --- a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/PackageArtifactModel.cs +++ b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/PackageArtifactModel.cs @@ -9,6 +9,12 @@ namespace Microsoft.DotNet.VersionTools.BuildManifest.Model { public class PackageArtifactModel { + private static readonly string[] AttributeOrder = + { + nameof(Id), + nameof(Version) + }; + public Dictionary Attributes { get; set; } = new Dictionary(); public string Id @@ -27,7 +33,7 @@ public string Version public XElement ToXml() => new XElement( "Package", - Attributes.CreateXmlAttributes()); + Attributes.CreateXmlAttributes(AttributeOrder)); public static PackageArtifactModel Parse(XElement xml) => new PackageArtifactModel { diff --git a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/XElementParsingExtensions.cs b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/XElementParsingExtensions.cs index c97325cad8..bf5d1ae5f8 100644 --- a/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/XElementParsingExtensions.cs +++ b/src/Microsoft.DotNet.VersionTools/BuildManifest/Model/XElementParsingExtensions.cs @@ -27,9 +27,15 @@ public static string GetRequiredAttribute(this XElement element, XName name) return element.Attributes().ToDictionary(a => a.Name.LocalName, a => a.Value); } - public static XAttribute[] CreateXmlAttributes(this Dictionary attributes) + public static XAttribute[] CreateXmlAttributes( + this Dictionary attributes, + string[] keySortOrder) { - return attributes.Select(pair => new XAttribute(pair.Key, pair.Value)).ToArray(); + return attributes + .OrderBy(pair => keySortOrder.TakeWhile(o => pair.Key != o).Count()) + .ThenBy(pair => pair.Key, StringComparer.OrdinalIgnoreCase) + .Select(pair => new XAttribute(pair.Key, pair.Value)) + .ToArray(); } } }