Mercurial > hg
view hgext/lfs/pointer.py @ 37499:75c13343cf38
templater: wrap result of '%' operation so it never looks like a thunk
This fixes min/max()/json() of map result. Before, it was taken as a lazy
byte string and stringified by evalfuncarg().
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 18 Mar 2018 23:36:52 +0900 |
parents | e30be4d2ac60 |
children | fb6226c15e54 |
line wrap: on
line source
# pointer.py - Git-LFS pointer serialization # # Copyright 2017 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import import re from mercurial.i18n import _ from mercurial import ( error, pycompat, ) class InvalidPointer(error.RevlogError): pass class gitlfspointer(dict): VERSION = 'https://git-lfs.github.com/spec/v1' def __init__(self, *args, **kwargs): self['version'] = self.VERSION super(gitlfspointer, self).__init__(*args) self.update(pycompat.byteskwargs(kwargs)) @classmethod def deserialize(cls, text): try: return cls(l.split(' ', 1) for l in text.splitlines()).validate() except ValueError: # l.split returns 1 item instead of 2 raise InvalidPointer(_('cannot parse git-lfs text: %r') % text) def serialize(self): sortkeyfunc = lambda x: (x[0] != 'version', x) items = sorted(self.validate().iteritems(), key=sortkeyfunc) return ''.join('%s %s\n' % (k, v) for k, v in items) def oid(self): return self['oid'].split(':')[-1] def size(self): return int(self['size']) # regular expressions used by _validate # see https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md _keyre = re.compile(br'\A[a-z0-9.-]+\Z') _valuere = re.compile(br'\A[^\n]*\Z') _requiredre = { 'size': re.compile(br'\A[0-9]+\Z'), 'oid': re.compile(br'\Asha256:[0-9a-f]{64}\Z'), 'version': re.compile(br'\A%s\Z' % re.escape(VERSION)), } def validate(self): """raise InvalidPointer on error. return self if there is no error""" requiredcount = 0 for k, v in self.iteritems(): if k in self._requiredre: if not self._requiredre[k].match(v): raise InvalidPointer(_('unexpected value: %s=%r') % (k, v)) requiredcount += 1 elif not self._keyre.match(k): raise InvalidPointer(_('unexpected key: %s') % k) if not self._valuere.match(v): raise InvalidPointer(_('unexpected value: %s=%r') % (k, v)) if len(self._requiredre) != requiredcount: miss = sorted(set(self._requiredre.keys()).difference(self.keys())) raise InvalidPointer(_('missed keys: %s') % ', '.join(miss)) return self deserialize = gitlfspointer.deserialize