def _execute(ui, repo, target=None): script = ui.config("stablerev", "script") if script is None: raise error.ConfigError(_("must set stablerev.script")) # Pass '--target $TARGET' for compatibility. # XXX: Remove this once the new code has been rolled out for some time. if target is not None: script += " --target %s" % util.shellquote(target) try: ui.debug("repo-specific script for stable: %s\n" % script) reporoot = repo.wvfs.join("") env = encoding.environ.copy() env.update({"REAL_CWD": pycompat.getcwd(), "HG_ROOT": reporoot}) if target is not None: env["TARGET"] = target ui.debug("setting current working directory to: %s\n" % reporoot) p = subprocess.Popen( script, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=util.closefds, cwd=reporoot, env=env, ) res = p.communicate() ui.debug("stable script returns: %r\n" % (res, )) return res except subprocess.CalledProcessError as e: raise error.Abort(_("couldn't fetch stable rev: %s") % e)
def getint(ui, section, name, default): # for "historical portability": # ui.configint has been available since 1.9 (or fa2b596db182) v = ui.config(section, name, None) if v is None: return default try: return int(v) except ValueError: raise error.ConfigError(("%s.%s is not an integer ('%s')") % (section, name, v))
def _rundriver(repo, ms, op, wctx, labels): ui = repo.ui mergedriver = ms.mergedriver if not mergedriver.startswith("python:"): raise error.ConfigError(_("merge driver must be a python hook")) ms.commit() raised = False # Don't write .pyc files for the loaded hooks (restore this setting # after running). Like the `loadedmodules` fix below, this is to prevent # drivers changed during a rebase from being loaded inconsistently. origbytecodesetting = sys.dont_write_bytecode sys.dont_write_bytecode = True origmodules = set(sys.modules.keys()) try: res = hook.runhooks( ui, repo, "mergedriver-%s" % op, [(op, "%s:%s" % (mergedriver, op))], throw=False, mergestate=ms, wctx=wctx, labels=labels, ) r, raised = res[op] except ImportError: # underlying function prints out warning r = True raised = True except (IOError, error.HookLoadError) as inst: if isinstance(inst, IOError) and inst.errno == errno.ENOENT: # this will usually happen when transitioning from not having a # merge driver to having one -- don't fail for this important use # case r, raised = False, False else: ui.warn(_("%s\n") % inst) r = True raised = True finally: # Evict the loaded module and all of its imports from memory. This is # necessary to ensure we always use the latest driver code from ., and # prevent cases with a half-loaded driver (where some of the cached # modules were loaded from an older commit.) loadedmodules = set(sys.modules.keys()) - origmodules for mod in loadedmodules: del sys.modules[mod] sys.dont_write_bytecode = origbytecodesetting return r, raised
def _lookupstables(repo, ctx): ui = repo.ui stablesscript = ui.config("stablerev", "stablesscript") if stablesscript is None: raise error.ConfigError(_("must set stablerev.stablesscript")) stablesscript = stablesscript.format(nodeid=util.shellquote(ctx.hex())) stdout = _executescript(stablesscript, repo) try: committostables = json.loads(stdout) except Exception as e: raise error.Abort( _("couldn't parse stablesscript stdout as json: %s") % e) return committostables.get(ctx.hex(), [])
def _executeandparse(ui, repo, target=None): script = ui.config("stablerev", "script") if script is None: raise error.ConfigError(_("must set stablerev.script")) # Pass '--target $TARGET' for compatibility. # XXX: Remove this once the new code has been rolled out for some time. env = {} if target is not None: script += " --target %s" % util.shellquote(target) env["TARGET"] = target stdout = _executescript(script, repo, env) try: # Prefer JSON output first. data = json.loads(stdout) if "node" in data: return _validaterevspec(ui, data["node"]) except Exception: pass # Fall back to stdout: return _validaterevspec(ui, stdout.strip())