mirror of
https://github.com/ScoopInstaller/Scoop.git
synced 2026-10-02 01:59:02 +00:00
Option to skip hash validation and error message improvements (#2260)
* Add show_app() function for displaying `app/bucket@version` * Add option to skip hash check on install/update Allows users to install an app when the manifest provides an outdated hash * Show filename instead of robocopy output when moving fails * Add new_issue_msg() for nicer error messages (with link bucket repo) - returns a message with a link to the buckets GitHub repository - clicking on the link opens a new issues with a predefined title * Use new_issue_msg() for errors while moving files - this removes the unreadable robocopy error dumps * Use new_issue_msg() error handling for check_hash() * Show robocopy exit code
This commit is contained in:
@@ -42,3 +42,25 @@ function find_manifest($app, $bucket) {
|
||||
if($manifest) { return $manifest, $bucket }
|
||||
}
|
||||
}
|
||||
|
||||
function new_issue_msg($app, $bucket, $title, $body) {
|
||||
$app, $manifest, $bucket, $url = locate $app $bucket
|
||||
$url = known_bucket_repo $bucket
|
||||
if($manifest -and $null -eq $url -and $null -eq $bucket) {
|
||||
$url = 'https://github.com/lukesampson/scoop'
|
||||
}
|
||||
if(!$url) {
|
||||
return "Please contact the bucket maintainer!"
|
||||
}
|
||||
|
||||
$title = [System.Web.HttpUtility]::UrlEncode("$app@$($manifest.version): $title")
|
||||
$body = [System.Web.HttpUtility]::UrlEncode($body)
|
||||
$url = $url -replace '^(.*).git$','$1'
|
||||
$url = "$url/issues/new?title=$title"
|
||||
if($body) {
|
||||
$url += "&body=$body"
|
||||
}
|
||||
|
||||
$msg = "`nPlease create a new issue by using the following link and paste your console output:"
|
||||
return "$msg`n$url"
|
||||
}
|
||||
|
||||
+11
-1
@@ -246,7 +246,7 @@ function movedir($from, $to) {
|
||||
|
||||
$out = robocopy "$from" "$to" /e /move
|
||||
if($lastexitcode -ge 8) {
|
||||
throw "Error moving directory: `n$out"
|
||||
throw "Could not find '$(fname $from)'! (error $lastexitcode)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,6 +501,16 @@ function parse_app([string] $app) {
|
||||
return $app, $null, $null
|
||||
}
|
||||
|
||||
function show_app($app, $bucket, $version) {
|
||||
if($bucket) {
|
||||
$app = "$bucket/$app"
|
||||
}
|
||||
if($version) {
|
||||
$app = "$app@$version"
|
||||
}
|
||||
return $app
|
||||
}
|
||||
|
||||
function last_scoop_update() {
|
||||
$last_update = (scoop config lastupdate)
|
||||
if(!$last_update) {
|
||||
|
||||
+33
-14
@@ -9,10 +9,9 @@ function nightly_version($date, $quiet = $false) {
|
||||
"nightly-$date_str"
|
||||
}
|
||||
|
||||
function install_app($app, $architecture, $global, $suggested, $use_cache = $true) {
|
||||
function install_app($app, $architecture, $global, $suggested, $use_cache = $true, $check_hash = $true) {
|
||||
$app, $bucket, $null = parse_app $app
|
||||
$app, $manifest, $bucket, $url = locate $app $bucket
|
||||
$check_hash = $true
|
||||
|
||||
if(!$manifest) {
|
||||
abort "Couldn't find manifest for '$app'$(if($url) { " at the URL $url" })."
|
||||
@@ -41,7 +40,7 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
|
||||
$original_dir = $dir # keep reference to real (not linked) directory
|
||||
$persist_dir = persistdir $app $global
|
||||
|
||||
$fname = dl_urls $app $version $manifest $architecture $dir $use_cache $check_hash
|
||||
$fname = dl_urls $app $version $manifest $bucket $architecture $dir $use_cache $check_hash
|
||||
unpack_inno $fname $manifest $dir
|
||||
pre_install $manifest $architecture
|
||||
run_installer $fname $manifest $architecture $dir $global
|
||||
@@ -272,7 +271,7 @@ function dl_progress($read, $total, $url) {
|
||||
[console]::SetCursorPosition($left, $top)
|
||||
}
|
||||
|
||||
function dl_urls($app, $version, $manifest, $architecture, $dir, $use_cache = $true, $check_hash = $true) {
|
||||
function dl_urls($app, $version, $manifest, $bucket, $architecture, $dir, $use_cache = $true, $check_hash = $true) {
|
||||
# we only want to show this warning once
|
||||
if(!$use_cache) { warn "Cache is being ignored." }
|
||||
|
||||
@@ -312,12 +311,16 @@ function dl_urls($app, $version, $manifest, $architecture, $dir, $use_cache = $t
|
||||
$fname = $data.$url.fname
|
||||
|
||||
if($check_hash) {
|
||||
$ok, $err = check_hash "$dir\$fname" $url $manifest $architecture
|
||||
$manifest_hash = hash_for_url $manifest $url $arch
|
||||
$ok, $err = check_hash "$dir\$fname" $manifest_hash $(show_app $app $bucket)
|
||||
if(!$ok) {
|
||||
# rm cached
|
||||
error $err
|
||||
$cached = cache_path $app $version $url
|
||||
if(test-path $cached) { Remove-Item -force $cached }
|
||||
abort $err
|
||||
if(test-path $cached) {
|
||||
# rm cached file
|
||||
Remove-Item -force $cached
|
||||
}
|
||||
abort $(new_issue_msg $app $bucket "hash check failed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +363,13 @@ function dl_urls($app, $version, $manifest, $architecture, $dir, $use_cache = $t
|
||||
}
|
||||
# fails if zip contains long paths (e.g. atom.json)
|
||||
#cp "$dir\_tmp\$extract_dir\*" "$dir\$extract_to" -r -force -ea stop
|
||||
movedir "$dir\_tmp\$extract_dir" "$dir\$extract_to"
|
||||
try {
|
||||
movedir "$dir\_tmp\$extract_dir" "$dir\$extract_to"
|
||||
}
|
||||
catch {
|
||||
error $_
|
||||
abort $(new_issue_msg $app $bucket "extract_dir error")
|
||||
}
|
||||
|
||||
if(test-path "$dir\_tmp") { # might have been moved by movedir
|
||||
try {
|
||||
@@ -430,11 +439,10 @@ function hash_for_url($manifest, $url, $arch) {
|
||||
}
|
||||
|
||||
# returns (ok, err)
|
||||
function check_hash($file, $url, $manifest, $arch) {
|
||||
$hash = hash_for_url $manifest $url $arch
|
||||
function check_hash($file, $hash, $app_name) {
|
||||
if(!$hash) {
|
||||
warn "Warning: No hash in manifest. SHA256 is:`n $(compute_hash (fullpath $file) 'sha256')"
|
||||
return $true
|
||||
return $true, $null
|
||||
}
|
||||
|
||||
write-host "Checking hash of $(url_remote_filename $url)... " -nonewline
|
||||
@@ -450,11 +458,21 @@ function check_hash($file, $url, $manifest, $arch) {
|
||||
|
||||
$actual = compute_hash (fullpath $file) $type
|
||||
|
||||
$expected = $expected.ToLower()
|
||||
$actual = $actual.ToLower()
|
||||
|
||||
if($actual -ne $expected) {
|
||||
return $false, "Hash check failed for '$url'.`nExpected:`n $($expected)`nActual:`n $($actual)"
|
||||
$msg = "Hash check failed!`n"
|
||||
$msg += "App: $app_name`n"
|
||||
$msg += "URL: $url`n"
|
||||
if($expected -or $actual) {
|
||||
$msg += "Expected: $expected`n"
|
||||
$msg += "Actual: $actual"
|
||||
}
|
||||
return $false, $msg
|
||||
}
|
||||
write-host "ok."
|
||||
return $true
|
||||
return $true, $null
|
||||
}
|
||||
|
||||
function compute_hash($file, $algname) {
|
||||
@@ -473,6 +491,7 @@ function compute_hash($file, $algname) {
|
||||
if($fs) { $fs.dispose() }
|
||||
if($alg) { $alg.dispose() }
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function cmd_available($cmd) {
|
||||
|
||||
@@ -20,11 +20,7 @@ $status = app_status $app $global
|
||||
$manifest, $bucket = find_manifest $app $bucket
|
||||
|
||||
if (!$manifest) {
|
||||
if ($bucket) {
|
||||
abort "Could not find manifest for '$bucket/$app'."
|
||||
} else {
|
||||
abort "Could not find manifest for '$app'."
|
||||
}
|
||||
abort "Could not find manifest for '$(show_app $app $bucket)'."
|
||||
}
|
||||
|
||||
$install = install_info $app $status.version $global
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
# When installing from your computer, you can leave the .json extension off if you like.
|
||||
#
|
||||
# Options:
|
||||
# -a, --arch <32bit|64bit> Use the specified architecture, if the app supports it
|
||||
# -g, --global Install the app globally
|
||||
# -i, --independent Don't install dependencies automatically
|
||||
# -k, --no-cache Don't use the download cache
|
||||
# -g, --global Install the app globally
|
||||
# -s, --skip Skip hash validation (use with caution!)
|
||||
# -a, --arch <32bit|64bit> Use the specified architecture, if the app supports it
|
||||
|
||||
. "$psscriptroot\..\lib\core.ps1"
|
||||
. "$psscriptroot\..\lib\manifest.ps1"
|
||||
@@ -46,10 +47,11 @@ function is_installed($app, $global) {
|
||||
return $false
|
||||
}
|
||||
|
||||
$opt, $apps, $err = getopt $args 'gika:' 'global', 'independent', 'no-cache', 'arch='
|
||||
$opt, $apps, $err = getopt $args 'gfiksa:' 'global', 'force', 'independent', 'no-cache', 'skip', 'arch='
|
||||
if($err) { "scoop install: $err"; exit 1 }
|
||||
|
||||
$global = $opt.g -or $opt.global
|
||||
$check_hash = !($opt.s -or $opt.skip)
|
||||
$independent = $opt.i -or $opt.independent
|
||||
$use_cache = !($opt.k -or $opt.'no-cache')
|
||||
$architecture = default_architecture
|
||||
@@ -117,7 +119,7 @@ $skip | Where-Object { $explicit_apps -contains $_} | ForEach-Object {
|
||||
}
|
||||
|
||||
$suggested = @{};
|
||||
$apps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache }
|
||||
$apps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }
|
||||
|
||||
show_suggestions $suggested
|
||||
|
||||
|
||||
+13
-11
@@ -6,11 +6,13 @@
|
||||
# You can use '*' in place of <app> to update all apps.
|
||||
#
|
||||
# Options:
|
||||
# --global, -g Update a globally installed app
|
||||
# --force, -f Force update even when there isn't a newer version
|
||||
# --no-cache, -k Don't use the download cache
|
||||
# --independent, -i Don't install dependencies automatically
|
||||
# --quiet, -q Hide extraneous messages
|
||||
# -f, --force Force update even when there isn't a newer version
|
||||
# -g, --global Update a globally installed app
|
||||
# -i, --independent Don't install dependencies automatically
|
||||
# -k, --no-cache Don't use the download cache
|
||||
# -s, --skip Skip hash validation (use with caution!)
|
||||
# -q, --quiet Hide extraneous messages
|
||||
|
||||
. "$psscriptroot\..\lib\core.ps1"
|
||||
. "$psscriptroot\..\lib\shortcuts.ps1"
|
||||
. "$psscriptroot\..\lib\psmodules.ps1"
|
||||
@@ -26,10 +28,11 @@
|
||||
|
||||
reset_aliases
|
||||
|
||||
$opt, $apps, $err = getopt $args 'gfkqi' 'global','force', 'no-cache', 'quiet', 'independent'
|
||||
$opt, $apps, $err = getopt $args 'gfiksq:' 'global', 'force', 'independent', 'no-cache', 'skip', 'quiet'
|
||||
if($err) { "scoop update: $err"; exit 1 }
|
||||
$global = $opt.g -or $opt.global
|
||||
$force = $opt.f -or $opt.force
|
||||
$check_hash = !($opt.s -or $opt.skip)
|
||||
$use_cache = !($opt.k -or $opt.'no-cache')
|
||||
$quiet = $opt.q -or $opt.quiet
|
||||
$independent = $opt.i -or $opt.independent
|
||||
@@ -104,11 +107,10 @@ function update_scoop() {
|
||||
success 'Scoop was updated successfully!'
|
||||
}
|
||||
|
||||
function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true) {
|
||||
function update($app, $global, $quiet = $false, $independent, $suggested, $use_cache = $true, $check_hash = $true) {
|
||||
$old_version = current_version $app $global
|
||||
$old_manifest = installed_manifest $app $old_version $global
|
||||
$install = install_info $app $old_version $global
|
||||
$check_hash = $true
|
||||
|
||||
# re-use architecture, bucket and url from first install
|
||||
$architecture = ensure_architecture $install.architecture
|
||||
@@ -118,7 +120,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
|
||||
if(!$independent) {
|
||||
# check dependencies
|
||||
$deps = @(deps $app $architecture) | Where-Object { !(installed $_) }
|
||||
$deps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache }
|
||||
$deps | ForEach-Object { install_app $_ $architecture $global $suggested $use_cache $check_hash }
|
||||
}
|
||||
|
||||
$version = latest_version $app $bucket $url
|
||||
@@ -161,7 +163,7 @@ function update($app, $global, $quiet = $false, $independent, $suggested, $use_c
|
||||
# add bucket name it was installed from
|
||||
$app = "$bucket/$app"
|
||||
}
|
||||
install_app $app $architecture $global $suggested $use_cache
|
||||
install_app $app $architecture $global $suggested $use_cache $check_hash
|
||||
}
|
||||
|
||||
if(!$apps) {
|
||||
@@ -210,7 +212,7 @@ if(!$apps) {
|
||||
|
||||
$suggested = @{};
|
||||
# # $outdated is a list of ($app, $global) tuples
|
||||
$outdated | ForEach-Object { update @_ $quiet $independent $suggested $use_cache }
|
||||
$outdated | ForEach-Object { update @_ $quiet $independent $suggested $use_cache $check_hash }
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user