Ejemplo n.º 1
0
def critique(ui, repo, entire=False, node=None, **kwargs):
    """Perform a critique of a changeset."""
    # We run into weird import issues when running static analysis if the
    # demandimporter is enabled.
    with demandimport.deactivated():
        from flake8.engine import get_style_guide
        from pep8 import DiffReport, parse_udiff

        style = get_style_guide(parse_argv=False, ignore='E128')

        ctx = repo[node]

        # Tell the reporter to ignore lines we didn't touch as part of this change.
        if not entire:
            diff = ''.join(ctx.diff())
            style.options.selected_lines = {}
            for k, v in parse_udiff(diff).items():
                if k.startswith('./'):
                    k = k[2:]

                style.options.selected_lines[k] = v

            style.options.report = DiffReport(style.options)

        deleted = repo.status(ctx.p1().node(), ctx.node()).deleted
        files = [f for f in ctx.files() if f.endswith('.py') and f not in deleted]
        style.check_files(files)
Ejemplo n.º 2
0
def critique(ui, repo, entire=False, node=None, **kwargs):
    """Perform a critique of a changeset."""
    # We run into weird import issues when running static analysis if the
    # demandimporter is enabled.
    with demandimport.deactivated():
        from flake8.engine import get_style_guide
        from pep8 import DiffReport, parse_udiff

        style = get_style_guide(parse_argv=False, ignore='E128')

        ctx = repo[node]

        # Tell the reporter to ignore lines we didn't touch as part of this change.
        if not entire:
            diff = ''.join(ctx.diff())
            style.options.selected_lines = {}
            for k, v in parse_udiff(diff).items():
                if k.startswith('./'):
                    k = k[2:]

                style.options.selected_lines[k] = v

            style.options.report = DiffReport(style.options)

        deleted = repo.status(ctx.p1().node(), ctx.node()).deleted
        files = [
            f for f in ctx.files() if f.endswith('.py') and f not in deleted
        ]
        style.check_files(files)
def pullreviews(repo, proto, args=None):
    proto.redirect()
    req = parsejsonpayload(proto, args)

    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient
    client = ReviewBoardClient(repo.ui.config('reviewboard', 'url').rstrip('/'),
                               username=req.get('bzusername'),
                               apikey=req.get('bzapikey'))
    root = client.get_root()

    res = {
        'reviewrequests': {},
    }

    for identifier in req.get('identifiers', []):
        rrs = root.get_review_requests(commit_id=identifier)

        if rrs.total_results != 1:
            continue

        rr = rrs[0]
        commit_data = client.get_path(
            '/extensions/mozreview.extension.MozReviewExtension/'
            'commit-data/%s/' % rr.id)

        try:
            is_squashed = commit_data.extra_data['p2rb.is_squashed']
        except KeyError:
            is_squashed = None

        # 'True' in RB <= 2.0.11; True in 2.0.11+. We may have old
        # values in the database, so keep checking for 'True' until we
        # have a migration.
        if is_squashed is True or is_squashed == 'True':
            if 'p2rb.commits' in commit_data.extra_data:
                commits = commit_data.extra_data['p2rb.commits']
            else:
                draft = rr.get_draft()
                if 'p2rb.commits' in commit_data.draft_extra_data:
                    commits = commit_data.draft_extra_data['p2rb.commits']
                else:
                    commits = '[]'

            for relation in json.loads(commits):
                rid = str(relation[1])

                res['reviewrequests'][str(rid)] = {
                    'status': rr.status,
                    'public': rr.public,
                }

        res['reviewrequests'][str(rr.id)] = {
            'status': rr.status,
            'public': rr.public,
            'reviewers': [p.title for p in rr.target_people],
        }

    return json.dumps(res, sort_keys=True)
Ejemplo n.º 4
0
def _processpublishreview(repo, req):
    from rbtools.api.errors import APIError
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient
    client = ReviewBoardClient(repo.ui.config('reviewboard',
                                              'url').rstrip('/'),
                               username=req['bzusername'],
                               apikey=req['bzapikey'])
    root = client.get_root()

    res = {
        'results': [],
    }

    for rrid in req.get('rrids', []):
        try:
            rr = root.get_review_request(review_request_id=rrid)
            draft = rr.get_draft()
            draft.update(public=True)
            res['results'].append({'rrid': rrid, 'success': True})
        except APIError as e:
            res['results'].append({'rrid': rrid, 'error': str(e)})

    return res
def submit_reviews(url, repoid, identifier, commits, privileged_username,
                   privileged_password, username=None, apikey=None):
    """Submit commits to Review Board."""
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient

    client = ReviewBoardClient(url, username=privileged_username,
                               password=privileged_password)
    root = client.get_root()

    batch_request_resource = root.get_extension(
        extension_name='mozreview.extension.MozReviewExtension')\
        .get_batch_review_requests()
    series_result = batch_request_resource.create(
        username=username,
        api_key=apikey,
        # This assumes that we pushed to the repository/URL that Review Board is
        # configured to use. This assumption may not always hold.
        repo_id=repoid,
        identifier=identifier,
        commits=json.dumps(commits, encoding='utf-8'))

    nodes = {node.encode('utf-8'): str(rid)
             for node, rid in series_result.nodes.iteritems()}

    return (
        str(series_result.squashed_rr),
        nodes,
        series_result.review_requests,
        series_result.warnings,
    )
Ejemplo n.º 6
0
def critique(ui, repo, entire=False, node=None, **kwargs):
    """Perform a critique of a changeset."""
    with demandimport.deactivated():
        from flake8.engine import get_style_guide
        from pycodestyle import DiffReport, parse_udiff

        style = get_style_guide(parse_argv=False, ignore='E128')

        ctx = repo[node]

        if not entire:
            diff = ''.join(ctx.diff())
            style.options.selected_lines = {}
            for k, v in parse_udiff(diff).items():
                if k.startswith('./'):
                    k = k[2:]

                style.options.selected_lines[k] = v

            style.options.report = DiffReport(style.options)

        deleted = repo.status(ctx.p1().node(), ctx.node())[2]
        files = [
            f for f in ctx.files() if f.endswith('.py') and f not in deleted
        ]
        for f in files:
            data = ctx.filectx(f).data()
            style.input_file(f, lines=data.splitlines())
Ejemplo n.º 7
0
def _try_curses_import():
    '''Attempt to import curses, returning `True`
    on success'''
    with demandimport.deactivated():
        try:
            import curses
        except Exception:
            try:
                import wcurses
            except Exception:
                return False

    return True
    def _log_push_attempt(self, event_message):
        """send an event message to Sentry
        parameters:
            event_message - a string with the text of the event message
        """
        sentry_dsn = self.ui.config(b"mozilla", b"sentry_dsn")
        if not sentry_dsn:
            # the sentry_dsn was an empty string - write to stdout instead of using sentry
            self.ui.write(b"%s\n" % event_message)
            return

        # `sentry_sdk` doesn't like the demandimporter. Deactivate it,
        # and only import when we need to ping Sentry.
        with demandimport.deactivated():
            import sentry_sdk

        try:
            sentry_sdk.init(sentry_dsn)

            sentry_head = self.head.decode("utf-8")
            sentry_repo = self.repo_name.decode("utf-8")

            with sentry_sdk.push_scope() as scope:
                scope.user = {"username": self.user_name}
                scope.set_tag("repo", sentry_repo)
                scope.set_tag("scm_level",
                              self.privilege_level.decode("utf-8"))
                scope.set_extra("changeset", sentry_head)
                scope.set_extra("justification",
                                self.justification.decode("utf-8"))
                scope.set_extra(
                    "url", REV_URL % {
                        "repo": sentry_repo,
                        "rev": sentry_head,
                    })

                sentry_sdk.capture_message(event_message.decode("utf-8"))

        except Exception as e:
            # The Sentry Documentation does not mention any exceptions that it could raise.
            # Inspection of the unified sentry-sdk source code shows that Sentry does not define
            # an exception hierarchy of its own. Therefore, we cannot predict what exceptions
            # might be raised during the connection and reporting phases: we have no choice but
            # to capture all exceptions.
            # If connecting to Sentry or reporting via Sentry fails, we do not want to derail the
            # users' intent on pushing.  We have nowhere to log the failure, so we notify the
            # user with a warning and proceed as if nothing bad had happened.
            print_banner(self.ui, b"warning",
                         SENTRY_FAILURE_WARNING_MESSAGE % pycompat.bytestr(e))
Ejemplo n.º 9
0
def _checkcurses(ui, cw):
    if ui.hasconfig('ui', 'interface'):
        return

    # curses isn't available on all platforms. Don't prompt if not
    # available.
    with demandimport.deactivated():
        try:
            import curses
        except Exception:
            try:
                import wcurses
            except Exception:
                return

    if ui.promptchoice(CURSES_INFO):
        return

    cw.c.setdefault('ui', {})
    cw.c['ui']['interface'] = 'curses'
Ejemplo n.º 10
0
def submit_reviews(url,
                   repoid,
                   identifier,
                   commits,
                   privileged_username,
                   privileged_password,
                   username=None,
                   apikey=None):
    """Submit commits to Review Board."""
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient

    client = ReviewBoardClient(url,
                               username=privileged_username,
                               password=privileged_password)
    root = client.get_root()

    batch_request_resource = root.get_extension(
        extension_name='mozreview.extension.MozReviewExtension')\
        .get_batch_review_requests()
    series_result = batch_request_resource.create(
        username=username,
        api_key=apikey,
        # This assumes that we pushed to the repository/URL that Review Board is
        # configured to use. This assumption may not always hold.
        repo_id=repoid,
        identifier=identifier,
        commits=json.dumps(commits, encoding='utf-8'))

    nodes = {
        node.encode('utf-8'): str(rid)
        for node, rid in series_result.nodes.iteritems()
    }

    return (
        str(series_result.squashed_rr),
        nodes,
        series_result.review_requests,
        series_result.warnings,
    )
Ejemplo n.º 11
0
def getreposfromreviewboard(repo):
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient

    client = ReviewBoardClient(repo.ui.config('reviewboard', 'url').rstrip('/'))
    root = client.get_root()
    urls = set()

    repos = root.get_repositories(max_results=250, tool='Mercurial')
    try:
        while True:
            for r in repos:
                urls.add(r.path)

            repos = repos.get_next()

    except StopIteration:
        pass

    return urls
Ejemplo n.º 12
0
def getreposfromreviewboard(repo):
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient

    client = ReviewBoardClient(repo.ui.config('reviewboard', 'url').rstrip('/'))
    root = client.get_root()
    urls = set()

    repos = root.get_repositories(max_results=250, tool='Mercurial')
    try:
        while True:
            for r in repos:
                urls.add(r.path)

            repos = repos.get_next()

    except StopIteration:
        pass

    return urls
Ejemplo n.º 13
0
def debugshell(ui, repo, **opts):
    bannermsg = "loaded repo : %s\n" \
                "using source: %s" % (repo.root,
                                      mercurial.__path__[0])

    pdbmap = {'pdb': 'code', 'ipdb': 'IPython'}

    debugger = ui.config("ui", "debugger")
    if not debugger:
        debugger = 'pdb'

    # if IPython doesn't exist, fallback to code.interact
    try:
        with demandimport.deactivated():
            __import__(pdbmap[debugger])
    except ImportError:
        ui.warn(("%s debugger specified but %s module was not found\n") %
                (debugger, pdbmap[debugger]))
        debugger = 'pdb'

    getattr(sys.modules[__name__], debugger)(ui, repo, bannermsg, **opts)
Ejemplo n.º 14
0
def debugshell(ui, repo, **opts):
    bannermsg = "loaded repo : %s\n" \
                "using source: %s" % (repo.root,
                                      mercurial.__path__[0])

    pdbmap = {
        'pdb'  : 'code',
        'ipdb' : 'IPython'
    }

    debugger = ui.config("ui", "debugger")
    if not debugger:
        debugger = 'pdb'

    # if IPython doesn't exist, fallback to code.interact
    try:
        with demandimport.deactivated():
            __import__(pdbmap[debugger])
    except ImportError:
        ui.warn("%s debugger specified but %s module was not found\n"
                % (debugger, pdbmap[debugger]))
        debugger = 'pdb'

    getattr(sys.modules[__name__], debugger)(ui, repo, bannermsg, **opts)
Ejemplo n.º 15
0
def _processpublishreview(repo, req):
    from rbtools.api.errors import APIError
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient
    client = ReviewBoardClient(repo.ui.config('reviewboard', 'url').rstrip('/'),
                               username=req['bzusername'],
                               apikey=req['bzapikey'])
    root = client.get_root()

    res = {
        'results': [],
    }

    for rrid in req.get('rrids', []):
        try:
            rr = root.get_review_request(review_request_id=rrid)
            draft = rr.get_draft()
            draft.update(public=True)
            res['results'].append({'rrid': rrid, 'success': True})
        except APIError as e:
            res['results'].append({'rrid': rrid, 'error': str(e)})

    return res
Ejemplo n.º 16
0
def extsetup(ui):
    '''Dynamically import the cache plugin and monkeypatch
    the required functions to enable caching
    '''
    plugin = ui.config('wireprotocache', 'plugin')

    # grab the correct import name from the __module__
    # value of this function. expecting a value like
    # `hgext_wireprotocache` due to the way Mercurial
    # loads extensions
    module = '%s.%s' % (extsetup.__module__, plugin)

    with demandimport.deactivated():
        cache_module = importlib.import_module(module)

    # Ensure the imported module has the required patching functions
    for attr in cache_module_attrs:
        assert util.safehasattr(cache_module, attr), \
            'function %s missing from %s' % (attr, plugin)

    extensions.wrapfunction(wireprotov2server, 'makeresponsecacher',
                            cache_module.makeresponsecacher)
    extensions.wrapfunction(wireprotov2server, 'getadvertisedredirecttargets',
                            cache_module.getadvertisedredirecttargets)
Ejemplo n.º 17
0
#
# The original module was split in an interface and an implementation
# file to defer pygments loading and speedup extension setup.

from __future__ import absolute_import

from mercurial import demandimport
demandimport.IGNORES.update(['pkgutil', 'pkg_resources', '__main__'])

from mercurial import (
    encoding, )

from mercurial.utils import (
    stringutil, )

with demandimport.deactivated():
    import pygments
    import pygments.formatters
    import pygments.lexers
    import pygments.plugin
    import pygments.util

    for unused in pygments.plugin.find_plugin_lexers():
        pass

highlight = pygments.highlight
ClassNotFound = pygments.util.ClassNotFound
guess_lexer = pygments.lexers.guess_lexer
guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
TextLexer = pygments.lexers.TextLexer
HtmlFormatter = pygments.formatters.HtmlFormatter
Ejemplo n.º 18
0
def associate_ldap_username(*args, **kwargs):
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import associate_ldap_username as alu
    return alu(*args, **kwargs)
Ejemplo n.º 19
0
def pullreviews(repo, proto, args=None):
    proto.redirect()
    req = parsejsonpayload(proto, args)

    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import ReviewBoardClient
    client = ReviewBoardClient(repo.ui.config('reviewboard',
                                              'url').rstrip('/'),
                               username=req.get('bzusername'),
                               apikey=req.get('bzapikey'))
    root = client.get_root()

    res = {
        'reviewrequests': {},
    }

    for identifier in req.get('identifiers', []):
        rrs = root.get_review_requests(commit_id=identifier)

        if rrs.total_results != 1:
            continue

        rr = rrs[0]
        commit_data = client.get_path(
            '/extensions/mozreview.extension.MozReviewExtension/'
            'commit-data/%s/' % rr.id)

        try:
            is_squashed = commit_data.extra_data['p2rb.is_squashed']
        except KeyError:
            is_squashed = None

        # 'True' in RB <= 2.0.11; True in 2.0.11+. We may have old
        # values in the database, so keep checking for 'True' until we
        # have a migration.
        if is_squashed is True or is_squashed == 'True':
            if 'p2rb.commits' in commit_data.extra_data:
                commits = commit_data.extra_data['p2rb.commits']
            else:
                draft = rr.get_draft()
                if 'p2rb.commits' in commit_data.draft_extra_data:
                    commits = commit_data.draft_extra_data['p2rb.commits']
                else:
                    commits = '[]'

            for relation in json.loads(commits):
                rid = str(relation[1])

                res['reviewrequests'][str(rid)] = {
                    'status': rr.status,
                    'public': rr.public,
                }

        res['reviewrequests'][str(rr.id)] = {
            'status': rr.status,
            'public': rr.public,
            'reviewers': [p.title for p in rr.target_people],
        }

    return json.dumps(res, sort_keys=True)
Ejemplo n.º 20
0
from mercurial import (
    demandimport,
    util
)
if util.safehasattr(demandimport, 'IGNORES'):
    # Since 670eb4fa1b86
    demandimport.IGNORES.update(['pkgutil', 'pkg_resources', '__main__'])
else:
    demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__'])

def missing(*args, **kwargs):
    raise error.Abort(_('remotefilelog extension requires lz4 support'))

lz4compress = lzcompresshc = lz4decompress = missing

with demandimport.deactivated():
    import lz4

    try:
        # newer python-lz4 has these functions deprecated as top-level ones,
        # so we are trying to import from lz4.block first
        def _compressHC(*args, **kwargs):
            return lz4.block.compress(*args, mode='high_compression', **kwargs)
        lzcompresshc = _compressHC
        lz4compress = lz4.block.compress
        lz4decompress = lz4.block.decompress
    except AttributeError:
        try:
            lzcompresshc = lz4.compressHC
            lz4compress = lz4.compress
            lz4decompress = lz4.decompress
Ejemplo n.º 21
0
def associate_ldap_username(*args, **kwargs):
    # Workaround an issue with "import _imp" in pkg_resources.
    with demandimport.deactivated():
        from reviewboardmods.pushhooks import associate_ldap_username as alu
    return alu(*args, **kwargs)
Ejemplo n.º 22
0
def configwizard(ui, repo, statedir=None, **opts):
    """Ensure your Mercurial configuration is up to date."""
    runsteps = set(wizardsteps)

    # Mercurial <1.7 had a bug where monkeypatching ui.__class__
    # during uisetup() doesn't work. So we do our own ui.hasconfig()
    # here. Other uses of ui.hasconfig() are allowed, as they will
    # have a properly monkeypatched ui.__class__.
    if 'steps' in ui._data(False)._data.get('configwizard', {}):
        runsteps = set(ui.configlist('configwizard', 'steps'))

    hgversion = util.versiontuple(n=3)

    # The point release version can be None for e.g. X.Y versions. Normalize
    # to make tuple compares work.
    if hgversion[2] is None:
        hgversion = (hgversion[0], hgversion[1], 0)

    if hgversion < MINIMUM_SUPPORTED_VERSION:
        ui.warn(VERSION_TOO_OLD % (
            hgversion[0],
            hgversion[1],
            MINIMUM_SUPPORTED_VERSION[0],
            MINIMUM_SUPPORTED_VERSION[1],
        ))
        raise error.Abort('upgrade Mercurial then run again')

    uiprompt(ui, INITIAL_MESSAGE, default='<RETURN>')

    with demandimport.deactivated():
        # Mercurial 4.2 moved function from scmutil to rcutil.
        try:
            from mercurial.rcutil import userrcpath
        except ImportError:
            from mercurial.scmutil import userrcpath

    configpaths = [p for p in userrcpath() if os.path.exists(p)]
    path = configpaths[0] if configpaths else userrcpath()[0]
    cw = configobjwrapper(path)

    if 'hgversion' in runsteps:
        if _checkhgversion(ui, hgversion):
            return 1

    if 'username' in runsteps:
        _checkusername(ui, cw)

    if 'tweakdefaults' in runsteps:
        _checktweakdefaults(ui, cw)

    if 'diff' in runsteps:
        _checkdiffsettings(ui, cw)

    if 'color' in runsteps:
        _checkcolor(ui, cw, hgversion)

    if 'pager' in runsteps:
        _checkpager(ui, cw, hgversion)

    if 'curses' in runsteps:
        _checkcurses(ui, cw)

    if 'historyediting' in runsteps:
        _checkhistoryediting(ui, cw, hgversion)

    if 'evolve' in runsteps:
        _checkevolve(ui, cw, hgversion)

    if 'fsmonitor' in runsteps:
        _checkfsmonitor(ui, cw, hgversion)

    if 'blackbox' in runsteps:
        _promptnativeextension(
            ui, cw, 'blackbox',
            'Enable logging of commands to help diagnose bugs '
            'and performance problems')

    if 'security' in runsteps:
        _checksecurity(ui, cw, hgversion)

    if 'firefoxtree' in runsteps:
        _promptvctextension(ui, cw, 'firefoxtree', FIREFOXTREE_INFO)

    if 'clang-format' in runsteps:
        _promptvctextension(ui, cw, 'clang-format', CLANG_FORMAT_INFO)

    if 'js-format' in runsteps:
        _promptvctextension(ui, cw, 'js-format', JS_FORMAT_INFO)

    if 'format-source' in runsteps:
        _checkformatsource(ui, cw)

    if 'wip' in runsteps:
        _checkwip(ui, cw)

    if 'smartannotate' in runsteps:
        _checksmartannotate(ui, cw)

    if 'codereview' in runsteps:
        _checkcodereview(ui, cw)

    if 'pushtotry' in runsteps:
        _promptvctextension(ui, cw, 'push-to-try', PUSHTOTRY_INFO)

    if 'multiplevct' in runsteps:
        _checkmultiplevct(ui, cw)

    if 'configchange' in runsteps:
        _handleconfigchange(ui, cw)

    if 'permissions' in runsteps:
        _checkpermissions(ui, cw)

    return 0