Esempio n. 1
0
File: fix.py Progetto: CJX32/my_blog
def fixfile(ui, repo, opts, fixers, fixctx, path, basectxs):
    """Run any configured fixers that should affect the file in this context

    Returns the file content that results from applying the fixers in some order
    starting with the file's content in the fixctx. Fixers that support line
    ranges will affect lines that have changed relative to any of the basectxs
    (i.e. they will only avoid lines that are common to all basectxs).

    A fixer tool's stdout will become the file's new content if and only if it
    exits with code zero. The fixer tool's working directory is the repository's
    root.
    """
    metadata = {}
    newdata = fixctx[path].data()
    for fixername, fixer in pycompat.iteritems(fixers):
        if fixer.affects(opts, fixctx, path):
            ranges = lineranges(opts, path, basectxs, fixctx, newdata)
            command = fixer.command(ui, path, ranges)
            if command is None:
                continue
            ui.debug(b'subprocess: %s\n' % (command, ))
            proc = subprocess.Popen(
                procutil.tonativestr(command),
                shell=True,
                cwd=procutil.tonativestr(repo.root),
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            stdout, stderr = proc.communicate(newdata)
            if stderr:
                showstderr(ui, fixctx.rev(), fixername, stderr)
            newerdata = stdout
            if fixer.shouldoutputmetadata():
                try:
                    metadatajson, newerdata = stdout.split(b'\0', 1)
                    metadata[fixername] = pycompat.json_loads(metadatajson)
                except ValueError:
                    ui.warn(
                        _(b'ignored invalid output from fixer tool: %s\n') %
                        (fixername, ))
                    continue
            else:
                metadata[fixername] = None
            if proc.returncode == 0:
                newdata = newerdata
            else:
                if not stderr:
                    message = _(b'exited with status %d\n') % (
                        proc.returncode, )
                    showstderr(ui, fixctx.rev(), fixername, message)
                checktoolfailureaction(
                    ui,
                    _(b'no fixes will be applied'),
                    hint=_(b'use --config fix.failure=continue to apply any '
                           b'successful fixes anyway'),
                )
    return metadata, newdata
Esempio n. 2
0
 def _fetch(self, burl):
     try:
         resp = url.open(self.ui, burl)
         return pycompat.json_loads(resp.read())
     except util.urlerr.httperror as inst:
         if inst.code == 401:
             raise error.Abort(_(b'authorization failed'))
         if inst.code == 404:
             raise NotFound()
         else:
             raise
Esempio n. 3
0
    def _submit(self, burl, data, method=b'POST'):
        data = json.dumps(data)
        if method == b'PUT':

            class putrequest(util.urlreq.request):
                def get_method(self):
                    return b'PUT'

            request_type = putrequest
        else:
            request_type = util.urlreq.request
        req = request_type(burl, data, {b'Content-Type': b'application/json'})
        try:
            resp = url.opener(self.ui).open(req)
            return pycompat.json_loads(resp.read())
        except util.urlerr.httperror as inst:
            if inst.code == 401:
                raise error.Abort(_(b'authorization failed'))
            if inst.code == 404:
                raise NotFound()
            else:
                raise
Esempio n. 4
0
def _processbatchrequest(repo, req, res):
    """Handle a request for the Batch API, which is the gateway to granting file
    access.

    https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md
    """

    # Mercurial client request:
    #
    #   HOST: localhost:$HGPORT
    #   ACCEPT: application/vnd.git-lfs+json
    #   ACCEPT-ENCODING: identity
    #   USER-AGENT: git-lfs/2.3.4 (Mercurial 4.5.2+1114-f48b9754f04c+20180316)
    #   Content-Length: 125
    #   Content-Type: application/vnd.git-lfs+json
    #
    #   {
    #     "objects": [
    #       {
    #         "oid": "31cf...8e5b"
    #         "size": 12
    #       }
    #     ]
    #     "operation": "upload"
    #  }

    if req.method != b'POST':
        _sethttperror(res, HTTP_METHOD_NOT_ALLOWED)
        return True

    if req.headers[b'Content-Type'] != b'application/vnd.git-lfs+json':
        _sethttperror(res, HTTP_UNSUPPORTED_MEDIA_TYPE)
        return True

    if req.headers[b'Accept'] != b'application/vnd.git-lfs+json':
        _sethttperror(res, HTTP_NOT_ACCEPTABLE)
        return True

    # XXX: specify an encoding?
    lfsreq = pycompat.json_loads(req.bodyfh.read())

    # If no transfer handlers are explicitly requested, 'basic' is assumed.
    if r'basic' not in lfsreq.get(r'transfers', [r'basic']):
        _sethttperror(
            res,
            HTTP_BAD_REQUEST,
            b'Only the basic LFS transfer handler is supported',
        )
        return True

    operation = lfsreq.get(r'operation')
    operation = pycompat.bytestr(operation)

    if operation not in (b'upload', b'download'):
        _sethttperror(
            res,
            HTTP_BAD_REQUEST,
            b'Unsupported LFS transfer operation: %s' % operation,
        )
        return True

    localstore = repo.svfs.lfslocalblobstore

    objects = [
        p for p in _batchresponseobjects(req, lfsreq.get(r'objects', []),
                                         operation, localstore)
    ]

    rsp = {
        r'transfer': r'basic',
        r'objects': objects,
    }

    res.status = hgwebcommon.statusmessage(HTTP_OK)
    res.headers[b'Content-Type'] = b'application/vnd.git-lfs+json'
    res.setbodybytes(pycompat.bytestr(json.dumps(rsp)))

    return True
Esempio n. 5
0
    def _batchrequest(self, pointers, action):
        """Get metadata about objects pointed by pointers for given action

        Return decoded JSON object like {'objects': [{'oid': '', 'size': 1}]}
        See https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md
        """
        objects = [
            {r'oid': pycompat.strurl(p.oid()), r'size': p.size()}
            for p in pointers
        ]
        requestdata = pycompat.bytesurl(
            json.dumps(
                {r'objects': objects, r'operation': pycompat.strurl(action),}
            )
        )
        url = b'%s/objects/batch' % self.baseurl
        batchreq = util.urlreq.request(pycompat.strurl(url), data=requestdata)
        batchreq.add_header(r'Accept', r'application/vnd.git-lfs+json')
        batchreq.add_header(r'Content-Type', r'application/vnd.git-lfs+json')
        try:
            with contextlib.closing(self.urlopener.open(batchreq)) as rsp:
                rawjson = rsp.read()
        except util.urlerr.httperror as ex:
            hints = {
                400: _(
                    b'check that lfs serving is enabled on %s and "%s" is '
                    b'supported'
                )
                % (self.baseurl, action),
                404: _(b'the "lfs.url" config may be used to override %s')
                % self.baseurl,
            }
            hint = hints.get(ex.code, _(b'api=%s, action=%s') % (url, action))
            raise LfsRemoteError(
                _(b'LFS HTTP error: %s') % stringutil.forcebytestr(ex),
                hint=hint,
            )
        except util.urlerr.urlerror as ex:
            hint = (
                _(b'the "lfs.url" config may be used to override %s')
                % self.baseurl
            )
            raise LfsRemoteError(
                _(b'LFS error: %s') % _urlerrorreason(ex), hint=hint
            )
        try:
            response = pycompat.json_loads(rawjson)
        except ValueError:
            raise LfsRemoteError(
                _(b'LFS server returns invalid JSON: %s')
                % rawjson.encode("utf-8")
            )

        if self.ui.debugflag:
            self.ui.debug(b'Status: %d\n' % rsp.status)
            # lfs-test-server and hg serve return headers in different order
            headers = pycompat.bytestr(rsp.info()).strip()
            self.ui.debug(b'%s\n' % b'\n'.join(sorted(headers.splitlines())))

            if r'objects' in response:
                response[r'objects'] = sorted(
                    response[r'objects'], key=lambda p: p[r'oid']
                )
            self.ui.debug(
                b'%s\n'
                % pycompat.bytesurl(
                    json.dumps(
                        response,
                        indent=2,
                        separators=(r'', r': '),
                        sort_keys=True,
                    )
                )
            )

        def encodestr(x):
            if isinstance(x, pycompat.unicode):
                return x.encode('utf-8')
            return x

        return pycompat.rapply(encodestr, response)