Last active
November 24, 2018 23:31
-
-
Save chrisoldwood/23322ea073576fce7990 to your computer and use it in GitHub Desktop.
Checks all packages.config files looking for version mismatches between different projects.
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 packages.config files in a .Net solution looking for multiple | |
versions of the same package. | |
.description | |
Ideally your .Net based solutions should always be using a consistent | |
set of NuGet packages to avoid subtle bugs. This script, a companion to | |
CheckPackageCache, analyses all the NuGet packages used by your solution | |
and tells you if multiple package versions are being referenced. | |
The script terminates with a non-zero exit code if any duplicates are | |
found so it can be used as part of a build pipeline. | |
.parameter SolutionFolder | |
The path to the solution folder. Assumes the CWD by default. | |
.example | |
CheckPackageVersions c:\solution | |
#> | |
Param( | |
[Parameter(Position=0,Mandatory=0)] | |
[string] $SolutionFolder | |
) | |
Set-StrictMode -Version Latest | |
$ErrorActionPreference = 'stop' | |
$folder = '.' | |
if ($SolutionFolder -ne '') | |
{ | |
$folder = $SolutionFolder | |
} | |
if (!(Test-Path $folder)) | |
{ | |
throw ("Invalid path: {0}" -f $folder) | |
} | |
$packages = @{} | |
$configFiles = @( Get-ChildItem -Path $folder -Recurse | | |
Where { $_.Name -eq 'packages.config' } ) | |
foreach ($file in $configFiles) | |
{ | |
$component = Split-Path -Leaf (Split-Path -Parent $file.FullName) | |
$lines = Get-Content $file.FullName | |
foreach ($line in $lines) | |
{ | |
if ($line -match '^\s*<package id="(?<name>[^"]+)"\s*version="(?<version>[^"]+)"') | |
{ | |
$packageName = $matches.name | |
$packageVersion = $matches.version | |
$package = New-Object psobject -Property @{ | |
Name = $packageName | |
Version = $packageVersion | |
Component = $component | |
} | |
if (!$packages.ContainsKey($packageName)) | |
{ | |
$packages.Add($packageName, @{}) | |
} | |
if (!$packages[$packageName].ContainsKey($packageVersion)) | |
{ | |
$packages[$packageName].Add($packageVersion, @()) | |
} | |
$packages[$packageName][$packageVersion] += $package | |
} | |
} | |
} | |
$mismatches = @( $packages.GetEnumerator() | | |
Where { $_.Value.Count -gt 1 } | | |
Sort Name ) | |
foreach ($mismatch in $mismatches) | |
{ | |
$heading = 'Package: ' + $mismatch.Name | |
Write-Output $heading | |
Write-Output ('=' * $heading.Length) | |
foreach ($version in $mismatch.Value.GetEnumerator()) | |
{ | |
$versionNumber = $version.Name | |
$components = ($version.Value | ForEach { $_.Component }) -Join ', ' | |
Write-Output ('{0}: {1}' -f $versionNumber,$components) | |
} | |
Write-Output '' | |
} | |
$mismatchCount = $mismatches.Count | |
if ($mismatchCount -ne 0) | |
{ | |
Write-Warning "$mismatchCount package mismatch(es) found" | |
exit 1 | |
} | |
else | |
{ | |
Write-Output "No package mismatches found" | |
exit 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The script recursively looks for the
packages.config
files and compares the version numbers of each package to ensure that the same version of each package is referenced in each project.When a mismatch is found it writes out which projects reference which version, e.g.
The script can be run automatically in a build pipeline as it correctly sets the exit code -
0
for success, or!0
if any mismatches have been found.