Skip to content

Commit 45b67c1

Browse files
committed
Merge branch 'stable'
* stable: (maint) rename Get-FileName to Get-WebFileName (maint) Log host version as well. (GH-512) Exit with same code as installer (GH-707) Exit with specific exit codes (GH-649) Error if executable is text file (GH-709) Get Exit code from PowerShell Host (GH-512) Display exit code for packages (GH-710) prompt with timeout on some commands (maint) better error handling
2 parents 47f8ec4 + 4b0558e commit 45b67c1

17 files changed

+258
-148
lines changed

src/chocolatey.resources/chocolatey.resources.csproj

+4-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@
123123
<EmbeddedResource Include="helpers\chocolateyScriptRunner.ps1" />
124124
</ItemGroup>
125125
<ItemGroup>
126-
<EmbeddedResource Include="helpers\functions\Get-FileName.ps1" />
126+
<EmbeddedResource Include="helpers\functions\Get-WebFileName.ps1" />
127127
</ItemGroup>
128128
<ItemGroup>
129129
<EmbeddedResource Include="helpers\functions\Get-ToolsLocation.ps1" />
@@ -137,6 +137,9 @@
137137
<ItemGroup>
138138
<EmbeddedResource Include="helpers\ChocolateyTabExpansion.ps1" />
139139
</ItemGroup>
140+
<ItemGroup>
141+
<EmbeddedResource Include="helpers\functions\Set-PowerShellExitCode.ps1" />
142+
</ItemGroup>
140143
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
141144
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
142145
Other similar extension points exist, see Microsoft.Common.targets.

src/chocolatey.resources/helpers/chocolateyInstaller.psm1

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ $packageParameters = $env:chocolateyPackageParameters
3232
# ensure module loading preference is on
3333
$PSModuleAutoLoadingPreference = "All";
3434

35-
Write-Debug "PowerShell Version is '$($PSVersionTable.PSVersion)' and CLR Version is '$($PSVersionTable.CLRVersion)'."
35+
Write-Debug "Host version is $($host.Version), PowerShell Version is '$($PSVersionTable.PSVersion)' and CLR Version is '$($PSVersionTable.CLRVersion)'."
3636

3737
# grab functions from files
3838
Get-Item $helpersPath\functions\*.ps1 |

src/chocolatey.resources/helpers/chocolateyScriptRunner.ps1

+15-1
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,18 @@ $ShimGen = Join-Path $chocoTools 'shimgen.exe'
4545
$checksumExe = Join-Path $chocoTools 'checksum.exe'
4646

4747
Write-Debug "Running `'$packageScript`'";
48-
& "$packageScript"
48+
& "$packageScript"
49+
50+
$scriptSuccess = $?
51+
52+
$exitCode = $LASTEXITCODE
53+
if ($exitCode -eq 0 -and -not $scriptSuccess) {
54+
$exitCode = 1
55+
}
56+
57+
if ($env:ChocolateyExitCode -ne $null -and $env:ChocolateyExitCode -ne '') {
58+
$exitCode = $env:ChocolateyExitCode
59+
}
60+
61+
62+
Exit $exitCode

src/chocolatey.resources/helpers/functions/Get-ChocolateyUnzip.ps1

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ param(
138138
Unregister-Event -SourceIdentifier "LogErrors_ChocolateyZipProc"
139139

140140
$exitCode = $process.ExitCode
141+
Set-PowerShellExitCode $exitCode
141142
$process.Dispose()
142143
Write-Debug "Command ['$7zip' $params] exited with `'$exitCode`'."
143144

src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1

+7-3
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ param(
129129
try {
130130
$fileDirectory = [System.IO.Path]::GetDirectoryName($fileFullPath)
131131
$originalFileName = [System.IO.Path]::GetFileName($fileFullPath)
132-
$fileFullPath = Get-FileName -url $url -defaultName $originalFileName
132+
$fileFullPath = Get-WebFileName -url $url -defaultName $originalFileName
133133
$fileFullPath = Join-Path $fileDirectory $fileFullPath
134134
$fileFullPath = [System.IO.Path]::GetFullPath($fileFullPath)
135135
} catch {
@@ -149,13 +149,17 @@ param(
149149
$headers = @{}
150150
if ($url.StartsWith('http')) {
151151
try {
152-
$headers = Get-WebHeaders $url
152+
$headers = Get-WebHeaders $url -ErrorAction "Stop"
153153
} catch {
154154
if ($host.Version -lt (new-object 'Version' 3,0)) {
155155
Write-Debug "Converting Security Protocol to SSL3 only for Powershell v2"
156156
# this should last for the entire duration
157157
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3
158-
$headers = Get-WebHeaders $url
158+
try {
159+
$headers = Get-WebHeaders $url -ErrorAction "Stop"
160+
} catch {
161+
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
162+
}
159163
} else {
160164
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
161165
}

src/chocolatey.resources/helpers/functions/Get-WebFile.ps1

+115-93
Original file line numberDiff line numberDiff line change
@@ -94,119 +94,141 @@ param(
9494
}
9595
}
9696

97-
$res = $req.GetResponse();
97+
try {
98+
[System.Net.HttpWebResponse]$res = $req.GetResponse();
9899

99-
try {
100-
$headers = @{}
101-
foreach ($key in $res.Headers) {
102-
$value = $res.Headers[$key];
103-
if ($value) {
104-
$headers.Add("$key","$value")
100+
try {
101+
$headers = @{}
102+
foreach ($key in $res.Headers) {
103+
$value = $res.Headers[$key];
104+
if ($value) {
105+
$headers.Add("$key","$value")
106+
}
105107
}
106-
}
107108

108-
if ($headers.ContainsKey("Content-Type")) {
109-
$contentType = $headers['Content-Type']
110-
if ($contentType -ne $null) {
111-
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
112-
Write-Warning "$fileName is of content type $contentType"
113-
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
109+
if ($headers.ContainsKey("Content-Type")) {
110+
$contentType = $headers['Content-Type']
111+
if ($contentType -ne $null) {
112+
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
113+
Write-Warning "$fileName is of content type $contentType"
114+
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
115+
}
114116
}
117+
}
118+
} catch {
119+
# not able to get content-type header
120+
Write-Debug "Error getting content type - $($_.Exception.Message)"
121+
}
122+
123+
if($fileName -and !(Split-Path $fileName)) {
124+
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
125+
}
126+
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
127+
{
128+
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
129+
$fileName = $fileName.trim("\/""'")
130+
if(!$fileName) {
131+
$fileName = $res.ResponseUri.Segments[-1]
132+
$fileName = $fileName.trim("\/")
133+
if(!$fileName) {
134+
$fileName = Read-Host "Please provide a file name"
135+
}
136+
$fileName = $fileName.trim("\/")
137+
if(!([IO.FileInfo]$fileName).Extension) {
138+
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
139+
}
115140
}
116-
}
117-
} catch {
118-
# not able to get content-type header
119-
Write-Debug "Error getting content type - $($_.Exception.Message)"
120-
}
141+
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
142+
}
143+
if($Passthru) {
144+
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
145+
[string]$output = ""
146+
}
121147

122-
if($fileName -and !(Split-Path $fileName)) {
123-
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
124-
}
125-
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
126-
{
127-
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
128-
$fileName = $fileName.trim("\/""'")
129-
if(!$fileName) {
130-
$fileName = $res.ResponseUri.Segments[-1]
131-
$fileName = $fileName.trim("\/")
132-
if(!$fileName) {
133-
$fileName = Read-Host "Please provide a file name"
134-
}
135-
$fileName = $fileName.trim("\/")
136-
if(!([IO.FileInfo]$fileName).Extension) {
137-
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
138-
}
148+
if($res.StatusCode -eq 401 -or $res.StatusCode -eq 403 -or $res.StatusCode -eq 404) {
149+
$env:ChocolateyExitCode = $res.StatusCode
150+
throw "Remote file either doesn't exist, is unauthorized, or is forbidden for '$url'."
139151
}
140-
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
141-
}
142-
if($Passthru) {
143-
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
144-
[string]$output = ""
145-
}
146152

147-
if($res.StatusCode -eq 200) {
148-
[long]$goal = $res.ContentLength
149-
$goalFormatted = Format-FileSize $goal
150-
$reader = $res.GetResponseStream()
153+
if($res.StatusCode -eq 200) {
154+
[long]$goal = $res.ContentLength
155+
$goalFormatted = Format-FileSize $goal
156+
$reader = $res.GetResponseStream()
151157

152-
if ($fileName) {
153-
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
154-
if (!(Test-Path($fileDirectory))) {
155-
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
156-
}
158+
if ($fileName) {
159+
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
160+
if (!(Test-Path($fileDirectory))) {
161+
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
162+
}
157163

158-
try {
159-
$writer = new-object System.IO.FileStream $fileName, "Create"
160-
} catch {
161-
throw $_.Exception
164+
try {
165+
$writer = new-object System.IO.FileStream $fileName, "Create"
166+
} catch {
167+
throw $_.Exception
168+
}
162169
}
163-
}
164170

165-
[byte[]]$buffer = new-object byte[] 1048576
166-
[long]$total = [long]$count = [long]$iterLoop =0
171+
[byte[]]$buffer = new-object byte[] 1048576
172+
[long]$total = [long]$count = [long]$iterLoop =0
167173

168-
$originalEAP = $ErrorActionPreference
169-
$ErrorActionPreference = 'Stop'
170-
try {
171-
do
172-
{
173-
$count = $reader.Read($buffer, 0, $buffer.Length);
174-
if($fileName) {
175-
$writer.Write($buffer, 0, $count);
176-
}
177-
178-
if($Passthru){
179-
$output += $encoding.GetString($buffer,0,$count)
180-
} elseif(!$quiet) {
181-
$total += $count
182-
$totalFormatted = Format-FileSize $total
183-
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
184-
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
174+
$originalEAP = $ErrorActionPreference
175+
$ErrorActionPreference = 'Stop'
176+
try {
177+
do
178+
{
179+
$count = $reader.Read($buffer, 0, $buffer.Length);
180+
if($fileName) {
181+
$writer.Write($buffer, 0, $count);
185182
}
183+
184+
if($Passthru){
185+
$output += $encoding.GetString($buffer,0,$count)
186+
} elseif(!$quiet) {
187+
$total += $count
188+
$totalFormatted = Format-FileSize $total
189+
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
190+
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
191+
}
186192

187-
if ($total -eq $goal) {
188-
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
193+
if ($total -eq $goal) {
194+
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
195+
}
189196
}
190-
}
191-
} while ($count -gt 0)
192-
Write-Host ""
193-
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
194-
} catch {
195-
throw $_.Exception
196-
} finally {
197-
$ErrorActionPreference = $originalEAP
198-
}
197+
} while ($count -gt 0)
198+
Write-Host ""
199+
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
200+
} catch {
201+
throw $_.Exception
202+
} finally {
203+
$ErrorActionPreference = $originalEAP
204+
}
199205

200-
$reader.Close()
201-
if($fileName) {
202-
$writer.Flush()
203-
$writer.Close()
206+
$reader.Close()
207+
if($fileName) {
208+
$writer.Flush()
209+
$writer.Close()
210+
}
211+
if($Passthru){
212+
$output
213+
}
214+
}
215+
} catch {
216+
if ($req -ne $null) {
217+
$req.ServicePoint.MaxIdleTime = 0
218+
$req.Abort();
219+
# ruthlessly remove $req to ensure it isn't reused
220+
Remove-Variable req
221+
Start-Sleep 1
222+
[GC]::Collect()
204223
}
205-
if($Passthru){
206-
$output
224+
225+
Set-PowerShellExitCode 404
226+
throw "The remote file either doesn't exist, is unauthorized, or is forbidden for url '$url'. $($_.Exception.Message)"
227+
} finally {
228+
if ($res -ne $null) {
229+
$res.Close()
207230
}
208231
}
209-
$res.Close();
210232
}
211233

212234
# this could be cleaned up with http://learn-powershell.net/2013/02/08/powershell-and-events-object-events/

src/chocolatey.resources/helpers/functions/Get-FileName.ps1 src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1

+16-9
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
# limitations under the License.
1414
#
1515
# Based on http://stackoverflow.com/a/13571471/18475
16-
function Get-FileName {
16+
function Get-WebFileName {
1717
param(
1818
[string]$url = '',
1919
[string]$defaultName,
2020
$userAgent = 'chocolatey command line'
2121
)
2222

23-
Write-Debug "Running 'Get-FileName' to determine name with url:'$url', defaultName:'$defaultName'";
23+
Write-Debug "Running 'Get-WebFileName' to determine name with url:'$url', defaultName:'$defaultName'";
2424

2525
$originalFileName = $defaultName
2626
$fileName = $null
@@ -126,9 +126,6 @@ param(
126126
$containsEquals = [System.IO.Path]::GetFileName($url).Contains('=')
127127
$fileName = [System.IO.Path]::GetFileName($response.ResponseUri.ToString())
128128
}
129-
130-
$response.Close()
131-
$response.Dispose()
132129

133130
[System.Text.RegularExpressions.Regex]$containsABadCharacter = New-Object Regex("[" + [System.Text.RegularExpressions.Regex]::Escape([System.IO.Path]::GetInvalidFileNameChars()) + "]", [System.Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace);
134131

@@ -141,12 +138,22 @@ param(
141138
Write-Debug "File name determined from url is '$fileName'"
142139

143140
return $fileName
144-
} catch
145-
{
146-
$request.ServicePoint.MaxIdleTime = 0
147-
$request.Abort();
141+
} catch {
142+
if ($request -ne $null) {
143+
$request.ServicePoint.MaxIdleTime = 0
144+
$request.Abort();
145+
# ruthlessly remove $request to ensure it isn't reused
146+
Remove-Variable request
147+
Start-Sleep 1
148+
[GC]::Collect()
149+
}
150+
148151
Write-Debug "Url request/response failed - file name will be '$originalFileName': $($_)"
149152

150153
return $originalFileName
154+
} finally {
155+
if ($response -ne $null) {
156+
$response.Close();
157+
}
151158
}
152159
}

0 commit comments

Comments
 (0)