Commit 78ddf912 authored by Aurélien Dunand's avatar Aurélien Dunand Committed by Sébastien Luttringer
Browse files

Handle complex version number

Image version now accept a string of digit separated by dots and extra char as
a qualifier (~ or +).

Example:
1.2.3.4~dev < 1.2.3.4 < 1.2.3.4+dev

Old repositories are still compatible thanks to sqlite type affinity
(https://www.sqlite.org/faq.html#q3

).

We use a package version comparison algorithm for image version comparison
inspired by Debian.

Seblu: Fix typos

Signed-off-by: default avatarSébastien Luttringer <sebastien.luttringer@smartjog.com>
parent b40a9b7f
Loading
Loading
Loading
Loading
+9 −3
Original line number Original line Diff line number Diff line
@@ -4,8 +4,8 @@ INSTALLSYSTEMS VERSIONNING
__________________________
__________________________


A valid version is an integer without dot.
A valid version is an integer without dot.
A version n, may be followed by a ~, to indicate it's inferior to n
A version n may be followed by a ~ to indicate it's inferior to n
A version n, may be followed by a +, to indicate it's superior to n
A version n may be followed by a + to indicate it's superior to n
Any following chars after ~ or + are ignored
Any following chars after ~ or + are ignored


Examples:
Examples:
@@ -17,4 +17,10 @@ Examples:


IMAGES VERSIONNING
IMAGES VERSIONNING
__________________
__________________
A valid version is an integer. Nothing more!
A valid version is a string of digits separated by dots.
 No newline at end of file
A version n may be followed by a ~ to indicate it's inferior to n
A version n may be followed by a + to indicate it's superior to n

Examples:
  1.2.3~dev < 1.2.3 < 1.2.3+dev
  7~dev < 7 < 7+dev
+1 −1
Original line number Original line Diff line number Diff line
@@ -160,7 +160,7 @@ def c_changelog(args):
    '''
    '''
    repoman = load_repositories(args)
    repoman = load_repositories(args)
    for image, repo in get_images(args.pattern, repoman, min=1):
    for image, repo in get_images(args.pattern, repoman, min=1):
        image.changelog.show(int(image.version), args.all_version)
        image.changelog.show(image.version, args.all_version)


def c_check(args):
def c_check(args):
    '''
    '''
+3 −3
Original line number Original line Diff line number Diff line
@@ -69,7 +69,7 @@ class Image(object):
        '''
        '''
        Check if @buf is a valid image version
        Check if @buf is a valid image version
        '''
        '''
        if re.match("^\d+$", buf) is None:
        if re.match("^\d+(\.\d+)*(([~+]).*)?$", buf) is None:
            raise ISError(u"Invalid image version %s" % buf)
            raise ISError(u"Invalid image version %s" % buf)


    @staticmethod
    @staticmethod
@@ -1340,9 +1340,9 @@ class Changelog(dict):
            if line.lstrip().startswith("#"):
            if line.lstrip().startswith("#"):
                continue
                continue
            # try to match a new version
            # try to match a new version
            m = re.match("\[(\d+)\]", line.lstrip())
            m = re.match("\[(\d+(?:\.\d+)*)(?:([~+]).*)?\]", line.lstrip())
            if m is not None:
            if m is not None:
                version = int(m.group(1))
                version = m.group(1)
                self[version] = []
                self[version] = []
                continue
                continue
            # if line are out of a version => invalid format
            # if line are out of a version => invalid format
+6 −5
Original line number Original line Diff line number Diff line
@@ -196,14 +196,15 @@ class Repository(object):


    def last(self, name):
    def last(self, name):
        '''
        '''
        Return last version of name in repo or -1 if not found
        Return last version of name in repo or None if not found
        '''
        '''
        r = self.db.ask("SELECT version FROM image WHERE name = ? ORDER BY version DESC LIMIT 1", (name,)).fetchone()
        r = self.db.ask("SELECT version FROM image WHERE name = ?", (name,)).fetchall()
        # no row => no way
        # no row => no way
        if r is None:
        if r is None:
            return -1
            return None
        f = lambda x,y: x[0] if istools.compare_versions(x[0], y[0]) > 0 else y[0]
        # return last
        # return last
        return r[0]
        return reduce(f, r)


    def add(self, image, delete=False):
    def add(self, image, delete=False):
        '''
        '''
@@ -455,7 +456,7 @@ class Repository(object):
        # is no version take the last
        # is no version take the last
        if version is None:
        if version is None:
            version = self.last(name)
            version = self.last(name)
            if version < 0:
            if version is None:
                raise ISError(u"Unable to find image %s in %s" % (name,
                raise ISError(u"Unable to find image %s in %s" % (name,
                                                                      self.config.name))
                                                                      self.config.name))
        # get file md5 from db
        # get file md5 from db
+1 −1
Original line number Original line Diff line number Diff line
@@ -82,7 +82,7 @@ arrow(u"hostname: %s" % namespace.hostname)
createdb = u"""
createdb = u"""
CREATE TABLE image (md5 TEXT NOT NULL PRIMARY KEY,
CREATE TABLE image (md5 TEXT NOT NULL PRIMARY KEY,
                    name TEXT NOT NULL,
                    name TEXT NOT NULL,
                    version INTEGER NOT NULL,
                    version TEXT NOT NULL,
                    date INTEGER NOT NULL,
                    date INTEGER NOT NULL,
                    author TEXT,
                    author TEXT,
                    description TEXT,
                    description TEXT,
Loading