f7b51407ba3c — Oben Sonne 11 years ago
Unify alert and merge tool configuration

!!! This changes the autosync command interface !!!

KISS. Now there's only one way to set an alerter tool, using the option
alert in section autosync of an HGRC file. Same thing for the merge
tool: it is defined in autosync->merge. This benefit here is that this
clearly distinguishes the merge tool configuration for the autosync
command and ohter commands which use ui->merge or HGMERGE to get the
merge tool.

This change also fixes a parameter type error when calling the alert
2 files changed, 34 insertions(+), 35 deletions(-)

M autosync.py
M tests/test-autosync
M autosync.py +33 -34
@@ 77,6 77,17 @@ def _cmdopts(cte, ouropts):
         cmdopts[key] = ouropts.get(key, optdesc[2])
     return cmdopts
+def _alert(ui, repo, error):
+    """Run the alert program, if defined."""
+    alert = repo.ui.config("autosync", "alert")
+    if alert:
+        alert = util.expandpath(alert)
+        try:
+            subprocess.call([alert, repo.root, str(error)])
+        except OSError, e:
+            ui.warn("sync: failed to run alert tool %s (%s)" % (alert, e))
 def _cycle(ui, root, commitopts, fetchopts, pushopts):
     """Run a single 'commit, fetch, push' cycle"""

@@ 88,7 99,7 @@ def _cycle(ui, root, commitopts, fetchop
     ui.status("sync: push local changes to other repository\n")
     commands.push(ui, repo, **pushopts)
-def _sync(ui, repo, other, **opts):
+def _sync(ui, repo, other, opts):
     """Synchronize once or continuously, depending on `opts`."""
     # check options

@@ 111,13 122,10 @@ def _sync(ui, repo, other, **opts):
     pushopts = _cmdopts(commands.table["^push"], opts)
     pushopts["dest"] = other
-    # force non-interactive merge (unless set explicitly in repo-hgrc)
+    # force non-interactive merge (unless defined otherwise in autosync->merge)
-    os.environ["HGMERGE"] = "internal:merge"
-    if repo.ui.config("ui", "merge"):
-        source = repo.ui.configsource("ui", "merge").split(":")[0]
-        if source == os.path.join(repo.root, ".hg", "hgrc"):
-            os.environ["HGMERGE"] = repo.ui.config("ui", "merge")
+    automerge = repo.ui.config("autosync", "merge")
+    os.environ["HGMERGE"] = automerge or "internal:merge"
     # run one synchronization cycle only ?

@@ 125,15 133,6 @@ def _sync(ui, repo, other, **opts):
         _cycle(ui, repo.root, commitopts, fetchopts, pushopts)
-    # detect alerter tool
-    if opts["alerter"]:
-        alerter = opts["alerter"]
-    elif os.path.exists(os.path.join(repo.root, ALERTER)):
-        alerter = os.path.join(repo.root, ALERTER)
-    else:
-        alerter = repo.ui.config("autosync", "alerter")
     # loop synchronization cycles !
     while True:

@@ 142,13 141,9 @@ def _sync(ui, repo, other, **opts):
             _cycle(ui, repo.root, commitopts, fetchopts, pushopts)
         except util.Abort, e:
-            ui.warn("error: %s\n" % e)
+            ui.warn("%s\n" % e)
             ui.warn("sync: an error occurred, will retry at next interval\n")
-            if alerter and os.path.exists(alerter):
-                try:
-                    subprocess.call([alerter, repo.root, e])
-                except OSError, e:
-                    ui.warn("sync: failed to run %s (%s)" % (alerter, e))
+            _alert(ui, repo, e)

@@ 177,17 172,22 @@ def autosync(ui, repo, other="default", 
     both repositories stay in sync (as long as they are no conflicting
+    HGRC configruation:
+    [autosync]
+    merge = <merger>
+    alert = <alert-tool>
+    By default Mercurial's internal non-interactive merge is used when fetching
+    from another repository. This can be changed with the `merge` option.
     Errors and merge conflicts which cannot be resolved automatically are
-    highlighted in the output. Additionally an alerter tool can be specified
-    to run on errors and conflicts. This tool can be set (1) by using option
-    --alerter, (2) by placing it in the repository root as a file called
-    `.hgalert` or (3) in an HGRC file using options `alerter` in section
-    `autosync` (locations are evaluated in that order). The alerter is supposed
-    to notify errors to a human. The repository path is given as first
-    argument, an error message as the second one. In any case the autosync
-    command keeps running and retries after the next interval, hoping things
-    get fixed externally.
+    highlighted in the output. Additionally, if option `alert` is defined, the
+    corresponding tool is called. This tool is supposed to notify problems to a
+    human. The repository path and an error message are passed as arguments to
+    the alert tool. Independent of these options, autosync keeps running when
+    there are problems and retries after the next interval, hoping things get
+    fixed externally.
     When running in daemon mode, any output gets logged into the file
     `autosync.log` within the repository's `.hg` directory (use --daemon-log
     to set a different file).

@@ 197,7 197,7 @@ def autosync(ui, repo, other="default", 
     autosync, pull or commit something first manually.
-    runfn = lambda: _sync(ui, repo, other, **opts)
+    runfn = lambda: _sync(ui, repo, other, opts)
     if not opts["daemon"]:
         logfile = None
     elif opts["daemon_log"] == LOGFILE:

@@ 216,7 216,6 @@ cmdtable = {
           "automatically synchronize new/missing files"),
          ("i", "interval", 600, "synchronization interval in seconds"),
          ("o", "once", False, "synchronize once only, don't loop"),
-         ("", "alerter", "", "program to run to alert errors"),
          # daemon options
          ("D", "daemon", False, "run in background"),
          ("", "daemon-log", LOGFILE, "log file for daemon mode"),

M tests/test-autosync +1 -1
@@ 90,7 90,7 @@ kill `cat sd-rb.pid` || echo "failed: sy
 echo "-> configure repos to use internal:local for merge"
 for repo in ra rb ; do
-    echo "[ui]" >> $repo/.hg/hgrc
+    echo "[autosync]" >> $repo/.hg/hgrc
     echo "merge = internal:local" >> $repo/.hg/hgrc