~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# Copyright 2009 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

__metaclass__ = type


def valid_debian_version(version):
    """
    Returns True if version is a valid debian version string

    As per http://www.debian.org/doc/debian-policy/ch-controlfields.html
    (Except we appear to need to allow ~ characters, which is not documented
    in the spec.)

    >>> valid_debian_version('1')
    True
    >>> valid_debian_version('1.0')
    True
    >>> valid_debian_version('1:1.0')
    True
    >>> valid_debian_version('1.0-1')
    True
    >>> valid_debian_version("1:1.0-1")
    True
    >>> valid_debian_version("3.4-2.1")
    True
    >>> valid_debian_version("1.5.4-1.woody.0")
    True
    >>> valid_debian_version("1.5.4-1.WOODY.0")
    True
    >>> valid_debian_version("1.6-0+1.5a-4")
    True
    >>> valid_debian_version("1.3~rc1-4")
    True
    >>> valid_debian_version("1:")
    False
    >>> valid_debian_version("1:-")
    False
    >>> valid_debian_version("44-")
    False
    >>> valid_debian_version("~-~")
    False
    >>> valid_debian_version("0~")
    True
    >>> valid_debian_version("0~-~")
    True
    >>> valid_debian_version(":44")
    False
    >>> valid_debian_version("foo:")
    False
    >>> valid_debian_version("12:12:alpha-alpha")
    True
    >>> valid_debian_version("build9-6")
    True
    """
    import re
    m = re.search("""^(?ix)
        ([0-9]+:)?
        ([0-9a-z][a-z0-9+:.~-]*?)
        (-[a-z0-9+.~]+)?
        $""", version)
    if m is None:
        return False
    epoch, version, revision = m.groups()
    if not epoch:
        # Can't contain : if no epoch
        if ":" in version:
            return False
    if not revision:
        # Can't contain - if no revision
        if "-" in version:
            return False
    return True


def sane_version(version):
    '''A sane version number for use by ProductRelease and DistroSeries.

    We may make it less strict if required, but it would be nice if we can
    enforce simple version strings because we use them in URLs

    >>> sane_version('hello')
    True
    >>> sane_version('HELLO')
    True
    >>> sane_version('1.0')
    True
    >>> sane_version('12:45')
    False
    >>> sane_version('1b2')
    True
    >>> sane_version('1-')
    False
    >>> sane_version('1-2')
    True
    >>> sane_version('-2')
    False
    >>> sane_version('uncle sam')
    False
    >>> sane_version('uncle_sam')
    True
    >>> sane_version('uncle-sam')
    True
    '''
    import re
    if re.search("""^(?ix)
        [0-9a-z]
        ( [0-9a-z] | [0-9a-z._-]*[0-9a-z] )*
        $""", version):
        return True
    return False