Exemple #1
0
def recode(s):
    if isinstance(s, pycompat.unicode):
        return s.encode(pycompat.sysstr(orig_encoding), 'replace')
    else:
        return s.decode('utf-8').encode(
            pycompat.sysstr(orig_encoding), 'replace'
        )
    def recordpushes(self, pushes, tr):
        """Record multiple pushes.

        This is effectively a version of ``recordpush()`` that accepts multiple
        pushes.

        It accepts in iterable of tuples:

          (pushid, user, time, nodes)

        Where ``nodes`` is an iterable of changeset identifiers (both bin and
        hex forms are accepted).

        The ``tr`` argument defines a Mercurial transaction to tie this
        operation to.
        """
        c = self._getconn(tr=tr)

        # Operate against unfiltered repo so we can insert entries for hidden
        # changesets.
        repo = self.repo.unfiltered()

        for pushid, user, when, nodes in pushes:
            c.execute('INSERT INTO pushlog (id, user, date) VALUES (?, ?, ?)',
                (pushid, pycompat.sysstr(user), when))
            for n in nodes:
                ctx = repo[n]
                rev = ctx.rev()
                node = ctx.hex()

                c.execute('INSERT INTO changesets (pushid, rev, node) '
                          'VALUES (?, ?, ?)', (pushid, rev, pycompat.sysstr(node)))
def pushkeyhook(ui, repo, namespace=None, key=None, old=None, new=None,
                ret=None, **kwargs):
    """Records that a pushkey update occurred."""
    # The way pushkey updates work with regards to transactions is wonky.
    # repo.pushkey() is the main function called to perform pushkey updates.
    # It's what calls hooks (like this function). However, it does not
    # necessarily have a transaction opened when called. This means that
    # there may not be an active transaction when we're called! However,
    # the low-level pushkey namespace implementations (e.g. phases.pushphase())
    # do obtain a transaction. So a transaction is involved with pushkey
    # updates.
    #
    # We don't write messages into the replication log until a transaction
    # has closed. Otherwise, transaction rollback could result in downstream
    # consumers seeing updates they shouldn't. So, we queue our messages for
    # writing. They will get flushed when the transaction associated with
    # the low-level pushkey update completes.
    #
    # Obsolescence markers are handled via a separate mechanism. So ignore
    # them.

    # Not all pushkey namespaces are consistent in their internal return
    # value. Some use int. Others bool. We want to be consistent in the type
    # written to the replication log. And int is more expressive. So we use
    # that.
    if isinstance(ret, bool):
        ret = 0 if ret else 1
    elif ret is None:
        ret = 0

    if namespace == b'obsolescence':
        return

    repo._replicationinfo['pushkey'].append(
        (pycompat.sysstr(namespace), pycompat.sysstr(key), pycompat.sysstr(old), pycompat.sysstr(new), ret))
def _promptvctextension(ui, cw, ext, msg):
    ext_path = _vctextpath(pycompat.sysstr(ext))

    # Do nothing (return) if the user has configured this extension, unless it
    # points to the directory that we manage and that directory is missing.
    users_ext_path = ui.config(b'extensions', ext)
    if users_ext_path != None:
        users_ext_path = pycompat.fsdecode(
            util.normpath(util.expandpath(users_ext_path)))
        if users_ext_path != ext_path or os.path.exists(ext_path):
            return

    # Verify the extension loads before prompting to enable it. This is
    # done out of paranoia.

    # Even if we launch hg.exe, sys.argv[0] is "hg" on Windows. Since "hg" isn't
    # a Windows application, we can't simply run it. So change to the ".exe"
    # variant if necessary.
    hg = sys.argv[0]
    if sys.platform in ('win32', 'msys') and hg.endswith('hg'):
        hg += '.exe'

    result = subprocess.check_output([
        hg, '--config',
        'extensions.testmodule=%s' % ext_path, '--config', 'ui.traceback=true'
    ],
                                     stderr=subprocess.STDOUT)
    if b'Traceback' in result:
        return

    if uipromptchoice(ui, b'%s (Yn) $$ &Yes $$ &No' % msg):
        return

    _enableext(cw, pycompat.sysstr(ext), ext_path)
def changegrouphook(ui, repo, node=None, source=None, **kwargs):
    """Record replication events after a changegroup has been added."""
    start = time.time()

    heads = set(repo.heads())
    pushnodes = []
    pushheads = []

    for rev in range(repo[node].rev(), len(repo)):
        ctx = repo[rev]

        pushnodes.append(pycompat.sysstr(ctx.hex()))

        if ctx.node() in heads:
            pushheads.append(pycompat.sysstr(ctx.hex()))

    with ui.kafkainteraction():
        repo.producerlog('CHANGEGROUPHOOK_SENDING')
        vcsrproducer.record_hg_changegroup(ui.replicationproducer,
                                           repo.replicationwireprotopath,
                                           pycompat.sysstr(source),
                                           pushnodes,
                                           pushheads,
                                           partition=repo.replicationpartition)
        duration = time.time() - start
        repo.producerlog('CHANGEGROUPHOOK_SENT')
        ui.status(_(b'recorded changegroup in replication log in %.3fs\n') %
                    duration)

        for key, value in sorted(repo._replicationinfo['obsolescence'].items()):
            sendpushkeymessage(ui, repo, 'obsolete', pycompat.sysstr(key), '', pycompat.sysstr(value), 0)
    def recordpush(self, nodes, user, when):
        '''Record a push into the pushlog.

        A push consists of a list of nodes, a username, and a time of the
        push.

        This function assumes it is running in the context of a transaction.
        There are valid scenarios where this may not hold true. However, we
        don't have a need to support them, so we error in these scenarios.
        '''
        c = self._getconn(tr=self.repo._transref())

        # Operate against unfiltered repo so we can insert entries for hidden
        # changesets.
        repo = self.repo.unfiltered()

        # Now that the hooks are installed, any exceptions will result in db
        # close via one of our abort handlers.
        res = c.execute('INSERT INTO pushlog (user, date) VALUES (?, ?)',
                        (pycompat.sysstr(user), when))
        pushid = res.lastrowid
        for e in nodes:
            ctx = repo[e]
            rev = ctx.rev()
            node = ctx.hex()

            c.execute('INSERT INTO changesets (pushid, rev, node) '
                      'VALUES (?, ?, ?)', (pushid, rev, pycompat.sysstr(node)))
Exemple #7
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
        def replicationwireprotopath(self):
            """Return the path to this repo as it is represented over wire.

            By setting entries in the [replicationpathrewrites] section, you can
            effectively normalize filesystem paths to a portable representation.
            For example, say all Mercurial repositories are stored in
            ``/repos/hg/`` on the local filesystem. You could create a rewrite
            rule as follows:

               [replicationpathrewrites]
               /repos/hg/ = {hg}/

            Over the wire, a local path such as ``/repos/hg/my-repo`` would be
            normalized to ``{hg}/my-repo``.

            Then on the consumer, you could design the opposite to map the
            repository to a different filesystem path. e.g.:

               [replicationpathrewrites]
               {hg}/ = /mirror/hg/

            The consumer would then expand the path to ``/mirror/hg/my-repo``.

            Matches are case insensitive but rewrites are case preserving.
            """
            lower = pycompat.sysstr(self.root.lower())
            for source, dest in self.ui.configitems(b'replicationpathrewrites'):
                if lower.startswith(pycompat.sysstr(source)):
                    return pycompat.sysstr(dest) + pycompat.sysstr(self.root[len(source):])

            raise error.Abort(b'repository path not configured for replication',
                              hint=b'add entry to [replicationpathrewrites]')
def logsyslog(ui, message):
    """Log a formatted message to syslog."""
    ident = pycompat.sysstr(ui.config(b'serverlog', b'syslog.ident'))
    facility_config = pycompat.sysstr(ui.config(b'serverlog', b'syslog.facility'))
    facility = getattr(syslog, facility_config)

    syslog.openlog(ident, 0, facility)
    syslog.syslog(syslog.LOG_NOTICE, pycompat.sysstr(message))
    syslog.closelog()
Exemple #10
0
def _updatedocstring():
    longest = max(map(len, showview._table.keys()))
    entries = []
    for key in sorted(showview._table.keys()):
        entries.append(pycompat.sysstr('    %s   %s' % (
            key.ljust(longest), showview._table[key]._origdoc)))

    cmdtable['show'][0].__doc__ = pycompat.sysstr('%s\n\n%s\n    ') % (
        cmdtable['show'][0].__doc__.rstrip(),
        pycompat.sysstr('\n\n').join(entries))
Exemple #11
0
def generate_css(web):
    pg_style = web.config(b'web', b'pygments_style', b'colorful')
    fmter = highlight.HtmlFormatter(style=pycompat.sysstr(pg_style))
    web.res.headers[b'Content-Type'] = b'text/css'
    style_defs = fmter.get_style_defs(pycompat.sysstr(b''))
    web.res.setbodybytes(b''.join([
        b'/* pygments_style = %s */\n\n' % pg_style,
        pycompat.bytestr(style_defs),
    ]))
    return web.res.sendresponse()
def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):

    # append a <link ...> to the syntax highlighting css
    tmpl.load(b'header')
    old_header = tmpl.cache[b'header']
    if SYNTAX_CSS not in old_header:
        new_header = old_header + SYNTAX_CSS
        tmpl.cache[b'header'] = new_header

    text = fctx.data()
    if stringutil.binary(text):
        return

    # str.splitlines() != unicode.splitlines() because "reasons"
    for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
        if c in text:
            text = text.replace(c, b'')

    # Pygments is best used with Unicode strings:
    # <http://pygments.org/docs/unicode/>
    text = text.decode(pycompat.sysstr(encoding.encoding), 'replace')

    # To get multi-line strings right, we can't format line-by-line
    try:
        path = pycompat.sysstr(fctx.path())
        lexer = guess_lexer_for_filename(path, text[:1024], stripnl=False)
    except (ClassNotFound, ValueError):
        # guess_lexer will return a lexer if *any* lexer matches. There is
        # no way to specify a minimum match score. This can give a high rate of
        # false positives on files with an unknown filename pattern.
        if guessfilenameonly:
            return

        try:
            lexer = guess_lexer(text[:1024], stripnl=False)
        except (ClassNotFound, ValueError):
            # Don't highlight unknown files
            return

    # Don't highlight text files
    if isinstance(lexer, TextLexer):
        return

    formatter = HtmlFormatter(nowrap=True, style=pycompat.sysstr(style))

    colorized = highlight(text, lexer, formatter)
    coloriter = (s.encode(pycompat.sysstr(encoding.encoding), 'replace')
                 for s in colorized.splitlines())

    tmpl._filters[b'colorize'] = lambda x: next(coloriter)

    oldl = tmpl.cache[field]
    newl = oldl.replace(b'line|escape', b'line|colorize')
    tmpl.cache[field] = newl
    def handledestroyed(self):
        """Handle a destroyed event in the repository.

        This is called when changesets have been destroyed from the repository.
        This function will reconcile the state of the pushlog to match new
        reality.

        Push IDs are explicitly not deleted. However, they may become empty.
        """
        repo = self.repo

        with self.conn() as c:
            if not c:
                return

            res = c.execute('SELECT pushid, rev, node FROM changesets '
                            'ORDER BY pushid, rev ASC')

            deletes = []
            revupdates = []

            for pushid, rev, node in res:
                try:
                    ctx = repo[node]
                    # Changeset has new ordering in revlog. Correct it.
                    if ctx.rev() != rev:
                        revupdates.append((node, ctx.rev()))
                        repo.ui.warn(b'changeset rev will be updated in '
                                     b'pushlog: %s\n' % node)
                except RepoLookupError:
                    # The changeset was stripped. Remove it from the pushlog.
                    deletes.append(node)
                    repo.ui.warn(b'changeset will be deleted from '
                                 b'pushlog: %s\n' % node)

            for node in deletes:
                c.execute('DELETE FROM changesets WHERE node = ?',
                          (pycompat.sysstr(node), ))

            if deletes:
                repo.ui.log(
                    b'pushlog', b'deleted %d changesets from pushlog: %s\n' %
                    (len(deletes), b', '.join(deletes)))

            for node, rev in revupdates:
                c.execute('UPDATE changesets SET rev=? WHERE node=?',
                          (rev, pycompat.sysstr(node)))

            if revupdates:
                repo.ui.log(
                    b'pushlog',
                    b'reordered %d changesets in pushlog\n' % len(revupdates))

            c.commit()
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)
Exemple #15
0
    def recode(self, s, encoding=None):
        if not encoding:
            encoding = self.encoding or 'utf-8'

        if isinstance(s, pycompat.unicode):
            return s.encode("utf-8")
        try:
            return s.decode(pycompat.sysstr(encoding)).encode("utf-8")
        except UnicodeError:
            try:
                return s.decode("latin-1").encode("utf-8")
            except UnicodeError:
                return s.decode(pycompat.sysstr(encoding),
                                "replace").encode("utf-8")
 def verify(self, data, sig):
     """ returns of the good and bad signatures"""
     sigfile = datafile = None
     try:
         # create temporary files
         fd, sigfile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".sig")
         fp = os.fdopen(fd, pycompat.sysstr('wb'))
         fp.write(sig)
         fp.close()
         fd, datafile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".txt")
         fp = os.fdopen(fd, pycompat.sysstr('wb'))
         fp.write(data)
         fp.close()
         gpgcmd = ("%s --logger-fd 1 --status-fd 1 --verify "
                   "\"%s\" \"%s\"" % (self.path, sigfile, datafile))
         ret = util.filter("", gpgcmd)
     finally:
         for f in (sigfile, datafile):
             try:
                 if f:
                     os.unlink(f)
             except OSError:
                 pass
     keys = []
     key, fingerprint = None, None
     for l in ret.splitlines():
         # see DETAILS in the gnupg documentation
         # filter the logger output
         if not l.startswith("[GNUPG:]"):
             continue
         l = l[9:]
         if l.startswith("VALIDSIG"):
             # fingerprint of the primary key
             fingerprint = l.split()[10]
         elif l.startswith("ERRSIG"):
             key = l.split(" ", 3)[:2]
             key.append("")
             fingerprint = None
         elif (l.startswith("GOODSIG") or
               l.startswith("EXPSIG") or
               l.startswith("EXPKEYSIG") or
               l.startswith("BADSIG")):
             if key is not None:
                 keys.append(key + [fingerprint])
             key = l.split(" ", 2)
             fingerprint = None
     if key is not None:
         keys.append(key + [fingerprint])
     return keys
Exemple #17
0
def _get_pushlog_info(hgclient, public_url, revs):
    template = b'{node}\\0{pushid}\\0{pushuser}\\0{pushdate|hgdate}\n'
    args = hglib.util.cmdbuilder(b'log', hidden=True, r=revs, template=template)
    out = hgclient.rawcommand(args)

    pushes = {}

    for line in out.splitlines():
        line = line.strip()
        if not line:
            continue

        node, pushid, pushuser, pushtime = line.split(b'\0')
        # Not all changegroup events have corresponding pushlog entries.
        # This should be rare.
        if not pushid:
            logger.warn('pushlog data missing!')
            continue

        pushid = int(pushid)

        # `hgdate` format is "timestamp offset"
        pushtime = int(pushtime.split()[0])

        q = 'startID=%d&endID=%d' % (pushid - 1, pushid)

        pushes.setdefault(pushid, {
            'pushid': pushid,
            'user': pycompat.sysstr(pushuser),
            'time': pushtime,
            'push_json_url': '%s/json-pushes?version=2&%s' % (public_url, q),
            'push_full_json_url': '%s/json-pushes?version=2&full=1&%s' % (public_url, q),
        })

    return pushes
def sendheadsmessage(ui, repo, success=True):
    """Repo-unlock callback function to send a message
    notifying callers about the new heads

    TRACKING hg53: make `success` default to `False`
    """
    # Don't send the heads message if the unlock was not a success
    if not success:
        return

    heads = [
        pycompat.sysstr(hex(n))
        for n in repo.filtered(b'served').heads()
    ]

    # Pull numeric push ID from the pushlog extensions, if available.
    if util.safehasattr(repo, 'pushlog'):
        last_push_id = repo.pushlog.lastpushid()
    else:
        last_push_id = None

    with ui.kafkainteraction():
        repo.producerlog('HEADS_SENDING')
        producer = ui.replicationproducer
        vcsrproducer.record_hg_repo_heads(producer,
                                          repo.replicationwireprotopath,
                                          heads,
                                          last_push_id,
                                          partition=repo.replicationpartition)

        repo.producerlog('HEADS_SENT')
Exemple #19
0
 def testtimedcmstatsstr(self):
     stats = util.timedcmstats()
     self.assertEqual(str(stats), '<unknown>')
     self.assertEqual(bytes(stats), b'<unknown>')
     stats.elapsed = 12.34
     self.assertEqual(str(stats), pycompat.sysstr(util.timecount(12.34)))
     self.assertEqual(bytes(stats), util.timecount(12.34))
Exemple #20
0
def togitnode(n):
    """Wrapper to convert a Mercurial binary node to a unicode hexlified node.

    pygit2 and sqlite both need nodes as strings, not bytes.
    """
    assert len(n) == 20
    return pycompat.sysstr(hex(n))
Exemple #21
0
 def __init__(self, path, cmdline):
     # We can't pass non-ASCII through docstrings (and path is
     # in an unknown encoding anyway), but avoid double separators on
     # Windows
     docpath = stringutil.escapestr(path).replace(b'\\\\', b'\\')
     self.__doc__ %= {r'path': pycompat.sysstr(stringutil.uirepr(docpath))}
     self._cmdline = cmdline
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()
Exemple #23
0
    def filter(self, filter, node, changelog, patchfile):
        '''arbitrarily rewrite changeset before applying it'''

        self.ui.status(_('filtering %s\n') % patchfile)
        user, date, msg = (changelog[1], changelog[2], changelog[4])
        fd, headerfile = tempfile.mkstemp(prefix='hg-transplant-')
        fp = os.fdopen(fd, pycompat.sysstr('w'))
        fp.write("# HG changeset patch\n")
        fp.write("# User %s\n" % user)
        fp.write("# Date %d %d\n" % date)
        fp.write(msg + '\n')
        fp.close()

        try:
            self.ui.system('%s %s %s' % (filter, util.shellquote(headerfile),
                                         util.shellquote(patchfile)),
                           environ={
                               'HGUSER': changelog[1],
                               'HGREVISION': nodemod.hex(node),
                           },
                           onerr=error.Abort,
                           errprefix=_('filter failed'),
                           blockedtag='transplant_filter')
            user, date, msg = self.parselog(file(headerfile))[1:4]
        finally:
            os.unlink(headerfile)

        return (user, date, msg)
Exemple #24
0
 def read(self, oid):
     # store.read() calls into here if the blob doesn't exist in its
     # self.vfs.  Raise the same error as a normal vfs when asked to read a
     # file that doesn't exist.  The only difference is the full file path
     # isn't available in the error.
     raise IOError(errno.ENOENT,
                   pycompat.sysstr(b'%s: No such file or directory' % oid))
Exemple #25
0
 def __init__(self, path, cmdline):
   # We can't pass non-ASCII through docstrings (and path is
   # in an unknown encoding anyway), but avoid double separators on
   # Windows
   docpath = stringutil.escapestr(path).replace(b'\\\\', b'\\')
   self.__doc__ %= {r'path': pycompat.sysstr(stringutil.uirepr(docpath))}
   self._cmdline = cmdline
    def _push_from_node(self, conn, node):
        res = conn.execute('SELECT pushid from changesets WHERE node=?',
                           (pycompat.sysstr(hex(node)),)).fetchone()
        if not res:
            return None

        return self.pushfromid(conn, res[0])
def _promptnativeextension(ui, cw, ext, msg):
    if ui.hasconfig(b'extensions', ext):
        return

    if not uipromptchoice(ui, b'%s (Yn) $$ &Yes $$ &No' % msg):
        if 'extensions' not in cw.c:
            cw.c['extensions'] = {}

        cw.c['extensions'][pycompat.sysstr(ext)] = ''
def read_consumer_groups(path):
    consumer_groups = []
    with open(path, 'rb') as fh:
        for line in fh:
            line = line.strip()
            if line:
                consumer_groups.append(pycompat.sysstr(line))

    return consumer_groups
        def replicationpartitionmap(self):
            pm = {}
            replicationproduceritems = (
                (pycompat.sysstr(k), pycompat.sysstr(v),)
                for k, v in self.configitems(b'replicationproducer')
            )
            for k, v in replicationproduceritems:
                # Ignore unrelated options in this section.
                if not k.startswith('partitionmap.'):
                    continue

                parts, expr = v.split(':', 1)
                parts = [int(x.strip()) for x in parts.split(',')]
                pm[k[len('partitionmap.'):]] = (parts, re.compile(expr))

            if not pm:
                raise error.Abort(_(b'partitions not defined'))

            return pm
Exemple #30
0
def _checkevolve(ui, cw, hg_version):
    if hg_version < (4, 3, 0):
        ui.warn(EVOLVE_INCOMPATIBLE)
        return

    remote_evolve_path = b'https://www.mercurial-scm.org/repo/evolve/'
    # Install to the same dir as v-c-t, unless the mozbuild directory path is passed (testing)
    evolve_clone_dir = ui.config(b'mozilla', b'mozbuild_state_path', _vcthome())

    local_evolve_path = b'%(evolve_clone_dir)s/evolve' % {b'evolve_clone_dir': evolve_clone_dir}
    evolve_config_value = os.path.normpath('%(evolve_path)s/hgext3rd/evolve' % \
                                           {'evolve_path': pycompat.sysstr(local_evolve_path)})

    users_evolve_path = ui.config(b'extensions', b'evolve')
    if users_evolve_path:
        users_evolve_path = os.path.normpath(pycompat.fsdecode(util.normpath(util.expandpath(users_evolve_path))))

    # If evolve is not installed, install it. (If the user's path to evolve is
    # the path that we manage, but it doesn't exist yet, assume that their
    # config file has been copied to a new machine and we need to clone evolve.
    if users_evolve_path == None or \
            (users_evolve_path == evolve_config_value and not os.path.exists(evolve_config_value)):
        if uipromptchoice(ui, EVOLVE_INFO_WARNING):
            return

        try:
            # Clone the evolve extension and enable
            hg.clone(ui, {}, remote_evolve_path, branch=(b'stable',), dest=local_evolve_path)
            _enableext(cw, 'evolve', evolve_config_value)

            ui.write(b'Evolve was downloaded successfully.\n')

        except error.Abort as hg_err:
            ui.write(pycompat.bytestr(hg_err))
            ui.write(EVOLVE_CLONE_ERROR)

        return

    # If evolve is installed and managed by this wizard,
    # update it via pull/update
    if users_evolve_path == evolve_config_value:
        if uipromptchoice(ui, EVOLVE_UPDATE_PROMPT % {b'evolve_dir': local_evolve_path}):
            return

        try:
            local_evolve_repo = hg.repository(ui, local_evolve_path)

            # Pull the latest stable, update to tip
            hgpull(ui, local_evolve_repo, source=remote_evolve_path, branch=(b'stable',))
            hgupdate(ui, local_evolve_repo, rev=b'stable')

            ui.write(b'Evolve was updated successfully.\n')

        except error.Abort as hg_err:
            ui.write(EVOLVE_CLONE_ERROR)
Exemple #31
0
def decode_guess(string, encoding):
    # text is not valid utf-8, try to make sense of it
    if encoding:
        try:
            return string.decode(pycompat.sysstr(encoding)).encode('utf-8')
        except UnicodeDecodeError:
            pass

    try:
        return string.decode('latin-1').encode('utf-8')
    except UnicodeDecodeError:
        return string.decode('ascii', 'replace').encode('utf-8')