Index: ../../trunk/pym/_emerge/EbuildFetcher.py =================================================================== --- ../../trunk/pym/_emerge/EbuildFetcher.py (revision 15311) +++ ../../trunk/pym/_emerge/EbuildFetcher.py (revision 15312) @@ -26,6 +26,12 @@ raise AssertionError("ebuild not found for '%s'" % self.pkg.cpv) settings = self.config_pool.allocate() settings.setcpv(self.pkg) + if self.prefetch and \ + self._prefetch_size_ok(portdb, settings, ebuild_path): + self.config_pool.deallocate(settings) + self.returncode = os.EX_OK + self.wait() + return # In prefetch mode, logging goes to emerge-fetch.log and the builddir # should not be touched since otherwise it could interfere with @@ -78,6 +84,52 @@ self.config_pool.deallocate(settings) SpawnProcess._start(self) + def _prefetch_size_ok(self, portdb, settings, ebuild_path): + pkgdir = os.path.dirname(ebuild_path) + mytree = os.path.dirname(os.path.dirname(pkgdir)) + distdir = settings["DISTDIR"] + use = None + if not self.fetchall: + use = frozenset(settings["PORTAGE_USE"].split()) + + try: + uri_map = portdb.getFetchMap(self.pkg.cpv, + useflags=use, mytree=mytree) + except portage.exception.InvalidDependString as e: + return False + + sizes = {} + for filename in uri_map: + try: + st = os.lstat(os.path.join(distdir, filename)) + except OSError: + return False + if st.st_size == 0: + return False + sizes[filename] = st.st_size + + digests = portage.Manifest(pkgdir, distdir).getTypeDigests("DIST") + for filename, actual_size in sizes.items(): + size = digests.get(filename, {}).get('size') + if size is None: + continue + if size != actual_size: + return False + + # All files are present and sizes are ok. In this case the normal + # fetch code will be skipped, so we need to generate equivalent + # output here. + if self.logfile is not None: + f = codecs.open(_unicode_encode(self.logfile, + encoding=_encodings['fs'], errors='strict'), + mode='a', encoding=_encodings['content'], errors='replace') + for filename in uri_map: + f.write((' * %s size ;-) ...' % \ + filename).ljust(73) + '[ ok ]\n') + f.close() + + return True + def _pipe(self, fd_pipes): """When appropriate, use a pty so that fetcher progress bars, like wget has, will work properly."""