cmder/scripts/update.ps1

267 lines
7.5 KiB
PowerShell
Raw Normal View History

2022-10-18 01:30:30 +08:00
<#
.Synopsis
Update Cmder vendored dependencies
.DESCRIPTION
This script updates dependencies to the latest version in vendor/sources.json file.
You will need to make this script executable by setting your Powershell Execution Policy to Remote signed
Then unblock the script for execution with UnblockFile .\build.ps1
.EXAMPLE
.\build.ps1
Updates the dependency sources in the default location, the vendor/sources.json file.
.EXAMPLE
.\build -verbose
Updates the dependency sources and see what's going on.
.EXAMPLE
.\build.ps1 -SourcesPath '~/custom/vendors.json'
Specify the path to update dependency sources file at.
.NOTES
AUTHORS
David Refoua <David@Refoua.me>
Part of the Cmder project.
.LINK
http://cmder.app/ - Project Home
#>
2022-11-04 23:17:16 +08:00
[CmdletBinding(SupportsShouldProcess = $true)]
2022-10-18 01:30:30 +08:00
Param(
# CmdletBinding will give us;
# -verbose switch to turn on logging and
# -whatif switch to not actually make changes
# Path to the vendor configuration source file
[string]$sourcesPath = "$PSScriptRoot\..\vendor\sources.json"
)
# Get the root directory of the cmder project.
$cmder_root = Resolve-Path "$PSScriptRoot\.."
# Dot source util functions into this scope
. "$PSScriptRoot\utils.ps1"
$ErrorActionPreference = "Stop"
# Attempts to match the current link with the new link, returning the count of matching characters.
function Match-Filenames {
param (
$url,
$downloadUrl,
$fromEnd
)
$filename = [System.IO.Path]::GetFileName($url)
$filenameDownload = [System.IO.Path]::GetFileName($downloadUrl)
$position = 0
2022-11-06 16:02:22 +08:00
if ([String]::IsNullOrEmpty($filename) -or [String]::IsNullOrEmpty($filenameDownload)) {
2022-10-18 01:30:30 +08:00
throw "Either one or both filenames are empty!"
}
if ($fromEnd) {
$arr = $filename -split ""
[array]::Reverse($arr)
$filename = $arr -join ''
$arr = $filenameDownload -split ""
[array]::Reverse($arr)
$filenameDownload = $arr -join ''
}
while ($filename.Substring($position, 1) -eq $filenameDownload.Substring($position, 1)) {
$position++
if ( ($position -ge $filename.Length) -or ($position -ge $filenameDownload.Length) ) {
break
}
}
return $position
}
# Uses the GitHub api in order to fetch the current download links for the latest releases of the repo.
function Fetch-DownloadUrl {
param (
[Parameter(Mandatory = $true)]
$urlStr
)
$url = [uri] $urlStr
2022-11-06 16:02:22 +08:00
if ((-not $url) -or ($null -eq $url) -or ($url -eq '')) {
2022-10-18 01:30:30 +08:00
throw "Failed to parse url: $urlStr"
}
2022-11-06 16:02:22 +08:00
if (-not ("http", "https" -contains $url.Scheme)) {
2022-10-18 01:30:30 +08:00
throw "unknown source scheme: $($url.Scheme)"
}
2022-11-06 16:02:22 +08:00
if (-not ($url.Host -ilike "*github.com")) {
2022-10-18 01:30:30 +08:00
throw "unknown source domain: $($url.Host)"
}
$p = $url.Segments.Split([Environment]::NewLine)
# Api server for GitHub
$urlHost = "api.github.com"
# Path for releases end-point
$urlPath = [IO.Path]::Combine('repos', $p[1], $p[2], 'releases').Trim('/')
$apiUrl = [uri] (New-Object System.UriBuilder -ArgumentList $url.Scheme, $urlHost, -1, $urlPath).Uri
$info = Invoke-RestMethod -Uri $apiUrl
$downloadLinks = (New-Object System.Collections.Generic.List[System.Object])
$charCount = 0
2022-11-06 16:02:22 +08:00
if (-not ($info -is [array])) {
2022-10-18 01:30:30 +08:00
throw "The response received from API server is invalid"
}
:loop foreach ($i in $info) {
2022-11-06 16:02:22 +08:00
if (-not ($i.assets -is [array])) {
2022-10-18 01:30:30 +08:00
continue
}
foreach ($a in $i.assets) {
if ([String]::IsNullOrEmpty($a.browser_download_url)) {
continue
}
2022-11-04 17:59:18 +08:00
# Skip some download links as we're not interested in them
2022-10-18 01:30:30 +08:00
if ( $a.browser_download_url -ilike "*_symbols*" ) {
continue
}
$score = Match-Filenames $url $a.browser_download_url
2022-11-04 17:59:18 +08:00
# Skip links that don't match or are less similar
2022-10-18 01:30:30 +08:00
if ( ($score -eq 0) -or ($score -lt $charCount) ) {
continue
}
2022-11-04 17:59:18 +08:00
# If we reach the same download link as we have
2022-10-18 01:30:30 +08:00
if ( $score -eq [System.IO.Path]::GetFileName($url).Length ) {
}
$charCount = $score
$downloadLinks.Add($a.browser_download_url)
}
2022-11-04 17:59:18 +08:00
# If at least one download link was found, don't continue with older releases
2022-10-18 01:30:30 +08:00
if ( $downloadLinks.Length -gt 0 ) {
break :loop
}
}
2022-11-04 17:59:18 +08:00
# Special case for archive downloads of repository
2022-11-06 16:02:22 +08:00
if (($null -eq $downloadLinks) -or (-not $downloadLinks)) {
if ((($p | ForEach-Object { $_.Trim('/') }) -contains "archive") -and $info[0].tag_name) {
2022-10-18 01:30:30 +08:00
for ($i = 0; $i -lt $p.Length; $i++) {
if ($p[$i].Trim('/') -eq "archive") {
2022-11-04 23:17:16 +08:00
$p[$i + 1] = $info[0].tag_name + ".zip"
2022-11-06 16:02:22 +08:00
$downloadLinks = $url.Scheme + "://" + $url.Host + ($p -join '')
2022-10-18 01:30:30 +08:00
return $downloadLinks
}
}
}
return ''
}
$temp = $downloadLinks | Where-Object { (Match-Filenames $url $_) -eq $charCount }
$downloadLinks = (New-Object System.Collections.Generic.List[System.Object])
$charCount = 0
foreach ($l in $temp) {
$score = Match-Filenames $url $l true
if ( ($score -eq 0) -or ($score -lt $charCount) ) {
continue
}
$charCount = $score
}
$downloadLinks = $temp | Where-Object { (Match-Filenames $url $_ true) -eq $charCount }
2022-11-06 16:02:22 +08:00
if (($null -eq $downloadLinks) -or (-not $downloadLinks)) {
2022-10-18 01:30:30 +08:00
throw "No suitable download links matched for the url!"
}
2022-11-06 16:02:22 +08:00
if (-not($downloadLinks -is [String])) {
2022-10-18 01:30:30 +08:00
throw "Found multiple matches for the same url:`n" + $downloadLinks
}
return $downloadLinks
}
$count = 0
# Read the current sources content
$sources = Get-Content $sourcesPath | Out-String | ConvertFrom-Json
foreach ($s in $sources) {
Write-Verbose "Updating sources link for $($s.name)..."
2022-11-04 17:59:18 +08:00
Write-Verbose "Old Link: $($s.url)"
2022-10-18 01:30:30 +08:00
$downloadUrl = Fetch-DownloadUrl $s.url
2022-11-06 16:02:22 +08:00
if (($null -eq $downloadUrl) -or ($downloadUrl -eq '')) {
2022-10-18 01:30:30 +08:00
Write-Verbose "No new links were found"
continue
}
Write-Verbose "Link: $downloadUrl"
$url = [uri] $downloadUrl
$version = ''
2022-11-06 16:02:22 +08:00
if (($url.Segments[-3] -eq "download/") -and ($url.Segments[-2].StartsWith("v"))) {
2022-10-18 01:30:30 +08:00
$version = $url.Segments[-2].TrimStart('v').TrimEnd('/')
}
2022-11-06 16:02:22 +08:00
if (($url.Segments[-2] -eq "archive/")) {
2022-10-18 01:30:30 +08:00
$version = [System.IO.Path]::GetFileNameWithoutExtension($url.Segments[-1].TrimStart('v').TrimEnd('/'))
}
2022-11-06 16:02:22 +08:00
if ($version -eq '') {
2022-10-18 01:30:30 +08:00
throw "Unable to extract version from url string"
}
Write-Verbose "Version: $version"
2022-11-04 17:59:18 +08:00
if ( $s.version -ne $version ) {
# if ( ([System.Version] $s.version) -gt ([System.Version] $version) ) {
# throw "The current version $($s.version) is already newer than the found version $version!"
# }
2022-10-18 01:30:30 +08:00
2022-11-04 17:59:18 +08:00
$count++
}
2022-10-18 01:30:30 +08:00
$s.url = $downloadUrl
$s.version = $version
}
$sources | ConvertTo-Json | Set-Content $sourcesPath
if ($count -eq 0) {
2022-11-04 17:59:18 +08:00
Write-Host -ForegroundColor yellow "No new releases were found."
return
2022-10-18 01:30:30 +08:00
}
2022-11-06 16:02:22 +08:00
if ($Env:APPVEYOR -eq 'True') {
2022-10-18 01:30:30 +08:00
Add-AppveyorMessage -Message "Successfully updated $count dependencies." -Category Information
}
2022-11-06 16:02:22 +08:00
if ($Env:GITHUB_ACTIONS -eq 'true') {
2022-10-18 01:50:32 +08:00
Write-Output "::notice title=Task Complete::Successfully updated $count dependencies."
2022-10-18 01:30:30 +08:00
}
Write-Host -ForegroundColor green "Successfully updated $count dependencies."