2 [Parameter
(Mandatory
=$true)][string
] $InputPath, # Full path to directory where NuGet packages to be checked are stored
3 [Parameter
(Mandatory
=$true)][string
] $ExtractPath, # Full path to directory where the packages will be extracted during validation
4 [Parameter
(Mandatory
=$true)][string
] $SymbolToolPath # Full path to directory where dotnet symbol-tool was installed
7 Add-Type
-AssemblyName System
.IO
.Compression
.FileSystem
8 . $PSScriptRoot\pipeline-logging-functions
.ps1
10 function FirstMatchingSymbolDescriptionOrDefault
{
12 [string
] $FullPath, # Full path to the module that has to be checked
13 [string
] $TargetServerParameter, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols
17 $FileName = [System
.IO
.Path
]::GetFileName
($FullPath)
18 $Extension = [System
.IO
.Path
]::GetExtension
($FullPath)
20 # Those below are potential symbol files that the `dotnet symbol` might
21 # return. Which one will be returned depend on the type of file we are
22 # checking and which type of file was uploaded.
24 # The file itself is returned
25 $SymbolPath = $SymbolsPath + '\' + $FileName
27 # PDB file for the module
28 $PdbPath = $SymbolPath.Replace
($Extension, '.pdb')
30 # PDB file for R2R module (created by crossgen)
31 $NGenPdb = $SymbolPath.Replace
($Extension, '.ni.pdb')
33 # DBG file for a .so library
34 $SODbg = $SymbolPath.Replace
($Extension, '.so.dbg')
36 # DWARF file for a .dylib
37 $DylibDwarf = $SymbolPath.Replace
($Extension, '.dylib.dwarf')
39 .\dotnet-symbol
.exe
--symbols
--modules
--windows-pdbs
$TargetServerParameter $FullPath -o
$SymbolsPath | Out-Null
41 if (Test-Path $PdbPath) {
44 elseif
(Test-Path $NGenPdb) {
47 elseif
(Test-Path $SODbg) {
50 elseif
(Test-Path $DylibDwarf) {
51 return 'Dwarf for Dylib'
53 elseif
(Test-Path $SymbolPath) {
61 function CountMissingSymbols
{
63 [string
] $PackagePath # Path to a NuGet package
66 # Ensure input file exist
67 if (!(Test-Path $PackagePath)) {
68 throw "Input file does not exist: $PackagePath"
71 # Extensions for which we'll look for symbols
72 $RelevantExtensions = @
('.dll', '.exe', '.so', '.dylib')
74 # How many files are missing symbol information
77 $PackageId = [System
.IO
.Path
]::GetFileNameWithoutExtension
($PackagePath)
78 $PackageGuid = New-Guid
79 $ExtractPath = Join-Path -Path
$ExtractPath -ChildPath
$PackageGuid
80 $SymbolsPath = Join-Path -Path
$ExtractPath -ChildPath
'Symbols'
82 [System
.IO
.Compression
.ZipFile
]::ExtractToDirectory
($PackagePath, $ExtractPath)
84 # Makes easier to reference `symbol tool`
85 Push-Location $SymbolToolPath
87 Get-ChildItem -Recurse
$ExtractPath |
88 Where-Object {$RelevantExtensions -contains
$_.Extension
} |
90 if ($_.FullName
-Match
'\\ref\\') {
91 Write-Host "`t Ignoring reference assembly file" $_.FullName
95 $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault
-FullPath
$_.FullName
-TargetServerParameter
'--microsoft-symbol-server' -SymbolsPath
$SymbolsPath
96 $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault
-FullPath
$_.FullName
-TargetServerParameter
'--internal-server' -SymbolsPath
$SymbolsPath
98 Write-Host -NoNewLine
"`t Checking file" $_.FullName
"... "
100 if ($SymbolsOnMSDL -ne
$null -and
$SymbolsOnSymWeb -ne
$null) {
101 Write-Host "Symbols found on MSDL (${$SymbolsOnMSDL}) and SymWeb (${$SymbolsOnSymWeb})"
106 if ($SymbolsOnMSDL -eq
$null -and
$SymbolsOnSymWeb -eq
$null) {
107 Write-Host 'No symbols found on MSDL or SymWeb!'
110 if ($SymbolsOnMSDL -eq
$null) {
111 Write-Host 'No symbols found on MSDL!'
114 Write-Host 'No symbols found on SymWeb!'
122 return $MissingSymbols
125 function CheckSymbolsAvailable
{
126 if (Test-Path $ExtractPath) {
127 Remove-Item $ExtractPath -Force
-Recurse
-ErrorAction SilentlyContinue
130 Get-ChildItem "$InputPath\*.nupkg" |
134 # These packages from Arcade-Services include some native libraries that
135 # our current symbol uploader can't handle. Below is a workaround until
136 # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted.
137 if ($FileName -Match
'Microsoft\.DotNet\.Darc\.') {
138 Write-Host "Ignoring Arcade-services file: $FileName"
142 elseif
($FileName -Match
'Microsoft\.DotNet\.Maestro\.Tasks\.') {
143 Write-Host "Ignoring Arcade-services file: $FileName"
148 Write-Host "Validating $FileName "
149 $Status = CountMissingSymbols
"$InputPath\$FileName"
152 Write-PipelineTelemetryError
-Category
'CheckSymbols' -Message
"Missing symbols for $Status modules in the package $FileName"
159 CheckSymbolsAvailable