forked from stcu/SharedScripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Find-ProjectPackages.ps1
135 lines (128 loc) · 5.87 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
<#
.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.
.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 |% 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 |% 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 |% 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 |% 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 = Select-Xml //msbuild:HintPath $file -Namespace @{'msbuild'='http://schemas.microsoft.com/developer/msbuild/2003'}
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |% {$dll = Join-Path (Split-Path $_.Path) $_.Node.InnerText; [pscustomobject]@{
name = $_.Node.ParentNode.Attributes['Include'].Value
version = $(if(Test-Path $dll -PathType Leaf) {ls $dll |% VersionInfo |% ProductVersion})
file = $file
}}))
}
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 |% Node
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |% {[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 |% Name
if(!$p) {Write-Verbose "No packages found in $file"; continue}
[void]$packages.AddRange([object[]]( $p |% {[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 |% {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 |% {[pscustomobject]@{
name = $_.Name
version = $_.Version
file = $file
}}))
}
$max = $packages.Count
}
Process
{
$packages |
? {$_.Name -like $PackageName} |
? {Compare-Version $_.Version}
}