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