D5299: phabricator: fallback reading arcanist config files

philpep (Philippe Pepiot) phabricator at mercurial-scm.org
Wed Feb 27 05:48:36 EST 2019


philpep updated this revision to Diff 14253.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5299?vs=14175&id=14253

REVISION DETAIL
  https://phab.mercurial-scm.org/D5299

AFFECTED FILES
  hgext/phabricator.py

CHANGE DETAILS

diff --git a/hgext/phabricator.py b/hgext/phabricator.py
--- a/hgext/phabricator.py
+++ b/hgext/phabricator.py
@@ -37,6 +37,9 @@
 
     # API token. Get it from https://$HOST/conduit/login/
     example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+As a fallback, read config from arc config files (.arcconfig, ~/.arcrc and
+/etc/arcconfig)
 """
 
 from __future__ import absolute_import
@@ -46,6 +49,7 @@
 import json
 import operator
 import re
+import os
 
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
@@ -60,13 +64,15 @@
     parser,
     patch,
     phases,
+    pycompat,
     registrar,
     scmutil,
     smartset,
     tags,
     templateutil,
     url as urlmod,
     util,
+    vfs as vfsmod,
 )
 from mercurial.utils import (
     procutil,
@@ -171,16 +177,49 @@
     process(b'', params)
     return util.urlreq.urlencode(flatparams)
 
+def readarcconfig(repo):
+    """Return url, token, callsign read from arcanist config files
+
+    This read and merge content of /etc/arcconfig, ~/.arcrc and .arconfig.
+    """
+    if pycompat.iswindows:
+        paths = [
+            vfsmod.vfs(encoding.environ['ProgramData']).join(
+                 'Phabricator', 'Arcanist', 'config'),
+            vfsmod.vfs(encoding.environ['AppData']).join('.arcrc')
+        ]
+    else:
+        paths = [
+            vfsmod.vfs('/etc').join('.arconfig'),
+            os.path.expanduser('~/.arcrc'),
+        ]
+    paths.append(vfsmod.vfs(repo.root).join('.arcconfig'))
+    config = {}
+    for path in paths:
+        if vfsmod.vfs(path).exists():
+            with vfsmod.vfs(path).open(None, auditpath=False) as f:
+                config.update(json.load(f))
+    callsign = config.get('repository.callsign')
+    conduit_uri = config.get('conduit_uri', config.get('config', {}).get('default'))
+    if conduit_uri is not None:
+        token = config.get('hosts', {}).get(conduit_uri, {}).get('token')
+    url = conduit_uri.rstrip('/api/')
+    return url, token, callsign
+
 def readurltoken(repo):
     """return conduit url, token and make sure they exist
 
-    Currently read from [auth] config section. In the future, it might
-    make sense to read from .arcconfig and .arcrc as well.
+    Currently read from [auth] config section and fallback to reading arc
+    config files.
     """
     url = repo.ui.config(b'phabricator', b'url')
     if not url:
-        raise error.Abort(_(b'config %s.%s is required')
-                          % (b'phabricator', b'url'))
+        url, token, __ = readarcconfig(repo)
+        if not url or not token:
+            raise error.Abort(_(b'unable to read phabricator conduit url and '
+                                b'token from config %s.%s or from arc config '
+                                b'files') % (b'phabricator', b'url'))
+        return url, token
 
     res = httpconnectionmod.readauthforuri(repo.ui, url, util.url(url).user)
     token = None
@@ -246,7 +285,9 @@
         return repophid
     callsign = repo.ui.config(b'phabricator', b'callsign')
     if not callsign:
-        return None
+        __, __, callsign = readarcconfig(repo)
+        if not callsign:
+            return None
     query = callconduit(repo, b'diffusion.repository.search',
                         {b'constraints': {b'callsigns': [callsign]}})
     if len(query[r'data']) == 0:



To: philpep, #hg-reviewers
Cc: mharbison72, mercurial-devel


More information about the Mercurial-devel mailing list