Exemple #1
0
def do_cinnabarclone(repo, manifest, store):
    url = None
    for line in manifest.splitlines():
        line = line.strip()
        spec, _, params = line.partition(' ')
        if params:
            # Future proofing: ignore lines with params.
            continue
        url, _, branch = spec.partition('#')
        url, branch = (url.split('#', 1) + [None])[:2]
        if url:
            break

    if not url:
        logging.warn('Server advertizes cinnabarclone but didn\'t provide '
                     'a git repository url to fetch from.')
        return False

    parsed_url = urlparse(url)
    if parsed_url.scheme not in ('http', 'https', 'git'):
        logging.warn('Server advertizes cinnabarclone but provided a non '
                     'http/https git repository. Skipping.')
        return False
    sys.stderr.write('Fetching cinnabar metadata from %s\n' % url)
    return store.merge(url, repo.url(), branch)
Exemple #2
0
def do_cinnabarclone(repo, manifest, store):
    data = manifest.splitlines()
    if not data:
        logging.warn('Server advertizes cinnabarclone but didn\'t provide '
                     'a git repository url to fetch from.')
        return False
    if len(data) > 1:
        logging.warn('cinnabarclone from multiple git repositories is not '
                     'supported yet.')
        return False

    url = data[0]
    url, branch = (url.split('#', 1) + [None])[:2]
    sys.stderr.write('Fetching cinnabar metadata from %s\n' % url)
    return store.merge(url, repo.url(), branch)
Exemple #3
0
 def instance(self, ui, url, create):
     scheme, path = url.split(':', 1)
     # strip the occasional leading // and
     # the tailing / of the new normalization
     path = path.strip('/')
     username = get_username(ui)
     if '/' not in path:
         path = username + '/' + path
     password = ui.config('bb', 'password', None)
     if password is not None:
         auth = '%s:%s@' % (username, password)
     else:
         auth = username + '@'
     formats = dict(path=path.rstrip('/') + '/', auth=auth)
     return self.factory(ui, self.url % formats, create)
Exemple #4
0
 def instance(self, ui, url, create):
     scheme, path = url.split(':', 1)
     if path.startswith('//'):
         path = path[2:]
     username = get_username(ui)
     if '/' not in path:
         path = username + '/' + path
     password = ui.config('bb', 'password', None)
     if password is not None:
         auth = '%s:%s@' % (username, password)
     else:
         auth = username + '@'
     formats = dict(
         path=path.rstrip('/') + '/',
         auth=auth
     )
     return self.factory(ui, self.url % formats, create)
Exemple #5
0
def do_cinnabarclone(repo, manifest, store):
    url = None
    for line in manifest.splitlines():
        line = line.strip()
        spec, _, params = line.partition(' ')
        params = {
            k: v
            for k, _, v in (p.partition('=') for p in params.split())
        }
        graft = params.pop('graft', None)
        if params:
            # Future proofing: ignore lines with unknown params, even if we
            # support some that are present.
            continue
        if store._graft:
            # When grafting, ignore lines without a graft revision.
            if not graft:
                continue
            graft = graft.split(',')
            revs = list(Git.iter('rev-parse', '--revs-only', *graft))
            if len(revs) != len(graft):
                continue
            # We apparently have all the grafted revisions locally, ensure
            # they're actually reachable.
            if not any(Git.iter(
                    'rev-list', '--branches', '--tags', '--remotes',
                    '--max-count=1', '--ancestry-path', '--stdin',
                    stdin=('^{}^@'.format(c) for c in graft))):
                continue
        url, _, branch = spec.partition('#')
        url, branch = (url.split('#', 1) + [None])[:2]
        if url:
            break

    if not url:
        logging.warn('Server advertizes cinnabarclone but didn\'t provide '
                     'a git repository url to fetch from.')
        return False

    parsed_url = urlparse(url)
    if parsed_url.scheme not in ('http', 'https', 'git'):
        logging.warn('Server advertizes cinnabarclone but provided a non '
                     'http/https git repository. Skipping.')
        return False
    sys.stderr.write('Fetching cinnabar metadata from %s\n' % url)
    return store.merge(url, repo.url(), branch)
Exemple #6
0
    def _check_url(cls, url, repoui=None):
        """
        Function will check given url and try to verify if it's a valid
        link. Sometimes it may happened that mercurial will issue basic
        auth request that can cause whole API to hang when used from python
        or other external calls.

        On failures it'll raise urllib2.HTTPError, exception is also thrown
        when the return code is non 200
        """
        # check first if it's not an local url
        url = safe_bytes(url)
        if os.path.isdir(url) or url.startswith(b'file:'):
            return True

        if url.startswith(b'ssh:'):
            # in case of invalid uri or authentication issues, sshpeer will
            # throw an exception.
            mercurial.sshpeer.instance(repoui or mercurial.ui.ui(), url,
                                       False).lookup(b'tip')
            return True

        url_prefix = None
        if b'+' in url[:url.find(b'://')]:
            url_prefix, url = url.split(b'+', 1)

        handlers = []
        url_obj = mercurial.util.url(url)
        test_uri, authinfo = url_obj.authinfo()
        url_obj.passwd = b'*****'
        cleaned_uri = str(url_obj)

        if authinfo:
            # create a password manager
            passmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
            passmgr.add_password(*authinfo)

            handlers.extend((mercurial.url.httpbasicauthhandler(passmgr),
                             mercurial.url.httpdigestauthhandler(passmgr)))

        o = urllib.request.build_opener(*handlers)
        o.addheaders = [('Content-Type', 'application/mercurial-0.1'),
                        ('Accept', 'application/mercurial-0.1')]

        req = urllib.request.Request(
            "%s?%s" %
            (test_uri,
             urllib.parse.urlencode({
                 'cmd': 'between',
                 'pairs': "%s-%s" % ('0' * 40, '0' * 40),
             })))

        try:
            resp = o.open(req)
            if resp.code != 200:
                raise Exception('Return Code is not 200')
        except Exception as e:
            # means it cannot be cloned
            raise urllib.error.URLError("[%s] org_exc: %s" % (cleaned_uri, e))

        if not url_prefix:  # skip svn+http://... (and git+... too)
            # now check if it's a proper hg repo
            try:
                mercurial.httppeer.instance(repoui or mercurial.ui.ui(), url,
                                            False).lookup(b'tip')
            except Exception as e:
                raise urllib.error.URLError(
                    "url [%s] does not look like an hg repo org_exc: %s" %
                    (cleaned_uri, e))

        return True
Exemple #7
0
def do_cinnabarclone(repo, manifest, store, limit_schemes=True):
    GRAFT = {
        None: None,
        b'false': False,
        b'true': True,
    }
    try:
        enable_graft = Git.config('cinnabar.graft',
                                  remote=repo.remote,
                                  values=GRAFT)
    except InvalidConfig:
        enable_graft = None

    url = None
    candidates = []
    for line in manifest.splitlines():
        line = line.strip()
        if not line:
            continue
        spec, _, params = line.partition(b' ')
        params = {
            k: v
            for k, _, v in (p.partition(b'=') for p in params.split())
        }
        graft = params.pop(b'graft', None)
        if params:
            # Future proofing: ignore lines with unknown params, even if we
            # support some that are present.
            continue
        # When grafting, ignore lines without a graft revision.
        if store._graft and not graft:
            continue
        # When explicitly disabling graft, ignore lines with a graft revision.
        if enable_graft is False and graft:
            continue

        graft = graft.split(b',') if graft else []
        graft_u = []
        for g in graft:
            if SHA1_RE.match(g):
                graft_u.append(g.decode('ascii'))
        if len(graft) != len(graft_u):
            continue
        if graft:
            revs = list(Git.iter('rev-parse', '--revs-only', *graft_u))
            if len(revs) != len(graft):
                continue
            # We apparently have all the grafted revisions locally, ensure
            # they're actually reachable.
            if not any(
                    Git.iter('rev-list',
                             '--branches',
                             '--tags',
                             '--remotes',
                             '--max-count=1',
                             '--ancestry-path',
                             '--stdin',
                             stdin=(b'^%s^@' % c for c in graft),
                             stderr=open(os.devnull, 'wb'))):
                continue

        candidates.append((spec, len(graft) != 0))

    if enable_graft is not False:
        graft_filters = [True, False]
    else:
        graft_filters = [False]
    for graft_filter in graft_filters:
        for spec, graft in candidates:
            if graft == graft_filter:
                url, _, branch = spec.partition(b'#')
                url, branch = (url.split(b'#', 1) + [None])[:2]
                if url:
                    break
        if url:
            break

    if not url:
        logging.warn('Server advertizes cinnabarclone but didn\'t provide '
                     'a git repository url to fetch from.')
        return False

    parsed_url = urlparse(url)
    if limit_schemes and parsed_url.scheme not in (b'http', b'https', b'git'):
        logging.warn('Server advertizes cinnabarclone but provided a non '
                     'http/https git repository. Skipping.')
        return False
    sys.stderr.write('Fetching cinnabar metadata from %s\n' % fsdecode(url))
    sys.stderr.flush()
    return store.merge(url, repo.url(), branch)