| Index: infra/libs/gitiles/gitiles.py
|
| diff --git a/infra/libs/gitiles/gitiles.py b/infra/libs/gitiles/gitiles.py
|
| index 97d16db8e5f9ee8eb8fc7ac47512938cb4b97355..4bf984fd81e8cd84637b4171baf186356ddb0c46 100644
|
| --- a/infra/libs/gitiles/gitiles.py
|
| +++ b/infra/libs/gitiles/gitiles.py
|
| @@ -8,6 +8,7 @@
|
|
|
| import base64
|
| import logging
|
| +import httplib
|
| import httplib2
|
| import json
|
| import urlparse
|
| @@ -18,11 +19,15 @@ import time
|
| LOGGER = logging.getLogger(__name__)
|
|
|
|
|
| +# The default number of retries when a Gitiles error is encountered.
|
| +DEFAULT_RETRIES = 10
|
| +
|
| +
|
| class GitilesError(Exception):
|
| pass
|
|
|
|
|
| -def call_gitiles(url, response_format, netrc_path=None, max_attempts=10):
|
| +def call_gitiles(url, response_format, netrc_path=None, max_attempts=None):
|
| """Invokes Gitiles API and parses the JSON result.
|
|
|
| Given a gitiles URL, makes a ?format=json or ?format=text call and interprets
|
| @@ -38,12 +43,13 @@ def call_gitiles(url, response_format, netrc_path=None, max_attempts=10):
|
| not specified, no authentication is used.
|
|
|
| max_attempts is the number of attempts to call gitiles before giving up on
|
| - error.
|
| + error. If None/zero, DEFAULT_RETRIES will be used.
|
| """
|
| assert response_format in ('json', 'text'), (
|
| 'response must be either json or text')
|
| assert '?' not in url, 'url must not have a query parameter (?)'
|
|
|
| + max_attempts = max_attempts or DEFAULT_RETRIES
|
| http = httplib2.Http()
|
| headers = {}
|
| if netrc_path:
|
| @@ -59,8 +65,10 @@ def call_gitiles(url, response_format, netrc_path=None, max_attempts=10):
|
| 'GET',
|
| headers=headers
|
| )
|
| - if response['status'] != '200':
|
| - LOGGER.warning('GET %s failed with HTTP code %s', url, response['status'])
|
| + if response.status != httplib.OK:
|
| + LOGGER.warning('GET %s failed with HTTP code %d', url, response.status)
|
| + if response.status < httplib.INTERNAL_SERVER_ERROR:
|
| + break
|
| if attempt != max_attempts:
|
| LOGGER.warning('Retrying...')
|
| continue # pragma: no cover (actually reached, see https://goo.gl/QA8B2U)
|
| @@ -85,3 +93,28 @@ def get_oauth_token_from_netrc(url, netrc_path):
|
| 'netrc file %s is missing an entry for %s' % (
|
| netrc_path, parsed.hostname))
|
| return auth[2]
|
| +
|
| +
|
| +class Repository(object):
|
| + def __init__(self, base_url, netrc_path=None, max_attempts=None):
|
| + self._base_url = self._trim_slashes(base_url)
|
| + self._netrc_path = netrc_path
|
| + self._max_attempts = max_attempts
|
| +
|
| + @staticmethod
|
| + def _trim_slashes(v):
|
| + return v.strip('/')
|
| +
|
| + def __call__(self, ref='master', subpath=None):
|
| + url = [self._base_url, '+', ref]
|
| + if subpath:
|
| + url.append(self._trim_slashes(subpath))
|
| + url = '/'.join(url)
|
| + return call_gitiles(
|
| + url,
|
| + 'json',
|
| + netrc_path=self._netrc_path,
|
| + max_attempts=self._max_attempts)
|
| +
|
| + def ref_info(self, ref):
|
| + return self(ref)
|
|
|