D5299: phabricator: fallback reading arcanist config files
philpep (Philippe Pepiot)
phabricator at mercurial-scm.org
Fri Nov 23 17:13:05 UTC 2018
philpep created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
This allow the phabricator extension to read arc config files to auto-configure
url, token and callsign.
We use it as a fallback when phabricator.url or phabricator.callsign aren't
defined.
This allow to configure conduit_uri and repository.callsign in a tracked
.arcconfig json file in the root of the repository, so users having lot of
small repositories in phabricator doesn't need to configure .hg/hgrc after a
fresh clone.
REPOSITORY
rHG Mercurial
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,14 +37,18 @@
# 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
import itertools
import json
import operator
import re
+import os
from mercurial.node import bin, nullid
from mercurial.i18n import _
@@ -167,16 +171,51 @@
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 os.name == 'nt':
+ paths = [
+ os.path.join(os.environ['ProgramData'],
+ 'Phabricator',
+ 'Arcanist',
+ 'config'),
+ os.path.join(os.environ['AppData'], '.arcrc'),
+ ]
+ else:
+ paths = [
+ os.path.join('/etc', 'arcconfig'),
+ os.path.join(os.path.expanduser('~'), '.arcrc'),
+ os.path.join(repo.root, '.arcconfig'),
+ ]
+ config = {}
+ for path in paths:
+ if os.path.exists(path):
+ with open(path, 'rb') 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
@@ -241,7 +280,9 @@
return repophid
callsign = repo.ui.config(b'phabricator', b'callsign')
if not callsign:
- return None
+ __, __, callsign = readarcconfig(repo)
+ if not callsign:
+ return callsign
query = callconduit(repo, b'diffusion.repository.search',
{b'constraints': {b'callsigns': [callsign]}})
if len(query[r'data']) == 0:
To: philpep, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list