-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add version variables to autoupdate.hash.regex #2996
Add version variables to autoupdate.hash.regex #2996
Conversation
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
} |
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. |
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".
Add version variables to
autoupdate.hash.regex
for 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 providesRELEASES
andRELEASES-x64
files that give sha1 hash of nupkg files. Unfortunately inRELEASES-x64
the nupkg file name isatom-1.34.0-full.nupkg
without-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: