mirror of
https://github.com/facebook/sapling.git
synced 2025-01-08 14:46:47 +03:00
9dc21f8d0b
Summary: D13853115 adds `edenscm/` to `sys.path` and code still uses `import mercurial`. That has nasty problems if both `import mercurial` and `import edenscm.mercurial` are used, because Python would think `mercurial.foo` and `edenscm.mercurial.foo` are different modules so code like `try: ... except mercurial.error.Foo: ...`, or `isinstance(x, mercurial.foo.Bar)` would fail to handle the `edenscm.mercurial` version. There are also some module-level states (ex. `extensions._extensions`) that would cause trouble if they have multiple versions in a single process. Change imports to use the `edenscm` so ideally the `mercurial` is no longer imported at all. Add checks in extensions.py to catch unexpected extensions importing modules from the old (wrong) locations when running tests. Reviewed By: phillco Differential Revision: D13868981 fbshipit-source-id: f4e2513766957fd81d85407994f7521a08e4de48
109 lines
3.7 KiB
Python
109 lines
3.7 KiB
Python
# Copyright 2017 Facebook, Inc.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
"""allows users to have JSON progress bar information written to a path
|
|
|
|
Controlled by the `ui.progressfile` config. Mercurial will overwrite this file
|
|
each time the progress bar is updated. It is not affected by HGPLAIN since it
|
|
does not write to stdout.
|
|
|
|
The schema of this file is (JSON):
|
|
|
|
- topics: array of topics from oldest to newest. (last is always the active one)
|
|
- state: map of topic names to objects with keys:
|
|
- topic (e.g. "changesets", "manifests")
|
|
- pos: which item number out of <total> we're processing
|
|
- total: total number of items (can change!)
|
|
- unit: name of the type of unit being processed (e.g., "changeset")
|
|
- item: the active item being processed (e.g., "changeset #5")
|
|
- active: whether this is the currently active progress bar
|
|
- units_per_sec: if active, how many <unit>s per sec we're processing
|
|
- speed_str: if active, a human-readable string of how many <unit>s per sec
|
|
we're processing
|
|
- estimate_sec: an estimate of how much time is left, in seconds
|
|
- estimate_str: if active, a human-readable string estimate of how much time
|
|
is left (e.g. "2m30s")
|
|
|
|
config example::
|
|
|
|
[progress]
|
|
# Where to write progress information
|
|
statefile = /some/path/to/file
|
|
# Append to the progress file, rather than replace
|
|
statefileappend = true
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import json
|
|
|
|
from edenscm.mercurial import progress, registrar
|
|
|
|
|
|
testedwith = "ships-with-fb-hgext"
|
|
|
|
configtable = {}
|
|
configitem = registrar.configitem(configtable)
|
|
|
|
configitem("progress", "statefile", default="")
|
|
|
|
|
|
def writeprogress(self, progressfile, filemode, bars):
|
|
topics = {}
|
|
for index, bar in enumerate(bars):
|
|
pos, item = progress._progvalue(bar.value)
|
|
topic = bar._topic
|
|
unit = bar._unit
|
|
total = bar._total
|
|
isactive = index == self._currentbarindex
|
|
cullempty = lambda str: str if str else None
|
|
info = {
|
|
"topic": topic,
|
|
"pos": pos,
|
|
"total": total,
|
|
"unit": cullempty(unit),
|
|
"item": cullempty(item),
|
|
"active": isactive,
|
|
"units_per_sec": None,
|
|
"speed_str": None,
|
|
"estimate_sec": None,
|
|
"estimate_str": None,
|
|
}
|
|
if isactive:
|
|
speed = progress.estimatespeed(bar)
|
|
remaining = progress.estimateremaining(bar) if total else None
|
|
info["units_per_sec"] = cullempty(speed)
|
|
info["estimate_sec"] = cullempty(remaining)
|
|
info["speed_str"] = cullempty(progress.fmtspeed(speed, bar))
|
|
info["estimate_str"] = cullempty(progress.fmtremaining(remaining))
|
|
topics[topic] = info
|
|
|
|
text = json.dumps(
|
|
{"state": topics, "topics": [bar._topic for bar in bars]}, sort_keys=True
|
|
)
|
|
try:
|
|
with open(progressfile, filemode) as f:
|
|
f.write(text + "\n")
|
|
except (IOError, OSError):
|
|
pass
|
|
|
|
|
|
def uisetup(ui):
|
|
progressfile = ui.config("progress", "statefile")
|
|
append = ui.configbool("progress", "statefileappend", False)
|
|
filemode = "a+" if append else "w+"
|
|
if progressfile:
|
|
|
|
class fileengine(progress._engine.__class__):
|
|
def _show(self, now):
|
|
super(fileengine, self)._show(now)
|
|
writeprogress(self, progressfile, filemode, self._bars)
|
|
|
|
def _complete(self):
|
|
super(fileengine, self)._complete()
|
|
writeprogress(self, progressfile, filemode, [])
|
|
|
|
progress._engine.__class__ = fileengine
|