Skip to content

Commit 209f88c

Browse files
authored
Handle dependencies better and refactor for reproducibility
This is a general refactoring seeking several simultaneous outcomes: * More tolerant (i.e. sane) dependency resolution * Apply implicit environment assumptions explicitly for interpreter to manage * Use of best practices wherever possible, specifically regarding: - Grammatical voice for runtime output messages - Scripting safety conventions for determinative behavior Setting global requirement on PowerShell Core makes the expectation of interpreter expressed in PSModule#36 much easier to understand and moves the source of guidance for it from local documentation to the runtime shell. Shifting from 'RequiresVersion' arguments to 'ModuleVersion' allows newer versions of modules to satisfy dependency constraints and adding the GUID makes the execution of third-party code more secure from namespace clobbering, be it incidental or malicious. Activating StrictMode at Script scope in PowerShell Core operations is loosely equivalent to the boilerplate `set -euo pipefail` incantation ubiquitously employed in POSIX shell scripts where potentially damaging activity will occur. Version 3 converts these "code smells" from warnings or recoverable errors to fatal errors: * Using method syntax (parentheses and commas) for function calls * References to: - Uninitialized variables - Non-existent object properties - Invalid/out-of-bounds collection indexes Best comprehension and accuracy for user-consumed runtime messages that announce actions before they are undertaken requires the use of gerund forms or third-person present tense for action verbs. The liberal use of the terminal ellipsis in such strings is a widely-understood rubric that reinforces the nature of the announcements as preemptive rather than conclusory. Resolves: PSModule#36 Resolves: PSModule#52
1 parent ef4331d commit 209f88c

1 file changed

Lines changed: 45 additions & 40 deletions

File tree

src/functions/public/Install-NerdFont.ps1

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
#Requires -Modules @{ ModuleName = 'Fonts'; RequiredVersion = '1.1.21' }
2-
#Requires -Modules @{ ModuleName = 'Admin'; RequiredVersion = '1.1.6' }
1+
#Requires -PSEdition Core
2+
#Requires -Modules @{ ModuleName = 'Admin'; ModuleVersion = '1.1.6'; GUID = '70660c5c-30db-4787-861e-0a626ca8683c' }
3+
#Requires -Modules @{ ModuleName = 'Fonts'; ModuleVersion = '1.1.21'; GUID = 'b6e7e61f-f8f5-4b0a-9fdd-f74a3311be0d' }
4+
5+
Set-StrictMode -Version 3.0
36

47
function Install-NerdFont {
58
<#
@@ -57,77 +60,79 @@ function Install-NerdFont {
5760
ParameterSetName = 'All',
5861
Mandatory
5962
)]
60-
[switch] $All,
63+
[switch] ${All},
6164

6265
[Parameter()]
6366
[ValidateSet('CurrentUser', 'AllUsers')]
64-
[string] $Scope = 'CurrentUser',
67+
[string] ${Scope} = 'CurrentUser',
6568

6669
# Force will overwrite existing fonts
6770
[Parameter()]
68-
[switch] $Force
71+
[switch] ${Force}
6972
)
7073

7174
begin {
72-
if ($Scope -eq 'AllUsers' -and -not (IsAdmin)) {
73-
$errorMessage = @'
74-
Administrator rights are required to install fonts.
75-
Please run the command again with elevated rights (Run as Administrator) or provide '-Scope CurrentUser' to your command."
75+
if (${Scope} -eq 'AllUsers' -and -not (IsAdmin)) {
76+
${errorMessage} = @'
77+
Administrator privileges are required to install system-wide fonts.
78+
79+
Please run this command again with elevated permissions ("Run as Administrator") or append '-Scope CurrentUser' to it for a user-level install.
7680
'@
77-
throw $errorMessage
81+
throw ${errorMessage}
7882
}
79-
$nerdFontsToInstall = @()
83+
${nerdFontsToInstall} = @()
8084

81-
$guid = (New-Guid).Guid
82-
$tempPath = Join-Path -Path $HOME -ChildPath "NerdFonts-$guid"
83-
if (-not (Test-Path -Path $tempPath -PathType Container)) {
84-
Write-Verbose "Create folder [$tempPath]"
85-
$null = New-Item -Path $tempPath -ItemType Directory
85+
${tempPath} = Join-Path -Path ${Env:TEMP} -ChildPath "NerdFonts-$([Convert]::ToString((Get-Random 16777216),16).PadLeft(6,'0'))"
86+
if (-not (Test-Path -Path ${tempPath} -PathType Container)) {
87+
Write-Verbose "Creating temporary download directory [${tempPath}]…"
88+
${null} = New-Item -Path ${tempPath} -ItemType Directory
8689
}
8790
}
8891

8992
process {
90-
if ($All) {
91-
$nerdFontsToInstall = $script:NerdFonts
93+
if (${All}) {
94+
${nerdFontsToInstall} = ${script:NerdFonts}
9295
} else {
93-
foreach ($fontName in $Name) {
94-
$nerdFontsToInstall += $script:NerdFonts | Where-Object { $_.Name -like $fontName }
96+
foreach (${fontName} in ${Name}) {
97+
${nerdFontsToInstall} += ${script:NerdFonts} | Where-Object {
98+
$_.Name -like ${fontName}
99+
}
95100
}
96101
}
97102

98-
Write-Verbose "[$Scope] - Installing [$($nerdFontsToInstall.count)] fonts"
103+
Write-Verbose "[${Scope}] - Installing [$(${nerdFontsToInstall}.count)] fonts"
99104

100-
foreach ($nerdFont in $nerdFontsToInstall) {
101-
$URL = $nerdFont.URL
102-
$fontName = $nerdFont.Name
103-
$downloadFileName = Split-Path -Path $URL -Leaf
104-
$downloadPath = Join-Path -Path $tempPath -ChildPath $downloadFileName
105+
foreach (${nerdFont} in ${nerdFontsToInstall}) {
106+
${URL} = ${nerdFont}.URL
107+
${fontName} = ${nerdFont}.Name
108+
${downloadFileName} = Split-Path -Path ${URL} -Leaf
109+
${downloadPath} = Join-Path -Path ${tempPath} -ChildPath ${downloadFileName}
105110

106-
Write-Verbose "[$fontName] - Downloading to [$downloadPath]"
107-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$downloadPath]", 'Download')) {
108-
Invoke-WebRequest -Uri $URL -OutFile $downloadPath -RetryIntervalSec 5 -MaximumRetryCount 5
111+
Write-Verbose "[${fontName}] - Downloading to [${downloadPath}]…"
112+
if (${PSCmdlet}.ShouldProcess("[${fontName}] to [${downloadPath}]", 'Download')) {
113+
Invoke-WebRequest -Uri ${URL} -OutFile ${downloadPath} -RetryIntervalSec 5 -MaximumRetryCount 5
109114
}
110115

111-
$extractPath = Join-Path -Path $tempPath -ChildPath $fontName
112-
Write-Verbose "[$fontName] - Extract to [$extractPath]"
113-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$extractPath]", 'Extract')) {
114-
Expand-Archive -Path $downloadPath -DestinationPath $extractPath -Force
115-
Remove-Item -Path $downloadPath -Force
116+
${extractPath} = Join-Path -Path ${tempPath} -ChildPath ${fontName}
117+
Write-Verbose "[${fontName}] - Extracting archive to [${extractPath}]…"
118+
if (${PSCmdlet}.ShouldProcess("[${fontName}] to [${extractPath}]", 'Extract')) {
119+
Expand-Archive -Path ${downloadPath} -DestinationPath ${extractPath} -Force
120+
Remove-Item -Path ${downloadPath} -Force
116121
}
117122

118-
Write-Verbose "[$fontName] - Install to [$Scope]"
119-
if ($PSCmdlet.ShouldProcess("[$fontName] to [$Scope]", 'Install font')) {
120-
Install-Font -Path $extractPath -Scope $Scope -Force:$Force
121-
Remove-Item -Path $extractPath -Force -Recurse
123+
Write-Verbose "[${fontName}] - Installing for [${Scope}]…"
124+
if (${PSCmdlet}.ShouldProcess("[${fontName}] to [${Scope}]", 'Install font')) {
125+
Install-Font -Path ${extractPath} -Scope ${Scope} -Force:${Force}
126+
Remove-Item -Path ${extractPath} -Force -Recurse
122127
}
123128
}
124129
}
125130

126131
end {
127-
Write-Verbose "Remove folder [$tempPath]"
132+
Write-Verbose "Removing temporary download directory [${tempPath}]…"
128133
}
129134

130135
clean {
131-
Remove-Item -Path $tempPath -Force
136+
Remove-Item -Path ${tempPath} -Force
132137
}
133138
}

0 commit comments

Comments
 (0)