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

Document changing host for rotating-url and assume same version based only on checksum and file size #439

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@ The version number for the latest version can be detected in two ways:
URL for the latest version, and the first match group is taken to be the
version. (This follows the convention used by
[`debian/watch`](https://wiki.debian.org/debian/watch) files.)
* If the application download is behind load-balanced URL that changes regularly
(e.g. `https://stable.dl2.example.com` and `dl.example.com`),
the regex needs to be adjusted to extract the version number in all cases.
Otherwise this project assumes a new version was published.
* You can use a non-capturing group for this use-case. For the use case above, use
the pattern below to allow downloads from:
* `https://dl.example.com/foo-v1.9.tar.gz`
* `https://stable.dl1.example.com/foo-v1.9.tar.gz`
* ...
```json
"x-checker-data": {
"type": "rotating-url",
"url": "http://example.com/last-version",
"pattern": "https://(?:dl|stable.dl\\d).example.com/foo-v([0-9.]+).tar.gz"
}
```

Some upstream vendors may add unwanted GET query parameters to
the download URL, such as identifiers for counting unique downloads.
Expand Down
27 changes: 24 additions & 3 deletions src/checkers/urlchecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ def extract_version(checker_data, url):
return m.group(1)


def is_same_version(checker_data, current_url, new_version):
"""
Check if the new application version is the same with the current one. If the
version number could be extracted, those strings are compared with each other
to be resilient against load-balanced urls pointing to the same file.
"""
if new_version.version is None:
# No pattern given or failed parsing the new version, so check only
# if the url is different
return current_url == new_version.url

current_version_string = extract_version(checker_data, current_url)
if current_version_string is None:
# If the pattern failed to apply to the old/current version,
# check again only the url. Otherwise we would compare None values
return current_url == new_version.url

return current_version_string == new_version.version


class URLChecker(Checker):
PRIORITY = 99
CHECKER_DATA_TYPE = "rotating-url"
Expand Down Expand Up @@ -138,9 +158,10 @@ async def check(self, external_data: ExternalBase):
if not is_rotating:
new_version = new_version._replace(url=url) # pylint: disable=no-member

same_version = is_same_version(
external_data.checker_data, external_data.current_version.url, new_version
)
external_data.set_new_version(
new_version,
is_update=(
is_rotating and external_data.current_version.url != new_version.url
),
is_update=is_rotating and not same_version,
)
6 changes: 2 additions & 4 deletions src/lib/externaldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,8 @@ def json(self) -> t.Dict[str, t.Any]:
def matches(self, other: ExternalFile):
for i in (self, other):
assert i.checksum is None or isinstance(i.checksum, MultiDigest), i.checksum
return (
self.url == other.url
and self.checksum == other.checksum
and (self.size is None or other.size is None or self.size == other.size)
return self.checksum == other.checksum and (
self.size is None or other.size is None or self.size == other.size
)

def is_same_version(self, other: ExternalFile):
Expand Down
Loading