Add version variables to autoupdate.hash.regex#2996
Merged
r15ch13 merged 3 commits intoScoopInstaller:masterfrom Jan 17, 2019
Merged
Conversation
Member
|
How about adding a function substitute($entity, [Hashtable] $params, [Bool]$regexEscape = $false) {
if ($entity -is [Array]) {
return $entity | ForEach-Object { substitute $_ $params $regexEscape}
} elseif ($entity -is [String]) {
$params.GetEnumerator() | ForEach-Object {
if($regexEscape -eq $false -or $null -eq $_.Value) {
$entity = $entity.Replace($_.Name, $_.Value)
} else {
$entity = $entity.Replace($_.Name, [Regex]::Escape($_.Value))
}
}
return $entity
}
}And instead of using diff --git a/lib/autoupdate.ps1 b/lib/autoupdate.ps1
index 5b77e759..b14e2d4e 100644
--- a/lib/autoupdate.ps1
+++ b/lib/autoupdate.ps1
@@ -29,7 +29,7 @@ function find_hash_in_rdf([String] $url, [String] $filename) {
return format_hash $digest.sha256
}
-function find_hash_in_textfile([String] $url, [String] $basename, [String] $regex) {
+function find_hash_in_textfile([String] $url, [Hashtable] $substitutions, [String] $regex = '^([a-fA-F0-9]+)$') {
$hashfile = $null
try {
@@ -43,15 +43,8 @@ function find_hash_in_textfile([String] $url, [String] $basename, [String] $rege
return
}
- # find single line hash in $hashfile (will be overridden by $regex)
- if ($regex.Length -eq 0) {
- $normalRegex = "^([a-fA-F0-9]+)$"
- } else {
- $normalRegex = $regex
- }
-
- $normalRegex = substitute $normalRegex @{'$basename' = [regex]::Escape($basename)}
- if ($hashfile -match $normalRegex) {
+ $regex = substitute $regex $substitutions $true
+ if ($hashfile -match $regex) {
$hash = $matches[1] -replace ' ',''
}
@@ -70,7 +63,7 @@ function find_hash_in_textfile([String] $url, [String] $basename, [String] $rege
# find hash with filename in $hashfile (will be overridden by $regex)
if ($hash.Length -eq 0 -and $regex.Length -eq 0) {
$filenameRegex = "([a-fA-F0-9]{32,128})[\x20\t]+.*`$basename(?:[\x20\t]+\d+)?"
- $filenameRegex = substitute $filenameRegex @{'$basename' = [regex]::Escape($basename)}
+ $filenameRegex = substitute $filenameRegex $substitutions $true
if ($hashfile -match $filenameRegex) {
$hash = $matches[1]
}
@@ -142,12 +135,12 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
$hashmode = $config.mode
$basename = url_remote_filename($url)
- $hashfile_url = substitute $config.url @{
- '$url' = (strip_fragment $url);
- '$baseurl' = (strip_filename (strip_fragment $url)).TrimEnd('/')
- '$basename' = $basename
- }
- $hashfile_url = substitute $hashfile_url $substitutions
+ $substitutions = $substitutions.Clone()
+ $substitutions.Add('$url', (strip_fragment $url))
+ $substitutions.Add('$baseurl', (strip_filename (strip_fragment $url)).TrimEnd('/'))
+ $substitutions.Add('$basename', $basename)
+
+ $hashfile_url = substitute $config.url $substitutions
if($hashfile_url) {
write-host -f DarkYellow 'Searching hash for ' -NoNewline
write-host -f Green $(url_remote_filename $url) -NoNewline
@@ -176,22 +169,16 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
$regex = $config.regex
}
- $substitutions.GetEnumerator() | ForEach-Object {
- if ($_.Value) {
- $regex = $regex.Replace($_.Name, [regex]::Escape($_.Value))
- }
- }
-
if (!$hashfile_url -and $url -match "(?:downloads\.)?sourceforge.net\/projects?\/(?<project>[^\/]+)\/(?:files\/)?(?<file>.*)") {
$hashmode = 'sourceforge'
# change the URL because downloads.sourceforge.net doesn't have checksums
$hashfile_url = (strip_filename (strip_fragment "https://sourceforge.net/projects/$($matches['project'])/files/$($matches['file'])")).TrimEnd('/')
- $hash = find_hash_in_textfile $hashfile_url $basename '"$basename":.*?"sha1":\s"([a-fA-F0-9]{40})"'
+ $hash = find_hash_in_textfile $hashfile_url $substitutions '"$basename":.*?"sha1":\s"([a-fA-F0-9]{40})"'
}
switch ($hashmode) {
'extract' {
- $hash = find_hash_in_textfile $hashfile_url $basename $regex
+ $hash = find_hash_in_textfile $hashfile_url $substitutions $regex
}
'json' {
$hash = find_hash_in_json $hashfile_url $basename $jsonpath
@@ -202,7 +189,7 @@ function get_hash_for_app([String] $app, $config, [String] $version, [String] $u
'metalink' {
$hash = find_hash_in_headers $url
if(!$hash) {
- $hash = find_hash_in_textfile "$url.meta4"
+ $hash = find_hash_in_textfile "$url.meta4" $substitutions
}
}
}
diff --git a/lib/core.ps1 b/lib/core.ps1
index 2205ce08..25980198 100644
--- a/lib/core.ps1
+++ b/lib/core.ps1
@@ -612,12 +612,16 @@ function is_scoop_outdated() {
return $last_update.AddHours(3) -lt $now.ToLocalTime()
}
-function substitute($entity, [Hashtable] $params) {
+function substitute($entity, [Hashtable] $params, [Bool]$regexEscape = $false) {
if ($entity -is [Array]) {
- return $entity | ForEach-Object { substitute $_ $params }
+ return $entity | ForEach-Object { substitute $_ $params $regexEscape}
} elseif ($entity -is [String]) {
$params.GetEnumerator() | ForEach-Object {
- $entity = $entity.Replace($_.Name, $_.Value)
+ if($regexEscape -eq $false -or $null -eq $_.Value) {
+ $entity = $entity.Replace($_.Name, $_.Value)
+ } else {
+ $entity = $entity.Replace($_.Name, [Regex]::Escape($_.Value))
+ }
}
return $entity
} |
Member
Author
|
Thanks @r15ch13, I've just made a minimal change to achieve my goal, and your implement are more systemic and readable. I've adopted your advise and extended it to JSONPath (though may not needed now). I've tested the code on atom's nupkg version (for regex), nuget (for jsonpath checkver) and openssl (for jsonpath hash extraction), everything is okay, the new logic works well and the old logic is not affected. It's good for me now, and if merged, I'll submit a pr about new hash extract method of atom. |
r15ch13
pushed a commit
that referenced
this pull request
Jan 21, 2019
Fix a bug introduced in #2996 that single line hash extraction is broken. When `find_hash_in_textfile()` is called in `get_hash_for_app()`, `$null` is used as `$regex` value for default single line hash extraction and the default value (`'^([a-fA-F0-9]+)$'`) is overriden, which leads a error of "hash not found".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add version variables to
autoupdate.hash.regexfor some hash extract situations.The idea is from Atom's nupkg hash extraction. Atom's releases page provides nupkg named
atom-1.34.0-full.nupkg(for i686) andatom-x64-1.34.0-full.nupkg(for x64_86), and it also providesRELEASESandRELEASES-x64files that give sha1 hash of nupkg files. Unfortunately inRELEASES-x64the nupkg file name isatom-1.34.0-full.nupkgwithout-x64.I haven't found some method to write a regex to extract the hash without
$version, butget_hash_for_app()only support `$basename$ in regex. So I add the code, and it works for the following hash extract: