From patchwork Thu Oct 10 21:52:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: D7047: phabricator: add the uploadfile function From: phabricator X-Patchwork-Id: 42203 Message-Id: To: Phabricator Cc: mercurial-devel@mercurial-scm.org Date: Thu, 10 Oct 2019 21:52:35 +0000 Kwan created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is needed to be able to submit binary files such as images in commits (and also non-UTF-8 text files). One of the primary disadvantages of the current use of createrawdiff is that Phabricator simply drops any binary diffs included in the patch, but not the files, so if such a diff is then committed it corrupts any binary files in it. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D7047 AFFECTED FILES hgext/phabricator.py CHANGE DETAILS To: Kwan, #hg-reviewers Cc: mercurial-devel diff --git a/hgext/phabricator.py b/hgext/phabricator.py --- a/hgext/phabricator.py +++ b/hgext/phabricator.py @@ -43,6 +43,7 @@ import base64 import contextlib +import hashlib import itertools import json import operator @@ -608,6 +609,43 @@ progress.complete() +def uploadfile(fctx): + """upload binary files to Phabricator""" + repo = fctx.repo() + ui = repo.ui + fname = fctx.path() + size = fctx.size() + fhash = pycompat.bytestr(hashlib.sha256(fctx.data()).hexdigest()) + + # an allocate call is required first to see if an upload is even required + # (Phab might already have it) and to determine if chunking is needed + allocateparams = { + b'name': fname, + b'contentLength': size, + b'contentHash': fhash, + } + filealloc = callconduit(ui, b'file.allocate', allocateparams) + fphid = filealloc[b'filePHID'] + + if filealloc[b'upload']: + ui.write(_(b'uploading %s\n') % bytes(fctx)) + if not fphid: + uploadparams = { + b'name': fname, + b'data_base64': base64.b64encode(fctx.data()), + } + fphid = callconduit(ui, b'file.upload', uploadparams) + else: + uploadchunks(fctx, fphid) + else: + ui.debug(b'server already has %s\n' % bytes(fctx)) + + if not fphid: + raise error.Abort(b'Upload of %s failed.' % bytes(fctx)) + + return fphid + + def creatediff(ctx): """create a Differential Diff""" repo = ctx.repo()