##// END OF EJS Templates
lfs: stabilize error message values for Python 2 and 3...
Augie Fackler -
r37945:fb6226c1 default
parent child Browse files
Show More
@@ -1,75 +1,82 b''
1 1 # pointer.py - Git-LFS pointer serialization
2 2 #
3 3 # Copyright 2017 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import re
11 11
12 12 from mercurial.i18n import _
13 13
14 14 from mercurial import (
15 15 error,
16 16 pycompat,
17 17 )
18 from mercurial.utils import (
19 stringutil,
20 )
18 21
19 22 class InvalidPointer(error.RevlogError):
20 23 pass
21 24
22 25 class gitlfspointer(dict):
23 26 VERSION = 'https://git-lfs.github.com/spec/v1'
24 27
25 28 def __init__(self, *args, **kwargs):
26 29 self['version'] = self.VERSION
27 30 super(gitlfspointer, self).__init__(*args)
28 31 self.update(pycompat.byteskwargs(kwargs))
29 32
30 33 @classmethod
31 34 def deserialize(cls, text):
32 35 try:
33 36 return cls(l.split(' ', 1) for l in text.splitlines()).validate()
34 37 except ValueError: # l.split returns 1 item instead of 2
35 raise InvalidPointer(_('cannot parse git-lfs text: %r') % text)
38 raise InvalidPointer(
39 _('cannot parse git-lfs text: %s') % stringutil.pprint(
40 text, bprefix=False))
36 41
37 42 def serialize(self):
38 43 sortkeyfunc = lambda x: (x[0] != 'version', x)
39 44 items = sorted(self.validate().iteritems(), key=sortkeyfunc)
40 45 return ''.join('%s %s\n' % (k, v) for k, v in items)
41 46
42 47 def oid(self):
43 48 return self['oid'].split(':')[-1]
44 49
45 50 def size(self):
46 51 return int(self['size'])
47 52
48 53 # regular expressions used by _validate
49 54 # see https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md
50 55 _keyre = re.compile(br'\A[a-z0-9.-]+\Z')
51 56 _valuere = re.compile(br'\A[^\n]*\Z')
52 57 _requiredre = {
53 58 'size': re.compile(br'\A[0-9]+\Z'),
54 59 'oid': re.compile(br'\Asha256:[0-9a-f]{64}\Z'),
55 60 'version': re.compile(br'\A%s\Z' % re.escape(VERSION)),
56 61 }
57 62
58 63 def validate(self):
59 64 """raise InvalidPointer on error. return self if there is no error"""
60 65 requiredcount = 0
61 66 for k, v in self.iteritems():
62 67 if k in self._requiredre:
63 68 if not self._requiredre[k].match(v):
64 raise InvalidPointer(_('unexpected value: %s=%r') % (k, v))
69 raise InvalidPointer(_('unexpected value: %s=%s') % (
70 k, stringutil.pprint(v, bprefix=False)))
65 71 requiredcount += 1
66 72 elif not self._keyre.match(k):
67 73 raise InvalidPointer(_('unexpected key: %s') % k)
68 74 if not self._valuere.match(v):
69 raise InvalidPointer(_('unexpected value: %s=%r') % (k, v))
75 raise InvalidPointer(_('unexpected value: %s=%s') % (
76 k, stringutil.pprint(v, bprefix=False)))
70 77 if len(self._requiredre) != requiredcount:
71 78 miss = sorted(set(self._requiredre.keys()).difference(self.keys()))
72 79 raise InvalidPointer(_('missed keys: %s') % ', '.join(miss))
73 80 return self
74 81
75 82 deserialize = gitlfspointer.deserialize
General Comments 0
You need to be logged in to leave comments. Login now