@@ -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: