Files
StoreWeb/Directory.Build.targets
T

58 lines
3.1 KiB
XML

<Project>
<UsingTask TaskName="FindHostDuplicatePluginFiles" TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<HostDirectory ParameterType="System.String" Required="true" />
<Duplicates ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Collections.Generic" />
<Using Namespace="System.Security.Cryptography" />
<Code Type="Fragment" Language="cs"><![CDATA[
var host = Path.GetFullPath(HostDirectory);
var plugins = Path.GetFullPath(Path.Combine(host, "Plugins"));
var duplicates = new List<Microsoft.Build.Framework.ITaskItem>();
if (Directory.Exists(plugins))
{
foreach (var plugin in Directory.GetDirectories(plugins))
{
foreach (var file in Directory.GetFiles(plugin, "*", SearchOption.AllDirectories))
{
var relative = file.Substring(plugin.TrimEnd(Path.DirectorySeparatorChar).Length + 1);
// Plugin settings are owned by the plugin even when identical to host settings.
if (Path.GetFileName(file).StartsWith("appsettings", StringComparison.OrdinalIgnoreCase)
&& string.Equals(Path.GetExtension(file), ".json", StringComparison.OrdinalIgnoreCase))
continue;
var shared = Path.GetFullPath(Path.Combine(host, relative));
// Only compare files below the host, outside its plugin subtree.
if (!shared.StartsWith(host.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)
|| shared.StartsWith(plugins + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)
|| !File.Exists(shared) || new FileInfo(file).Length != new FileInfo(shared).Length)
continue;
using (var hash = SHA256.Create())
using (var source = File.OpenRead(file))
using (var target = File.OpenRead(shared))
{
if (Convert.ToBase64String(hash.ComputeHash(source)) == Convert.ToBase64String(hash.ComputeHash(target)))
duplicates.Add(new Microsoft.Build.Utilities.TaskItem(file));
}
}
}
}
Duplicates = duplicates.ToArray();
]]></Code>
</Task>
</UsingTask>
<!-- Run again after the host build, so plugin-first build order is supported. -->
<Target Name="RemoveHostDuplicatePluginFiles" AfterTargets="Build"
Condition="'$(MSBuildProjectName)' == 'Store.Api' and '$(DesignTimeBuild)' != 'true'">
<FindHostDuplicatePluginFiles HostDirectory="$(StoreHostOutputPath)">
<Output TaskParameter="Duplicates" ItemName="_HostDuplicatePluginFile" />
</FindHostDuplicatePluginFiles>
<Delete Files="@(_HostDuplicatePluginFile)" />
</Target>
</Project>