Skip to content

Instantly share code, notes, and snippets.

@KirillOsenkov
Last active October 25, 2017 17:48
Show Gist options
  • Save KirillOsenkov/4cd32c40bffd3045f77e to your computer and use it in GitHub Desktop.
Save KirillOsenkov/4cd32c40bffd3045f77e to your computer and use it in GitHub Desktop.
Override MSBuild Copy task
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Copy SourceFiles="copy.proj" DestinationFiles="destination.proj" />
</Target>
<UsingTask TaskName="Copy" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<SourceFiles Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
<DestinationFolder ParameterType="Microsoft.Build.Framework.ITaskItem" />
<Retries ParameterType="System.Int32" />
<RetryDelayMilliseconds ParameterType="System.Int32" />
<UseHardlinksIfPossible ParameterType="System.Boolean" />
<SkipUnchangedFiles ParameterType="System.Boolean" />
<DestinationFiles Output="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
<CopiedFiles Output="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
<OverwriteReadOnlyFiles ParameterType="System.Boolean" />
</ParameterGroup>
<Task>
<Reference Include="mscorlib" />
<Reference Include="Microsoft.Build" />
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="Microsoft.Build.Tasks.Core" />
<Using Namespace="System" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Text" />
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="Microsoft.Build.Shared" />
<Using Namespace="Microsoft.Build.Tasks" />
<Using Namespace="Microsoft.Build.Utilities" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Action<ITaskItem> DumpMetadata = i =>
{
foreach (var m in i.MetadataNames)
{
Log.LogMessage(m.ToString() + "=" + i.GetMetadata(m.ToString()) + "\n");
}
};
Func<Microsoft.Build.Tasks.Copy, string> PrintItems = c =>
{
var sb = new StringBuilder();
foreach(var item in c.CopiedFiles)
{
var originalItemSpec = item.GetMetadata("OriginalItemSpec");
var sourceItem = c.SourceFiles.FirstOrDefault(i =>
i.GetMetadata("OriginalItemSpec") == originalItemSpec ||
i.ToString() == originalItemSpec ||
i.GetMetadata("FullPath") == originalItemSpec ||
i.GetMetadata("Identity") == originalItemSpec);
if (sourceItem != null)
{
sb.AppendLine(sourceItem.GetMetadata("FullPath"));
sb.AppendLine(item.GetMetadata("FullPath"));
}
else
{
Log.LogError(originalItemSpec);
foreach (var s in c.SourceFiles)
{
DumpMetadata(s);
}
foreach (var s in c.CopiedFiles)
{
DumpMetadata(s);
}
}
}
return sb.ToString();
};
var copy = new Microsoft.Build.Tasks.Copy();
copy.BuildEngine = BuildEngine;
copy.SourceFiles = SourceFiles;
copy.DestinationFolder = DestinationFolder;
copy.DestinationFiles = DestinationFiles;
copy.Retries = Retries;
copy.RetryDelayMilliseconds = RetryDelayMilliseconds;
copy.UseHardlinksIfPossible = UseHardlinksIfPossible;
copy.SkipUnchangedFiles = SkipUnchangedFiles;
copy.OverwriteReadOnlyFiles = OverwriteReadOnlyFiles;
var result = copy.Execute();
//Log.LogMessage(string.Format("COPY:\r\n{0}{1}", PrintItems(copy.SourceFiles), PrintItems(copy.CopiedFiles), PrintItems(copy.DestinationFiles)));
lock(this.GetType())
{
File.AppendAllText("copylog.txt", PrintItems(copy));
}
return result;
]]>
</Code>
</Task>
</UsingTask>
</Project>
@binki
Copy link

binki commented Jun 21, 2016

This is a sizable chunk of code and I’m interested in doing something similar. Could a license header be added?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment