Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement: fix issue with Plist writing additional characters to info.plist during serialization #673

Merged
merged 1 commit into from
Mar 26, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 63 additions & 86 deletions src/Nuke/Xamarin/Plist.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Globalization;
using System.Text;
using System.Collections;
using System.Globalization;
using System.Xml.Linq;
using Nuke.Common.IO;
using Serilog;

namespace Rocket.Surgery.Nuke.Xamarin;

/// <summary>
/// Taken from https://github.com/cake-contrib/Cake.Plist/blob/develop/src/Cake.Plist/PlistConverter.cs
/// Taken from https://github.com/cake-contrib/Cake.Plist/blob/develop/src/Cake.Plist/PlistConverter.cs.
/// </summary>
internal static class Plist
{
Expand All @@ -28,36 +29,17 @@ public static dynamic Deserialize(AbsolutePath plist)
/// </summary>
/// <param name="path">The path to the plist.</param>
/// <param name="value">The object to serialize.</param>
/// <returns>The deserialized plist.</returns>
public static void Serialize(AbsolutePath path, object value)
{
var doc = SerializeDocument(value);

string result;

using (var sw = new MemoryStream())
{
using (var strw = new StreamWriter(sw))
{
doc.Save(strw);
result = new UTF8Encoding(false).GetString(sw.ToArray());
}
}

using (var stream = File.OpenWrite(path))
{
using (var write = new StreamWriter(stream, new UTF8Encoding(false), 1024, true))
{
write.Write(result);
}
}
SerializeDocument(value)
.Save(path, SaveOptions.OmitDuplicateNamespaces);
}

/// <summary>
/// Serializes the .plist file provided.
/// </summary>
/// <param name="item">The plist object</param>
/// <returns>The xml document</returns>
/// <param name="item">The plist object.</param>
/// <returns>The xml document.</returns>
private static XDocument SerializeDocument(object item)
{
var doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"));
Expand All @@ -66,7 +48,7 @@ private static XDocument SerializeDocument(object item)
"plist",
"-//Apple//DTD PLIST 1.0//EN",
"http://www.apple.com/DTDs/PropertyList-1.0.dtd",
""
string.Empty
)
);

Expand All @@ -81,78 +63,71 @@ private static XDocument SerializeDocument(object item)
/// <summary>
/// Serializes the .plist file provided.
/// </summary>
/// <param name="item">The plist object</param>
/// <returns>The xml element</returns>
/// <param name="item">The plist object.</param>
/// <returns>The xml element.</returns>
private static XElement? SerializeObject(object item)
{
if (item is string)
switch (item)
{
return new XElement("string", item);
}

if (item is double || item is float || item is decimal)
{
return new XElement("real", Convert.ToString(item, CultureInfo.InvariantCulture));
}

if (item is int || item is long)
{
return new XElement("integer", Convert.ToString(item, CultureInfo.InvariantCulture));
}

if (item is bool && item as bool? == true)
{
return new XElement("true");
}

if (item is bool && item as bool? == false)
{
return new XElement("false");
}

if (item is DateTime time)
{
return new XElement("date", time.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeFormatInfo.InvariantInfo));
}

if (item is DateTimeOffset offset)
{
return new XElement("date", offset.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeFormatInfo.InvariantInfo));
}

if (item is byte[] bytes)
{
return new XElement("data", Convert.ToBase64String(bytes));
}
case string:
Log.Verbose("string: {String}", item);
return new XElement("string", item);
case double:
case float:
case decimal:
Log.Verbose("floating point: {Float}", item);
return new XElement("real", Convert.ToString(item, CultureInfo.InvariantCulture));
case int:
case long:
Log.Verbose("integer: {Integer}", item);
return new XElement("integer", Convert.ToString(item, CultureInfo.InvariantCulture));
case bool when item as bool? == true:
Log.Verbose("boolean: {Boolean}", item);
return new XElement("true");
case bool when item as bool? == false:
Log.Verbose("boolean: {Boolean}", item);
return new XElement("false");
case DateTime time:
Log.Verbose("DateTime: {DateTime}", item);
return new XElement("date", time.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeFormatInfo.InvariantInfo));
case DateTimeOffset offset:
Log.Verbose("DateTimeOffset: {DateTimeOffset}", item);
return new XElement("date", offset.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ", DateTimeFormatInfo.InvariantInfo));
case byte[] bytes:
Log.Verbose("DateTimeOffset: {DateTimeOffset}", item);
return new XElement("data", Convert.ToBase64String(bytes));
case IDictionary dictionary:
{
var dict = new XElement("dict");

if (item is System.Collections.IDictionary dictionary)
{
var dict = new XElement("dict");
var enumerator = dictionary.GetEnumerator();

var enumerator = dictionary.GetEnumerator();
while (enumerator.MoveNext())
{
dict.Add(new XElement("key", enumerator.Key));
dict.Add(SerializeObject(enumerator.Value!));
}

while (enumerator.MoveNext())
{
dict.Add(new XElement("key", enumerator.Key));
dict.Add(SerializeObject(enumerator.Value!));
Log.Verbose("Dictionary: {Dictionary}", item);
return dict;
}

return dict;
}
case IEnumerable enumerable:
{
var array = new XElement("array");

if (item is System.Collections.IEnumerable enumerable)
{
var array = new XElement("array");
foreach (var itm in enumerable)
{
array.Add(SerializeObject(itm!));
}

foreach (var itm in enumerable)
{
array.Add(SerializeObject(itm!));
Log.Verbose("Array: {Array}", item);
return array;
}

return array;
default:
return null;
}

return null;
}

private static dynamic DeserializeXml(XElement element)
Expand Down Expand Up @@ -195,6 +170,7 @@ private static dynamic DeserializeXml(XElement element)

return typedArray;
}

case "dict":
{
var dictionary = new Dictionary<string, object>();
Expand All @@ -217,6 +193,7 @@ private static dynamic DeserializeXml(XElement element)

return dictionary;
}

default:
return null!;
}
Expand Down