euscan: allow to use .ebuild files in any directory

Even outside PORTDIR_OVERLAY !

Signed-off-by: Corentin Chary <corentin.chary@gmail.com>
This commit is contained in:
Corentin Chary 2012-05-24 23:44:05 +02:00
parent 7f8fb05c23
commit 177d77842f
3 changed files with 113 additions and 100 deletions

86
pym/euscan/ebuild.py Normal file
View File

@ -0,0 +1,86 @@
import os, sys, imp
import portage
from portage.const import VDB_PATH
from portage import _encodings
from portage import _shell_quote
from portage import _unicode_decode
from portage import _unicode_encode
# Stolen from the ebuild command
def package_from_ebuild(ebuild):
pf = None
if ebuild.endswith(".ebuild"):
pf = os.path.basename(ebuild)[:-7]
else:
return False
if not os.path.isabs(ebuild):
mycwd = os.getcwd()
# Try to get the non-canonical path from the PWD evironment variable,
# since the canonical path returned from os.getcwd() may may be
# unusable in cases where the directory stucture is built from
# symlinks.
pwd = os.environ.get('PWD', '')
if sys.hexversion < 0x3000000:
pwd = _unicode_decode(pwd, encoding=_encodings['content'],
errors='strict')
if pwd and pwd != mycwd and \
os.path.realpath(pwd) == mycwd:
mycwd = portage.normalize_path(pwd)
ebuild = os.path.join(mycwd, ebuild)
ebuild = portage.normalize_path(ebuild)
# portdbapi uses the canonical path for the base of the portage tree, but
# subdirectories of the base can be built from symlinks (like crossdev
# does).
ebuild_portdir = os.path.realpath(
os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
vdb_path = os.path.join(portage.settings['ROOT'], VDB_PATH)
# Make sure that portdb.findname() returns the correct ebuild.
if ebuild_portdir != vdb_path and \
ebuild_portdir not in portage.portdb.porttrees:
if sys.hexversion >= 0x3000000:
os.environ["PORTDIR_OVERLAY"] = \
os.environ.get("PORTDIR_OVERLAY", "") + \
" " + _shell_quote(ebuild_portdir)
else:
os.environ["PORTDIR_OVERLAY"] = \
os.environ.get("PORTDIR_OVERLAY", "") + \
" " + _unicode_encode(_shell_quote(ebuild_portdir),
encoding=_encodings['content'], errors='strict')
portage.close_portdbapi_caches()
imp.reload(portage)
del portage.portdb.porttrees[1:]
if ebuild_portdir != portage.portdb.porttree_root:
portage.portdb.porttrees.append(ebuild_portdir)
if not os.path.exists(ebuild):
return False
ebuild_split = ebuild.split("/")
cpv = "%s/%s" % (ebuild_split[-3], pf)
if not portage.catpkgsplit(cpv):
return False
if ebuild.startswith(os.path.join(portage.root, portage.const.VDB_PATH)):
mytree = "vartree"
portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
if os.path.realpath(portage_ebuild) != ebuild:
return False
else:
mytree = "porttree"
portage_ebuild = portage.portdb.findname(cpv)
if not portage_ebuild or portage_ebuild != ebuild:
return False
return cpv

View File

@ -3,10 +3,12 @@ import sys
import re import re
import pkg_resources import pkg_resources
import errno import errno
import imp
import urllib2 import urllib2
import portage
from portage import dep
try: try:
from urllib import robotparser from urllib import robotparser
from urllib import urlparse from urllib import urlparse
@ -14,13 +16,6 @@ except ImportError:
import robotparser import robotparser
import urlparse import urlparse
import portage
from portage import dep
from portage.const import VDB_PATH
from portage import _encodings
from portage import _shell_quote
from portage import _unicode_decode
from portage import _unicode_encode
from euscan import CONFIG, BLACKLIST_VERSIONS, ROBOTS_TXT_BLACKLIST_DOMAINS from euscan import CONFIG, BLACKLIST_VERSIONS, ROBOTS_TXT_BLACKLIST_DOMAINS
import euscan import euscan
@ -546,7 +541,6 @@ def generate_scan_paths(url):
return steps return steps
def parse_mirror(uri): def parse_mirror(uri):
from random import shuffle from random import shuffle
@ -573,82 +567,3 @@ def parse_mirror(uri):
return None return None
return uri return uri
# Stolen from ebuild
def query_from_ebuild(ebuild):
pf = None
if ebuild.endswith(".ebuild"):
pf = os.path.basename(ebuild)[:-7]
else:
return False
if not os.path.isabs(ebuild):
mycwd = os.getcwd()
# Try to get the non-canonical path from the PWD evironment variable,
# since the canonical path returned from os.getcwd() may may be
# unusable in cases where the directory stucture is built from
# symlinks.
pwd = os.environ.get('PWD', '')
if sys.hexversion < 0x3000000:
pwd = _unicode_decode(pwd, encoding=_encodings['content'],
errors='strict')
if pwd and pwd != mycwd and \
os.path.realpath(pwd) == mycwd:
mycwd = portage.normalize_path(pwd)
ebuild = os.path.join(mycwd, ebuild)
ebuild = portage.normalize_path(ebuild)
# portdbapi uses the canonical path for the base of the portage tree, but
# subdirectories of the base can be built from symlinks (like crossdev
# does).
ebuild_portdir = os.path.realpath(
os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
vdb_path = os.path.join(portage.settings['ROOT'], VDB_PATH)
# Make sure that portdb.findname() returns the correct ebuild.
if ebuild_portdir != vdb_path and \
ebuild_portdir not in portage.portdb.porttrees:
if sys.hexversion >= 0x3000000:
os.environ["PORTDIR_OVERLAY"] = \
os.environ.get("PORTDIR_OVERLAY", "") + \
" " + _shell_quote(ebuild_portdir)
else:
os.environ["PORTDIR_OVERLAY"] = \
os.environ.get("PORTDIR_OVERLAY", "") + \
" " + _unicode_encode(_shell_quote(ebuild_portdir),
encoding=_encodings['content'], errors='strict')
portage.close_portdbapi_caches()
imp.reload(portage)
del portage.portdb.porttrees[1:]
if ebuild_portdir != portage.portdb.porttree_root:
portage.portdb.porttrees.append(ebuild_portdir)
if not os.path.exists(ebuild):
return False
ebuild_split = ebuild.split("/")
cpv = "%s/%s" % (ebuild_split[-3], pf)
if not portage.catpkgsplit(cpv):
return False
if ebuild.startswith(os.path.join(portage.root, portage.const.VDB_PATH)):
mytree = "vartree"
portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
if os.path.realpath(portage_ebuild) != ebuild:
return False
else:
mytree = "porttree"
portage_ebuild = portage.portdb.findname(cpv)
if not portage_ebuild or portage_ebuild != ebuild:
return False
return cpv

View File

@ -2,20 +2,20 @@ import os
import sys import sys
import portage import portage
from portage.dbapi import porttree from portage.dbapi import porttree
import gentoolkit.pprinter as pp import gentoolkit.pprinter as pp
from gentoolkit.query import Query from gentoolkit.query import Query
from gentoolkit.package import Package
from gentoolkit.eclean.search import (port_settings) from gentoolkit.eclean.search import (port_settings)
from euscan import CONFIG, BLACKLIST_PACKAGES from euscan import CONFIG, BLACKLIST_PACKAGES
from euscan import handlers from euscan import handlers
from euscan import helpers from euscan import helpers
from euscan.ebuild import package_from_ebuild
import euscan import euscan
def filter_versions(cp, versions): def filter_versions(cp, versions):
filtered = {} filtered = {}
@ -64,15 +64,27 @@ def scan_upstream_urls(cpv, urls):
cp, ver, rev = portage.pkgsplit(cpv) cp, ver, rev = portage.pkgsplit(cpv)
return filter_versions(cp, versions) return filter_versions(cp, versions)
# gentoolkit stores PORTDB, so even if we modify it to add an overlay
# it will still use the old dbapi
def reload_gentoolkit():
import gentoolkit.package
import gentoolkit.query
PORTDB = portage.db[portage.root]["porttree"].dbapi
if hasattr(gentoolkit.package, 'PORTDB'):
gentoolkit.package.PORTDB = PORTDB
if hasattr(gentoolkit.query, 'PORTDB'):
gentoolkit.query.PORTDB = PORTDB
def scan_upstream(query): def scan_upstream(query):
matches = []
# check if the query is an ebuild file. if query.endswith(".ebuild"):
# if it's a valid ebuild convert the filename in an euscan query cpv = package_from_ebuild(query)
ebuild_query = helpers.query_from_ebuild(query) if cpv:
if ebuild_query: reload_gentoolkit()
query = ebuild_query matches = [Package(cpv)]
else:
matches = Query(query).find( matches = Query(query).find(
include_masked=True, include_masked=True,
in_installed=False in_installed=False