in eden/scm/edenscm/hgext/rage.py [0:0]
def _makerage(ui, repo, **opts):
configoverrides = {
# Make graphlog shorter.
("experimental", "graphshorten"): "1",
# Force use of lines-square renderer, as the user's configuration may
# not render properly in a text file.
("experimental", "graph.renderer"): "lines-square",
# Reduce the amount of data used for debugnetwork speed tests to
# increase the chance they complete within 20s.
("debugnetwork", "speed-test-download-size"): "4M",
("debugnetwork", "speed-test-upload-size"): "1M",
}
# Override the encoding to "UTF-8" to generate the rage in UTF-8.
oldencoding = encoding.encoding
oldencodingmode = encoding.encodingmode
encoding.encoding = "UTF-8"
encoding.encodingmode = "replace"
def hgcmd(cmdname, *args, **additional_opts):
cmd, opts = cmdutil.getcmdanddefaultopts(cmdname, commands.table)
opts.update(additional_opts)
_repo = repo
if "_repo" in opts:
_repo = opts["_repo"]
del opts["_repo"]
# If we failed to popbuffer for some reason, do not mess up with the
# main `ui` object.
newui = ui.copy()
newui.pushbuffer(error=True, subproc=True)
newui._colormode = None
def remoteui(orig, src, opts):
rui = orig(src, opts)
rui._outputui = newui
return rui
try:
with newui.configoverride(
configoverrides, "rage"
), extensions.wrappedfunction(hg, "remoteui", remoteui):
if cmd.norepo:
cmd(newui, *args, **opts)
else:
cmd(newui, _repo, *args, **opts)
finally:
return newui.popbuffer()
basic = [
("date", lambda: time.ctime()),
("unixname", lambda: encoding.environ.get("LOGNAME")),
("hostname", lambda: socket.gethostname()),
("repo location", lambda: repo.root),
("cwd", lambda: pycompat.getcwd()),
("fstype", lambda: util.getfstype(repo.root)),
("active bookmark", lambda: bookmarks._readactive(repo, repo._bookmarks)),
(
"hg version",
lambda: __import__(
"edenscm.mercurial.__version__"
).mercurial.__version__.version,
),
]
def _edenfs_rage():
ragecmd = "edenfsctl rage --stdout"
if opts.get("preview"):
return shcmd(ragecmd + " --dry-run")
return shcmd(ragecmd)
detailed = [
(
"disk space usage",
lambda: shcmd(
"wmic LogicalDisk Where DriveType=3 Get DeviceId,FileSystem,FreeSpace,Size"
if pycompat.iswindows
else "df -h",
check=False,
),
),
# smartlog as the user sees it
("hg sl", lambda: hgcmd("smartlog", template="{sl_debug}")),
(
"hg debugmetalog -t 'since 2d ago'",
lambda: hgcmd("debugmetalog", time_range=["since 2d ago"]),
),
(
'first 20 lines of "hg status"',
lambda: "\n".join(hgcmd("status").splitlines()[:20]),
),
(
"hg debugmutation -r 'draft() & date(-4)' -t 'since 4d ago'",
lambda: hgcmd(
"debugmutation", rev=["draft() & date(-4)"], time_range=["since 4d ago"]
),
),
(
"hg bookmarks --list-subscriptions",
lambda: hgcmd("bookmarks", list_subscriptions=True),
),
("sigtrace", lambda: readsigtraces(repo)),
(
"hg blackbox",
lambda: "\n".join(
hgcmd("blackbox", pattern=BLACKBOX_PATTERN).splitlines()[-500:]
),
),
("hg summary", lambda: hgcmd("summary")),
("hg cloud status", lambda: hgcmd("cloud status")),
("hg debugprocesstree", lambda: hgcmd("debugprocesstree")),
("hg config (local)", lambda: "\n".join(localconfig(ui))),
("hg sparse", lambda: hgcmd("sparse")),
("hg debugchangelog", lambda: hgcmd("debugchangelog")),
("hg debugexpandpaths", lambda: hgcmd("debugexpandpaths")),
("hg debuginstall", lambda: hgcmd("debuginstall")),
("hg debugdetectissues", lambda: hgcmd("debugdetectissues")),
("usechg", usechginfo),
(
"uptime",
lambda: shcmd(
"wmic path Win32_OperatingSystem get LastBootUpTime"
if pycompat.iswindows
else "uptime"
),
),
("rpm info", (partial(rpminfo, ui))),
("klist", lambda: shcmd("klist", check=False)),
("ifconfig", lambda: shcmd("ipconfig" if pycompat.iswindows else "ifconfig")),
(
"airport",
lambda: shcmd(
"/System/Library/PrivateFrameworks/Apple80211."
+ "framework/Versions/Current/Resources/airport "
+ "--getinfo",
check=False,
),
),
("hg debugnetwork", lambda: hgcmd("debugnetwork")),
("infinitepush backup state", lambda: readinfinitepushbackupstate(repo)),
("commit cloud workspace sync state", lambda: readcommitcloudstate(repo)),
(
"infinitepush / commitcloud backup logs",
lambda: infinitepushbackuplogs(ui, repo),
),
("scm daemon logs", lambda: scmdaemonlog(ui, repo)),
("debugstatus", lambda: hgcmd("debugstatus")),
("debugtree", lambda: hgcmd("debugtree")),
("hg config (all)", lambda: "\n".join(allconfig(ui))),
("edenfs rage", _edenfs_rage),
(
"environment variables",
lambda: "\n".join(
sorted(["{}={}".format(k, v) for k, v in encoding.environ.items()])
),
),
("ssh config", lambda: shcmd("ssh -G hg.vip.facebook.com", check=False)),
("debuglocks", lambda: hgcmd("debuglocks")),
("x2pagentd info", lambda: checkproxyagentstate(ui)),
("sks-agent rage", lambda: sksagentrage(ui)),
]
msg = ""
footnotes = []
timeout = opts.get("timeout") or 20
def _failsafe(gen, timeout=timeout):
class TimedOut(RuntimeError):
pass
def target(result, gen):
try:
result.append(gen())
except TimedOut:
return
except Exception as ex:
index = len(footnotes) + 1
footnotes.append(
"[%d]: %s\n%s\n\n" % (index, str(ex), traceback.format_exc())
)
result.append("(Failed. See footnote [%d])" % index)
result = []
thread = threading.Thread(target=target, args=(result, gen))
thread.daemon = True
thread.start()
thread.join(timeout)
if result:
value = result[0]
return value
else:
if thread.is_alive():
# Attempt to stop the thread, since hg is not thread safe.
# There is no pure Python API to interrupt a thread.
# But CPython C API can do that.
ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), ctypes.py_object(TimedOut)
)
return (
"(Did not complete in %s seconds, rerun with a larger --timeout to collect this)"
% timeout
)
msg = []
profile = []
allstart = time.time()
for name, gen in basic:
msg.append("%s: %s\n\n" % (name, _failsafe(gen)))
profile.append((time.time() - allstart, "basic info", None))
for name, gen in detailed:
start = time.time()
with progress.spinner(ui, name):
value = _failsafe(gen)
finish = time.time()
msg.append(
"%s: (%.2f s)\n---------------------------\n%s\n\n"
% (name, finish - start, value)
)
profile.append((finish - start, name, value.count("\n")))
allfinish = time.time()
profile.append((allfinish - allstart, "total time", None))
msg.append("hg rage profile:\n")
width = max([len(name) for _t, name, _l in profile])
for timetaken, name, lines in reversed(sorted(profile)):
m = " %-*s %8.2f s" % (width + 1, name + ":", timetaken)
if lines is not None:
msg.append("%s for %4d lines\n" % (m, lines))
else:
msg.append("%s\n" % m)
msg.append("\n")
msg.extend(footnotes)
msg = "".join(msg)
encoding.encoding = oldencoding
encoding.encodingmode = oldencodingmode
return msg