forked from brianary/scripts
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Find-ProjectPackages.ps1
142 lines (134 loc) · 6.18 KB
/
Find-ProjectPackages.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<#
.SYNOPSIS
Find modules used in projects.
.INPUTS
System.String containing a package name (wildcards supported).
.OUTPUTS
System.Management.Automation.PSCustomObject each with properties for the Name,
Version, and File of packages found.
.FUNCTIONALITY
Packages and libraries
.LINK
Select-Xml
.LINK
ConvertFrom-Json
.EXAMPLE
Find-ProjectModule.ps1 jQuery*
Name Version File
---- ------- ----
jquery.datatables 1.10.9 C:\Repo\packages.config
jQuery 1.7 C:\Repo\packages.config
jQuery 1.8.3 C:\OtherRepo\packages.config
#>
#Requires -Version 3
[CmdletBinding()][OutputType([Management.Automation.PSCustomObject])] Param(
<#
The name of a package to search for.
Wildcards (as supported by -like) are allowed.
#>
[Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)][string] $PackageName,
<#
The path of a folder to search within.
Uses the current working directory ($PWD) by default.
#>
[string] $Path = $PWD,
# The minimum (inclusive) version of the package to return.
[version] $MinVersion,
# The maximum (inclusive) version of the package to return.
[version] $MaxVersion
)
Begin
{
function Compare-Version([string]$version)
{
if(!$MinVersion -and !$MaxVersion) {return $true}
if(!($version -match '(?<Version>\b\d+\.\d+(?:\.\d+)?)')) {Write-Warning "Can't parse version $version"; return $true}
$v = [version]$Matches.Version
if(!$MaxVersion) {return $v -ge $MinVersion}
elseif(!$MinVersion) {return $v -le $MaxVersion}
else {return ($v -ge $MinVersion) -and ($v -le $MaxVersion)}
}
$action = 'Find Project Packages'
Write-Progress $action 'Getting proj package lists' -PercentComplete 0
[string[]]$projFiles = Get-ChildItem $Path -Recurse -Filter *proj |Select-Object -ExpandProperty FullName
if(!$projFiles) {[string[]]$projFiles = @()}
Write-Verbose "Found $($projFiles.Length) *proj files."
Write-Progress $action 'Getting NuGet package lists' -PercentComplete 15
[string[]]$nugetFiles = Get-ChildItem $Path -Recurse -Filter packages.config |Select-Object -ExpandProperty FullName
if(!$nugetFiles) {[string[]]$nugetFiles = @()}
Write-Verbose "Found $($nugetFiles.Length) packages.config files."
Write-Progress $action 'Getting npm package lists' -PercentComplete 30
[string[]]$npmFiles = Get-ChildItem $Path -Recurse -Filter package.json |Select-Object -ExpandProperty FullName
if(!$npmFiles) {[string[]]$npmFiles = @()}
Write-Verbose "Found $($npmFiles.Length) package.json files."
Write-Progress $action 'Getting paket.lock package lists' -PercentComplete 45
[string[]]$paketFiles = Get-ChildItem $Path -Recurse -Filter paket.lock |Select-Object -ExpandProperty FullName
if(!$paketFiles) {[string[]]$paketFiles = @()}
Write-Verbose "Found $($paketFiles.Length) paket.lock files."
$max = $projFiles.Length + $nugetFiles.Length + $npmFiles.Length + $paketFiles.Length
Write-Verbose "Found $max package files."
if(!$max) {Write-Error "No package lists found!"; return}
$packages,$i = (New-Object Collections.ArrayList),0
foreach($file in $projFiles)
{
Write-Verbose "Parsing $file"
Write-Progress $action "Parsing *proj package files: found $($projFiles.Count)" -CurrentOperation $file -PercentComplete (10*$i++/$max+60)
$p = (dotnet list $file package --format json |ConvertFrom-Json).projects |
Select-Object -ExpandProperty frameworks |
Where-Object {$_.PSObject.Properties.Match('topLevelPackages').Count} |
Select-Object -ExpandProperty topLevelPackages |
ForEach-Object {[pscustomobject]@{
name = $_.id
version = $_.resolvedVersion
file = $file
}}
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]$p)
}
foreach($file in $nugetFiles)
{
Write-Verbose "Parsing $file"
Write-Progress $action "Parsing NuGet package files: found $($nugetFiles.Count)" -CurrentOperation $file -PercentComplete (10*$i++/$max+70)
$p = Select-Xml /packages/package $file |Select-Object -ExpandProperty Node
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |ForEach-Object {[pscustomobject]@{
name = $_.id
version = $_.version
file = $file
}}))
}
foreach($file in $npmFiles)
{
Write-Verbose "Parsing $file"
Write-Progress $action "Parsing npm package files: found $($npmFiles.Count)" -CurrentOperation $file -PercentComplete (10*$i++/$max+80)
$j = ConvertFrom-Json (Get-Content $file -Raw)
if(!(Get-Member -InputObject $j -Name dependencies)) {Write-Verbose "No dependencies found in $file"; continue}
$p = Get-Member -InputObject $j.dependencies -MemberType NoteProperty |Select-Object -ExpandProperty Name
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |ForEach-Object {[pscustomobject]@{
name = $_
version = $j.dependencies.$_
file = $file
}}))
}
foreach($file in $paketFiles)
{
Write-Verbose "Parsing $file"
Write-Progress $action "Parsing paket.lock package files: found $($paketFiles.Count)" -CurrentOperation $file -PercentComplete (10*$i++/$max+90)
$lockpattern = '\A\s{4}(?<Name>\w\S+)\s\((?:>= )?(?<Version>\d+(?:\.\d+)+)\b'
$p = Get-Content $file |ForEach-Object {if($_ -match $lockpattern){[pscustomobject]@{Name=$Matches.Name;Version=$Matches.Version}}}
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |ForEach-Object {[pscustomobject]@{
name = $_.Name
version = $_.Version
file = $file
}}))
}
$max = $packages.Count
}
Process
{
$packages |
Where-Object {$_.Name -like $PackageName} |
Where-Object {Compare-Version $_.Version}
}