From 7c8b45189312d1a73a3125be99aae32d0a891ffe Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 5 Mar 2018 16:52:38 +0000 Subject: [PATCH 1/3] [Xamarin.Android.Build.Tasks] The "ConvertResourcesCases" task failed unexpectedly. DevDiv Issue 571365 We have a report that `ConvertResourcesCases` is failing with the follow error. error MSB4018: The "ConvertResourcesCases" task failed unexpectedly. Android/Xamarin.Android.Common.targets(1334,2): error MSB4018: System.IO.FileNotFoundException: /design_layout_snackbar.xml.tmp does not exist This is completely weird, especially as the Task is not called in parallel. What I susepct is happening is VSForMac is running is UpdateResources task at the same time the user is doing a build. Because the name of the temp files we are just `foo.xml.tmp` it is highly possible that one instance of the task is deleting the file while the other instance is still running. This is difficult to replicate. This change uses System.IO.Path.GetFileName (System.IO.Path.GetTempFileName ()); to generate a random temp file name for the temp file. This should stop filename collisions. --- src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs index d83db6a3e43..e8f8e9249e7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs @@ -54,7 +54,7 @@ void FixupResources (ITaskItem item, Dictionary acwMap) foreach (string file in xmls) { Log.LogDebugMessage (" Processing: {0}", file); var srcmodifiedDate = File.GetLastWriteTimeUtc (file); - var tmpdest = file + ".tmp"; + var tmpdest = file + "_" + Path.GetFileName (Path.GetTempFileName ()); MonoAndroidHelper.CopyIfChanged (file, tmpdest); MonoAndroidHelper.SetWriteable (tmpdest); try { From 7977d56c875e09f5beabb0a25c33fc07667b44ad Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 7 Mar 2018 11:13:48 +0000 Subject: [PATCH 2/3] Updated to use true temp files rather than appending .tmp --- src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs | 2 +- .../Tasks/CopyAndConvertResources.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs index e8f8e9249e7..94875c911fc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs @@ -54,7 +54,7 @@ void FixupResources (ITaskItem item, Dictionary acwMap) foreach (string file in xmls) { Log.LogDebugMessage (" Processing: {0}", file); var srcmodifiedDate = File.GetLastWriteTimeUtc (file); - var tmpdest = file + "_" + Path.GetFileName (Path.GetTempFileName ()); + var tmpdest = Path.GetTempFileName (); MonoAndroidHelper.CopyIfChanged (file, tmpdest); MonoAndroidHelper.SetWriteable (tmpdest); try { diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs index 16102d253de..1e7b18bcbe4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs @@ -86,7 +86,7 @@ public override bool Execute () var destfilename = p.Value; var srcmodifiedDate = File.GetLastWriteTimeUtc (filename); var dstmodifiedDate = File.Exists (destfilename) ? File.GetLastAccessTimeUtc (destfilename) : DateTime.MinValue; - var tmpdest = p.Value + ".tmp"; + var tmpdest = Path.GetTempFileName (); MonoAndroidHelper.CopyIfChanged (filename, tmpdest); MonoAndroidHelper.SetWriteable (tmpdest); try { From 709c7a6b96e21892410b4c9442a95a8473018c72 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 7 Mar 2018 17:01:52 +0000 Subject: [PATCH 3/3] rework --- .../Tasks/ConvertResourcesCases.cs | 2 +- .../Tasks/CopyAndConvertResources.cs | 3 ++- .../Utilities/AndroidResource.cs | 7 ++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs index 94875c911fc..4905d7d2d2c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ConvertResourcesCases.cs @@ -58,7 +58,7 @@ void FixupResources (ITaskItem item, Dictionary acwMap) MonoAndroidHelper.CopyIfChanged (file, tmpdest); MonoAndroidHelper.SetWriteable (tmpdest); try { - AndroidResource.UpdateXmlResource (tmpdest, acwMap, + AndroidResource.UpdateXmlResource (resdir, tmpdest, acwMap, ResourceDirectories.Where (s => s != item).Select(s => s.ItemSpec)); // We strip away an eventual UTF-8 BOM from the XML file. diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs index 1e7b18bcbe4..b197d50b60b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CopyAndConvertResources.cs @@ -87,10 +87,11 @@ public override bool Execute () var srcmodifiedDate = File.GetLastWriteTimeUtc (filename); var dstmodifiedDate = File.Exists (destfilename) ? File.GetLastAccessTimeUtc (destfilename) : DateTime.MinValue; var tmpdest = Path.GetTempFileName (); + var res = Path.Combine (Path.GetDirectoryName (filename), ".."); MonoAndroidHelper.CopyIfChanged (filename, tmpdest); MonoAndroidHelper.SetWriteable (tmpdest); try { - AndroidResource.UpdateXmlResource (tmpdest, acw_map); + AndroidResource.UpdateXmlResource (res, tmpdest, acw_map); if (MonoAndroidHelper.CopyIfChanged (tmpdest, destfilename)) { MonoAndroidHelper.SetWriteable (destfilename); MonoAndroidHelper.SetLastAccessAndWriteTimeUtc (destfilename, srcmodifiedDate, Log); diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/AndroidResource.cs b/src/Xamarin.Android.Build.Tasks/Utilities/AndroidResource.cs index e9bcb993d9b..8ce97de1c03 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/AndroidResource.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/AndroidResource.cs @@ -9,17 +9,14 @@ namespace Monodroid { static class AndroidResource { - public static void UpdateXmlResource (string filename, Dictionary acwMap, IEnumerable additionalDirectories = null) + public static void UpdateXmlResource (string res, string filename, Dictionary acwMap, IEnumerable additionalDirectories = null) { // use a temporary file so we only update the real file if things actually changed string tmpfile = filename + ".bk"; try { XDocument doc = XDocument.Load (filename, LoadOptions.SetLineInfo); - // The assumption here is that the file we're fixing up is in a directory below the - // obj/${Configuration}/res/ directory and so appending ../gives us the actual path to - // 'res/' - UpdateXmlResource (Path.Combine (Path.GetDirectoryName (filename), ".."), doc.Root, acwMap, additionalDirectories); + UpdateXmlResource (res, doc.Root, acwMap, additionalDirectories); using (var stream = File.OpenWrite (tmpfile)) using (var xw = new LinePreservedXmlWriter (new StreamWriter (stream))) xw.WriteNode (doc.CreateNavigator (), false);