Digital-Sapphire / PyUpdater

Pyinstaller auto-update library
https://www.pyupdater.org
459 stars 90 forks source link

get_highest_version() returns wrong version for pre-release channels #315

Closed dennisvang closed 2 years ago

dennisvang commented 2 years ago

Description and cause

The get_highest_version() returns the wrong version, because it does not recognize the numeric pre-release value from the internal version representation.

This is due to dsdev-utils 1.3 only supporting PEP440 versions:

Although the internal version format N.N.N.N.N is allowed by PEP440, it does not contain a valid PEP440 pre-release segment, such as 'a' or 'b'. As a result all internal versions are interpreted as final release.

How to reproduce

Using pyupdater 4.0-2-g7093d76 on python 3.8.7:

Run TestChannelStrict, and see it fail.

Or, moving directly to the source of the problem:

from dsdev_utils.helpers import Version
internal_version = '0.0.0.0.0'
assert str(Version(internal_version)) == internal_version  # Version returns '0.0.0.2.0'

Quick fix

Although the problem is ultimately caused by dsdev_utils, I guess it makes more sense to coerce all internal versions into PEP440 compliance on the pyupdater side, before passing them to dsdev_utils.helpers.Version.

Long term fix

Perhaps even work towards dropping dsdev_utils.helpers.Version altogether, and using packaging.version.Version directly?

dennisvang commented 2 years ago

Turns out the use of dsdev_utils.helpers.Version also causes trouble in the Patcher.__init__().

Basically here's what happens if we boil down this and this:

current_version = Version(str(Version("<user supplied version string>")))
dennisvang commented 2 years ago

The deeper I dive into this, the more I am in favor of dropping the dsdev_utils.helpers.Version altogether, including its "internal" version format (e.g. 1.0.0.2.0), which is used in pyupdater config and version files.

Instead I would use packaging.version.Version natively, only use the full Version objects for comparisons (not strings), and use its __str__() output as the version key in pyupdater files, instead of the current "internal" version.

For backward compatibility we need to make sure that

JessicaTegner commented 2 years ago

It's again, as I've mentioned, we need some form of version for the metadata / config files, so we can add stuff like this. What do you think on this @dennisvang