31 # curl command to use. If not set (default), use builtin HTTP library to |
31 # curl command to use. If not set (default), use builtin HTTP library to |
32 # communicate. If set, use the specified curl command. This could be useful |
32 # communicate. If set, use the specified curl command. This could be useful |
33 # if you need to specify advanced options that is not easily supported by |
33 # if you need to specify advanced options that is not easily supported by |
34 # the internal library. |
34 # the internal library. |
35 curlcmd = curl --connect-timeout 2 --retry 3 --silent |
35 curlcmd = curl --connect-timeout 2 --retry 3 --silent |
|
36 |
|
37 [phabricator.auth] |
|
38 example.url = https://phab.example.com/ |
|
39 # API token. Get it from https://$HOST/conduit/login/ |
|
40 example.token = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx |
36 """ |
41 """ |
37 |
42 |
38 from __future__ import absolute_import |
43 from __future__ import absolute_import |
39 |
44 |
40 import itertools |
45 import itertools |
98 """return conduit url, token and make sure they exist |
103 """return conduit url, token and make sure they exist |
99 |
104 |
100 Currently read from [phabricator] config section. In the future, it might |
105 Currently read from [phabricator] config section. In the future, it might |
101 make sense to read from .arcconfig and .arcrc as well. |
106 make sense to read from .arcconfig and .arcrc as well. |
102 """ |
107 """ |
103 values = [] |
108 url = repo.ui.config('phabricator', 'url') |
104 section = 'phabricator' |
109 if not url: |
105 for name in ['url', 'token']: |
110 raise error.Abort(_('config %s.%s is required') |
106 value = repo.ui.config(section, name) |
111 % ('phabricator', 'url')) |
107 if not value: |
112 |
108 raise error.Abort(_('config %s.%s is required') % (section, name)) |
113 groups = {} |
109 values.append(value) |
114 for key, val in repo.ui.configitems('phabricator.auth'): |
110 return values |
115 if '.' not in key: |
|
116 repo.ui.warn(_("ignoring invalid [phabricator.auth] key '%s'\n") |
|
117 % key) |
|
118 continue |
|
119 group, setting = key.rsplit('.', 1) |
|
120 groups.setdefault(group, {})[setting] = val |
|
121 |
|
122 token = None |
|
123 for group, auth in groups.iteritems(): |
|
124 if url != auth.get('url'): |
|
125 continue |
|
126 token = auth.get('token') |
|
127 if token: |
|
128 break |
|
129 |
|
130 if not token: |
|
131 raise error.Abort(_('Can\'t find conduit token associated to %s') |
|
132 % (url,)) |
|
133 |
|
134 return url, token |
111 |
135 |
112 def callconduit(repo, name, params): |
136 def callconduit(repo, name, params): |
113 """call Conduit API, params is a dict. return json.loads result, or None""" |
137 """call Conduit API, params is a dict. return json.loads result, or None""" |
114 host, token = readurltoken(repo) |
138 host, token = readurltoken(repo) |
115 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo() |
139 url, authinfo = util.url('/'.join([host, 'api', name])).authinfo() |