]> git.decadent.org.uk Git - dak.git/blob - daklib/srcformats.py
Merge commit 'lamby/master' into merge
[dak.git] / daklib / srcformats.py
1 import re
2
3 from regexes import re_verwithext
4 from dak_exceptions import UnknownFormatError
5
6 srcformats = []
7
8 def get_format_from_string(txt):
9     """
10     Returns the SourceFormat class that corresponds to the specified .changes
11     Format value. If the string does not match any class, UnknownFormatError
12     is raised.
13     """
14
15     for format in srcformats:
16         if format.re_format.match(txt):
17             return format
18
19     raise UnknownFormatError, "Unknown format %r" % txt
20
21 def parse_format(txt):
22     """
23     Parse a .changes Format string into a tuple representation for easy
24     comparison.
25
26     >>> parse_format('1.0')
27     (1, 0)
28     >>> parse_format('8.4 (hardy)')
29     (8, 4, 'hardy')
30
31     If the format doesn't match these forms, raises UnknownFormatError.
32     """
33
34     format = re_verwithext.search(txt)
35
36     if format is None:
37         raise UnknownFormatError, txt
38
39     format = format.groups()
40
41     if format[1] is None:
42         format = int(float(format[0])), 0, format[2]
43     else:
44         format = int(format[0]), int(format[1]), format[2]
45
46     if format[2] is None:
47         format = format[:2]
48
49     return format
50
51 class SourceFormat(type):
52     def __new__(cls, name, bases, attrs):
53         klass = super(SourceFormat, cls).__new__(cls, name, bases, attrs)
54         srcformats.append(klass)
55
56         assert str(klass.name)
57         assert iter(klass.requires)
58         assert iter(klass.disallowed)
59
60         klass.re_format = re.compile(klass.format)
61
62         return klass
63
64     @classmethod
65     def reject_msgs(cls, has):
66         if len(cls.requires) != len([x for x in cls.requires if has[x]]):
67             yield "lack of required files for format %s" % cls.name
68
69         for key in cls.disallowed:
70             if has[key]:
71                 yield "contains source files not allowed in format %s" % cls.name
72
73     @classmethod
74     def validate_format(cls, format, is_a_dsc=False, field='files'):
75         """
76         Raises UnknownFormatError if the specified format tuple is not valid for
77         this format (for example, the format (1, 0) is not valid for the
78         "3.0 (quilt)" format). Return value is undefined in all other cases.
79         """
80         pass
81
82 class FormatOne(SourceFormat):
83     __metaclass__ = SourceFormat
84
85     name = '1.0'
86     format = r'1.0'
87
88     requires = ()
89     disallowed = ('debian_tar', 'more_orig_tar')
90
91     @classmethod
92     def reject_msgs(cls, has):
93         if not (has['native_tar_gz'] or (has['orig_tar_gz'] and has['debian_diff'])):
94             yield "no .tar.gz or .orig.tar.gz+.diff.gz in 'Files' field."
95         if has['native_tar_gz'] and has['debian_diff']:
96             yield "native package with diff makes no sense"
97         if (has['orig_tar_gz'] != has['orig_tar']) or \
98            (has['native_tar_gz'] != has['native_tar']):
99             yield "contains source files not allowed in format %s" % cls.name
100
101         for msg in super(FormatOne, cls).reject_msgs(has):
102             yield msg
103
104     @classmethod
105     def validate_format(cls, format, is_a_dsc=False, field='files'):
106         msg = "Invalid format %s definition: %r" % (cls.name, format)
107
108         if is_a_dsc:
109             if format != (1, 0):
110                 raise UnknownFormatError, msg
111         else:
112             if (format < (1,5) or format > (1,8)):
113                 raise UnknownFormatError, msg
114             if field != "files" and format < (1,8):
115                 raise UnknownFormatError, msg
116
117 class FormatThree(SourceFormat):
118     __metaclass__ = SourceFormat
119
120     name = '3.x (native)'
121     format = r'3\.\d+ \(native\)'
122
123     requires = ('native_tar',)
124     disallowed = ('orig_tar', 'debian_diff', 'debian_tar', 'more_orig_tar')
125
126     @classmethod
127     def validate_format(cls, format, **kwargs):
128         if format != (3, 0, 'native'):
129             raise UnknownFormatError, "Invalid format %s definition: %r" % \
130                 (cls.name, format)
131
132 class FormatThreeQuilt(SourceFormat):
133     __metaclass__ = SourceFormat
134
135     name = '3.x (quilt)'
136     format = r'3\.\d+ \(quilt\)'
137
138     requires = ('orig_tar', 'debian_tar')
139     disallowed = ('debian_diff', 'native_tar')
140
141     @classmethod
142     def validate_format(cls, format, **kwargs):
143         if format != (3, 0, 'quilt'):
144             raise UnknownFormatError, "Invalid format %s definition: %r" % \
145                 (cls.name, format)