Skip to content

Commit a4b282f

Browse files
committed
New commands: Set-PhpDownloadCache, Get-PhpDownloadCache
1 parent 955bcdc commit a4b282f

13 files changed

+316
-85
lines changed

.appveyor.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ environment:
1616
PsgKey:
1717
secure: tlhLuUS6x8FcP159+X/EIBDlj9m+u5KCTTuqwzsiNHlPX6K4AolpaZcfAP4ClOdB
1818

19+
cache:
20+
- C:\downloads -> .appveyor.yml
21+
- '%ProgramFiles%\WindowsPowerShell\Modules\VcRedist -> .appveyor.yml'
22+
1923
install:
2024
- ps: Import-Module -Force .\PhpManager
2125

@@ -27,6 +31,7 @@ test_script:
2731
Set-StrictMode -Version 2.0
2832
$ProgressPreference = 'SilentlyContinue'
2933
$ErrorActionPreference = 'Stop'
34+
Set-PhpDownloadCache -Path C:\downloads
3035
# Check that Get-PhpAvailableVersion works
3136
$latest72 = Get-PhpAvailableVersion -State Release | Where-Object { $_.BaseVersion -match '^7.2\.' -and $_.Architecture -eq 'x86' -and $_.ThreadSafe -eq $true }
3237
If (-Not($latest72)) { Throw 'PHP release 7.2 not not found!' }
@@ -98,7 +103,13 @@ deploy_script:
98103
If ($previousTag -eq '') {
99104
Write-Host 'Unable to find the previously published tag: empty release notes'
100105
} Else {
101-
$commitMessages = @(& git log --format='- %s' --no-merges --reverse ("$previousTag..." + $Env:APPVEYOR_REPO_TAG_NAME) -- .\PhpManager)
106+
$rawCommitMessages = @(& git log --format='- %s' --no-merges --reverse ("$previousTag..." + $Env:APPVEYOR_REPO_TAG_NAME) -- .\PhpManager)
107+
$commitMessages = @()
108+
ForEach ($rawCommitMessage in $rawCommitMessages) {
109+
If (-Not($rawCommitMessage -imatch '^\[minor\]')) {
110+
$commitMessages += $rawCommitMessage
111+
}
112+
}
102113
If ($commitMessages.Count -lt 1) {
103114
Write-Host 'No relevant commit messages found: empty release notes'
104115
} Else {

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,10 @@
77
"files.trimTrailingWhitespace": true,
88
"[bat]": {
99
"files.encoding": "iso88591"
10+
},
11+
"[markdown]": {
12+
"editor.wordWrap": "on",
13+
"editor.quickSuggestions": false,
14+
"files.trimTrailingWhitespace": false
1015
}
1116
}

PhpManager/PhpManager.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# TypesToProcess = @()
2020
# FormatsToProcess = @()
2121
# NestedModules = @()
22-
FunctionsToExport = 'Get-PhpAvailableVersion', 'Install-Php', 'Update-Php', 'Uninstall-Php', 'Get-Php', 'Set-PhpIniKey', 'Get-PhpIniKey', 'Get-PhpExtension', 'Enable-PhpExtension', 'Disable-PhpExtension', 'Install-PhpExtension', 'Update-PhpCAInfo'
22+
FunctionsToExport = 'Get-PhpAvailableVersion', 'Install-Php', 'Update-Php', 'Uninstall-Php', 'Get-Php', 'Set-PhpIniKey', 'Get-PhpIniKey', 'Get-PhpExtension', 'Enable-PhpExtension', 'Disable-PhpExtension', 'Install-PhpExtension', 'Update-PhpCAInfo', 'Set-PhpDownloadCache', 'Get-PhpDownloadCache'
2323
CmdletsToExport = ''
2424
VariablesToExport = ''
2525
AliasesToExport = ''
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
Function Get-FileFromUrlOrCache
2+
{
3+
<#
4+
.Synopsis
5+
Gets a file from the download cache or (if unavailable) download and cache it (if the cache is enabled)
6+
7+
.Parameter Url
8+
The URL to be downloaded from.
9+
10+
.Parameter CachedFileName
11+
The name of the file to be used to store the downloaded resource in the cache.
12+
13+
.Example
14+
Get-FileFromUrlOrCache 'http://www.example.com/test.zip'
15+
16+
.Example
17+
Get-FileFromUrlOrCache 'http://www.example.com/test.zip' 'cached-file-name.zip'
18+
19+
.Outputs
20+
[System.Array]
21+
#>
22+
Param (
23+
[Parameter(Mandatory = $True, Position = 0)]
24+
[ValidateNotNull()]
25+
[ValidateLength(1, [int]::MaxValue)]
26+
[string] $Url,
27+
[Parameter(Mandatory = $False, Position = 1)]
28+
[string] $CachedFileName
29+
)
30+
Begin {
31+
$localFile = $null
32+
$fromCache = $null
33+
}
34+
Process {
35+
$extension = ''
36+
If ($null -ne $CachedFileName -and $CachedFileName -ne '') {
37+
$match = $CachedFileName | Select-String -Pattern '.(\.[A-Za-z0-9_\-]+)$'
38+
If ($match) {
39+
$extension = $match.Matches.Groups[1].Value
40+
}
41+
} Else {
42+
$CachedFileName = ''
43+
$match = $Url | Select-String -Pattern '^[^:]+:/+[^?#/]+/(?:[^?#/]*/)*([^?#/]+)(?:$|^|#)'
44+
If ($match) {
45+
$nameFromUrl = $match.Matches.Groups[1].Value
46+
$match = $nameFromUrl | Select-String -Pattern '.(\.[A-Za-z0-9_\-]+)$'
47+
If ($match) {
48+
$extension = $match.Matches.Groups[1].Value
49+
}
50+
If ($nameFromUrl -imatch '^[a-z0-9_\-][a-z0-9_\-\.]*[a-z0-9_\-]$') {
51+
$CachedFileName = $nameFromUrl;
52+
}
53+
}
54+
If ($CachedFileName -eq '') {
55+
$stream = New-Object System.IO.MemoryStream
56+
Try {
57+
$streamWriter = New-Object -TypeName System.IO.BinaryWriter -ArgumentList @($stream)
58+
Try {
59+
$streamWriter.Write([System.Text.Encoding]::UTF8.GetBytes($Url))
60+
$streamWriter.Flush()
61+
$stream.Position = 0
62+
$hash = Get-FileHash -InputStream $stream -Algorithm SHA1
63+
$CachedFileName = $hash.Hash
64+
}
65+
Finally {
66+
$streamWriter.Dispose()
67+
}
68+
}
69+
Finally {
70+
$stream.Dispose()
71+
}
72+
}
73+
}
74+
If ($Script:DOWNLOADCACHE_PATH -eq '') {
75+
$fullCachePath = ''
76+
} Else {
77+
If (-Not(Test-Path -LiteralPath $Script:DOWNLOADCACHE_PATH -PathType Container)) {
78+
New-Item -Path $Script:DOWNLOADCACHE_PATH -ItemType Directory | Out-Null
79+
}
80+
$fullCachePath = Join-Path -Path $Script:DOWNLOADCACHE_PATH -ChildPath $CachedFileName
81+
}
82+
If ($fullCachePath -ne '' -and (Test-Path -LiteralPath $fullCachePath -PathType Leaf)) {
83+
$localFile = $fullCachePath
84+
$fromCache = $true
85+
} Else {
86+
$temporaryFile = Get-TemporaryFileWithExtension -Extension $extension
87+
Try {
88+
Try {
89+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + [Net.SecurityProtocolType]::Tls11 + [Net.SecurityProtocolType]::Tls
90+
}
91+
Catch {
92+
Write-Debug '[Net.ServicePointManager] or [Net.SecurityProtocolType] not found in current environment'
93+
}
94+
Write-Debug "Downloading from $Url"
95+
Invoke-WebRequest -UseBasicParsing $Url -OutFile $temporaryFile
96+
If ($fullCachePath -ne '') {
97+
Move-Item -LiteralPath $temporaryFile -Destination $fullCachePath
98+
$localFile = $fullCachePath
99+
$fromCache = $true
100+
} Else {
101+
$localFile = $fullCachePath
102+
$fromCache = $false
103+
}
104+
} Catch {
105+
Try {
106+
Remove-Item -LiteralPath $temporaryFile
107+
} Catch {
108+
Write-Debug 'Failed to remove a temporary file'
109+
}
110+
Throw
111+
}
112+
}
113+
}
114+
End {
115+
$localFile
116+
$fromCache
117+
}
118+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
function Get-TemporaryFileWithExtension() {
2+
<#
3+
.Synopsis
4+
Creates a new empty temporary file with the specified file extension.
5+
6+
.Parameter Extension
7+
The extension of the file.
8+
9+
.Example
10+
Get-TemporaryFileWithExtension -Extension 'zip'
11+
12+
.Example
13+
Get-TemporaryFileWithExtension -Extension '.zip'
14+
15+
.Outputs
16+
string
17+
#>
18+
Param(
19+
[Parameter(Mandatory = $True, Position = 0)]
20+
[ValidateNotNull()]
21+
[ValidateLength(1, [int]::MaxValue)]
22+
[string] $Extension
23+
)
24+
Begin {
25+
$temporaryFilePath = $null
26+
}
27+
Process {
28+
If ($null -eq $Extension -or $Extension -eq '') {
29+
$Extension = ''
30+
} ElseIf ($Extension[0] -ne '.') {
31+
$Extension = '.' + $Extension
32+
}
33+
$originalTemporaryFilePath = [System.IO.Path]::GetTempFileName()
34+
Try {
35+
$temporaryDirectoryPath = [System.IO.Path]::GetDirectoryName($originalTemporaryFilePath)
36+
$temporaryFileName = [System.IO.Path]::GetFileNameWithoutExtension($originalTemporaryFilePath)
37+
For ($i = 0;; $i++) {
38+
If ($i -eq 0) {
39+
$suffix = ''
40+
} Else {
41+
$suffix = '-' + [string]$i
42+
}
43+
$temporaryFilePath = [System.IO.Path]::Combine($temporaryDirectoryPath, $temporaryFileName + $suffix + $Extension)
44+
If ($temporaryFilePath -eq $originalTemporaryFilePath) {
45+
Break
46+
}
47+
If (-Not(Test-Path -LiteralPath $temporaryFilePath)) {
48+
Rename-Item -LiteralPath $originalTemporaryFilePath -NewName $temporaryFilePath
49+
Break
50+
}
51+
}
52+
} Catch {
53+
Try {
54+
Remove-Item -LiteralPath $originalTemporaryFilePath
55+
} Catch {
56+
Write-Debug 'Failed to remove a temporary file'
57+
}
58+
}
59+
}
60+
End {
61+
$temporaryFilePath
62+
}
63+
}

PhpManager/private/Get-ZipFromUrl.ps1

Lines changed: 0 additions & 58 deletions
This file was deleted.

PhpManager/private/Install-PhpExtensionPrerequisite.ps1

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,17 @@ function Install-PhpExtensionPrerequisite() {
4444
Throw ('Unable to find the imagick package dependencies on {0} for {1}' -f $pageUrl, $PhpVersion.DisplayName)
4545
}
4646
Write-Output "Downloading and extracting $zipUrl"
47-
$zipFile = Get-ZipFromUrl -Url $zipUrl
47+
$zipFile, $keepZipFile = Get-FileFromUrlOrCache -Url $zipUrl
4848
Try {
4949
$tempFolder = New-TempDirectory
5050
Try {
51-
Expand-Archive -LiteralPath $zipFile -DestinationPath $tempFolder
51+
Try {
52+
Expand-Archive -LiteralPath $zipFile -DestinationPath $tempFolder
53+
}
54+
Catch {
55+
$keepZipFile = $false
56+
Throw
57+
}
5258
$phpFolder = [System.IO.Path]::GetDirectoryName($PhpVersion.ExecutablePath)
5359
Get-ChildItem -LiteralPath $tempFolder -Recurse -File -Filter *.dll `
5460
| Where-Object {$_.Name -like 'CORE_RL_*.dll' -or $_.Name -like 'IM_MOD_RL_*.dll' } `
@@ -64,11 +70,13 @@ function Install-PhpExtensionPrerequisite() {
6470
}
6571
}
6672
Finally {
67-
Try {
68-
Remove-Item -Path $zipFile
69-
}
70-
Catch {
71-
Write-Debug 'Failed to remove temporary zip file'
73+
If (-Not($keepZipFile)) {
74+
Try {
75+
Remove-Item -Path $zipFile
76+
}
77+
Catch {
78+
Write-Debug 'Failed to remove temporary zip file'
79+
}
7280
}
7381
}
7482
}

PhpManager/private/Install-PhpFromUrl.ps1

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,18 @@ function Install-PhpFromUrl() {
3333
Begin {
3434
}
3535
Process {
36-
$temporaryFile = Get-ZipFromUrl -Url $Url
36+
$temporaryFile, $keepTemporaryFile = Get-FileFromUrlOrCache -Url $Url
3737
Try {
3838
$temporaryDirectory = New-TempDirectory
3939
Try {
4040
Write-Debug "Extracting $temporaryFile to temporary directory"
41-
Expand-Archive -LiteralPath $temporaryFile -DestinationPath $temporaryDirectory -Force
41+
Try {
42+
Expand-Archive -LiteralPath $temporaryFile -DestinationPath $temporaryDirectory -Force
43+
}
44+
Catch {
45+
$keepTemporaryFile = $false
46+
Throw
47+
}
4248
$exePath = Join-Path -Path $temporaryDirectory -ChildPath 'php.exe'
4349
If (-Not(Test-Path -Path $exePath -PathType Leaf)) {
4450
Throw "Unable to find php.exe in the downloaded archive"
@@ -108,10 +114,12 @@ function Install-PhpFromUrl() {
108114
Write-Debug "Extracting $temporaryFile to destination directory"
109115
Expand-Archive -LiteralPath $temporaryFile -DestinationPath $Path -Force
110116
} Finally {
111-
Try {
112-
Remove-Item -Path $temporaryFile
113-
} Catch {
114-
Write-Debug 'Failed to remove temporary file'
117+
If (-Not($keepTemporaryFile)) {
118+
Try {
119+
Remove-Item -Path $temporaryFile
120+
} Catch {
121+
Write-Debug 'Failed to remove temporary file'
122+
}
115123
}
116124
}
117125
}

PhpManager/private/Variables.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ New-Variable -Option ReadOnly -Scope Script -Name 'AVAILABLEVERSIONS_RELEASE' -V
33
New-Variable -Option ReadOnly -Scope Script -Name 'AVAILABLEVERSIONS_ARCHIVE' -Value $null
44

55
New-Variable -Option ReadOnly -Scope Script -Name 'PECL_PACKAGES' -Value $null
6+
7+
New-Variable -Option ReadOnly -Scope Script -Name 'DOWNLOADCACHE_PATH' -Value ''

0 commit comments

Comments
 (0)