Bug 1385380 - Detect watchman more resiliently; r=glandium
authorGregory Szorc <gps@mozilla.com>
Fri, 28 Jul 2017 16:11:22 -0700
changeset 1251792 6cb26a4c377737cc905eef2cb5caf575f46c3c08
parent 1251791 6dacffdd0ed1ea53f7e2a56d1f44e2c90b959144
child 1251793 d033c0e7f61aaf0093c25a1bc2e1497e135cdf77
push idunknown
push userunknown
push dateunknown
reviewersglandium
bugs1385380
milestone57.0a1
Bug 1385380 - Detect watchman more resiliently; r=glandium Before, a non-runnable watchman would result in configure error. A trivial refactor to ignore `watchman version` errors would still result in setting WATCHMAN and exposing its presence to downstream consumers. Since we want WATCHMAN tied to a working watchman install, we refactor the code so that binary location and its version test are in the same function. They are either both defined or none of them are. MozReview-Commit-ID: 7wvBvYuOlmJ
moz.configure
--- a/moz.configure
+++ b/moz.configure
@@ -363,25 +363,51 @@ def tup_progs(build_backends):
             return ['tup']
     return None
 
 tup = check_prog('TUP', tup_progs)
 
 # watchman detection
 # ==============================================================
 
-watchman = check_prog('WATCHMAN', ('watchman',), allow_missing=True)
+option(env='WATCHMAN', nargs=1, help='Path to the watchman program')
 
-@depends_if(watchman)
-@checking('for watchman version')
+@depends('WATCHMAN')
 @imports('json')
-def watchman_version(watchman):
-    out = check_cmd_output(watchman, 'version')
-    res = json.loads(out)
-    return Version(res['version'])
+def watchman_info(prog):
+    if not prog:
+        prog = find_program('watchman')
+
+    if not prog:
+        return
+
+    out = check_cmd_output(prog, 'version', onerror=lambda: None)
+    if out is None:
+        return
+
+    # Assume a process not emitting JSON is not watchman or is a
+    # broken watchman.
+    try:
+        res = json.loads(out)
+    except ValueError:
+        return
+
+    return namespace(path=prog, version=Version(res['version']))
+
+@depends_if(watchman_info)
+@checking('for watchman')
+def watchman(w):
+    return w.path
+
+@depends_if(watchman_info)
+@checking('for watchman version')
+def watchman_version(w):
+    return w.version
+
+set_config('WATCHMAN', watchman)
 
 @depends_all(hg_version, hg_config, watchman)
 @checking('for watchman Mercurial integration')
 @imports('os')
 def watchman_hg(hg_version, hg_config, watchman):
     if hg_version < Version('3.8'):
         return 'no (Mercurial 3.8+ required)'