From 43f87ec4c149386e4140729c38a48b8aa3e429aa Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 25 Mar 2022 14:08:05 +0100 Subject: [PATCH] [msbuild] Only conditionally copy the entire input directory from Windows in the Ditto task. (#14495) Sometimes we want to copy the entire input directory from Windows to the Mac when executing the Ditto task remotely, and sometimes we don't. In particular we do not want to copy the input directory when the directory on Windows is an incomplete mirror of what's on the Mac - one scenario being when copying the app bundle to prepare for IPA creation. The .app directory on Windows is not complete - all the files are there (maybe? not quite sure, but that's beside the point here), but some may be empty, because when we only care about the timestamp for a file, we'll create an empty file on Windows to mirror the actual file on Mac. Copying this incomplete directory to the Mac, overwriting the correct files there, will break things badly. However, sometimes we're not mirroring a directory on Windows, but instead we have directories as actual build input (for instances frameworks from NuGets), and in that case we want to copy everything to the Mac. So this PR adds a parameter to the Ditto task to optionally copy the directory from Windows for remote builds, and we enable this behavior when we want it - specifically when copying frameworks. Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1506009 while not regressing https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1492635. Ref: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1506009 Ref: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1492635 Ref: https://github.com/xamarin/xamarin-macios/pull/14375 --- dotnet/targets/Xamarin.Shared.Sdk.targets | 4 ++++ .../Xamarin.MacDev.Tasks.Core/Tasks/DittoTaskBase.cs | 10 ++++++++++ msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs | 3 +++ 3 files changed, 17 insertions(+) diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index d1225438ad..d618a95625 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -677,6 +677,7 @@ @@ -1610,6 +1612,7 @@ SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" AdditionalArguments="-x -k" + CopyFromWindows="true" Source="%(_CompressedPlugIns.Identity)" Destination="$(_IntermediateDecompressionDir)/%(Filename)%(Extension)" > @@ -1656,6 +1659,7 @@ SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" AdditionalArguments="-x -k" + CopyFromWindows="true" Source="%(_CompressedAppleFrameworks.Identity)" Destination="$(_IntermediateFrameworksDir)/%(Filename)%(Extension)" > diff --git a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/DittoTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/DittoTaskBase.cs index 47261e6425..b992d0e5c8 100644 --- a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/DittoTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/DittoTaskBase.cs @@ -13,6 +13,16 @@ namespace Xamarin.MacDev.Tasks public string? AdditionalArguments { get; set; } + // If the input directory should be copied from Windows to the Mac in + // a remote build. In some cases we only maintain empty files on + // Windows to keep track of modified files, so that we don't have to + // transfer the entire file back to Windows, and in those cases we + // don't want to copy the empty content back to the Mac. In other + // cases the input comes from Windows, and in that case we want to + // copy the entire input to the Mac - so we need an option to select + // the mode. + public bool CopyFromWindows { get; set; } + [Required] public ITaskItem? Source { get; set; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs index b223cf1626..06ee3f9814 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs @@ -35,6 +35,9 @@ namespace Xamarin.MacDev.Tasks if (!Directory.Exists(Source.ItemSpec)) return Enumerable.Empty (); + if (!CopyFromWindows) + return Enumerable.Empty (); + // TaskRunner doesn't know how to copy directories to Mac but `ditto` can take directories (and that's why we use ditto often). // If Source is a directory path, let's add each file within it as an TaskItem, as TaskRunner knows how to copy files to Mac. return Directory.GetFiles (Source.ItemSpec, "*", SearchOption.AllDirectories)