Last active
November 27, 2019 13:40
-
-
Save HowardvanRooijen/a4c4c463e1c27b8857cb to your computer and use it in GitHub Desktop.
AutoFix-VisualStudioFiles.ps1 which formats and alphabetically organises elements in .config & .csproj files which commonly cause git merge conflicts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Scans the solution folder (the parent of the .git folder) for all app.config, web.config and *.csproj files | |
and auto-formats them to minimise the possibility of getting merge conflicts based on the ordering of | |
elements within these files. | |
N.B. Use of this script is entirely at your own risk. We shall not be liable for any damage which may | |
result from using it. | |
.DESCRIPTION | |
app.config & web.config files - sorts appSettings elements by key, in alphabetic order, sorts | |
assemblyBinding.dependentAssembly elements alphabetically based on the assemblyIdentity.name | |
attribute | |
.csproj files - sorts appSettings elements by key, in alphabetic order, sorts Reference, | |
ProjectReference & Compile elements | |
.NOTES | |
File Name : AutoFix-VisualStudioFiles.ps1 | |
Author : Howard van Rooijen (@HowardvRooijen) | |
Requires : PowerShell v3 | |
.LINK | |
#> | |
Function AutoFix-WebConfig([string] $rootDirectory) | |
{ | |
$files = Get-ChildItem -Path $rootDirectory -Filter web.config -Recurse | |
return Scan-ConfigFiles($files) | |
} | |
Function AutoFix-AppConfig([string] $rootDirectory) | |
{ | |
$files = Get-ChildItem -Path $rootDirectory -Filter app.config -Recurse | |
return Scan-ConfigFiles($files) | |
} | |
Function Scan-ConfigFiles([System.IO.FileInfo[]] $files) | |
{ | |
$modifiedfiles = @() | |
foreach($file in $files) | |
{ | |
$original = [xml] (Get-Content $file.FullName) | |
$workingCopy = $original.Clone() | |
if ($workingCopy.configuration.appSettings -ne $null){ | |
$sorted = $workingCopy.configuration.appSettings.add | sort { [string]$_.key } | |
$lastChild = $sorted[-1] | |
$sorted[0..($sorted.Length-2)] | foreach {$workingCopy.configuration.appSettings.InsertBefore($_, $lastChild)} | Out-Null | |
} | |
if ($workingCopy.configuration.runtime.assemblyBinding -ne $null){ | |
$sorted = $workingCopy.configuration.runtime.assemblyBinding.dependentAssembly | sort { [string]$_.assemblyIdentity.name } | |
$lastChild = $sorted[-1] | |
$sorted[0..($sorted.Length-2)] | foreach {$workingCopy.configuration.runtime.assemblyBinding.InsertBefore($_,$lastChild)} | Out-Null | |
} | |
$differencesCount = (Compare-Object -ReferenceObject (Select-Xml -Xml $original -XPath "//*") -DifferenceObject (Select-Xml -Xml $workingCopy -XPath "//*")).Length | |
if ($differencesCount -ne 0) | |
{ | |
$workingCopy.Save($file.FullName) | Out-Null | |
$modifiedfiles += $file.FullName | |
} | |
} | |
return $modifiedfiles | |
} | |
Function AutoFix-CsProj([string] $rootDirectory) | |
{ | |
$files = Get-ChildItem -Path $rootDirectory -Filter *.csproj -Recurse | |
$modifiedfiles = @() | |
foreach($file in $files) | |
{ | |
$original = [xml] (Get-Content $file.FullName) | |
$workingCopy = $original.Clone() | |
foreach($itemGroup in $workingCopy.Project.ItemGroup){ | |
# Sort the reference elements | |
if ($itemGroup.Reference -ne $null){ | |
$sorted = $itemGroup.Reference | sort { [string]$_.Include } | |
$itemGroup.RemoveAll() | Out-Null | |
foreach($item in $sorted){ | |
$itemGroup.AppendChild($item) | Out-Null | |
} | |
} | |
# Sort the compile elements | |
if ($itemGroup.Compile -ne $null){ | |
$sorted = $itemGroup.Compile | sort { [string]$_.Include } | |
$itemGroup.RemoveAll() | Out-Null | |
foreach($item in $sorted){ | |
$itemGroup.AppendChild($item) | Out-Null | |
} | |
} | |
# Sort the project references elements | |
if ($itemGroup.ProjectReference -ne $null){ | |
$sorted = $itemGroup.ProjectReference | sort { [string]$_.Include } | |
$itemGroup.RemoveAll() | Out-Null | |
foreach($item in $sorted){ | |
$itemGroup.AppendChild($item) | Out-Null | |
} | |
} | |
} | |
$differencesCount = (Compare-Object -ReferenceObject (Select-Xml -Xml $original -XPath "//*") -DifferenceObject (Select-Xml -Xml $workingCopy -XPath "//*")).Length | |
if ($differencesCount -ne 0) | |
{ | |
$workingCopy.Save($file.FullName) | Out-Null | |
$modifiedfiles += $file.FullName | |
} | |
} | |
return $modifiedfiles | |
} | |
$rootDirectory = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) "\..\..\" | |
$exitCode = 0; | |
$changedfiles = @() | |
$changedfiles += AutoFix-AppConfig($rootDirectory) | |
$changedfiles += AutoFix-CsProj($rootDirectory) | |
$changedfiles += AutoFix-WebConfig($rootDirectory) | |
if ($changedfiles.Count -gt 0) | |
{ | |
Write-Host "=== endjin git hooks ===" | |
Write-Host "The following files have been auto-formatted" | |
Write-Host "to reduce the likelyhood of merge conflicts:" | |
foreach($file in $changedfiles) | |
{ | |
Write-Host $file | |
} | |
$exitCode = 1; | |
} | |
exit $exitcode |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Entries like this
gets removed after running this script.
I think this exception that is getting thrown is related, I never really needed to use powershell until now.
Don't really know how to debug it. (I'm going to try to fix it, but if u could help I'd appreciate ;x)
UPDATE:
Actually the exception seems to be about another thing.
I believe this lines shouldn't be there, right?
https://gist.github.com/HowardvanRooijen/a4c4c463e1c27b8857cb#file-autofix-visualstudiofiles-ps1-L91
https://gist.github.com/HowardvanRooijen/a4c4c463e1c27b8857cb#file-autofix-visualstudiofiles-ps1-L103
https://gist.github.com/HowardvanRooijen/a4c4c463e1c27b8857cb#file-autofix-visualstudiofiles-ps1-L115
UPDATE2:
I created a Fork and made a few changes to your script.
Seems to be working fine now. ;)