hgext/lfs/pointer.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43105 649d3ac37a12
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    21 class InvalidPointer(error.StorageError):
    21 class InvalidPointer(error.StorageError):
    22     pass
    22     pass
    23 
    23 
    24 
    24 
    25 class gitlfspointer(dict):
    25 class gitlfspointer(dict):
    26     VERSION = 'https://git-lfs.github.com/spec/v1'
    26     VERSION = b'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[b'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(b' ', 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(
    38             raise InvalidPointer(
    39                 _('cannot parse git-lfs text: %s') % stringutil.pprint(text)
    39                 _(b'cannot parse git-lfs text: %s') % stringutil.pprint(text)
    40             )
    40             )
    41 
    41 
    42     def serialize(self):
    42     def serialize(self):
    43         sortkeyfunc = lambda x: (x[0] != 'version', x)
    43         sortkeyfunc = lambda x: (x[0] != b'version', x)
    44         items = sorted(self.validate().iteritems(), key=sortkeyfunc)
    44         items = sorted(self.validate().iteritems(), key=sortkeyfunc)
    45         return ''.join('%s %s\n' % (k, v) for k, v in items)
    45         return b''.join(b'%s %s\n' % (k, v) for k, v in items)
    46 
    46 
    47     def oid(self):
    47     def oid(self):
    48         return self['oid'].split(':')[-1]
    48         return self[b'oid'].split(b':')[-1]
    49 
    49 
    50     def size(self):
    50     def size(self):
    51         return int(self['size'])
    51         return int(self[b'size'])
    52 
    52 
    53     # regular expressions used by _validate
    53     # regular expressions used by _validate
    54     # see https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md
    54     # see https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md
    55     _keyre = re.compile(br'\A[a-z0-9.-]+\Z')
    55     _keyre = re.compile(br'\A[a-z0-9.-]+\Z')
    56     _valuere = re.compile(br'\A[^\n]*\Z')
    56     _valuere = re.compile(br'\A[^\n]*\Z')
    57     _requiredre = {
    57     _requiredre = {
    58         'size': re.compile(br'\A[0-9]+\Z'),
    58         b'size': re.compile(br'\A[0-9]+\Z'),
    59         'oid': re.compile(br'\Asha256:[0-9a-f]{64}\Z'),
    59         b'oid': re.compile(br'\Asha256:[0-9a-f]{64}\Z'),
    60         'version': re.compile(br'\A%s\Z' % stringutil.reescape(VERSION)),
    60         b'version': re.compile(br'\A%s\Z' % stringutil.reescape(VERSION)),
    61     }
    61     }
    62 
    62 
    63     def validate(self):
    63     def validate(self):
    64         """raise InvalidPointer on error. return self if there is no error"""
    64         """raise InvalidPointer on error. return self if there is no error"""
    65         requiredcount = 0
    65         requiredcount = 0
    66         for k, v in self.iteritems():
    66         for k, v in self.iteritems():
    67             if k in self._requiredre:
    67             if k in self._requiredre:
    68                 if not self._requiredre[k].match(v):
    68                 if not self._requiredre[k].match(v):
    69                     raise InvalidPointer(
    69                     raise InvalidPointer(
    70                         _('unexpected lfs pointer value: %s=%s')
    70                         _(b'unexpected lfs pointer value: %s=%s')
    71                         % (k, stringutil.pprint(v))
    71                         % (k, stringutil.pprint(v))
    72                     )
    72                     )
    73                 requiredcount += 1
    73                 requiredcount += 1
    74             elif not self._keyre.match(k):
    74             elif not self._keyre.match(k):
    75                 raise InvalidPointer(_('unexpected lfs pointer key: %s') % k)
    75                 raise InvalidPointer(_(b'unexpected lfs pointer key: %s') % k)
    76             if not self._valuere.match(v):
    76             if not self._valuere.match(v):
    77                 raise InvalidPointer(
    77                 raise InvalidPointer(
    78                     _('unexpected lfs pointer value: %s=%s')
    78                     _(b'unexpected lfs pointer value: %s=%s')
    79                     % (k, stringutil.pprint(v))
    79                     % (k, stringutil.pprint(v))
    80                 )
    80                 )
    81         if len(self._requiredre) != requiredcount:
    81         if len(self._requiredre) != requiredcount:
    82             miss = sorted(set(self._requiredre.keys()).difference(self.keys()))
    82             miss = sorted(set(self._requiredre.keys()).difference(self.keys()))
    83             raise InvalidPointer(
    83             raise InvalidPointer(
    84                 _('missing lfs pointer keys: %s') % ', '.join(miss)
    84                 _(b'missing lfs pointer keys: %s') % b', '.join(miss)
    85             )
    85             )
    86         return self
    86         return self
    87 
    87 
    88 
    88 
    89 deserialize = gitlfspointer.deserialize
    89 deserialize = gitlfspointer.deserialize