Skip to content

Commit ddd8014

Browse files
perf: parallelize font downloads/extract (closes #71)
1 parent 7a054ea commit ddd8014

1 file changed

Lines changed: 41 additions & 28 deletions

File tree

src/functions/public/Install-NerdFont.ps1

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ function Install-NerdFont {
6868
[ValidateSet('All', 'Standard', 'Mono', 'Propo')]
6969
[string] $Variant = 'All',
7070

71+
# Max concurrent downloads.
72+
[Parameter()]
73+
[ValidateRange(1, 32)]
74+
[int] $ThrottleLimit = 8,
75+
7176
# Force will overwrite existing fonts
7277
[Parameter()]
7378
[switch] $Force
@@ -129,10 +134,9 @@ Please run the command again with elevated rights (Run as Administrator) or prov
129134
)
130135
}
131136

137+
$toProcess = [System.Collections.Generic.List[object]]::new()
132138
foreach ($nerdFont in $nerdFontsToInstall) {
133-
$URL = $nerdFont.URL
134139
$fontName = $nerdFont.Name
135-
136140
if (-not $Force -and $installedFamilies) {
137141
$alreadyInstalled = $false
138142
foreach ($family in $installedFamilies) {
@@ -143,27 +147,37 @@ Please run the command again with elevated rights (Run as Administrator) or prov
143147
continue
144148
}
145149
}
150+
$toProcess.Add($nerdFont)
151+
}
152+
153+
$extracted = $toProcess | ForEach-Object -ThrottleLimit $ThrottleLimit -Parallel {
154+
$nerdFont = $_
155+
$tempPath = $using:tempPath
156+
$cacheRoot = $using:cacheRoot
157+
$Variant = $using:Variant
158+
$Force = $using:Force
146159

160+
$URL = $nerdFont.URL
161+
$fontName = $nerdFont.Name
147162
$downloadFileName = Split-Path -Path $URL -Leaf
148163
$downloadPath = Join-Path -Path $tempPath -ChildPath $downloadFileName
149-
150-
$cacheTag = if ($URL -match '/releases/download/([^/]+)/') { $Matches[1] } else { 'unknown' }
164+
$cacheTag = if ($URL -match '/releases/download/([^/]+)/') {
165+
$Matches[1]
166+
} else {
167+
'unknown'
168+
}
151169
$cacheTagDir = Join-Path -Path $cacheRoot -ChildPath $cacheTag
152170
$cachedFile = Join-Path -Path $cacheTagDir -ChildPath $downloadFileName
153171

154172
if ((Test-Path -LiteralPath $cachedFile) -and -not $Force) {
155-
Write-Verbose "[$fontName] - Cache hit at [$cachedFile]"
156173
Copy-Item -LiteralPath $cachedFile -Destination $downloadPath -Force
157174
} else {
158-
Write-Verbose "[$fontName] - Downloading to [$downloadPath]"
159-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$downloadPath]", 'Download')) {
160-
$previousProgress = $ProgressPreference
161-
$ProgressPreference = 'SilentlyContinue'
162-
try {
163-
Invoke-WebRequest -Uri $URL -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5
164-
} finally {
165-
$ProgressPreference = $previousProgress
166-
}
175+
$previousProgress = $ProgressPreference
176+
$ProgressPreference = 'SilentlyContinue'
177+
try {
178+
Invoke-WebRequest -Uri $URL -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5
179+
} finally {
180+
$ProgressPreference = $previousProgress
167181
}
168182
if (-not (Test-Path -LiteralPath $cacheTagDir)) {
169183
$null = New-Item -ItemType Directory -Path $cacheTagDir -Force
@@ -172,14 +186,12 @@ Please run the command again with elevated rights (Run as Administrator) or prov
172186
}
173187

174188
$extractPath = Join-Path -Path $tempPath -ChildPath $fontName
175-
Write-Verbose "[$fontName] - Extract to [$extractPath]"
176-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$extractPath]", 'Extract')) {
177-
if (-not (Test-Path -LiteralPath $extractPath)) {
178-
$null = New-Item -ItemType Directory -Path $extractPath
179-
}
180-
[System.IO.Compression.ZipFile]::ExtractToDirectory($downloadPath, $extractPath, $true)
181-
Remove-Item -Path $downloadPath -Force
189+
if (-not (Test-Path -LiteralPath $extractPath)) {
190+
$null = New-Item -ItemType Directory -Path $extractPath
182191
}
192+
Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction SilentlyContinue
193+
[System.IO.Compression.ZipFile]::ExtractToDirectory($downloadPath, $extractPath, $true)
194+
Remove-Item -Path $downloadPath -Force
183195

184196
if ($Variant -ne 'All') {
185197
$allFiles = Get-ChildItem -Path $extractPath -Recurse -File -Include '*.ttf', '*.otf'
@@ -203,20 +215,21 @@ Please run the command again with elevated rights (Run as Administrator) or prov
203215
$keepNames,
204216
[System.StringComparer]::OrdinalIgnoreCase
205217
)
206-
$removed = 0
207218
foreach ($f in $allFiles) {
208219
if (-not $keepSet.Contains($f.FullName)) {
209220
Remove-Item -LiteralPath $f.FullName -Force -ErrorAction SilentlyContinue
210-
$removed++
211221
}
212222
}
213-
Write-Verbose "[$fontName] - Variant '$Variant' kept $($keep.Count) files, removed $removed"
214223
}
215224

216-
Write-Verbose "[$fontName] - Install to [$Scope]"
217-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$Scope]", 'Install font')) {
218-
Install-Font -Path $extractPath -Scope $Scope -Force:$Force
219-
Remove-Item -Path $extractPath -Force -Recurse
225+
[pscustomobject]@{ Name = $fontName; ExtractPath = $extractPath }
226+
}
227+
228+
foreach ($e in $extracted) {
229+
Write-Verbose "[$($e.Name)] - Install to [$Scope]"
230+
if ($PSCmdlet.ShouldProcess("[$($e.Name)] to [$Scope]", 'Install font')) {
231+
Install-Font -Path $e.ExtractPath -Scope $Scope -Force:$Force
232+
Remove-Item -Path $e.ExtractPath -Force -Recurse
220233
}
221234
}
222235

0 commit comments

Comments
 (0)