Beispiel #1
0
def handlewsgirequest(orig, rctx, req, res, checkperm):
    """Wrap wireprotoserver.handlewsgirequest() to possibly process an LFS
    request if it is left unprocessed by the wrapped method.
    """
    if orig(rctx, req, res, checkperm):
        return True

    if not rctx.repo.ui.configbool(b'experimental', b'lfs.serve'):
        return False

    if not util.safehasattr(rctx.repo.svfs, 'lfslocalblobstore'):
        return False

    if not req.dispatchpath:
        return False

    try:
        if req.dispatchpath == b'.git/info/lfs/objects/batch':
            checkperm(rctx, req, b'pull')
            return _processbatchrequest(rctx.repo, req, res)
        # TODO: reserve and use a path in the proposed http wireprotocol /api/
        #       namespace?
        elif req.dispatchpath.startswith(b'.hg/lfs/objects'):
            return _processbasictransfer(
                rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm))
        return False
    except hgwebcommon.ErrorResponse as e:
        # XXX: copied from the handler surrounding wireprotoserver._callhttp()
        #      in the wrapped function.  Should this be moved back to hgweb to
        #      be a common handler?
        for k, v in e.headers:
            res.headers[k] = v
        res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
        res.setbodybytes(b'0\n%s\n' % pycompat.bytestr(e))
        return True
def parseoptions(ui, cmdoptions, args):
    cmdoptions = list(cmdoptions)
    opts = {}
    args = list(args)
    while True:
        try:
            args = fancyopts.fancyopts(list(args), cmdoptions, opts, True)
            break
        except getopt.GetoptError as ex:
            if "requires argument" in ex.msg:
                raise
            if ('--' + ex.opt) in ex.msg:
                flag = b'--' + pycompat.bytestr(ex.opt)
            elif ('-' + ex.opt) in ex.msg:
                flag = b'-' + pycompat.bytestr(ex.opt)
            else:
                raise error.Abort(
                    _(b"unknown option %s") % pycompat.bytestr(ex.opt))
            try:
                args.remove(flag)
            except Exception:
                msg = _(b"unknown option '%s' packed with other options")
                hint = _(b"please try passing the option as its own flag: -%s")
                raise error.Abort(
                    msg % pycompat.bytestr(ex.opt),
                    hint=hint % pycompat.bytestr(ex.opt),
                )

            ui.warn(_(b"ignoring unknown option %s\n") % flag)

    args = list([convert(x) for x in args])
    opts = dict([(k, convert(v)) if isinstance(v, bytes) else (k, v)
                 for k, v in pycompat.iteritems(opts)])

    return args, opts
def find_profiles_path():
    """Find the path containing Firefox profiles.

    The location of Firefox profiles is OS dependent. This function handles the
    differences.
    """
    path = None
    if platform.system() == 'Darwin':
        from Carbon import Folder, Folders
        pathref = Folder.FSFindFolder(Folders.kUserDomain,
                                      Folders.kApplicationSupportFolderType,
                                      Folders.kDontCreateFolder)
        basepath = pathref.FSRefMakePath()
        path = pycompat.bytestr(os.path.join(basepath, 'Firefox'))
    elif platform.system() == 'Windows':
        # From http://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx
        CSIDL_APPDATA = 26
        path = pycompat.bytestr(win_get_folder_path(CSIDL_APPDATA))
        if path:
            path = os.path.join(path, b'Mozilla', b'Firefox')
    else:
        # Assume POSIX
        # Pretty simple in comparison, eh?
        path = pycompat.bytestr(os.path.expanduser('~/.mozilla/firefox'))

    # This is a backdoor to facilitate testing, since find_profiles_path()
    # doesn't need to be run-time configurable.
    path = pycompat.bytestr(os.environ.get('FIREFOX_PROFILES_DIR', path))

    return path
Beispiel #4
0
 def makecommandline(self, fieldname, value):
     if self.bzvermajor >= 4:
         return "@%s %s" % (fieldname, pycompat.bytestr(value))
     else:
         if fieldname == "id":
             fieldname = "bug_id"
         return "@%s = %s" % (fieldname, pycompat.bytestr(value))
Beispiel #5
0
    def _basictransfer(self, obj, action, localstore):
        """Download or upload a single object using basic transfer protocol

        obj: dict, an object description returned by batch API
        action: string, one of ['upload', 'download']
        localstore: blobstore.local

        See https://github.com/git-lfs/git-lfs/blob/master/docs/api/\
        basic-transfers.md
        """
        oid = pycompat.bytestr(obj['oid'])

        href = pycompat.bytestr(obj['actions'][action].get('href'))
        headers = obj['actions'][action].get('header', {}).items()

        request = util.urlreq.request(href)
        if action == 'upload':
            # If uploading blobs, read data from local blobstore.
            if not localstore.verify(oid):
                raise error.Abort(_('detected corrupt lfs object: %s') % oid,
                                  hint=_('run hg verify'))
            request.data = filewithprogress(localstore.open(oid), None)
            request.get_method = lambda: 'PUT'
            request.add_header('Content-Type', 'application/octet-stream')

        for k, v in headers:
            request.add_header(k, v)

        response = b''
        try:
            req = self.urlopener.open(request)

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

            if action == 'download':
                # If downloading blobs, store downloaded data to local blobstore
                localstore.download(oid, req)
            else:
                while True:
                    data = req.read(1048576)
                    if not data:
                        break
                    response += data
                if response:
                    self.ui.debug('lfs %s response: %s' % (action, response))
        except util.urlerr.httperror as ex:
            if self.ui.debugflag:
                self.ui.debug('%s: %s\n' % (oid, ex.read()))
            raise LfsRemoteError(_('HTTP error: %s (oid=%s, action=%s)')
                                 % (ex, oid, action))
def get_bugzilla_login_cookie_from_profile(profile, url):
    """Given a Firefox profile path, try to find the login cookies for the given bugzilla URL."""
    try:
        import sqlite3
    except:
        raise NoSQLiteError()

    cookies = os.path.join(profile, b'cookies.sqlite')
    if not os.path.exists(cookies):
        return None, None

    host = pycompat.sysstr(urllibcompat.urlreq.urlparse(url).hostname)
    path = pycompat.sysstr(urllibcompat.urlreq.urlparse(url).path)

    # Firefox locks this file, so if we can't open it (browser is running)
    # then copy it somewhere else and try to open it.
    tempdir = None
    try:
        tempdir = tempfile.mkdtemp()
        tempcookies = os.path.join(tempdir, 'cookies.sqlite')
        shutil.copyfile(cookies, tempcookies)
        # Firefox uses sqlite's WAL feature, which bumps the sqlite
        # version number. Older sqlites will refuse to open the db,
        # but the actual format is the same (just the journalling is different).
        # Patch the file to give it an older version number so we can open it.
        with open(tempcookies, 'r+b') as f:
            f.seek(18, 0)
            f.write(b'\x01\x01')
        conn = sqlite3.connect(tempcookies)
        logins = conn.execute(
            "select value, path from moz_cookies "
            "where name = 'Bugzilla_login' and (host = ? or host = ?)",
            (host, "." + host)).fetchall()
        row = sorted(logins,
                     key=lambda row: -matching_path_len(row[1], path))[0]
        login = row[0]
        cookie = conn.execute(
            "select value from moz_cookies "
            "where name = 'Bugzilla_logincookie' "
            " and (host = ? or host= ?) "
            " and path = ?", (host, "." + host, row[1])).fetchone()[0]
        conn.close()
        login = pycompat.bytestr(login)
        cookie = pycompat.bytestr(cookie)
        return login, cookie

    except IndexError:
        return None, None

    finally:
        if tempdir:
            shutil.rmtree(tempdir)
def feedentrygenerator(_context, entries, repo, url, urlbase):
    """Generator of mappings for pushlog feed entries field
    """
    for pushid, user, date, node in entries:
        ctx = scmutil.revsingle(repo, node)
        filesgen = [{b'name': fn} for fn in ctx.files()]
        yield {
            b'node': pycompat.bytestr(node),
            b'date': isotime(date),
            b'user': xmlescape(pycompat.bytestr(user)),
            b'urlbase': pycompat.bytestr(urlbase),
            b'url': pycompat.bytestr(url),
            b'files': templateutil.mappinglist(filesgen),
        }
Beispiel #8
0
def bzauth(ui, require=False, fakegetpass=None, ffprofile=None):
    if fakegetpass:
        def newgetpass(arg):
            return fakegetpass
        getpass.getpass = newgetpass

    a = getbugzillaauth(ui, require=require, profile=ffprofile)
    if a:
        ui.write(b'userid: %s\n' % pycompat.bytestr(a.userid))
        ui.write(b'cookie: %s\n' % pycompat.bytestr(a.cookie))
        ui.write(b'username: %s\n' % pycompat.bytestr(a.username))
        ui.write(b'password: %s\n' % pycompat.bytestr(a.password))
        ui.write(b'apikey: %s\n' % pycompat.bytestr(a.apikey))
    else:
        ui.write(b'no auth\n')
Beispiel #9
0
def hook(ui, repo, hooktype, node=None, **kwargs):
    if hooktype != b"pretxnclose":
        raise error.Abort(
            _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype))
    ctx = repo.unfiltered()[node]
    branches = set()
    for rev in repo.changelog.revs(start=ctx.rev()):
        rev = repo[rev]
        branches.add(rev.branch())
    for branch in branches:
        if len(repo.revs("head() and not closed() and branch(%s)",
                         branch)) > 1:
            raise error.Abort(
                _(b'Changes on branch %r resulted in multiple heads') %
                pycompat.bytestr(branch))
Beispiel #10
0
def wrappedcommit(orig, repo, *args, **kwargs):
    try:
        path_matcher = args[3]
    except IndexError:
        # In a rebase for example
        return orig(repo, *args, **kwargs)

    # In case hg changes the position of the arg
    # path_matcher will be empty in case of histedit
    assert isinstance(path_matcher, match.basematcher) or path_matcher is None

    try:
        lock = repo.wlock()
        status = repo.status(match=path_matcher)
        changed_files = sorted(status.modified + status.added)

        if changed_files:
            call_js_format(repo, changed_files)

    except Exception as e:
        repo.ui.warn(b'Exception %s\n' % pycompat.bytestr(str(e)))

    finally:
        lock.release()
        return orig(repo, *args, **kwargs)
    def __init__(self, path):
        self.path = path
        self._random = pycompat.bytestr(uuid.uuid4())

        lines = []

        if os.path.exists(path):
            with open(path, 'rb') as fh:
                for line in fh:
                    # Mercurial has special syntax to include other files.
                    # ConfigObj doesn't recognize it. Normalize on read and
                    # restore on write to preserve it.
                    if line.startswith(b'%include'):
                        line = b'#%s %s' % (self._random, line)

                    if line.startswith(b';'):
                        raise error.Abort(
                            b'semicolon (;) comments in config '
                            b'files not supported',
                            hint=b'use # for comments')

                    lines.append(line)

        self.c = ConfigObj(infile=lines,
                           encoding='utf-8',
                           write_empty_values=True,
                           list_values=False)
def _vcthome():  # Returns the directory where the vct clone is located
    here = os.path.dirname(os.path.abspath(__file__))
    ext_dir = os.path.normpath(os.path.join(here, '..'))
    vct_dir = os.path.normpath(os.path.join(ext_dir, '..'))
    vcthome_dir = os.path.normpath(os.path.join(vct_dir, '..'))

    return pycompat.bytestr(vcthome_dir)
def pushlogwireproto(repo, proto, firstpush):
    """Return pushlog data from a start offset.

    The response is a series of lines.

    The first line starts with "0" or "1". This indicates success. If the line
    starts with "0", an error message should follow. e.g.
    ``0 exception when accessing sqlite``.

    All subsequent lines describe individual pushes. The format of these lines
    is:

      <push ID> <author> <when> <node0> [<node1> [<node2> ...]]

    That is:

      * An integer ID for the push.
      * A string of the user (SSH username) who performed the push
      * Integer seconds since UNIX epoch when this push was performed
      * A list of 40 byte hex changesets included in the push, in revset order
    """
    lines = [b'1']

    try:
        firstpush = int(firstpush)

        for pushid, who, when, nodes in repo.pushlog.pushes(start_id=firstpush):
            lines.append(b'%d %s %d %s' % (pushid, who, when, b' '.join(nodes)))

        return b'\n'.join(lines)
    except Exception as e:
        return b'\n'.join([b'0', pycompat.bytestr(e)])
        def _runwsgi(self, req, res, repo):
            bytelimit = repo.ui.configint(b'badserver', b'bytelimit')

            untilgoodcount = repo.vfs.tryread(b'badserveruntilgood')
            if untilgoodcount:
                untilgoodcount = int(untilgoodcount)

            # This check is different than the one above because it is
            # comparing an int type instead of a string. The first check could
            # be true for "0" but this check would be false for int(0).
            if untilgoodcount:
                repo.vfs.write(b'badserveruntilgood',
                               pycompat.bytestr(untilgoodcount - 1))

            bytecount = 0
            for r in super(droppinghgweb, self)._runwsgi(req, res, repo):
                # We serviced the requested number of requests. Do everything
                # like normal.
                if untilgoodcount == 0:
                    yield r
                    continue

                if bytelimit:
                    if bytecount + len(r) >= bytelimit:
                        yield r[0:bytelimit - bytecount]
                        return

                bytecount += len(r)
                yield r

                bytecount += len(r)
Beispiel #15
0
def diffpatch(ui, repo, node1, node2, tmproot, matcher, cmdline):
    template = b'hg-%h.patch'
    # write patches to temporary files
    with formatter.nullformatter(ui, b'extdiff', {}) as fm:
        cmdutil.export(
            repo,
            [repo[node1].rev(), repo[node2].rev()],
            fm,
            fntemplate=repo.vfs.reljoin(tmproot, template),
            match=matcher,
        )
    label1 = cmdutil.makefilename(repo[node1], template)
    label2 = cmdutil.makefilename(repo[node2], template)
    file1 = repo.vfs.reljoin(tmproot, label1)
    file2 = repo.vfs.reljoin(tmproot, label2)
    cmdline = formatcmdline(
        cmdline,
        repo.root,
        # no 3way while comparing patches
        do3way=False,
        parent1=file1,
        plabel1=label1,
        # while comparing patches, there is no second parent
        parent2=None,
        plabel2=None,
        child=file2,
        clabel=label2,
    )
    ui.debug(b'running %r in %s\n' % (pycompat.bytestr(cmdline), tmproot))
    ui.system(cmdline, cwd=tmproot, blockedtag=b'extdiff')
    return 1
def wrappeddispatch(orig, repo, proto, command):
    """Wraps wireprotov1server.dispatch() to record command requests."""
    # TRACKING hg46
    # For historical reasons, SSH and HTTP use different log events. With
    # the unification of the dispatch code in 4.6, we could likely unify these.
    # Keep in mind this function is only called on 4.6+: 4.5 has a different
    # code path completely.

    if isinstance(proto, wireprotoserver.httpv1protocolhandler):
        logevent(repo.ui, repo._serverlog, 'BEGIN_PROTOCOL', command)
    elif isinstance(proto, wireprotoserver.sshv1protocolhandler):
        logevent(repo.ui, repo._serverlog, 'BEGIN_SSH_COMMAND', command)

        startusage = resource.getrusage(resource.RUSAGE_SELF)

        repo._serverlog.update({
            'requestid': pycompat.bytestr(uuid.uuid1()),
            'startcpu': startusage.ru_utime + startusage.ru_stime,
            'starttime': time.time(),
            'ui': weakref.ref(repo.ui),
        })
    else:
        raise error.ProgrammingError(b'unhandled protocol handler: %r' % proto)

    # If the return type is a `pushres`, `_sshv1respondbytes` will be called twice.
    # We only want to log a completed SSH event on the second call, so flip the
    # `ignorecall` flag here.
    res = orig(repo, proto, command)
    if isinstance(res, wireprototypes.pushres):
        repo._serverlog['ignorecall'] = True

    return res
Beispiel #17
0
def debuginstall(ui, fm):
    fm.write(
        b"fsmonitor-watchman",
        _(b"fsmonitor checking for watchman binary... (%s)\n"),
        ui.configpath(b"fsmonitor", b"watchman_exe"),
    )
    root = tempfile.mkdtemp()
    c = watchmanclient.client(ui, root)
    err = None
    try:
        v = c.command(b"version")
        fm.write(
            b"fsmonitor-watchman-version",
            _(b" watchman binary version %s\n"),
            pycompat.bytestr(v["version"]),
        )
    except watchmanclient.Unavailable as e:
        err = stringutil.forcebytestr(e)
    fm.condwrite(
        err,
        b"fsmonitor-watchman-error",
        _(b" watchman binary missing or broken: %s\n"),
        err,
    )
    return 1 if err else 0
Beispiel #18
0
def _handleconfigchange(ui, cw):
    # Obtain the old and new content so we can show a diff.
    newbuf = pycompat.bytesio()
    cw.write(newbuf)
    newbuf.seek(0)
    newlines = [pycompat.sysstr(l.rstrip()) for l in newbuf.readlines()]
    oldlines = []
    if os.path.exists(cw.path):
        with open(cw.path, 'rb') as fh:
            oldlines = [pycompat.sysstr(l.rstrip()) for l in fh.readlines()]

    diff = list(difflib.unified_diff(oldlines, newlines,
                                     'hgrc.old', 'hgrc.new',
                                     lineterm=''))

    if len(diff):
        ui.write(b'Your config file needs updating.\n')
        if not ui.promptchoice(b'Would you like to see a diff of the changes first (Yn)? $$ &Yes $$ &No'):
            for line in diff:
                ui.write(b'%s\n' % pycompat.bytestr(line))
            ui.write(b'\n')

        if not ui.promptchoice(b'Write changes to hgrc file (Yn)? $$ &Yes $$ &No'):
            with open(cw.path, 'wb') as fh:
                fh.write(newbuf.getvalue())
        else:
            ui.write(b'config changes not written; we would have written the following:\n')
            ui.write(newbuf.getvalue())
            return 1
Beispiel #19
0
def _releases_mapped_generator(context, builds):
    """Generates build object mappings for use in the template layer
    """
    for i, build in enumerate(builds):
        build[b'parity'] = pycompat.bytestr(i % 2)
        build[b'anchor'] = releasedb.build_anchor(build)
        yield build
Beispiel #20
0
def hook(ui, repo, hooktype, node=None, **kwargs):
    if hooktype != b"txnclose-phase":
        raise error.Abort(
            _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype))
    ctx = repo.unfiltered()[node]
    if kwargs['oldphase'] == b'draft' and kwargs['phase'] == b'public':
        _report_commit(ui, repo, ctx)
Beispiel #21
0
    def send_message(self, o, partition):
        """Send a single message from a Python object.

        The partition, if specified, overwrites whatever the default partition
        is configured as.
        """
        # Add the message created time to all messages. This is used to monitor
        # latency.
        o['_created'] = time.time()
        # We currently only support 1 message format. It is
        # "1\n" followed by a JSON payload. No length is encoded,
        # as Kafka does this for us.
        j = pycompat.bytestr(json.dumps(o, sort_keys=True))
        msg = b''.join([MESSAGE_HEADER_V1, j])

        try:
            return super(Producer, self).send_messages(self.topic, partition,
                                                       msg)

        except KafkaError:
            logger.exception('error sending message to Kafka; '
                             'reinitializing client to retry')
            self.client.reinit()

            return super(Producer, self).send_messages(self.topic, partition,
                                                       msg)
Beispiel #22
0
    def description(self):
        if self.querystart == QueryType.COUNT and not self.userquery and not self.changesetquery:
            return b''
        bits = []
        isotime = lambda x: pycompat.bytestr(
            datetime.fromtimestamp(x).isoformat(' '))
        if self.querystart == QueryType.DATE:
            bits.append(b'after %s' % isotime(self.querystart_value))
        elif self.querystart == QueryType.CHANGESET:
            bits.append(b'after changeset %s' % self.querystart_value)
        elif self.querystart == QueryType.PUSHID:
            bits.append(b'after push ID %s' % self.querystart_value)

        if self.queryend == QueryType.DATE:
            bits.append(b'before %s' % isotime(self.queryend_value))
        elif self.queryend == QueryType.CHANGESET:
            bits.append(b'up to and including changeset %s' %
                        self.queryend_value)
        elif self.queryend == QueryType.PUSHID:
            bits.append(b'up to and including push ID %s' %
                        self.queryend_value)

        if self.userquery:
            bits.append(b'by user %s' % b' or '.join(self.userquery))

        if self.changesetquery:
            bits.append(b'with changeset %s' %
                        b' and '.join(self.changesetquery))

        return b'Changes pushed ' + b', '.join(bits)
def run_command(client, args):
    """Run a Mercurial command through a client.

    This is kind of like ``client.rawcommand()`` except it performs logging
    and doesn't do fancy error handling.
    """
    combined = io.BytesIO()
    out = io.BytesIO()
    err = io.BytesIO()

    def log_combined():
        v = combined.getvalue()

        if not v or b'\n' not in v:
            return

        lines = v.splitlines()
        for line in lines:
            logger.warn('  > %s' % pycompat.sysstr(line))

        # Truncate the stream.
        combined.seek(0)
        combined.truncate()

        # Restore the final line fragment if there is one.
        if not v.endswith(b'\n'):
            combined.write(lines[-1])

    def write_out(s):
        out.write(s)
        combined.write(s)
        log_combined()

    def write_err(s):
        err.write(s)
        combined.write(s)
        log_combined()

    channels = {
        b'o': write_out,
        b'e': write_err,
    }

    quoteable_args = [
        pycompat.sysstr(arg)
        for arg in [hglib.HGPATH] + args
    ]

    logger.warn('  $ %s' % ' '.join(
        map(pipes.quote, quoteable_args)))

    unquotable_args = [
        pycompat.bytestr(arg)
        for arg in quoteable_args
    ]

    ret = client.runcommand(unquotable_args[1:], {}, channels)
    logger.warn('  [%d]' % ret)

    return ret, out.getvalue(), err.getvalue()
Beispiel #24
0
    def update(self, bugid, newstate, ctx):
        '''update bugzilla bug with reference to changeset.'''
        def webroot(root):
            '''strip leading prefix of repo root and turn into
            url-safe path.'''
            count = int(self.ui.config('bugzilla', 'strip'))
            root = util.pconvert(root)
            while count > 0:
                c = root.find('/')
                if c == -1:
                    break
                root = root[c + 1:]
                count -= 1
            return root

        mapfile = None
        tmpl = self.ui.config('bugzilla', 'template')
        if not tmpl:
            mapfile = self.ui.config('bugzilla', 'style')
        if not mapfile and not tmpl:
            tmpl = _('changeset {node|short} in repo {root} refers '
                     'to bug {bug}.\ndetails:\n\t{desc|tabindent}')
        spec = logcmdutil.templatespec(tmpl, mapfile)
        t = logcmdutil.changesettemplater(self.ui, self.repo, spec)
        self.ui.pushbuffer()
        t.show(ctx,
               changes=ctx.changeset(),
               bug=pycompat.bytestr(bugid),
               hgweb=self.ui.config('web', 'baseurl'),
               root=self.repo.root,
               webroot=webroot(self.repo.root))
        data = self.ui.popbuffer()
        self.bzdriver.updatebug(bugid, newstate, data,
                                stringutil.email(ctx.user()))
Beispiel #25
0
    def load(cls, repo):
        version = cls._getversion(repo)
        if version < cls._version:
            d = cls._readold(repo)
        elif version == cls._version:
            d = scmutil.simplekeyvaluefile(repo.vfs, cls._filename)\
                       .read(firstlinenonkeyval=True)
        else:
            raise error.Abort(_('this version of shelve is incompatible '
                                'with the version used in this repo'))

        cls._verifyandtransform(d)
        try:
            obj = cls()
            obj.name = d['name']
            obj.wctx = repo[d['originalwctx']]
            obj.pendingctx = repo[d['pendingctx']]
            obj.parents = d['parents']
            obj.nodestoremove = d['nodestoremove']
            obj.branchtorestore = d.get('branchtorestore', '')
            obj.keep = d.get('keep') == cls._keep
            obj.activebookmark = ''
            if d.get('activebook', '') != cls._noactivebook:
                obj.activebookmark = d.get('activebook', '')
        except (error.RepoLookupError, KeyError) as err:
            raise error.CorruptedState(pycompat.bytestr(err))

        return obj
def servehgmo(orig, ui, repo, *args, **kwargs):
    """Wraps commands.serve to provide --hgmo flag."""
    if kwargs.get('hgmo', False):
        kwargs['style'] = b'gitweb_mozilla'
        kwargs['templates'] = os.path.join(pycompat.bytestr(ROOT),
                                           b'hgtemplates')

        # ui.copy() is funky. Unless we do this, extension settings get
        # lost when calling hg.repository().
        ui = ui.copy()

        def setconfig(name, paths):
            ui.setconfig(
                b'extensions', name,
                os.path.join(pycompat.bytestr(ROOT), b'hgext', *paths))

        setconfig(b'firefoxreleases', [b'firefoxreleases'])
        setconfig(b'pushlog', [b'pushlog'])
        setconfig(b'pushlog-feed', [b'pushlog', b'feed.py'])

        ui.setconfig(b'web', b'logoimg', b'moz-logo-bw-rgb.svg')

        # Since new extensions may have been flagged for loading, we need
        # to obtain a new repo instance to a) trigger loading of these
        # extensions b) force extensions' reposetup function to run.
        repo = hg.repository(ui, repo.root)

    return orig(ui, repo, *args, **kwargs)
def hook(ui, repo, hooktype, node=None, **kwargs):
    if hooktype != b"txnclose":
        raise error.Abort(
            _(b'Unsupported hook type %r') % pycompat.bytestr(hooktype))
    for rev in obsutil.getobsoleted(repo, changes=kwargs['changes']):
        ctx = repo.unfiltered()[rev]
        if not has_successor(repo, ctx.node()):
            _report_commit(ui, repo, ctx)
def narrow_widen(repo, proto, oldincludes, oldexcludes, newincludes,
                 newexcludes, commonheads, cgversion, known, ellipses):
    """wireprotocol command to send data when a narrow clone is widen. We will
    be sending a changegroup here.

    The current set of arguments which are required:
    oldincludes: the old includes of the narrow copy
    oldexcludes: the old excludes of the narrow copy
    newincludes: the new includes of the narrow copy
    newexcludes: the new excludes of the narrow copy
    commonheads: list of heads which are common between the server and client
    cgversion(maybe): the changegroup version to produce
    known: list of nodes which are known on the client (used in ellipses cases)
    ellipses: whether to send ellipses data or not
    """

    preferuncompressed = False
    try:
        oldincludes = wireprototypes.decodelist(oldincludes)
        newincludes = wireprototypes.decodelist(newincludes)
        oldexcludes = wireprototypes.decodelist(oldexcludes)
        newexcludes = wireprototypes.decodelist(newexcludes)
        # validate the patterns
        narrowspec.validatepatterns(set(oldincludes))
        narrowspec.validatepatterns(set(newincludes))
        narrowspec.validatepatterns(set(oldexcludes))
        narrowspec.validatepatterns(set(newexcludes))

        common = wireprototypes.decodelist(commonheads)
        known = None
        if known:
            known = wireprototypes.decodelist(known)
        if ellipses == '0':
            ellipses = False
        else:
            ellipses = bool(ellipses)
        cgversion = cgversion
        newmatch = narrowspec.match(repo.root,
                                    include=newincludes,
                                    exclude=newexcludes)
        oldmatch = narrowspec.match(repo.root,
                                    include=oldincludes,
                                    exclude=oldexcludes)

        bundler = bundle2.widen_bundle(repo, oldmatch, newmatch, common, known,
                                       cgversion, ellipses)
    except error.Abort as exc:
        bundler = bundle2.bundle20(repo.ui)
        manargs = [('message', pycompat.bytestr(exc))]
        advargs = []
        if exc.hint is not None:
            advargs.append(('hint', exc.hint))
        bundler.addpart(bundle2.bundlepart('error:abort', manargs, advargs))
        preferuncompressed = True

    chunks = bundler.getchunks()
    return wireprototypes.streamres(gen=chunks,
                                    prefer_uncompressed=preferuncompressed)
 def pre(self, node):
     self.repo_level = repo_owner(self.repo)
     # `privilege_level` has only three allowable states: None, SCM_ALLOW_DIRECT_PUSH, and
     # and self.repo_level
     self.privilege_level = None
     self.head = None
     self.justification = None
     try:
         # The hit on LDAP should only happen once at the beginning of the check process.
         # `pre` is the only opportunity to do so before the iteration through the
         # commits in the changegroup by the `check` method.
         self.user_name, self.user_groups = get_user_and_group_affiliations(
         )
     except Exception as e:
         # The `_get_user_and_group_affiliations` method has raised an unexpected exception.
         # It is not likely an LDAP connection error because the `get_scm_groups` method
         # suppresses all LDAP exceptions in favor of logging to stderr and returning None.
         # However,`get_scm_groups` does have other opportunities to raise exceptions that
         # have not been suppressed. As we have no user information at this point, we cannot
         # let the push proceed.
         # Since this method `pre` cannot react to fatal errors, the `None` value in
         # `privilege_level` will abort this check in the future call to method `check`
         print_banner(
             self.ui, b"error",
             LDAP_USER_EXCEPTION_FAILURE_MESSAGE % pycompat.bytestr(e))
         return
     if not self.user_groups:
         # Since this method `pre` cannot react to fatal errors, the `None` value in
         # `privilege_level` will abort this check in the future call to method `check`
         print_banner(self.ui, b"error", LDAP_USER_FAILURE_MESSAGE)
         return
     elif ((self.direct_push_enabled
            or pycompat.bytestr(self.user_name) in self.landing_users)
           and SCM_ALLOW_DIRECT_PUSH in self.user_groups):
         self.privilege_level = SCM_ALLOW_DIRECT_PUSH
     elif self.repo_level in self.user_groups:
         self.privilege_level = self.repo_level
     else:
         # neither SCM_ALLOW_DIRECT_PUSH nor self.repo_level
         # Since this method `pre` cannot react to fatal errors, the `None` value in
         # `privilege_level` will abort this check in the future call to method `check`
         # Note: We should never get here, as the user will not have permission to start
         # a transaction on this repository, but provide a good error message anyway.
         print_banner(self.ui, b"error",
                      INSUFFICIENT_PRIVILEGE_FAILURE_MESSAGE)
Beispiel #30
0
def publish(name, desc, path, port):
    global server, localip
    if not server:
        ip = getip()
        if ip.startswith('127.'):
            # if we have no internet connection, this can happen.
            return
        localip = socket.inet_aton(ip)
        server = Zeroconf.Zeroconf(ip)

    hostname = socket.gethostname().split('.')[0]
    host = hostname + ".local"
    name = "%s-%s" % (hostname, name)

    # advertise to browsers
    svc = Zeroconf.ServiceInfo(
        b'_http._tcp.local.',
        pycompat.bytestr(name + '._http._tcp.local.'),
        server=host,
        port=port,
        properties={
            b'description': desc,
            b'path': b"/" + path
        },
        address=localip,
        weight=0,
        priority=0,
    )
    server.registerService(svc)

    # advertise to Mercurial clients
    svc = Zeroconf.ServiceInfo(
        b'_hg._tcp.local.',
        pycompat.bytestr(name + '._hg._tcp.local.'),
        server=host,
        port=port,
        properties={
            b'description': desc,
            b'path': b"/" + path
        },
        address=localip,
        weight=0,
        priority=0,
    )
    server.registerService(svc)
Beispiel #31
0
def dodiff(ui, repo, cmdline, pats, opts):
  """Do the actual diff."""

  revs = opts.get('rev')
  old, new = scmutil.revpair(repo, revs)

  subrepos = opts.get('subrepos')

  matcher = scmutil.match(new, pats, opts)

  status = old.status(new, matcher, listsubrepos=subrepos)
  copy = copies.pathcopies(old, new, matcher)

  mod, add, rem = map(set, status[:3])
  paths_new = mod | add
  paths_old = mod | set(copy.values())
  paths_all = paths_old | paths_new
  if not paths_all:
    return 0

  tmproot = pycompat.mkdtemp(prefix='extdiff2.')
  try:
    # Always make a copy of old
    dir_old = snapshot(ui, repo, paths_old, old.node(), tmproot, subrepos)
    dir_old = os.path.join(tmproot, dir_old)
    label_old = '@%d' % old.rev()

    # If new in not the wc, copy it
    if new.node():
      dir_new = snapshot(ui, repo, paths_new, new.node(), tmproot, subrepos)
      label_new = '@%d' % new.rev()
    else:
      # This lets the diff tool open the changed file(s) directly
      dir_new = ''
      label_new = ''

    # Diff the files instead of the directories
    # Handle bogus modifies correctly by checking if the files exist
    for path in paths_new:
      path = util.localpath(path)
      path_old = os.path.join(dir_old, copy.get(path, path))
      label_old = path + label_old
      #if not os.path.isfile(path_old):
      #path_old = os.devnull

      path_new = os.path.join(repo.root, path)
      if not dir_new:
        path_new = os.path.relpath(path_new)
      label_new = path + label_new

      # Function to quote file/dir names in the argument string.
      replace = {
          'old': path_old,
          'olabel': label_old,
          'nlabel': label_new,
          'new': path_new,
          'root': repo.root
      }

      def quote(match):
        pre = match.group(2)
        key = match.group(3)
        return pre + procutil.shellquote(replace[key])

      regex = (br"""(['"]?)([^\s'"$]*)""" br'\$(old|new|olabel|nlabel|root)\1')
      if not re.search(regex, cmdline):
        cmdline2 = cmdline + ' $old $new'
      else:
        cmdline2 = cmdline
      cmdline3 = re.sub(regex, quote, cmdline2)

      ui.write(pycompat.bytestr(cmdline3) + b'\n')
      ui.system(cmdline3, blockedtag='extdiff2')

    return 1
  finally:
    ui.note(_('cleaning up temp directory\n'))
    shutil.rmtree(tmproot)