Last active
November 24, 2018 23:29
-
-
Save chrisoldwood/0894f002f40229ac7813 to your computer and use it in GitHub Desktop.
Checks the solution's packages folder looking for multiple versions of the same package.
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 | |
Looks for multiple versions of the same NuGet package in the NuGet | |
packages folder for a .Net based soluton. | |
.description | |
If you check your NuGet dependencies into your source control repository | |
it's easy for old versions to be left hanging around. This script, a | |
companion to CheckPackageVersions, highlights where you might have stale | |
packages left behind. | |
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. | |
Note: it does not cross reference with the solution's packages.config | |
files, it only looks at the package folder names and infers from that. | |
.parameter PackagesFolder | |
The path to the packages folder. Assumes the CWD by default. | |
.example | |
CheckPackageCache c:\solution\packages | |
#> | |
Param( | |
[Parameter(Position=0,Mandatory=0)] | |
[string] $PackagesFolder | |
) | |
Set-StrictMode -Version Latest | |
$ErrorActionPreference = 'stop' | |
$folder = '.' | |
if ($PackagesFolder -ne '') | |
{ | |
$folder = $PackagesFolder | |
} | |
if (!(Test-Path $folder)) | |
{ | |
throw ("Invalid path: {0}" -f $folder) | |
} | |
$packageFolders = @( Get-ChildItem -Path $folder | | |
Where { $_.PSIsContainer -eq $true } ) | |
$packages = @{} | |
foreach ($folder in $packageFolders) | |
{ | |
# Version number is generally numeric with a variable number of version parts | |
# e.g. "x", "x.y", "x.y.z", etc. However the last part sometimes contain a dash | |
# and a textual suffix, e.g. "5.2.0-rc" or "3.0.0-beta1". | |
# But we don't want to match where a digit is in the name, e.g. "log4net". | |
if ($folder.Name -match '^(?<name>.+?)(?<version>[0-9\.]+|[0-9\.]+-[0-9a-z]+)$') | |
{ | |
$packageName = $matches.name | |
$packageVersion = $matches.version.SubString(1) | |
$package = New-Object psobject -Property @{ | |
Name = $packageName | |
Version = $packageVersion | |
} | |
if (!$packages.ContainsKey($packageName)) | |
{ | |
$packages.Add($packageName, @{}) | |
} | |
if (!$packages[$packageName].ContainsKey($packageVersion)) | |
{ | |
$packages[$packageName].Add($packageVersion, @()) | |
} | |
$packages[$packageName][$packageVersion] += $package | |
} | |
} | |
$duplicates = @( $packages.GetEnumerator() | | |
Where { $_.Value.Count -gt 1 } | | |
Sort Name ) | |
foreach ($duplicate in $duplicates) | |
{ | |
$heading = 'Package: ' + $duplicate.Name | |
Write-Output $heading | |
Write-Output ('=' * $heading.Length) | |
$versions = $duplicate.Value.GetEnumerator() | Sort Name | |
foreach ($version in $versions) | |
{ | |
Write-Output $version.Name | |
} | |
Write-Output '' | |
} | |
$duplicateCount = $duplicates.Count | |
if ($duplicateCount -ne 0) | |
{ | |
Write-Warning "$duplicateCount duplicate package(s) found" | |
exit 1 | |
} | |
else | |
{ | |
Write-Output "No duplicate packages found" | |
exit 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you check-in your NuGet packages as part of your solution you may find over time that older, unreferenced versions of packages still exist in the
packages
folder as Visual Studio does not always clear up after itself, or the folder deletions may not get checked-in. This script just looks at the names of thepackages
sub-folders and points out any that have multiple versions.The script can be run automatically in a build pipeline as it correctly sets the exit code -
0
for success, or!0
if any duplicates have been found.