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