Beispiel #1
0
    def fetch_dist(self,
                   dist,
                   fetch_dir,
                   force=False,
                   check_md5=False,
                   dry_run=False):
        """
        Get a distribution, i.e. copy or download the distribution into
        fetch_dir.

        force:
            force download or copy

        check_md5:
            when determining if a file needs to be downloaded or copied,
            check it's MD5.  This is, of course, slower but more reliable
            then just checking the file-size (which always done first).
            Note:
              * This option has option has nothing to do with checking the
                MD5 of a download.  The md5 is always checked when files are
                downloaded (regardless of this option).
              * If force=True, this option is has no effect, because the file
                is forcefully downloaded, ignoring any existing file (as well
                as the MD5).
        """
        md5 = self.index[dist].get('md5', None)
        size = self.index[dist].get('size', None)

        fn = dist_naming.filename_dist(dist)
        dst = join(fetch_dir, fn)
        # if force is not used, see if (i) the file exists (ii) its size is
        # the expected (iii) optionally, make sure the md5 is the expected.
        if (not force and isfile(dst) and getsize(dst) == size
                and (not check_md5 or md5_file(dst) == md5)):
            if self.verbose:
                print "Not forcing refetch, %r already exists" % dst
            return

        pprint_fn_action(fn, ['copying',
                              'downloading'][dist.startswith('http://')])
        if dry_run:
            return

        if self.verbose:
            print "Copying: %r" % dist
            print "     to: %r" % dst

        fo = open(dst + '.part', 'wb')
        write_data_from_url(fo, dist, md5, size)
        fo.close()
        rm_rf(dst)
        os.rename(dst + '.part', dst)
Beispiel #2
0
    def fetch_dist(self, dist, fetch_dir, force=False, check_md5=False,
                   dry_run=False):
        """
        Get a distribution, i.e. copy or download the distribution into
        fetch_dir.

        force:
            force download or copy

        check_md5:
            when determining if a file needs to be downloaded or copied,
            check it's MD5.  This is, of course, slower but more reliable
            then just checking the file-size (which is always done first).
            Note:
              * This option has nothing to do with checking the MD5 of the
                download.  The md5 is always checked when files are
                downloaded (regardless of this option).
              * If force=True, this option is has no effect, because the file
                is forcefully downloaded, ignoring any existing file (as well
                as the MD5).
        """
        md5 = self.index[dist].get('md5')
        size = self.index[dist].get('size')

        fn = dist_naming.filename_dist(dist)
        dst = join(fetch_dir, fn)
        # if force is not used, see if (i) the file exists (ii) its size is
        # the expected (iii) optionally, make sure the md5 is the expected.
        if (not force and isfile(dst) and getsize(dst) == size and
                   (not check_md5 or md5_file(dst) == md5)):
            if self.verbose:
                print "Not forcing refetch, %r already exists" % dst
            return
        self.file_action_callback(fn, ('copying', 'downloading')
                                  [dist.startswith(('http://', 'https://'))])
        if dry_run:
            return

        if self.verbose:
            print "Copying: %r" % dist
            print "     to: %r" % dst

        fo = open(dst + '.part', 'wb')
        write_data_from_url(fo, dist, md5, size,
                            progress_callback=self.download_progress_callback)
        fo.close()
        rm_rf(dst)
        os.rename(dst + '.part', dst)
Beispiel #3
0
    def determine_install_order(self, dists):
        """
        given the distributions 'dists' (which are already complete, i.e.
        the for each distribution all dependencies are also included in
        the 'dists'), return a list of the same distribution in the correct
        install order
        """
        dists = list(dists)
        assert self.are_complete(dists)

        # make sure each project name is listed only once
        assert len(dists) == len(set(self.cname_dist(d) for d in dists))

        # the distributions corresponding to the requirements must be sorted
        # because the output of this function is otherwise not deterministic
        dists.sort(key=self.cname_dist)

        # maps dist -> set of required (project) names
        rns = {}
        for dist in dists:
            rns[dist] = set(r.name for r in self.reqs_dist(dist))

        # as long as we have things missing, simply look for things which
        # can be added, i.e. all the requirements have been added already
        result = []
        names_inst = set()
        while len(result) < len(dists):
            n = len(result)
            for dist in dists:
                if dist in result:
                    continue
                # see if all required packages were added already
                if all(bool(name in names_inst) for name in rns[dist]):
                    result.append(dist)
                    names_inst.add(self.index[dist]['cname'])
                    assert len(names_inst) == len(result)

            if len(result) == n:
                # nothing was added
                raise Exception("Loop in dependency graph\n%r" %
                                [dist_naming.filename_dist(d) for d in dists])
        return result
Beispiel #4
0
    def determine_install_order(self, dists):
        """
        given the distributions 'dists' (which are already complete, i.e.
        the for each distribution all dependencies are also included in
        the 'dists'), return a list of the same distribution in the correct
        install order
        """
        dists = list(dists)
        assert self.are_complete(dists)

        # make sure each project name is listed only once
        assert len(dists) == len(set(self.cname_dist(d) for d in dists))

        # the distributions corresponding to the requirements must be sorted
        # because the output of this function is otherwise not deterministic
        dists.sort(key=self.cname_dist)

        # maps dist -> set of required (project) names
        rns = {}
        for dist in dists:
            rns[dist] = set(r.name for r in self.reqs_dist(dist))

        # as long as we have things missing, simply look for things which
        # can be added, i.e. all the requirements have been added already
        result = []
        names_inst = set()
        while len(result) < len(dists):
            n = len(result)
            for dist in dists:
                if dist in result:
                    continue
                # see if all required packages were added already
                if all(bool(name in names_inst) for name in rns[dist]):
                    result.append(dist)
                    names_inst.add(self.index[dist]['cname'])
                    assert len(names_inst) == len(result)

            if len(result) == n:
                # nothing was added
                raise Exception("Loop in dependency graph\n%r" %
                                [dist_naming.filename_dist(d) for d in dists])
        return result
Beispiel #5
0
def dist_as_req(dist, strictness=3):
    """
    Return the distribution in terms of the a requirement object.
    That is: What requirement gives me the distribution?
    """
    return filename_as_req(filename_dist(dist), strictness)
Beispiel #6
0
def dist_as_req(dist, strictness=3):
    """
    Return the distribution in terms of the a requirement object.
    That is: What requirement gives me the distribution?
    """
    return filename_as_req(filename_dist(dist), strictness)