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 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)
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, )
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())
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))
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'
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, )
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
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)
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)
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)
# # 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
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)
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
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