diff --git a/.editorconfig b/.editorconfig index 1f3a579c3..87230b083 100644 --- a/.editorconfig +++ b/.editorconfig @@ -18,3 +18,8 @@ end_of_line = crlf [*.{yml, yaml}] indent_size = 2 + +# Makefiles require tab indentation +[{{M,m,GNU}akefile{,.*},*.mak,*.mk}] +indent_style = tab +end_of_line = lf diff --git a/bin/checkver.ps1 b/bin/checkver.ps1 index 70d356079..83555b3aa 100644 --- a/bin/checkver.ps1 +++ b/bin/checkver.ps1 @@ -196,8 +196,11 @@ while ($in_progress -gt 0) { $expected_ver = $json.version $ver = '' - $err = $ev.SourceEventArgs.Error $page = $ev.SourceEventArgs.Result + $err = $ev.SourceEventArgs.Error + if ($json.checkver.script) { + $page = $json.checkver.script -join "`r`n" | Invoke-Expression + } if ($err) { next "$($err.message)`r`nURL $url is not valid" diff --git a/bin/scoop.ps1 b/bin/scoop.ps1 index c8d4494cc..f449590ad 100644 --- a/bin/scoop.ps1 +++ b/bin/scoop.ps1 @@ -10,14 +10,6 @@ set-strictmode -off reset_aliases -# TODO: remove this in a few weeks -if ((Get-LocalBucket) -notcontains 'main') { - warn "The main bucket of Scoop has been separated to 'https://github.com/ScoopInstaller/Main'" - warn "You don't have the main bucket added, adding main bucket for you..." - add_bucket 'main' - exit -} - $commands = commands if ('--version' -contains $cmd -or (!$cmd -and '-v' -contains $args)) { Push-Location $(versiondir 'scoop' 'current') diff --git a/lib/autoupdate.ps1 b/lib/autoupdate.ps1 index f1b2c63e6..c486cae3d 100644 --- a/lib/autoupdate.ps1 +++ b/lib/autoupdate.ps1 @@ -178,6 +178,9 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u $substitutions.Add('$url', (strip_fragment $url)) $substitutions.Add('$baseurl', (strip_filename (strip_fragment $url)).TrimEnd('/')) $substitutions.Add('$basename', $basename) + $substitutions.Add('$urlNoExt', (strip_ext (strip_fragment $url))) + $substitutions.Add('$basenameNoExt', (strip_ext $basename)) + debug $substitutions $hashfile_url = substitute $config.url $substitutions diff --git a/lib/core.ps1 b/lib/core.ps1 index a917f2673..9b3b2871d 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -578,7 +578,7 @@ function shim($path, $global, $name, $arg) { if($path -match '\.(exe|com)$') { # for programs with no awareness of any shell - Copy-Item "$(versiondir 'scoop' 'current')\supporting\shimexe\bin\shim.exe" "$shim.exe" -force + Copy-Item (get_shim_path) "$shim.exe" -force write-output "path = $resolved_path" | out-file "$shim.shim" -encoding utf8 if($arg) { write-output "args = $arg" | out-file "$shim.shim" -encoding utf8 -append @@ -608,6 +608,18 @@ powershell -noprofile -ex unrestricted `"& '$resolved_path' $arg %args%;exit `$l } } +function get_shim_path() { + $shim_path = "$(versiondir 'scoop' 'current')\supporting\shimexe\bin\shim.exe" + $shim_version = get_config 'shim' 'default' + switch ($shim_version) { + '71' { $shim_path = "$(versiondir 'scoop' 'current')\supporting\shims\71\shim.exe"; Break } + 'kiennq' { $shim_path = "$(versiondir 'scoop' 'current')\supporting\shims\kiennq\shim.exe"; Break } + 'default' { Break } + default { warn "Unknown shim version: '$shim_version'" } + } + return $shim_path +} + function search_in_path($target) { $path = (env 'PATH' $false) + ";" + (env 'PATH' $true) foreach($dir in $path.split(';')) { @@ -900,6 +912,7 @@ function handle_special_urls($url) $Body = @{ projectUri = $Matches.name; fileName = $Matches.filename; + source = 'CF'; isLatestVersion = $true } if ((Invoke-RestMethod -Uri $url) -match '"p":"(?[a-f0-9]{24}).*?"r":"(?[a-f0-9]{24})') { diff --git a/lib/diagnostic.ps1 b/lib/diagnostic.ps1 index 4c67454cf..9eb7579e1 100644 --- a/lib/diagnostic.ps1 +++ b/lib/diagnostic.ps1 @@ -50,3 +50,14 @@ function check_long_paths { return $true } + +function check_envs_requirements { + if ($null -eq $env:COMSPEC) { + warn '$env:COMSPEC environment variable is missing.' + Write-Host " By default the variable should points to the cmd.exe in Windows: '%SystemRoot%\system32\cmd.exe'." + + return $false + } + + return $true +} diff --git a/lib/git.ps1 b/lib/git.ps1 index d06aaa64a..92879fe9e 100644 --- a/lib/git.ps1 +++ b/lib/git.ps1 @@ -4,7 +4,7 @@ function git_proxy_cmd { if($proxy -and $proxy -ne 'none') { $cmd = "SET HTTPS_PROXY=$proxy&&SET HTTP_PROXY=$proxy&&$cmd" } - & "$env:COMSPEC" /c $cmd + & "$env:COMSPEC" /d /c $cmd } function git_clone { @@ -20,7 +20,7 @@ function git_checkout { } function git_pull { - git_proxy_cmd pull $args + git_proxy_cmd pull --rebase=false $args } function git_fetch { diff --git a/lib/install.ps1 b/lib/install.ps1 index c5638c8b5..5c78268b3 100644 --- a/lib/install.ps1 +++ b/lib/install.ps1 @@ -225,6 +225,7 @@ function dl_with_cache_aria2($app, $version, $manifest, $architecture, $dir, $co "--min-tls-version=TLSv1.2" "--stop-with-process=$PID" "--continue" + "--summary-interval 0" ) if($cookies) { @@ -282,21 +283,29 @@ function dl_with_cache_aria2($app, $version, $manifest, $architecture, $dir, $co # handle aria2 console output Write-Host "Starting download with aria2 ..." - $prefix = "Download: " + Invoke-Expression $aria2 | ForEach-Object { - if([String]::IsNullOrWhiteSpace($_)) { - # skip blank lines - return - } - Write-Host $prefix -NoNewline - if($_.StartsWith('(OK):')) { - Write-Host $_ -f Green - } elseif($_.StartsWith('[') -and $_.EndsWith(']')) { - Write-Host $_ -f Cyan - } else { - Write-Host $_ -f Gray + # Skip blank lines + if ([String]::IsNullOrWhiteSpace($_)) { return } + + # Prevent potential overlaping of text when one line is shorter + $len = $Host.UI.RawUI.WindowSize.Width - $_.Length - 20 + $blank = if ($len -gt 0) { ' ' * $len } else { '' } + $color = 'Gray' + + if ($_.StartsWith('(OK):')) { + $noNewLine = $true + $color = 'Green' + } elseif ($_.StartsWith('[') -and $_.EndsWith(']')) { + $noNewLine = $true + $color = 'Cyan' + } elseif ($_.StartsWith('Download Results:')) { + $noNewLine = $false } + + Write-Host "`rDownload: $_$blank" -ForegroundColor $color -NoNewline:$noNewLine } + Write-Host '' if($lastexitcode -gt 0) { error "Download failed! (Error $lastexitcode) $(aria_exit_code $lastexitcode)" @@ -365,7 +374,41 @@ function dl($url, $to, $cookies, $progress) { } } - $wres = $wreq.getresponse() + try { + $wres = $wreq.GetResponse() + } catch [System.Net.WebException] { + $exc = $_.Exception + $handledCodes = @( + [System.Net.HttpStatusCode]::MovedPermanently, # HTTP 301 + [System.Net.HttpStatusCode]::Found, # HTTP 302 + [System.Net.HttpStatusCode]::SeeOther, # HTTP 303 + [System.Net.HttpStatusCode]::TemporaryRedirect # HTTP 307 + ) + + # Only handle redirection codes + $redirectRes = $exc.Response + if ($handledCodes -notcontains $redirectRes.StatusCode) { + throw $exc + } + + # Get the new location of the file + if ((-not $redirectRes.Headers) -or ($redirectRes.Headers -notcontains 'Location')) { + throw $exc + } + + $newUrl = $redirectRes.Headers['Location'] + info "Following redirect to $newUrl..." + + # Handle manual file rename + if ($url -like '*#/*') { + $null, $postfix = $url -split '#/' + $newUrl = "$newUrl#/$postfix" + } + + dl $newUrl $to $cookies $progress + return + } + $total = $wres.ContentLength if($total -eq -1 -and $wreq -is [net.ftpwebrequest]) { $total = ftp_file_size($url) @@ -939,13 +982,17 @@ function find_dir_or_subdir($path, $dir) { function env_add_path($manifest, $dir, $global, $arch) { $env_add_path = arch_specific 'env_add_path' $manifest $arch - $env_add_path | Where-Object { $_ } | ForEach-Object { - $path_dir = Join-Path $dir $_ + if ($env_add_path) { + # GH-3785: Add path in ascending order. + [Array]::Reverse($env_add_path) + $env_add_path | Where-Object { $_ } | ForEach-Object { + $path_dir = Join-Path $dir $_ - if (!(is_in_dir $dir $path_dir)) { - abort "Error in manifest: env_add_path '$_' is outside the app directory." + if (!(is_in_dir $dir $path_dir)) { + abort "Error in manifest: env_add_path '$_' is outside the app directory." + } + add_first_in_path $path_dir $global } - add_first_in_path $path_dir $global } } @@ -1022,11 +1069,11 @@ function prune_installed($apps, $global) { # check whether the app failed to install function failed($app, $global) { - $ver = current_version $app $global - if(!$ver) { return $false } - $info = install_info $app $ver $global - if(!$info) { return $true } - return $false + if (is_directory (appdir $app $global)) { + return !(install_info $app (current_version $app $global) $global) + } else { + return $false + } } function ensure_none_failed($apps, $global) { diff --git a/lib/manifest.ps1 b/lib/manifest.ps1 index 391c928f4..7b0a57d1d 100644 --- a/lib/manifest.ps1 +++ b/lib/manifest.ps1 @@ -59,8 +59,20 @@ function install_info($app, $version, $global) { } function default_architecture { - if ([Environment]::Is64BitOperatingSystem) { return "64bit" } - "32bit" + $arch = get_config 'default-architecture' + $system = if ([Environment]::Is64BitOperatingSystem) { '64bit' } else { '32bit' } + if ($null -eq $arch) { + $arch = $system + } else { + try { + $arch = ensure_architecture $arch + } catch { + warn 'Invalid default architecture configured. Determining default system architecture' + $arch = $system + } + } + + return $arch } function arch_specific($prop, $manifest, $architecture) { diff --git a/libexec/scoop-checkup.ps1 b/libexec/scoop-checkup.ps1 index df4a8b6ec..d515469cd 100644 --- a/libexec/scoop-checkup.ps1 +++ b/libexec/scoop-checkup.ps1 @@ -12,6 +12,7 @@ $issues += !(check_windows_defender $false) $issues += !(check_windows_defender $true) $issues += !(check_main_bucket) $issues += !(check_long_paths) +$issues += !(check_envs_requirements) if (!(Test-HelperInstalled -Helper 7zip)) { error "'7-Zip' is not installed! It's required for unpacking most programs. Please Run 'scoop install 7zip' or 'scoop install 7zip-zstd'." diff --git a/libexec/scoop-hold.ps1 b/libexec/scoop-hold.ps1 index e5be3ef28..e21b8d8c0 100644 --- a/libexec/scoop-hold.ps1 +++ b/libexec/scoop-hold.ps1 @@ -27,7 +27,7 @@ $apps | ForEach-Object { $json | Get-Member -MemberType Properties | ForEach-Object { $install.Add($_.Name, $json.($_.Name))} $install.hold = $true save_install_info $install $dir - success "$app is now locked and can not be updated anymore." + success "$app is now held and can not be updated anymore." } exit $exitcode diff --git a/libexec/scoop-info.ps1 b/libexec/scoop-info.ps1 index bf24d7c0f..e13119a94 100644 --- a/libexec/scoop-info.ps1 +++ b/libexec/scoop-info.ps1 @@ -35,6 +35,7 @@ if (!$manifest) { } $install = install_info $app $status.version $global +$status.installed = $install.bucket -eq $bucket $version_output = $manifest.version if (!$manifest_file) { $manifest_file = manifest_path $app $bucket diff --git a/libexec/scoop-list.ps1 b/libexec/scoop-list.ps1 index de366ddfa..44c45a741 100644 --- a/libexec/scoop-list.ps1 +++ b/libexec/scoop-list.ps1 @@ -32,7 +32,7 @@ if($apps) { if (!$install_info) { Write-Host ' *failed*' -ForegroundColor DarkRed -NoNewline } if ($install_info.hold) { Write-Host ' *hold*' -ForegroundColor DarkMagenta -NoNewline } - if ($install_info.bucket -and ($install_info.bucket -ne 'main')) { + if ($install_info.bucket) { write-host -f Yellow " [$($install_info.bucket)]" -NoNewline } elseif ($install_info.url) { write-host -f Yellow " [$($install_info.url)]" -NoNewline diff --git a/libexec/scoop-unhold.ps1 b/libexec/scoop-unhold.ps1 index 0799b6d17..a6d216d29 100644 --- a/libexec/scoop-unhold.ps1 +++ b/libexec/scoop-unhold.ps1 @@ -27,7 +27,7 @@ $apps | ForEach-Object { $json | Get-Member -MemberType Properties | ForEach-Object { $install.Add($_.Name, $json.($_.Name))} $install.hold = $null save_install_info $install $dir - success "$app is now unlocked and can be updated again." + success "$app is no longer held and can be updated again." } exit $exitcode diff --git a/libexec/scoop-update.ps1 b/libexec/scoop-update.ps1 index 29512e281..a81edfb86 100644 --- a/libexec/scoop-update.ps1 +++ b/libexec/scoop-update.ps1 @@ -52,16 +52,9 @@ if (!$configBranch) { if(($PSVersionTable.PSVersion.Major) -lt 5) { # check powershell version - # should be deleted after Oct 1, 2019 - If ((Get-Date).ToUniversalTime() -ge "2019-10-01") { - Write-Output "PowerShell 5 or later is required to run Scoop." - Write-Output "Upgrade PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell" - break - } else { - Write-Output "Scoop is going to stop supporting old version of PowerShell." - Write-Output "Please upgrade to PowerShell 5 or later version before Oct 1, 2019 UTC." - Write-Output "Guideline: https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell" - } + Write-Output "PowerShell 5 or later is required to run Scoop." + Write-Output "Upgrade PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows" + break } function update_scoop() { @@ -319,7 +312,7 @@ if (!$apps) { $outdated += applist $app $global write-host -f yellow ("$app`: $($status.version) -> $($status.latest_version){0}" -f ('',' (global)')[$global]) } else { - warn "'$app' is locked to version $($status.version)" + warn "'$app' is held to version $($status.version)" } } elseif ($apps_param -ne '*') { write-host -f green "$app`: $($status.version) (latest version)" diff --git a/schema.json b/schema.json index 788aa80b2..6ace8898d 100644 --- a/schema.json +++ b/schema.json @@ -260,6 +260,10 @@ }, "useragent": { "type": "string" + }, + "script": { + "$ref": "#/definitions/stringOrArrayOfStrings", + "description": "Custom PowerShell script to retrieve application version using more complex approach." } }, "type": "object" diff --git a/supporting/shims/71/checksum.sha256 b/supporting/shims/71/checksum.sha256 new file mode 100644 index 000000000..37a3bd111 --- /dev/null +++ b/supporting/shims/71/checksum.sha256 @@ -0,0 +1 @@ +70d4690b8ac3b3f715f537cdea6e07a39fda4bc0347bf6b958e4f3ff2f0e04d4 shim.exe diff --git a/supporting/shims/71/checksum.sha512 b/supporting/shims/71/checksum.sha512 new file mode 100644 index 000000000..116bcee6e --- /dev/null +++ b/supporting/shims/71/checksum.sha512 @@ -0,0 +1 @@ +ecde07b32192846c4885cf4d2208eedc170765ea115ae49b81509fed0ce474e21064100bb2f3d815ee79f1c12463d32ef013d4182647eae71855cd18e4196176 shim.exe diff --git a/supporting/shims/71/shim.exe b/supporting/shims/71/shim.exe new file mode 100644 index 000000000..a81263707 Binary files /dev/null and b/supporting/shims/71/shim.exe differ diff --git a/supporting/shims/kiennq/.gitignore b/supporting/shims/kiennq/.gitignore new file mode 100644 index 000000000..d271c6ed4 --- /dev/null +++ b/supporting/shims/kiennq/.gitignore @@ -0,0 +1,2 @@ +*.zip +*.bak diff --git a/supporting/shims/kiennq/Makefile b/supporting/shims/kiennq/Makefile new file mode 100644 index 000000000..da872b946 --- /dev/null +++ b/supporting/shims/kiennq/Makefile @@ -0,0 +1,52 @@ + +VER?=2.2.1 +ZIP=shimexe-$(VER).zip +URL?=https://github.com/kiennq/scoop-better-shimexe/releases/download/$(VER)/$(ZIP) +LATEST_URL?=https://github.com/kiennq/scoop-better-shimexe/releases/latest +NEWVER=$(shell cat version.txt) + +all: verify ## make download unzip verify + +version.txt: + @curl --max-redirs 0 -s -D - -o /dev/null $(LATEST_URL) | grep -i ^location | sed -E -e "s|.*/([^/]+)$$|\1|" >version.txt + @printf "%s " "Latest version is:" + @cat version.txt + +check: version.txt ## Check the version number in version.txt and update if needed + +bump: check ## Bump version number in Makefile + @rm -f Makefile.bak + @sed -i.bak -e 's|=$(VER)|=$(NEWVER)|' Makefile + @cmp --quiet Makefile{,.bak} || echo "Makefile bumped from $(VER) to $(NEWVER)" + +$(ZIP): version.txt + curl -L -s -o $(ZIP) $(URL) + @touch $@ + +download: $(ZIP) ## Download shim from https://github.com/kiennq/scoop-better-shimexe + +shim.exe: $(ZIP) + unzip -z -j -o $(ZIP) + @touch $@ + +unzip: shim.exe ## Unzip download + +verify: shim.exe ## Verify SHA256 checksum for shim.exe + sed -e "s|bin/||" checksum.sha256 | sha256sum -c + +clean: ## Clean .zip files + rm -f *.zip + +help: ## Display help text + @printf "%-8s %s\n" Target Description + @printf "%-8s %s\n" '--------' '------------------------------------------' + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-8s %s\n", $$1, $$2}' + +.PHONY: all +.PHONY: bump +.PHONY: check +.PHONY: clean +.PHONY: download +.PHONY: help +.PHONY: unzip +.PHONY: verify diff --git a/supporting/shims/kiennq/checksum.sha256 b/supporting/shims/kiennq/checksum.sha256 new file mode 100644 index 000000000..32944ff85 --- /dev/null +++ b/supporting/shims/kiennq/checksum.sha256 @@ -0,0 +1 @@ +aa685053f4a5c0e7145f2a27514c8a56ceae25b0824062326f04037937caa558 bin/shim.exe diff --git a/supporting/shims/kiennq/checksum.sha512 b/supporting/shims/kiennq/checksum.sha512 new file mode 100644 index 000000000..c7014db2a --- /dev/null +++ b/supporting/shims/kiennq/checksum.sha512 @@ -0,0 +1 @@ +67c605c8163869d8ef8153c64eb09b82645cbae8228928c0fef944d0259a7b2d3791ecf4b4b01e23566916a878ee7977bfc1a59846bccf3c63bd6a1cf4f521b5 bin/shim.exe diff --git a/supporting/shims/kiennq/shim.exe b/supporting/shims/kiennq/shim.exe new file mode 100644 index 000000000..743c9f105 Binary files /dev/null and b/supporting/shims/kiennq/shim.exe differ diff --git a/supporting/shims/kiennq/version.txt b/supporting/shims/kiennq/version.txt new file mode 100644 index 000000000..c043eea77 --- /dev/null +++ b/supporting/shims/kiennq/version.txt @@ -0,0 +1 @@ +2.2.1