comparison hgext/largefiles/proto.py @ 36067:caca3ac2ac04

wireproto: use maybecapturestdio() for push responses (API) The "pushres" and "pusherr" response types currently call proto.restore() in the HTTP protocol. This completes the pairing with proto.redirect() that occurs in the @wireprotocommand functions. (But since the SSH protocol has a no-op redirect(), it doesn't bother calling restore() because it would also be a no-op.) Having the disconnect between these paired calls is very confusing. Knowing that you must use proto.redirect() if returning a "pushres" or a "pusherr" is even wonkier. We replace this confusing code with our new context manager for [maybe] capturing output. The "pushres" and "pusherr" types have gained an "output" argument to their constructor and an attribute to hold captured data. The HTTP protocol now retrieves output from these objects. .. api:: ``wireproto.pushres`` and ``wireproto.pusherr`` now explicitly track stdio output. Differential Revision: https://phab.mercurial-scm.org/D2082
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 07 Feb 2018 20:19:06 -0800
parents a39a9df7ecca
children 90ca4986616c
comparison
equal deleted inserted replaced
36066:2ad145fbde54 36067:caca3ac2ac04
32 httpoldcallstream = None 32 httpoldcallstream = None
33 33
34 def putlfile(repo, proto, sha): 34 def putlfile(repo, proto, sha):
35 '''Server command for putting a largefile into a repository's local store 35 '''Server command for putting a largefile into a repository's local store
36 and into the user cache.''' 36 and into the user cache.'''
37 proto.redirect() 37 with proto.mayberedirectstdio() as output:
38 path = lfutil.storepath(repo, sha)
39 util.makedirs(os.path.dirname(path))
40 tmpfp = util.atomictempfile(path, createmode=repo.store.createmode)
38 41
39 path = lfutil.storepath(repo, sha) 42 try:
40 util.makedirs(os.path.dirname(path)) 43 proto.getfile(tmpfp)
41 tmpfp = util.atomictempfile(path, createmode=repo.store.createmode) 44 tmpfp._fp.seek(0)
45 if sha != lfutil.hexsha1(tmpfp._fp):
46 raise IOError(0, _('largefile contents do not match hash'))
47 tmpfp.close()
48 lfutil.linktousercache(repo, sha)
49 except IOError as e:
50 repo.ui.warn(_('largefiles: failed to put %s into store: %s\n') %
51 (sha, e.strerror))
52 return wireproto.pushres(1, output.getvalue() if output else '')
53 finally:
54 tmpfp.discard()
42 55
43 try: 56 return wireproto.pushres(0, output.getvalue() if output else '')
44 proto.getfile(tmpfp)
45 tmpfp._fp.seek(0)
46 if sha != lfutil.hexsha1(tmpfp._fp):
47 raise IOError(0, _('largefile contents do not match hash'))
48 tmpfp.close()
49 lfutil.linktousercache(repo, sha)
50 except IOError as e:
51 repo.ui.warn(_('largefiles: failed to put %s into store: %s\n') %
52 (sha, e.strerror))
53 return wireproto.pushres(1)
54 finally:
55 tmpfp.discard()
56
57 return wireproto.pushres(0)
58 57
59 def getlfile(repo, proto, sha): 58 def getlfile(repo, proto, sha):
60 '''Server command for retrieving a largefile from the repository-local 59 '''Server command for retrieving a largefile from the repository-local
61 cache or user cache.''' 60 cache or user cache.'''
62 filename = lfutil.findfile(repo, sha) 61 filename = lfutil.findfile(repo, sha)