mirror of
				https://github.com/cmderdev/cmder.git
				synced 2025-10-31 09:22:15 +08:00 
			
		
		
		
	initial update vendors script
This commit is contained in:
		
							
								
								
									
										266
									
								
								scripts/update.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								scripts/update.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,266 @@ | ||||
| <# | ||||
| .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 | ||||
| #> | ||||
| [CmdletBinding(SupportsShouldProcess=$true)] | ||||
| 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 | ||||
|  | ||||
|     if ([String]::IsNullOrEmpty($filename) -Or [String]::IsNullOrEmpty($filenameDownload)) { | ||||
|         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 | ||||
|  | ||||
|     if ((-Not $url) -Or ($null -eq $url) -Or ($url -eq '')) { | ||||
|         throw "Failed to parse url: $urlStr" | ||||
|     } | ||||
|  | ||||
|     if (-Not ("http", "https" -Contains $url.Scheme)) { | ||||
|         throw "unknown source scheme: $($url.Scheme)" | ||||
|     } | ||||
|  | ||||
|     if (-Not ($url.Host -ilike "*github.com")) { | ||||
|         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 | ||||
|  | ||||
|     if (-Not ($info -Is [array])) { | ||||
|         throw "The response received from API server is invalid" | ||||
|     } | ||||
|  | ||||
|     :loop foreach ($i in $info) { | ||||
|         if (-Not ($i.assets -Is [array])) { | ||||
|             continue | ||||
|         } | ||||
|  | ||||
|         foreach ($a in $i.assets) { | ||||
|             if ([String]::IsNullOrEmpty($a.browser_download_url)) { | ||||
|                 continue | ||||
|             } | ||||
|  | ||||
| 			# Skip some download links as we're not interested in them | ||||
|             if ( $a.browser_download_url -ilike "*_symbols*" ) { | ||||
|                 continue | ||||
|             } | ||||
|  | ||||
|             $score = Match-Filenames $url $a.browser_download_url | ||||
|  | ||||
| 			# Skip links that don't match or are less similar | ||||
|             if ( ($score -eq 0) -or ($score -lt $charCount) ) { | ||||
|                 continue | ||||
|             } | ||||
|  | ||||
| 			# If we reach the same download link as we have | ||||
|             if ( $score -eq [System.IO.Path]::GetFileName($url).Length ) { | ||||
|             } | ||||
|  | ||||
|             $charCount = $score | ||||
|             $downloadLinks.Add($a.browser_download_url) | ||||
|         } | ||||
|  | ||||
| 		# If at least one download link was found, don't continue with older releases | ||||
|         if ( $downloadLinks.Length -gt 0 ) { | ||||
|             break :loop | ||||
|         } | ||||
|     } | ||||
|  | ||||
| 	# Special case for archive downloads of repository | ||||
|     if (($null -eq $downloadLinks) -Or (-Not $downloadLinks)) { | ||||
|         if ((($p | % {$_.Trim('/')}) -Contains "archive") -And $info[0].tag_name) { | ||||
|             for ($i = 0; $i -lt $p.Length; $i++) { | ||||
|                 if ($p[$i].Trim('/') -eq "archive") { | ||||
|                     $p[$i+1] = $info[0].tag_name + ".zip" | ||||
|                     $downloadLinks = $url.Scheme + "://" + $url.Host + ($p -Join '') | ||||
|                     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 } | ||||
|  | ||||
|     if (($null -eq $downloadLinks) -Or (-Not $downloadLinks)) { | ||||
|         throw "No suitable download links matched for the url!" | ||||
|     } | ||||
|  | ||||
|     if (-Not($downloadLinks -is [String])) { | ||||
|         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)..." | ||||
|  | ||||
| 	Write-Verbose "Old Link: $($s.url)" | ||||
|  | ||||
|     $downloadUrl = Fetch-DownloadUrl $s.url | ||||
|  | ||||
|     if (($null -eq $downloadUrl) -Or ($downloadUrl -eq '')) { | ||||
|         Write-Verbose "No new links were found" | ||||
|         continue | ||||
|     } | ||||
|  | ||||
|     Write-Verbose "Link: $downloadUrl" | ||||
|  | ||||
|     $url = [uri] $downloadUrl | ||||
|  | ||||
|     $version = '' | ||||
|  | ||||
|     if ( ($url.Segments[-3] -eq "download/") -And ($url.Segments[-2].StartsWith("v")) ) { | ||||
|         $version = $url.Segments[-2].TrimStart('v').TrimEnd('/') | ||||
|     } | ||||
|  | ||||
|     if ( ($url.Segments[-2] -eq "archive/") ) { | ||||
|         $version = [System.IO.Path]::GetFileNameWithoutExtension($url.Segments[-1].TrimStart('v').TrimEnd('/')) | ||||
|     } | ||||
|  | ||||
|     if ( $version -eq '' ) { | ||||
|         throw "Unable to extract version from url string" | ||||
|     } | ||||
|  | ||||
|     Write-Verbose "Version: $version" | ||||
|  | ||||
| 	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!" | ||||
| 		} | ||||
|  | ||||
| 		$count++ | ||||
| 	} | ||||
|  | ||||
|     $s.url = $downloadUrl | ||||
|     $s.version = $version | ||||
| } | ||||
|  | ||||
| $sources | ConvertTo-Json | Set-Content $sourcesPath | ||||
|  | ||||
| if ($count -eq 0) { | ||||
| 	Write-Host -ForegroundColor yellow "No new releases were found." | ||||
| 	return | ||||
| } | ||||
|  | ||||
| if ( $Env:APPVEYOR -eq 'True' ) { | ||||
|     Add-AppveyorMessage -Message "Successfully updated $count dependencies." -Category Information | ||||
| } | ||||
|  | ||||
| if ( $Env:GITHUB_ACTIONS -eq 'true' ) { | ||||
|     Write-Output "::notice title=Build Complete::Successfully updated $count dependencies." | ||||
| } | ||||
|  | ||||
| Write-Host -ForegroundColor green "Successfully updated $count dependencies." | ||||
		Reference in New Issue
	
	Block a user