239 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from __future__ import print_function
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| from datetime import datetime
 | |
| 
 | |
| import portage
 | |
| from portage.dbapi import porttree
 | |
| 
 | |
| import gentoolkit.pprinter as pp
 | |
| from gentoolkit.query import Query
 | |
| from gentoolkit.package import Package
 | |
| 
 | |
| from euscan import CONFIG, BLACKLIST_PACKAGES
 | |
| from euscan import handlers, output
 | |
| from euscan.helpers import version_blacklisted,
 | |
| from euscan.version import is_version_stable
 | |
| from euscan.ebuild import package_from_ebuild
 | |
| 
 | |
| 
 | |
| def filter_versions(cp, versions):
 | |
|     filtered = {}
 | |
| 
 | |
|     for url, version, handler, confidence in versions:
 | |
| 
 | |
|         # Try to keep the most specific urls (determinted by the length)
 | |
|         if version in filtered and len(url) < len(filtered[version]):
 | |
|             continue
 | |
| 
 | |
|         # Remove blacklisted versions
 | |
|         if version_blacklisted(cp, version):
 | |
|             continue
 | |
| 
 | |
|         filtered[version] = {
 | |
|             "url": url,
 | |
|             "handler": handler,
 | |
|             "confidence": confidence
 | |
|         }
 | |
| 
 | |
|     return [
 | |
|         (cp, filtered[version]["url"], version, filtered[version]["handler"],
 | |
|          filtered[version]["confidence"])
 | |
|         for version in filtered
 | |
|     ]
 | |
| 
 | |
| 
 | |
| def scan_upstream_urls(cpv, urls, on_progress):
 | |
|     versions = []
 | |
| 
 | |
|     if on_progress:
 | |
|         progress_available = 70
 | |
|         num_urls = sum([len(urls[fn]) for fn in urls])
 | |
|         if num_urls > 0:
 | |
|             progress_increment = progress_available / num_urls
 | |
|         else:
 | |
|             progress_increment = 0
 | |
| 
 | |
|     for filename in urls:
 | |
|         for url in urls[filename]:
 | |
| 
 | |
|             if on_progress and progress_available > 0:
 | |
|                 on_progress(increment=progress_increment)
 | |
|                 progress_available -= progress_increment
 | |
| 
 | |
|             if not CONFIG['quiet'] and not CONFIG['format']:
 | |
|                 pp.uprint()
 | |
|             output.einfo("SRC_URI is '%s'" % url)
 | |
| 
 | |
|             if '://' not in url:
 | |
|                 output.einfo("Invalid url '%s'" % url)
 | |
|                 continue
 | |
| 
 | |
|             # Try normal scan
 | |
|             if CONFIG["scan-dir"]:
 | |
|                 try:
 | |
|                     versions.extend(handlers.scan(cpv, url))
 | |
|                 except Exception as e:
 | |
|                     output.ewarn("Handler failed: [%s] %s"
 | |
|                             % (e.__class__.__name__, e.message))
 | |
| 
 | |
|             if versions and CONFIG['oneshot']:
 | |
|                 break
 | |
| 
 | |
|             # Brute Force
 | |
|             if CONFIG["brute-force"] > 0:
 | |
|                 versions.extend(handlers.brute_force(cpv, url))
 | |
| 
 | |
|             if versions and CONFIG['oneshot']:
 | |
|                 break
 | |
| 
 | |
|     cp, ver, rev = portage.pkgsplit(cpv)
 | |
| 
 | |
|     result = filter_versions(cp, versions)
 | |
| 
 | |
|     if on_progress and progress_available > 0:
 | |
|         on_progress(increment=progress_available)
 | |
| 
 | |
|     return result
 | |
| 
 | |
| 
 | |
| # gentoolkit stores PORTDB, so even if we modify it to add an overlay
 | |
| # it will still use the old dbapi
 | |
| def reload_gentoolkit():
 | |
|     from gentoolkit import dbapi
 | |
|     import gentoolkit.package
 | |
|     import gentoolkit.query
 | |
| 
 | |
|     PORTDB = portage.db[portage.root]["porttree"].dbapi
 | |
|     dbapi.PORTDB = PORTDB
 | |
| 
 | |
|     if hasattr(dbapi, 'PORTDB'):
 | |
|         dbapi.PORTDB = PORTDB
 | |
|     if hasattr(gentoolkit.package, 'PORTDB'):
 | |
|         gentoolkit.package.PORTDB = PORTDB
 | |
|     if hasattr(gentoolkit.query, 'PORTDB'):
 | |
|         gentoolkit.query.PORTDB = PORTDB
 | |
| 
 | |
| 
 | |
| def scan_upstream(query, on_progress=None):
 | |
|     """
 | |
|     Scans the upstream searching new versions for the given query
 | |
|     """
 | |
| 
 | |
|     matches = []
 | |
| 
 | |
|     if query.endswith(".ebuild"):
 | |
|         cpv = package_from_ebuild(query)
 | |
|         if cpv:
 | |
|             reload_gentoolkit()
 | |
|             matches = [Package(cpv)]
 | |
|     else:
 | |
|         matches = Query(query).find(
 | |
|             include_masked=True,
 | |
|             in_installed=False
 | |
|         )
 | |
| 
 | |
|     if not matches:
 | |
|         output.ewarn(
 | |
|             pp.warn("No package matching '%s'" % pp.pkgquery(query))
 | |
|         )
 | |
|         return None
 | |
| 
 | |
|     matches = sorted(matches)
 | |
|     pkg = matches.pop()
 | |
| 
 | |
|     while '9999' in pkg.version and len(matches):
 | |
|         pkg = matches.pop()
 | |
| 
 | |
|     if not pkg:
 | |
|         output.ewarn(
 | |
|             pp.warn("Package '%s' only have a dev version (9999)"
 | |
|                     % pp.pkgquery(pkg.cp))
 | |
|         )
 | |
|         return None
 | |
| 
 | |
|     # useful data only for formatted output
 | |
|     start_time = datetime.now()
 | |
|     output.metadata("datetime", start_time.isoformat(), show=False)
 | |
|     output.metadata("cp", pkg.cp, show=False)
 | |
|     output.metadata("cpv", pkg.cpv, show=False)
 | |
| 
 | |
|     if on_progress:
 | |
|         on_progress(increment=10)
 | |
| 
 | |
|     if pkg.cp in BLACKLIST_PACKAGES:
 | |
|         output.ewarn(
 | |
|             pp.warn("Package '%s' is blacklisted" % pp.pkgquery(pkg.cp))
 | |
|         )
 | |
|         return None
 | |
| 
 | |
|     if not CONFIG['quiet']:
 | |
|         if not CONFIG['format']:
 | |
|             pp.uprint(
 | |
|                 " * %s [%s]" % (pp.cpv(pkg.cpv), pp.section(pkg.repo_name()))
 | |
|             )
 | |
|             pp.uprint()
 | |
|         else:
 | |
|             output.metadata("overlay", pp.section(pkg.repo_name()))
 | |
| 
 | |
|         ebuild_path = pkg.ebuild_path()
 | |
|         if ebuild_path:
 | |
|             output.metadata(
 | |
|                 "ebuild", pp.path(os.path.normpath(ebuild_path))
 | |
|             )
 | |
| 
 | |
|         output.metadata("repository", pkg.repo_name())
 | |
|         output.metadata("homepage", pkg.environment("HOMEPAGE"))
 | |
|         output.metadata("description", pkg.environment("DESCRIPTION"))
 | |
| 
 | |
|     cpv = pkg.cpv
 | |
| 
 | |
|     _, _, ver, _ = portage.catpkgsplit(cpv)
 | |
|     is_current_version_stable = is_version_stable(ver)
 | |
| 
 | |
|     metadata = {
 | |
|         "EAPI": portage.settings["EAPI"],
 | |
|         "SRC_URI": pkg.environment("SRC_URI", False),
 | |
|     }
 | |
|     use = frozenset(portage.settings["PORTAGE_USE"].split())
 | |
|     try:
 | |
|         alist = porttree._parse_uri_map(cpv, metadata, use=use)
 | |
|         aalist = porttree._parse_uri_map(cpv, metadata)
 | |
|     except Exception as e:
 | |
|         output.ewarn(pp.warn("%s\n" % str(e)))
 | |
|         output.ewarn(
 | |
|             pp.warn("Invalid SRC_URI for '%s'" % pp.pkgquery(cpv))
 | |
|         )
 | |
|         return None
 | |
| 
 | |
|     if "mirror" in portage.settings.features:
 | |
|         urls = aalist
 | |
|     else:
 | |
|         urls = alist
 | |
| 
 | |
|     # output scan time for formatted output
 | |
|     scan_time = (datetime.now() - start_time).total_seconds()
 | |
|     output.metadata("scan_time", scan_time, show=False)
 | |
| 
 | |
|     result = scan_upstream_urls(pkg.cpv, urls, on_progress)
 | |
| 
 | |
|     if on_progress:
 | |
|         on_progress(increment=10)
 | |
| 
 | |
|     if len(result) > 0:
 | |
|         if not (CONFIG['format'] or CONFIG['quiet']):
 | |
|             print("\n", file=sys.stderr)
 | |
| 
 | |
|         for cp, url, version, handler, confidence in result:
 | |
|             if CONFIG["ignore-pre-release"]:
 | |
|                 if not is_version_stable(version):
 | |
|                     continue
 | |
|             if CONFIG["ignore-pre-release-if-stable"]:
 | |
|                 if is_current_version_stable and \
 | |
|                    not is_version_stable(version):
 | |
|                     continue
 | |
|             output.result(cp, version, url, handler, confidence)
 | |
| 
 | |
|     return result
 |