1+ # !/usr/bin/env pwsh
2+ <#
3+ . SYNOPSIS
4+ Merges one publish directory into another, allowing only identical file collisions.
5+
6+ . PARAMETER Source
7+ The publish directory to copy from.
8+
9+ . PARAMETER Destination
10+ The publish directory to copy into.
11+ #>
12+
13+ [CmdletBinding ()]
14+ param (
15+ [Parameter (Mandatory )]
16+ [string ] $Source ,
17+
18+ [Parameter (Mandatory )]
19+ [string ] $Destination
20+ )
21+
22+ $ErrorActionPreference = ' Stop'
23+
24+ if (-not (Test-Path $Source - PathType Container)) {
25+ throw " Source directory '$Source ' does not exist."
26+ }
27+
28+ if (-not (Test-Path $Destination - PathType Container)) {
29+ throw " Destination directory '$Destination ' does not exist."
30+ }
31+
32+ $Source = (Resolve-Path $Source ).Path
33+ $Destination = (Resolve-Path $Destination ).Path
34+
35+ $sourceWinsConflicts = @ {
36+ ' Microsoft.Extensions.DependencyInjection.Abstractions.dll' = $true
37+ ' Microsoft.VisualBasic.dll' = $true
38+ ' Microsoft.Win32.SystemEvents.dll' = $true
39+ ' System.Diagnostics.EventLog.dll' = $true
40+ ' System.Drawing.Common.dll' = $true
41+ ' System.Drawing.dll' = $true
42+ ' System.Private.Windows.Core.dll' = $true
43+ ' System.Security.Cryptography.Pkcs.dll' = $true
44+ ' System.Security.Cryptography.Xml.dll' = $true
45+ ' WindowsBase.dll' = $true
46+ }
47+
48+ $destinationWinsConflicts = @ {
49+ ' Microsoft.Windows.SDK.NET.dll' = $true
50+ ' WinRT.Runtime.dll' = $true
51+ }
52+
53+ Get-ChildItem $Source - Recurse - File | ForEach-Object {
54+ $relativePath = $_.FullName.Substring ($Source.Length ).TrimStart(' \' , ' /' )
55+ $destinationPath = Join-Path $Destination $relativePath
56+ $destinationDirectory = Split-Path $destinationPath - Parent
57+
58+ if (Test-Path $destinationPath - PathType Leaf) {
59+ $sourceHash = (Get-FileHash $_.FullName - Algorithm SHA256).Hash
60+ $destinationHash = (Get-FileHash $destinationPath - Algorithm SHA256).Hash
61+
62+ if ($sourceHash -ne $destinationHash ) {
63+ $fileName = [System.IO.Path ]::GetFileName($relativePath )
64+
65+ if ($sourceWinsConflicts.ContainsKey ($fileName )) {
66+ Copy-Item $_.FullName - Destination $destinationPath - Force
67+ return
68+ }
69+
70+ if ($destinationWinsConflicts.ContainsKey ($fileName )) {
71+ return
72+ }
73+
74+ throw " Publish merge conflict for '$relativePath ': source and destination files differ."
75+ }
76+
77+ return
78+ }
79+
80+ if (-not (Test-Path $destinationDirectory - PathType Container)) {
81+ New-Item $destinationDirectory - ItemType Directory - Force | Out-Null
82+ }
83+
84+ Copy-Item $_.FullName - Destination $destinationPath - Force
85+ }
0 commit comments