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