Skip to content

Commit f93cab4

Browse files
Copilottg123
andauthored
Order YAML type meta fields before resource data (#1717)
* Initial plan * Order yaml type meta fields first Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> * Fix StyleCop blank line in KubernetesYaml Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
1 parent 415161a commit f93cab4

2 files changed

Lines changed: 56 additions & 9 deletions

File tree

src/KubernetesClient/KubernetesYaml.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ public static string Serialize(object value)
293293
private static TBuilder WithOverridesFromJsonPropertyAttributes<TBuilder>(this TBuilder builder)
294294
where TBuilder : BuilderSkeleton<TBuilder>
295295
{
296+
var preferredPropertyOrder = new[] { "ApiVersion", "Kind", "Metadata" };
296297
// Use VersionInfo from the model namespace as that should be stable.
297298
// If this is not generated in the future we will get an obvious compiler error.
298299
var targetNamespace = typeof(VersionInfo).Namespace;
@@ -307,15 +308,39 @@ private static TBuilder WithOverridesFromJsonPropertyAttributes<TBuilder>(this T
307308
// Map any JsonPropertyAttribute instances to YamlMemberAttribute instances.
308309
foreach (var type in types)
309310
{
310-
foreach (var property in type.GetProperties())
311+
var properties = type.GetProperties()
312+
.OrderBy(property => property.MetadataToken)
313+
.ToArray();
314+
var usePreferredOrder = properties.Any(property =>
315+
property.Name == "ApiVersion" ||
316+
property.Name == "Kind");
317+
var nextOrder = usePreferredOrder ? preferredPropertyOrder.Length : 0;
318+
foreach (var property in properties)
311319
{
312320
var jsonAttribute = property.GetCustomAttribute<JsonPropertyNameAttribute>();
313-
if (jsonAttribute == null)
321+
if (jsonAttribute == null && !usePreferredOrder)
314322
{
315323
continue;
316324
}
317325

318-
var yamlAttribute = new YamlMemberAttribute { Alias = jsonAttribute.Name, ApplyNamingConventions = false };
326+
var yamlAttribute = new YamlMemberAttribute();
327+
if (usePreferredOrder)
328+
{
329+
var order = Array.IndexOf(preferredPropertyOrder, property.Name);
330+
if (order < 0)
331+
{
332+
order = nextOrder++;
333+
}
334+
335+
yamlAttribute.Order = order;
336+
}
337+
338+
if (jsonAttribute != null)
339+
{
340+
yamlAttribute.Alias = jsonAttribute.Name;
341+
yamlAttribute.ApplyNamingConventions = false;
342+
}
343+
319344
builder.WithAttributeOverride(type, property.Name, yamlAttribute);
320345
}
321346
}

tests/KubernetesClient.Tests/KubernetesYamlTests.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -822,12 +822,12 @@ public void WriteSecret()
822822
{
823823
var kManifest = """
824824
apiVersion: v1
825-
data:
826-
username: YlhrdFlYQnc=
827-
password: TXprMU1qZ2tkbVJuTjBwaQ==
828825
kind: Secret
829826
metadata:
830827
name: test-secret
828+
data:
829+
username: YlhrdFlYQnc=
830+
password: TXprMU1qZ2tkbVJuTjBwaQ==
831831
""";
832832

833833
var result = KubernetesYaml.Deserialize<V1Secret>(kManifest, true);
@@ -860,13 +860,13 @@ public void WriteConfigMap()
860860
{
861861
var kManifest = """
862862
apiVersion: v1
863+
kind: ConfigMap
864+
metadata:
865+
name: test-configmap
863866
binaryData:
864867
username: YlhrdFlYQnc=
865868
data:
866869
password: Mzk1MjgkdmRnN0pi
867-
kind: ConfigMap
868-
metadata:
869-
name: test-configmap
870870
""";
871871

872872
var result = KubernetesYaml.Deserialize<V1ConfigMap>(kManifest, true);
@@ -875,6 +875,28 @@ public void WriteConfigMap()
875875
Assert.Equal(kManifest, yaml);
876876
}
877877

878+
[Fact]
879+
public void WriteConfigMapOrdersTypeMetaFirst()
880+
{
881+
var configMap = new V1ConfigMap
882+
{
883+
ApiVersion = "v1",
884+
Kind = "ConfigMap",
885+
Metadata = new V1ObjectMeta { Name = "my-configmap", NamespaceProperty = "my-namespace" },
886+
Data = new Dictionary<string, string> { { "array.json", "value" } },
887+
};
888+
889+
var yaml = KubernetesYaml.Serialize(configMap);
890+
891+
Assert.Equal(ToLines(@"apiVersion: v1
892+
kind: ConfigMap
893+
metadata:
894+
name: my-configmap
895+
namespace: my-namespace
896+
data:
897+
array.json: value"), ToLines(yaml));
898+
}
899+
878900
[Fact]
879901
public void DeserializeWithJsonPropertyName()
880902
{

0 commit comments

Comments
 (0)