'Downloads an archive or checks out code from a repository.'

def fetch(self, mirror_only=False):

    self.chdir()
    fetchers = []
    if (not mirror_only):
        fetchers.append(self.default_fetcher)
    self.skip_checksum_for_mirror = True
    if self.mirror_path:
        mirrors = spack.config.get_config('mirrors')
        mirror_roots = [(root if root.endswith('/') else (root + '/')) for root in mirrors.values()]
        urls = [urljoin(root, self.mirror_path) for root in mirror_roots]
        digest = None
        expand = True
        extension = None
        if isinstance(self.default_fetcher, fs.URLFetchStrategy):
            digest = self.default_fetcher.digest
            expand = self.default_fetcher.expand_archive
            extension = self.default_fetcher.extension
        self.skip_checksum_for_mirror = (not bool(digest))
        for url in urls:
            fetchers.insert(0, fs.URLFetchStrategy(url, digest, expand=expand, extension=extension))
        if self.default_fetcher.cachable:
            fetchers.insert(0, spack.fetch_cache.fetcher(self.mirror_path, digest, expand=expand, extension=extension))
    def generate_fetchers():
        for fetcher in fetchers:
            (yield fetcher)
        if (self.search_fn and (not mirror_only)):
            dynamic_fetchers = self.search_fn()
            for fetcher in dynamic_fetchers:
                (yield fetcher)
    for fetcher in generate_fetchers():
        try:
            fetcher.set_stage(self)
            self.fetcher = fetcher
            self.fetcher.fetch()
            break
        except spack.fetch_strategy.NoCacheError as e:
            continue
        except spack.error.SpackError as e:
            tty.msg(('Fetching    from    %s    failed.' % fetcher))
            tty.debug(e)
            continue
    else:
        errMessage = ('All    fetchers    failed    for    %s' % self.name)
        self.fetcher = self.default_fetcher
        raise fs.FetchError(errMessage, None)
