Last active
April 12, 2025 20:53
-
-
Save brianvanderlugt/78cf683bb785422c529cd095c7be4f3b to your computer and use it in GitHub Desktop.
PowerShell script to output graph dependency to help resolve nuget dependencies.
This file contains hidden or 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
#Requires -RunAsAdministrator | |
# Pre-requisites | |
Install-Module PowerShellGet -Force # to install additional packages | |
Import-Module PowerShellGet -MinimumVersion 2.2.0 | |
# Doesn't work because PowerShellGet doesn't support SemVer 2.0 yet. https://github.com/PowerShell/PowerShellGet/issues/222 | |
Install-Package NuGet.Core,NuGet.ProjectModel | |
# Instead run. Recommmend copy as installs additional libraries already cover by NETStandard 2.0 | |
nuget install -Framework NETStandard2.0 Nuget.ProjectModel # <- Copy required packages to C:\Program Files\PackageManagement\NuGet\Packages\ |
This file contains hidden or 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
# Source: https://www.jerriepelser.com/blog/analyze-dotnet-project-dependencies-part-1/ | |
param( | |
[ValidateScript({Test-Path -Path $(Resolve-Path -Path $_) -PathType Leaf})] | |
[String]$SolutionPath = '.\Path\TestFile.sln' | |
) | |
(Resolve-Path -Path C:\src\cleanspark\SitePlatform\CleanSpark.Site\CleanSpark.Site.sln).Path.Substring(0, 'C:\src\cleanspark\SitePlatform\CleanSpark.Site\CleanSpark.Site.sln'.LastIndexOf([System.IO.Path]::DirectorySeparatorChar)) | |
$resolvedSolutionPath = (Resolve-Path -Path $SolutionPath).Path | |
Push-Location $resolvedSolutionPath.Substring(0, $resolvedSolutionPath.LastIndexOf([System.IO.Path]::DirectorySeparatorChar)) | |
function Out-ReportDependency{ | |
param( | |
[NuGet.ProjectModel.LockFileTargetLibrary] $projectLibrary, | |
[NuGet.ProjectModel.LockFileTarget] $lockFileTargetFramework, | |
[int] $indentLevel = 1 | |
) | |
$indentation = $(New-Object System.String -ArgumentList ' ',($indentLevel * 2)) | |
Write-Output "${indentation}$($projectLibrary.Name), v$($projectLibrary.Version)" | |
foreach ($childDependency in $projectLibrary.Dependencies){ | |
$childLibrary = $lockFileTargetFramework.Libraries.Where({$_.Name -eq $childDependency.Id}) | select -First 1 | |
Out-ReportDependency -projectLibrary $childLibrary -lockFileTargetFramework $lockFileTargetFramework -indentLevel ($indentLevel + 1) | |
} | |
} | |
try{ | |
Get-ChildItem -Path 'C:\Program Files\PackageManagement\NuGet\Packages\' -Filter Nuget.* -Include *.dll -Recurse | | |
where{$_.FullName -like "*netstandard2.0*"} | | |
foreach{Add-Type -Path $_.FullName} | |
Add-Type -AssemblyName Newtonsoft.Json | |
dotnet msbuild $resolvedSolutionPath /t:GenerateRestoreGraphFile /p:RestoreGraphOutputPath=graph.dg | |
$fileText = Get-Content -Path .\graph.dg -Raw | |
$json = [Newtonsoft.Json.JsonConvert]::DeserializeObject($fileText, [Newtonsoft.Json.Linq.JObject]) | |
$dependencyGraph = [NuGet.ProjectModel.DependencyGraphSpec]::new($json) | |
Write-Output "$(Get-Date): Direct dependencies`n`n" | |
foreach ($project in $dependencyGraph.Projects.Where({$_.RestoreMetadata.ProjectStyle -eq [NuGet.ProjectModel.ProjectStyle]::PackageReference})){ | |
Write-Output $project.Name | |
foreach($targetFramework in $project.TargetFrameworks){ | |
Write-Output " [{$targetFramework.FrameworkName}]" | |
foreach($dependency in $targetFramework.Dependencies){ | |
Write-Output " $($dependency.Name), v$($dependency.LibraryRange.VersionRange.ToShortString())" | |
} | |
} | |
} | |
Write-Output "$(Get-Date): Transient dependencies`n`n" | |
foreach ($project in $dependencyGraph.Projects.Where({$_.RestoreMetadata.ProjectStyle -eq [NuGet.ProjectModel.ProjectStyle]::PackageReference})){ | |
$runStatus = (dotnet restore "$($project.FilePath)") | |
$lockFilePath = Join-Path -Path $project.RestoreMetadata.OutputPath -ChildPath 'project.assets.json' | |
$lockFile = [NuGet.ProjectModel.LockFileUtilities]::GetLockFile($lockFilePath, [NuGet.Common.NullLogger]::Instance) | |
Write-Output $project.Name | |
foreach ($targetFramework in $project.TargetFrameworks){ | |
Write-Output " [{$targetFramework.FrameworkName}]" | |
$lockFileTargetFramework = $null | |
$lockFileTargetFramework = $lockFile.Targets.Where({$_.TargetFramework -eq $targetFramework.FrameworkName}) | select -First 1 | |
if ($null -ne $lockFileTargetFramework){ | |
foreach($dependency in $targetFramework.Dependencies){ | |
$projectLibrary = $lockFileTargetFramework.Libraries.Where({$_.Name -eq $dependency.Name}) | select -First 1 | |
Out-ReportDependency -projectLibrary $projectLibrary -lockFileTargetFramework $lockFileTargetFramework | |
} | |
} | |
} | |
} | |
} | |
finally{ | |
Pop-Location | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment