Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to skip hash validation and error message improvements #2260

Merged
merged 7 commits into from
Jun 14, 2018
Merged
22 changes: 22 additions & 0 deletions lib/buckets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
12 changes: 11 additions & 1 deletion lib/core.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ function movedir($from, $to) {

$out = robocopy "$from" "$to" /e /move
if($lastexitcode -ge 8) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps:

throw "Could not find '$(fname $from)'! (error $lastexitcode)"

?

throw "Error moving directory: `n$out"
throw "Could not find '$(fname $from)'!"
}
}

Expand Down Expand Up @@ -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) {
Expand Down
47 changes: 33 additions & 14 deletions lib/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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" })."
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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." }

Expand Down Expand Up @@ -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")
}
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -473,6 +491,7 @@ function compute_hash($file, $algname) {
if($fs) { $fs.dispose() }
if($alg) { $alg.dispose() }
}
return ''
}

function cmd_available($cmd) {
Expand Down
6 changes: 1 addition & 5 deletions libexec/scoop-info.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 6 additions & 4 deletions libexec/scoop-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
24 changes: 13 additions & 11 deletions libexec/scoop-update.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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