~tempo-openerp/+junk/loewert-report-name

« back to all changes in this revision

Viewing changes to server/openerp/tools/parse_version.py

  • Committer: jbe at tempo-consulting
  • Date: 2013-08-21 08:48:11 UTC
  • Revision ID: jbe@tempo-consulting.fr-20130821084811-913uo4l7b5ayxq8m
[NEW] Création de la branche trunk Loewert

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#    
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
 
6
#
 
7
#    This program is free software: you can redistribute it and/or modify
 
8
#    it under the terms of the GNU Affero General Public License as
 
9
#    published by the Free Software Foundation, either version 3 of the
 
10
#    License, or (at your option) any later version.
 
11
#
 
12
#    This program is distributed in the hope that it will be useful,
 
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#    GNU Affero General Public License for more details.
 
16
#
 
17
#    You should have received a copy of the GNU Affero General Public License
 
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
 
19
#
 
20
##############################################################################
 
21
 
 
22
## this functions are taken from the setuptools package (version 0.6c8)
 
23
## http://peak.telecommunity.com/DevCenter/PkgResources#parsing-utilities
 
24
 
 
25
import re
 
26
 
 
27
component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
 
28
replace = {'pre':'c', 'preview':'c','-':'final-','_':'final-','rc':'c','dev':'@'}.get
 
29
 
 
30
def _parse_version_parts(s):
 
31
    for part in component_re.split(s):
 
32
        part = replace(part,part)
 
33
        if not part or part=='.':
 
34
            continue
 
35
        if part[:1] in '0123456789':
 
36
            yield part.zfill(8)    # pad for numeric comparison
 
37
        else:
 
38
            yield '*'+part
 
39
 
 
40
    yield '*final'  # ensure that alpha/beta/candidate are before final
 
41
 
 
42
def parse_version(s):
 
43
    """Convert a version string to a chronologically-sortable key
 
44
 
 
45
    This is a rough cross between distutils' StrictVersion and LooseVersion;
 
46
    if you give it versions that would work with StrictVersion, then it behaves
 
47
    the same; otherwise it acts like a slightly-smarter LooseVersion. It is
 
48
    *possible* to create pathological version coding schemes that will fool
 
49
    this parser, but they should be very rare in practice.
 
50
 
 
51
    The returned value will be a tuple of strings.  Numeric portions of the
 
52
    version are padded to 8 digits so they will compare numerically, but
 
53
    without relying on how numbers compare relative to strings.  Dots are
 
54
    dropped, but dashes are retained.  Trailing zeros between alpha segments
 
55
    or dashes are suppressed, so that e.g. "2.4.0" is considered the same as
 
56
    "2.4". Alphanumeric parts are lower-cased.
 
57
 
 
58
    The algorithm assumes that strings like "-" and any alpha string that
 
59
    alphabetically follows "final"  represents a "patch level".  So, "2.4-1"
 
60
    is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is
 
61
    considered newer than "2.4-1", whic in turn is newer than "2.4".
 
62
 
 
63
    Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that
 
64
    come before "final" alphabetically) are assumed to be pre-release versions,
 
65
    so that the version "2.4" is considered newer than "2.4a1".
 
66
 
 
67
    Finally, to handle miscellaneous cases, the strings "pre", "preview", and
 
68
    "rc" are treated as if they were "c", i.e. as though they were release
 
69
    candidates, and therefore are not as new as a version string that does not
 
70
    contain them.
 
71
    """
 
72
    parts = []
 
73
    for part in _parse_version_parts((s or '0.1').lower()):
 
74
        if part.startswith('*'):
 
75
            if part<'*final':   # remove '-' before a prerelease tag
 
76
                while parts and parts[-1]=='*final-': parts.pop()
 
77
            # remove trailing zeros from each series of numeric parts
 
78
            while parts and parts[-1]=='00000000':
 
79
                parts.pop()
 
80
        parts.append(part)
 
81
    return tuple(parts)
 
82
 
 
83
if __name__ == '__main__':
 
84
        
 
85
        def cmp(a, b):
 
86
            msg = '%s < %s == %s' % (a, b, a < b)
 
87
            assert a < b, msg
 
88
            return b
 
89
 
 
90
        def chk(lst, verbose=False):
 
91
            pvs = []
 
92
            for v in lst:
 
93
                pv = parse_version(v)
 
94
                pvs.append(pv)
 
95
                if verbose:
 
96
                    print v, pv
 
97
            reduce(cmp, pvs)
 
98
        
 
99
        chk(('0', '4.2', '4.2.3.4', '5.0.0-alpha', '5.0.0-rc1', '5.0.0-rc1.1', '5.0.0_rc2', '5.0.0_rc3', '5.0.0'), False)
 
100
        chk(('5.0.0-0_rc3', '5.0.0-1dev', '5.0.0-1'), False) 
 
101
        
 
102
 
 
103
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: