hgext3rd/topic/revset.py
author Anton Shestakov <av6@dwimlabs.net>
Thu, 13 Sep 2018 00:04:17 +0800
changeset 4108 ef3c9ecb8099
parent 4095 aabf436c11cb
child 4290 09337aae08d4
permissions -rw-r--r--
cmdrewrite: rename variable and move it closer to where it is used Renaming to satisfy pep8-naming linter plugin, which complained on this variable because all-uppercase names are reserved for constants, and constants need to be module-level. This variable is not a good choice for moving up to the module level because it's used only in one place. Additionally, let's have it closer to the place it's actually used to potentially avoid an extra call to _() function (however cheap it may be).

from __future__ import absolute_import

from mercurial import (
    error,
    registrar,
    revset,
    util,
)

from . import (
    destination,
    stack,
)

try:
    mkmatcher = revset._stringmatcher
except AttributeError:
    try:
        from mercurial.utils import stringutil
        mkmatcher = stringutil.stringmatcher
    except (ImportError, AttributeError):
        mkmatcher = util.stringmatcher

revsetpredicate = registrar.revsetpredicate()

def getstringstrict(x, err):
    if x and x[0] == 'string':
        return x[1]
    raise error.ParseError(err)

@revsetpredicate('topic([string or set])')
def topicset(repo, subset, x):
    """All changesets with the specified topic or the topics of the given
    changesets. Without the argument, all changesets with any topic specified.

    If `string` starts with `re:` the remainder of the name is treated
    as a regular expression.
    """
    args = revset.getargs(x, 0, 1, 'topic takes one or no arguments')

    mutable = revset._notpublic(repo, revset.fullreposet(repo), ())

    if not args:
        return (subset & mutable).filter(lambda r: bool(repo[r].topic()))

    try:
        topic = getstringstrict(args[0], '')
    except error.ParseError:
        # not a string, but another revset
        pass
    else:
        kind, pattern, matcher = mkmatcher(topic)

        if topic.startswith('literal:') and pattern not in repo.topics:
            raise error.RepoLookupError("topic '%s' does not exist" % pattern)

        def matches(r):
            topic = repo[r].topic()
            if not topic:
                return False
            return matcher(topic)

        return (subset & mutable).filter(matches)

    s = revset.getset(repo, revset.fullreposet(repo), x)
    topics = {repo[r].topic() for r in s}
    topics.discard('')

    def matches(r):
        if r in s:
            return True
        topic = repo[r].topic()
        if not topic:
            return False
        return topic in topics

    return (subset & mutable).filter(matches)

@revsetpredicate('ngtip([branch])')
def ngtipset(repo, subset, x):
    """The untopiced tip.

    Name is horrible so that people change it.
    """
    args = revset.getargs(x, 1, 1, 'topic takes one')
    # match a specific topic
    branch = revset.getstring(args[0], 'ngtip() argument must be a string')
    if branch == '.':
        branch = repo['.'].branch()
    return subset & revset.baseset(destination.ngtip(repo, branch))

@revsetpredicate('stack()')
def stackset(repo, subset, x):
    """All relevant changes in the current topic,

    This is roughly equivalent to 'topic(.) - obsolete' with a sorting moving
    unstable changeset after there future parent (as if evolve where already
    run)."""
    err = 'stack() takes no argument, it works on current topic'
    revset.getargs(x, 0, 0, err)
    topic = None
    branch = None
    if repo.currenttopic:
        topic = repo.currenttopic
    else:
        branch = repo[None].branch()
    return revset.baseset(stack.stack(repo, branch=branch, topic=topic)[1:]) & subset