Merge git://github.com/volpino/euscan
Conflicts: pym/euscan/scan.py
This commit is contained in:
commit
687851ffcb
180
bin/euscan
180
bin/euscan
@ -6,51 +6,58 @@ Distributed under the terms of the GNU General Public License v2
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
""" Meta """
|
|
||||||
|
# Meta
|
||||||
|
|
||||||
__author__ = "Corentin Chary (iksaif)"
|
__author__ = "Corentin Chary (iksaif)"
|
||||||
__email__ = "corentin.chary@gmail.com"
|
__email__ = "corentin.chary@gmail.com"
|
||||||
__version__ = "git"
|
__version__ = "git"
|
||||||
__productname__ = "euscan"
|
__productname__ = "euscan"
|
||||||
__description__ = "A tool to detect new upstream releases."
|
__description__ = "A tool to detect new upstream releases."
|
||||||
__version__ = "git"
|
|
||||||
|
|
||||||
""" Imports """
|
|
||||||
|
# Imports
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
import errno
|
import errno
|
||||||
import httplib
|
import httplib
|
||||||
|
|
||||||
from portage.output import white, yellow, turquoise, green, EOutput
|
from portage.output import white, yellow, turquoise, green
|
||||||
from portage.exception import AmbiguousPackageName
|
from portage.exception import AmbiguousPackageName
|
||||||
|
|
||||||
from gentoolkit import pprinter as pp
|
from gentoolkit import pprinter as pp
|
||||||
from gentoolkit.eclean.search import (port_settings)
|
from gentoolkit.eclean.search import (port_settings)
|
||||||
from gentoolkit.errors import GentoolkitException
|
from gentoolkit.errors import GentoolkitException
|
||||||
|
|
||||||
import euscan
|
from euscan import CONFIG, output
|
||||||
from euscan import CONFIG
|
|
||||||
from euscan.scan import scan_upstream
|
from euscan.scan import scan_upstream
|
||||||
|
|
||||||
""" Globals """
|
|
||||||
|
# Globals
|
||||||
|
|
||||||
|
def exit_helper(status):
|
||||||
|
if CONFIG["format"]:
|
||||||
|
print(output.get_formatted_output())
|
||||||
|
sys.exit(status)
|
||||||
|
|
||||||
|
|
||||||
def setupSignals():
|
def setup_signals():
|
||||||
""" This block ensures that ^C interrupts are handled quietly. """
|
"""This block ensures that ^C interrupts are handled quietly."""
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
def exithandler(signum, frame):
|
def exithandler(signum, frame):
|
||||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||||
print()
|
print()
|
||||||
sys.exit(errno.EINTR)
|
exit_helper(errno.EINTR)
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, exithandler)
|
signal.signal(signal.SIGINT, exithandler)
|
||||||
signal.signal(signal.SIGTERM, exithandler)
|
signal.signal(signal.SIGTERM, exithandler)
|
||||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||||
|
|
||||||
|
|
||||||
def printVersion():
|
def print_version():
|
||||||
"""Output the version info."""
|
"""Output the version info."""
|
||||||
print("%s (%s) - %s" \
|
print("%s (%s) - %s" \
|
||||||
% (__productname__, __version__, __description__))
|
% (__productname__, __version__, __description__))
|
||||||
@ -60,23 +67,26 @@ def printVersion():
|
|||||||
print("Distributed under the terms of the GNU General Public License v2")
|
print("Distributed under the terms of the GNU General Public License v2")
|
||||||
|
|
||||||
|
|
||||||
def printUsage(_error=None, help=None):
|
def print_usage(_error=None, help=None):
|
||||||
"""Print help message. May also print partial help to stderr if an
|
"""Print help message. May also print partial help to stderr if an
|
||||||
error from {'options'} is specified."""
|
error from {'options'} is specified."""
|
||||||
|
|
||||||
out = sys.stdout
|
out = sys.stdout
|
||||||
if _error:
|
if _error:
|
||||||
out = sys.stderr
|
out = sys.stderr
|
||||||
|
|
||||||
if not _error in ('global-options', 'packages',):
|
if not _error in ('global-options', 'packages',):
|
||||||
_error = None
|
_error = None
|
||||||
|
|
||||||
if not _error and not help:
|
if not _error and not help:
|
||||||
help = 'all'
|
help = 'all'
|
||||||
|
|
||||||
if _error in ('global-options',):
|
if _error in ('global-options',):
|
||||||
print(pp.error("Wrong option on command line."), file=out)
|
output.eerror("Wrong option on command line.\n")
|
||||||
print(file=out)
|
|
||||||
if _error in ('packages',):
|
if _error in ('packages',):
|
||||||
print(pp.error("You need to specify exactly one package."), file=out)
|
output.eerror("You need to specify exactly one package.\n")
|
||||||
print(file=out)
|
|
||||||
print(white("Usage:"), file=out)
|
print(white("Usage:"), file=out)
|
||||||
if _error in ('global-options', 'packages',) or help == 'all':
|
if _error in ('global-options', 'packages',) or help == 'all':
|
||||||
print(" " + turquoise(__productname__),
|
print(" " + turquoise(__productname__),
|
||||||
@ -106,14 +116,19 @@ def printUsage(_error=None, help=None):
|
|||||||
" (default: 2)\n" +
|
" (default: 2)\n" +
|
||||||
" " * 29 + "bigger levels will generate more versions numbers\n" +
|
" " * 29 + "bigger levels will generate more versions numbers\n" +
|
||||||
" " * 29 + "0 means disabled", file=out)
|
" " * 29 + "0 means disabled", file=out)
|
||||||
|
print(yellow(" -f, --format=<format>") +
|
||||||
|
" - define the output " + yellow("<format>") +
|
||||||
|
" (available: json)", file=out)
|
||||||
print(file=out)
|
print(file=out)
|
||||||
|
|
||||||
if _error in ('packages',) or help:
|
if _error in ('packages',) or help:
|
||||||
print(green(" package") +
|
print(green(" package") +
|
||||||
" - the packages (or ebuilds) you want to scan",
|
" - the packages (or ebuilds) you want to scan",
|
||||||
file=out)
|
file=out)
|
||||||
print(file=out)
|
print(file=out)
|
||||||
'''print( "More detailed instruction can be found in",
|
|
||||||
turquoise("`man %s`" % __productname__), file=out)'''
|
#print( "More detailed instruction can be found in",
|
||||||
|
#turquoise("`man %s`" % __productname__), file=out)
|
||||||
|
|
||||||
|
|
||||||
class ParseArgsException(Exception):
|
class ParseArgsException(Exception):
|
||||||
@ -125,12 +140,12 @@ class ParseArgsException(Exception):
|
|||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
|
|
||||||
def parseArgs():
|
def parse_args():
|
||||||
"""Parse the command line arguments. Raise exceptions on
|
"""Parse the command line arguments. Raise exceptions on
|
||||||
errors. Returns package and affect the CONFIG dict.
|
errors. Returns packages and affects the CONFIG dict.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def optionSwitch(opts):
|
def option_switch(opts):
|
||||||
"""local function for interpreting command line options
|
"""local function for interpreting command line options
|
||||||
and setting options accordingly"""
|
and setting options accordingly"""
|
||||||
return_code = True
|
return_code = True
|
||||||
@ -151,29 +166,35 @@ def parseArgs():
|
|||||||
CONFIG['brute-force'] = int(a)
|
CONFIG['brute-force'] = int(a)
|
||||||
elif o in ("-v", "--verbose") and not CONFIG['quiet']:
|
elif o in ("-v", "--verbose") and not CONFIG['quiet']:
|
||||||
CONFIG['verbose'] += 1
|
CONFIG['verbose'] += 1
|
||||||
|
elif o in ("-f", "--format"):
|
||||||
|
CONFIG['format'] = a
|
||||||
|
CONFIG['nocolor'] = True
|
||||||
|
pp.output.nocolor()
|
||||||
else:
|
else:
|
||||||
return_code = False
|
return_code = False
|
||||||
|
|
||||||
return return_code
|
return return_code
|
||||||
|
|
||||||
' here are the different allowed command line options (getopt args) '
|
# here are the different allowed command line options (getopt args)
|
||||||
getopt_options = {'short': {}, 'long': {}}
|
getopt_options = {'short': {}, 'long': {}}
|
||||||
getopt_options['short']['global'] = "hVCqv1b:"
|
getopt_options['short']['global'] = "hVCqv1bf:"
|
||||||
getopt_options['long']['global'] = ["help", "version", "nocolor", "quiet",
|
getopt_options['long']['global'] = [
|
||||||
"verbose", "oneshot", "brute-force="]
|
"help", "version", "nocolor", "quiet", "verbose", "oneshot",
|
||||||
|
"brute-force=", "format="
|
||||||
|
]
|
||||||
|
|
||||||
short_opts = getopt_options['short']['global']
|
short_opts = getopt_options['short']['global']
|
||||||
long_opts = getopt_options['long']['global']
|
long_opts = getopt_options['long']['global']
|
||||||
opts_mode = 'global'
|
opts_mode = 'global'
|
||||||
|
|
||||||
' apply getopts to command line, show partial help on failure '
|
# apply getopts to command line, show partial help on failure
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], short_opts, long_opts)
|
opts, args = getopt.getopt(sys.argv[1:], short_opts, long_opts)
|
||||||
except:
|
except:
|
||||||
raise ParseArgsException(opts_mode + '-options')
|
raise ParseArgsException(opts_mode + '-options')
|
||||||
|
|
||||||
' set options accordingly '
|
# set options accordingly
|
||||||
optionSwitch(opts)
|
option_switch(opts)
|
||||||
|
|
||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
raise ParseArgsException('packages')
|
raise ParseArgsException('packages')
|
||||||
@ -183,81 +204,80 @@ def parseArgs():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Parse command line and execute all actions."""
|
"""Parse command line and execute all actions."""
|
||||||
CONFIG['nocolor'] = (port_settings["NOCOLOR"] in ('yes', 'true')
|
CONFIG['nocolor'] = (
|
||||||
or not sys.stdout.isatty())
|
port_settings["NOCOLOR"] in ('yes', 'true') or not sys.stdout.isatty()
|
||||||
|
)
|
||||||
if CONFIG['nocolor']:
|
if CONFIG['nocolor']:
|
||||||
pp.output.nocolor()
|
pp.output.nocolor()
|
||||||
' parse command line options and actions '
|
|
||||||
|
# parse command line options and actions
|
||||||
try:
|
try:
|
||||||
packages = parseArgs()
|
queries = parse_args()
|
||||||
except ParseArgsException as e:
|
except ParseArgsException as e:
|
||||||
if e.value == 'help':
|
if e.value == 'help':
|
||||||
printUsage(help='all')
|
print_usage(help='all')
|
||||||
sys.exit(0)
|
exit_helper(0)
|
||||||
elif e.value[:5] == 'help-':
|
|
||||||
printUsage(help=e.value[5:])
|
elif e.value[:5] == 'help-':
|
||||||
sys.exit(0)
|
print_usage(help=e.value[5:])
|
||||||
elif e.value == 'version':
|
exit_helper(0)
|
||||||
printVersion()
|
|
||||||
sys.exit(0)
|
elif e.value == 'version':
|
||||||
else:
|
print_version()
|
||||||
printUsage(e.value)
|
exit_helper(0)
|
||||||
sys.exit(errno.EINVAL)
|
|
||||||
|
else:
|
||||||
|
print_usage(e.value)
|
||||||
|
exit_helper(errno.EINVAL)
|
||||||
|
|
||||||
""" Change euscan's output """
|
|
||||||
euscan.output = EOutput(CONFIG['quiet'])
|
|
||||||
if CONFIG['verbose'] > 2:
|
if CONFIG['verbose'] > 2:
|
||||||
httplib.HTTPConnection.debuglevel = 1
|
httplib.HTTPConnection.debuglevel = 1
|
||||||
|
|
||||||
for package in packages:
|
for query in queries:
|
||||||
ret = []
|
ret = []
|
||||||
|
|
||||||
|
output.set_query(query)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = scan_upstream(package)
|
ret = scan_upstream(query)
|
||||||
except AmbiguousPackageName as e:
|
except AmbiguousPackageName as e:
|
||||||
pkgs = e.args[0]
|
pkgs = e.args[0]
|
||||||
for candidate in pkgs:
|
output.eerror("\n".join(pkgs))
|
||||||
print(candidate)
|
|
||||||
|
|
||||||
from os.path import basename # To get the short name
|
from os.path import basename # To get the short name
|
||||||
|
|
||||||
print(file=sys.stderr)
|
output.error(
|
||||||
print(
|
"The short ebuild name '%s' is ambiguous. Please specify" %
|
||||||
pp.error(
|
basename(pkgs[0]),
|
||||||
"The short ebuild name '%s' is ambiguous. Please specify" \
|
"one of the above fully-qualified ebuild names instead."
|
||||||
% basename(pkgs[0])
|
|
||||||
),
|
|
||||||
file=sys.stderr, end=""
|
|
||||||
)
|
)
|
||||||
pp.die(1, "one of the above fully-qualified ebuild names instead.")
|
exit_helper(1)
|
||||||
except GentoolkitException as err:
|
|
||||||
pp.die(1, '%s: %s' % (package, str(err)))
|
|
||||||
except Exception as err:
|
|
||||||
pp.die(1, '%s: %s' % (package, str(err)))
|
|
||||||
|
|
||||||
if not CONFIG['quiet']:
|
except GentoolkitException as err:
|
||||||
|
output.eerror('%s: %s' % (query, str(err)))
|
||||||
|
exit_helper(1)
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
output.eerror('%s: %s' % (query, str(err)))
|
||||||
|
exit_helper(1)
|
||||||
|
|
||||||
|
if not CONFIG['quiet'] and not CONFIG['format']:
|
||||||
print()
|
print()
|
||||||
|
|
||||||
for cp, url, version in ret:
|
if ret is not None:
|
||||||
if not CONFIG['quiet']:
|
if len(ret) > 0:
|
||||||
print("Upstream Version: "
|
for cp, url, version, handler, confidence in ret:
|
||||||
+ pp.number("%s" % version)
|
output.result(cp, version, url, handler, confidence)
|
||||||
+ pp.path(" %s" % url))
|
elif not CONFIG['quiet']:
|
||||||
else:
|
output.ewarn(
|
||||||
print(pp.cpv("%s-%s" % (cp, version))
|
"Didn't find any new version, check package's homepage " +
|
||||||
+ ": " + pp.path(url))
|
"for more informations"
|
||||||
|
)
|
||||||
|
|
||||||
if not len(ret) and not CONFIG['quiet']:
|
output.set_query(None)
|
||||||
print(pp.warn("Didn't find any new version, "
|
|
||||||
+ "check package's homepage for "
|
|
||||||
+ "more informations"))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
setup_signals()
|
||||||
setupSignals()
|
|
||||||
main()
|
main()
|
||||||
except KeyboardInterrupt:
|
exit_helper(0)
|
||||||
print("Aborted.")
|
|
||||||
sys.exit(errno.EINTR)
|
|
||||||
sys.exit(0)
|
|
||||||
|
@ -3,11 +3,17 @@
|
|||||||
# Copyright 2011 Corentin Chary <corentin.chary@gmail.com>
|
# Copyright 2011 Corentin Chary <corentin.chary@gmail.com>
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
# Distributed under the terms of the GNU General Public License v2
|
||||||
|
|
||||||
|
from io import StringIO
|
||||||
|
from collections import defaultdict
|
||||||
|
import json
|
||||||
|
|
||||||
|
from gentoolkit import pprinter as pp
|
||||||
|
from portage.output import EOutput
|
||||||
|
|
||||||
|
|
||||||
__version__ = "git"
|
__version__ = "git"
|
||||||
|
|
||||||
|
|
||||||
from portage.output import EOutput
|
|
||||||
|
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
'nocolor': False,
|
'nocolor': False,
|
||||||
'quiet': False,
|
'quiet': False,
|
||||||
@ -20,11 +26,11 @@ CONFIG = {
|
|||||||
'oneshot': True,
|
'oneshot': True,
|
||||||
'user-agent': 'escan (http://euscan.iksaif.net)',
|
'user-agent': 'escan (http://euscan.iksaif.net)',
|
||||||
'skip-robots-txt': False,
|
'skip-robots-txt': False,
|
||||||
'cache': False
|
'cache': False,
|
||||||
|
'format': None,
|
||||||
|
'indent': 2
|
||||||
}
|
}
|
||||||
|
|
||||||
output = EOutput(CONFIG['quiet'])
|
|
||||||
|
|
||||||
BLACKLIST_VERSIONS = [
|
BLACKLIST_VERSIONS = [
|
||||||
# Compatibility package for running binaries linked against a
|
# Compatibility package for running binaries linked against a
|
||||||
# pre gcc 3.4 libstdc++, won't be updated
|
# pre gcc 3.4 libstdc++, won't be updated
|
||||||
@ -53,10 +59,11 @@ BRUTEFORCE_BLACKLIST_PACKAGES = [
|
|||||||
BRUTEFORCE_BLACKLIST_URLS = [
|
BRUTEFORCE_BLACKLIST_URLS = [
|
||||||
'http://(.*)dockapps.org/download.php/id/(.*)', # infinite loop
|
'http://(.*)dockapps.org/download.php/id/(.*)', # infinite loop
|
||||||
'http://hydra.nixos.org/build/(.*)', # infinite loop
|
'http://hydra.nixos.org/build/(.*)', # infinite loop
|
||||||
'http://www.rennings.net/gentoo/distfiles/(.*)', # Doesn't respect 404, infinite loop
|
# Doesn't respect 404, infinite loop
|
||||||
'http://art.gnome.org/download/(.*)', # Doesn't respect 404, infinite loop
|
'http://www.rennings.net/gentoo/distfiles/(.*)',
|
||||||
'http://barelysufficient.org/~olemarkus/(.*)', # Doesn't respect 404, infinite loop
|
'http://art.gnome.org/download/(.*)',
|
||||||
'http://olemarkus.org/~olemarkus/(.*)', # Doesn't respect 404, infinite loop
|
'http://barelysufficient.org/~olemarkus/(.*)',
|
||||||
|
'http://olemarkus.org/~olemarkus/(.*)',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROBOTS_TXT_BLACKLIST_DOMAINS = [
|
ROBOTS_TXT_BLACKLIST_DOMAINS = [
|
||||||
@ -67,3 +74,94 @@ ROBOTS_TXT_BLACKLIST_DOMAINS = [
|
|||||||
'(.*)chromium.org(.*)',
|
'(.*)chromium.org(.*)',
|
||||||
'(.*)nodejs.org(.*)',
|
'(.*)nodejs.org(.*)',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class EOutputFile(EOutput):
|
||||||
|
"""
|
||||||
|
Override of EOutput, allows to specify an output file for writes
|
||||||
|
"""
|
||||||
|
def __init__(self, out_file=None, *args, **kwargs):
|
||||||
|
super(EOutputFile, self).__init__(*args, **kwargs)
|
||||||
|
self.out_file = out_file
|
||||||
|
|
||||||
|
def _write(self, f, msg):
|
||||||
|
if self.out_file is None:
|
||||||
|
super(EOutputFile, self)._write(f, msg)
|
||||||
|
else:
|
||||||
|
super(EOutputFile, self)._write(self.out_file, msg)
|
||||||
|
|
||||||
|
|
||||||
|
class EuscanOutput(object):
|
||||||
|
"""
|
||||||
|
Class that handles output for euscan
|
||||||
|
"""
|
||||||
|
def __init__(self, config):
|
||||||
|
self.config = config
|
||||||
|
self.queries = defaultdict(dict)
|
||||||
|
self.current_query = None
|
||||||
|
|
||||||
|
def set_query(self, query):
|
||||||
|
self.current_query = query
|
||||||
|
if query is not None:
|
||||||
|
if not query in self.queries:
|
||||||
|
self.queries[query] = {
|
||||||
|
"messages": defaultdict(StringIO),
|
||||||
|
"result": [],
|
||||||
|
"metadata": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_formatted_output(self):
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
for query in self.queries:
|
||||||
|
data[query] = {
|
||||||
|
"result": self.queries[query]["result"],
|
||||||
|
"metadata": self.queries[query]["metadata"],
|
||||||
|
"messages": {}
|
||||||
|
}
|
||||||
|
for key in self.queries[query]["messages"]:
|
||||||
|
if key not in ("ebegin", "eend"):
|
||||||
|
_msg = self.queries[query]["messages"][key].getvalue()
|
||||||
|
val = [x for x in _msg.split("\n") if x]
|
||||||
|
data[query]["messages"][key] = val
|
||||||
|
|
||||||
|
if self.config["format"].lower() == "json":
|
||||||
|
return json.dumps(data, indent=self.config["indent"])
|
||||||
|
else:
|
||||||
|
raise TypeError("Invalid output format")
|
||||||
|
|
||||||
|
def result(self, cp, version, url, handler, confidence):
|
||||||
|
from euscan.helpers import get_version_type
|
||||||
|
|
||||||
|
if self.config['format']:
|
||||||
|
_curr = self.queries[self.current_query]
|
||||||
|
_curr["result"].append(
|
||||||
|
{"version": version, "urls": [url], "handler": handler,
|
||||||
|
"confidence": confidence, "type": get_version_type(version)}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if not self.config['quiet']:
|
||||||
|
print "Upstream Version:", pp.number("%s" % version),
|
||||||
|
print pp.path(" %s" % url)
|
||||||
|
else:
|
||||||
|
print pp.cpv("%s-%s" % (cp, version)) + ":", pp.path(url)
|
||||||
|
|
||||||
|
def metadata(self, key, value, show=True):
|
||||||
|
if self.config["format"]:
|
||||||
|
self.queries[self.current_query]["metadata"][key] = value
|
||||||
|
elif show:
|
||||||
|
print "%s: %s" % (key.capitalize(), value)
|
||||||
|
|
||||||
|
def __getattr__(self, key):
|
||||||
|
if self.config["format"]:
|
||||||
|
out_file = self.queries[self.current_query]["messages"][key]
|
||||||
|
|
||||||
|
_output = EOutputFile(out_file=out_file,
|
||||||
|
quiet=self.config['quiet'])
|
||||||
|
ret = getattr(_output, key)
|
||||||
|
else:
|
||||||
|
ret = getattr(EOutputFile(quiet=self.config['quiet']), key)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
output = EuscanOutput(CONFIG)
|
||||||
|
@ -3,8 +3,10 @@ import portage
|
|||||||
import urllib2
|
import urllib2
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from euscan import helpers
|
from euscan import helpers, output
|
||||||
import euscan
|
|
||||||
|
HANDLER_NAME = "cpan"
|
||||||
|
CONFIDENCE = 100.0
|
||||||
|
|
||||||
_cpan_package_name_re = re.compile("mirror://cpan/authors/.*/([^/.]*).*")
|
_cpan_package_name_re = re.compile("mirror://cpan/authors/.*/([^/.]*).*")
|
||||||
|
|
||||||
@ -83,7 +85,7 @@ def scan(cpv, url):
|
|||||||
orig_url = url
|
orig_url = url
|
||||||
url = 'http://search.cpan.org/api/dist/%s' % pkg
|
url = 'http://search.cpan.org/api/dist/%s' % pkg
|
||||||
|
|
||||||
euscan.output.einfo("Using: " + url)
|
output.einfo("Using: " + url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fp = helpers.urlopen(url)
|
fp = helpers.urlopen(url)
|
||||||
@ -125,7 +127,7 @@ def scan(cpv, url):
|
|||||||
if url == orig_url:
|
if url == orig_url:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ret.append((url, pv))
|
ret.append((url, pv, HANDLER_NAME, CONFIDENCE))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -7,9 +7,13 @@ from BeautifulSoup import BeautifulSoup
|
|||||||
import portage
|
import portage
|
||||||
|
|
||||||
from euscan import CONFIG, SCANDIR_BLACKLIST_URLS, \
|
from euscan import CONFIG, SCANDIR_BLACKLIST_URLS, \
|
||||||
BRUTEFORCE_BLACKLIST_PACKAGES, BRUTEFORCE_BLACKLIST_URLS
|
BRUTEFORCE_BLACKLIST_PACKAGES, BRUTEFORCE_BLACKLIST_URLS, output, helpers
|
||||||
from euscan import helpers
|
|
||||||
import euscan
|
HANDLER_NAME = "generic"
|
||||||
|
CONFIDENCE = 50.0
|
||||||
|
|
||||||
|
BRUTEFORCE_HANDLER_NAME = "brute_force"
|
||||||
|
BRUTEFORCE_CONFIDENCE = 30.0
|
||||||
|
|
||||||
|
|
||||||
def scan_html(data, url, pattern):
|
def scan_html(data, url, pattern):
|
||||||
@ -53,7 +57,7 @@ def scan_directory_recursive(cp, ver, rev, url, steps, orig_url):
|
|||||||
|
|
||||||
steps = steps[1:]
|
steps = steps[1:]
|
||||||
|
|
||||||
euscan.output.einfo("Scanning: %s" % url)
|
output.einfo("Scanning: %s" % url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fp = helpers.urlopen(url)
|
fp = helpers.urlopen(url)
|
||||||
@ -87,7 +91,7 @@ def scan_directory_recursive(cp, ver, rev, url, steps, orig_url):
|
|||||||
path = url + path
|
path = url + path
|
||||||
|
|
||||||
if not steps and path not in orig_url:
|
if not steps and path not in orig_url:
|
||||||
versions.append((path, pv))
|
versions.append((path, pv, HANDLER_NAME, CONFIDENCE))
|
||||||
|
|
||||||
if steps:
|
if steps:
|
||||||
ret = scan_directory_recursive(cp, ver, rev, path, steps, orig_url)
|
ret = scan_directory_recursive(cp, ver, rev, path, steps, orig_url)
|
||||||
@ -99,7 +103,7 @@ def scan_directory_recursive(cp, ver, rev, url, steps, orig_url):
|
|||||||
def scan(cpv, url):
|
def scan(cpv, url):
|
||||||
for bu in SCANDIR_BLACKLIST_URLS:
|
for bu in SCANDIR_BLACKLIST_URLS:
|
||||||
if re.match(bu, url):
|
if re.match(bu, url):
|
||||||
euscan.output.einfo("%s is blacklisted by rule %s" % (url, bu))
|
output.einfo("%s is blacklisted by rule %s" % (url, bu))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
resolved_url = helpers.parse_mirror(url)
|
resolved_url = helpers.parse_mirror(url)
|
||||||
@ -112,23 +116,25 @@ def scan(cpv, url):
|
|||||||
if ver not in resolved_url:
|
if ver not in resolved_url:
|
||||||
newver = helpers.version_change_end_sep(ver)
|
newver = helpers.version_change_end_sep(ver)
|
||||||
if newver and newver in resolved_url:
|
if newver and newver in resolved_url:
|
||||||
euscan.output.einfo(
|
output.einfo(
|
||||||
"Version: using %s instead of %s" % (newver, ver)
|
"Version: using %s instead of %s" % (newver, ver)
|
||||||
)
|
)
|
||||||
ver = newver
|
ver = newver
|
||||||
|
|
||||||
template = helpers.template_from_url(resolved_url, ver)
|
template = helpers.template_from_url(resolved_url, ver)
|
||||||
if '${' not in template:
|
if '${' not in template:
|
||||||
euscan.output.einfo(
|
output.einfo(
|
||||||
"Url doesn't seems to depend on version: %s not found in %s" %
|
"Url doesn't seems to depend on version: %s not found in %s" %
|
||||||
(ver, resolved_url)
|
(ver, resolved_url)
|
||||||
)
|
)
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
euscan.output.einfo("Scanning: %s" % template)
|
output.einfo("Scanning: %s" % template)
|
||||||
|
|
||||||
steps = helpers.generate_scan_paths(template)
|
steps = helpers.generate_scan_paths(template)
|
||||||
return scan_directory_recursive(cp, ver, rev, "", steps, url)
|
ret = scan_directory_recursive(cp, ver, rev, "", steps, url)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def brute_force(cpv, url):
|
def brute_force(cpv, url):
|
||||||
@ -140,37 +146,37 @@ def brute_force(cpv, url):
|
|||||||
|
|
||||||
for bp in BRUTEFORCE_BLACKLIST_PACKAGES:
|
for bp in BRUTEFORCE_BLACKLIST_PACKAGES:
|
||||||
if re.match(bp, cp):
|
if re.match(bp, cp):
|
||||||
euscan.output.einfo("%s is blacklisted by rule %s" % (cp, bp))
|
output.einfo("%s is blacklisted by rule %s" % (cp, bp))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
for bp in BRUTEFORCE_BLACKLIST_URLS:
|
for bp in BRUTEFORCE_BLACKLIST_URLS:
|
||||||
if re.match(bp, url):
|
if re.match(bp, url):
|
||||||
euscan.output.einfo("%s is blacklisted by rule %s" % (cp, bp))
|
output.einfo("%s is blacklisted by rule %s" % (cp, bp))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
euscan.output.einfo("Generating version from " + ver)
|
output.einfo("Generating version from " + ver)
|
||||||
|
|
||||||
components = helpers.split_version(ver)
|
components = helpers.split_version(ver)
|
||||||
versions = helpers.gen_versions(components, CONFIG["brute-force"])
|
versions = helpers.gen_versions(components, CONFIG["brute-force"])
|
||||||
|
|
||||||
""" Remove unwanted versions """
|
# Remove unwanted versions
|
||||||
for v in versions:
|
for v in versions:
|
||||||
if helpers.vercmp(cp, ver, helpers.join_version(v)) >= 0:
|
if helpers.vercmp(cp, ver, helpers.join_version(v)) >= 0:
|
||||||
versions.remove(v)
|
versions.remove(v)
|
||||||
|
|
||||||
if not versions:
|
if not versions:
|
||||||
euscan.output.einfo("Can't generate new versions from " + ver)
|
output.einfo("Can't generate new versions from " + ver)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
template = helpers.template_from_url(url, ver)
|
template = helpers.template_from_url(url, ver)
|
||||||
|
|
||||||
if '${PV}' not in template:
|
if '${PV}' not in template:
|
||||||
euscan.output.einfo(
|
output.einfo(
|
||||||
"Url doesn't seems to depend on full version: %s not found in %s" %
|
"Url doesn't seems to depend on full version: %s not found in %s" %
|
||||||
(ver, url))
|
(ver, url))
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
euscan.output.einfo("Brute forcing: %s" % template)
|
output.einfo("Brute forcing: %s" % template)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
@ -195,10 +201,11 @@ def brute_force(cpv, url):
|
|||||||
if not infos:
|
if not infos:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
result.append([url, version])
|
result.append([url, version, BRUTEFORCE_HANDLER_NAME,
|
||||||
|
BRUTEFORCE_CONFIDENCE])
|
||||||
|
|
||||||
if len(result) > CONFIG['brute-force-false-watermark']:
|
if len(result) > CONFIG['brute-force-false-watermark']:
|
||||||
euscan.output.einfo(
|
output.einfo(
|
||||||
"Broken server detected ! Skipping brute force."
|
"Broken server detected ! Skipping brute force."
|
||||||
)
|
)
|
||||||
return []
|
return []
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from euscan.handlers import generic
|
from euscan.handlers import generic
|
||||||
|
|
||||||
|
HANDLER_NAME = "kde"
|
||||||
|
|
||||||
|
|
||||||
def can_handle(cpv, url):
|
def can_handle(cpv, url):
|
||||||
if url.startswith('mirror://kde/'):
|
if url.startswith('mirror://kde/'):
|
||||||
@ -10,10 +12,10 @@ def can_handle(cpv, url):
|
|||||||
def clean_results(results):
|
def clean_results(results):
|
||||||
ret = []
|
ret = []
|
||||||
|
|
||||||
for path, version in results:
|
for path, version, confidence in results:
|
||||||
if version == '5SUMS':
|
if version == '5SUMS':
|
||||||
continue
|
continue
|
||||||
ret.append((path, version))
|
ret.append((path, version, HANDLER_NAME, confidence))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -3,8 +3,10 @@ import portage
|
|||||||
import urllib2
|
import urllib2
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|
||||||
from euscan import helpers
|
from euscan import helpers, output
|
||||||
import euscan
|
|
||||||
|
HANDLER_NAME = "php"
|
||||||
|
CONFIDENCE = 100.0
|
||||||
|
|
||||||
|
|
||||||
def can_handle(cpv, url):
|
def can_handle(cpv, url):
|
||||||
@ -34,7 +36,7 @@ def scan(cpv, url):
|
|||||||
orig_url = url
|
orig_url = url
|
||||||
url = 'http://%s/rest/r/%s/allreleases.xml' % (channel, pkg.lower())
|
url = 'http://%s/rest/r/%s/allreleases.xml' % (channel, pkg.lower())
|
||||||
|
|
||||||
euscan.output.einfo("Using: " + url)
|
output.einfo("Using: " + url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fp = helpers.urlopen(url)
|
fp = helpers.urlopen(url)
|
||||||
@ -64,7 +66,7 @@ def scan(cpv, url):
|
|||||||
if url == orig_url:
|
if url == orig_url:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ret.append((url, pv))
|
ret.append((url, pv, HANDLER_NAME, CONFIDENCE))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -3,8 +3,10 @@ import re
|
|||||||
|
|
||||||
import portage
|
import portage
|
||||||
|
|
||||||
from euscan import helpers
|
from euscan import helpers, output
|
||||||
import euscan
|
|
||||||
|
HANDLER_NAME = "pypi"
|
||||||
|
CONFIDENCE = 100.0
|
||||||
|
|
||||||
|
|
||||||
def can_handle(cpv, url):
|
def can_handle(cpv, url):
|
||||||
@ -26,7 +28,7 @@ def scan(cpv, url):
|
|||||||
|
|
||||||
package = guess_package(cpv, url)
|
package = guess_package(cpv, url)
|
||||||
|
|
||||||
euscan.output.einfo("Using PyPi XMLRPC: " + package)
|
output.einfo("Using PyPi XMLRPC: " + package)
|
||||||
|
|
||||||
client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
|
client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi')
|
||||||
versions = client.package_releases(package)
|
versions = client.package_releases(package)
|
||||||
@ -46,7 +48,7 @@ def scan(cpv, url):
|
|||||||
continue
|
continue
|
||||||
urls = client.release_urls(package, up_pv)
|
urls = client.release_urls(package, up_pv)
|
||||||
urls = " ".join([infos['url'] for infos in urls])
|
urls = " ".join([infos['url'] for infos in urls])
|
||||||
ret.append((urls, pv))
|
ret.append((urls, pv, HANDLER_NAME, CONFIDENCE))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -3,8 +3,10 @@ import portage
|
|||||||
import json
|
import json
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
from euscan import helpers
|
from euscan import helpers, output
|
||||||
import euscan
|
|
||||||
|
HANDLER_NAME = "rubygem"
|
||||||
|
CONFIDENCE = 100.0
|
||||||
|
|
||||||
|
|
||||||
def can_handle(cpv, url):
|
def can_handle(cpv, url):
|
||||||
@ -31,13 +33,13 @@ def scan(cpv, url):
|
|||||||
|
|
||||||
gem = guess_gem(cpv, url)
|
gem = guess_gem(cpv, url)
|
||||||
if not gem:
|
if not gem:
|
||||||
euscan.output.eerror("Can't guess gem name using %s and %s" % \
|
output.eerror("Can't guess gem name using %s and %s" % \
|
||||||
(cpv, url))
|
(cpv, url))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
url = 'http://rubygems.org/api/v1/versions/%s.json' % gem
|
url = 'http://rubygems.org/api/v1/versions/%s.json' % gem
|
||||||
|
|
||||||
euscan.output.einfo("Using: " + url)
|
output.einfo("Using: " + url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fp = helpers.urlopen(url)
|
fp = helpers.urlopen(url)
|
||||||
@ -65,7 +67,7 @@ def scan(cpv, url):
|
|||||||
if helpers.version_filtered(cp, ver, pv):
|
if helpers.version_filtered(cp, ver, pv):
|
||||||
continue
|
continue
|
||||||
url = 'http://rubygems.org/gems/%s-%s.gem' % (gem, up_pv)
|
url = 'http://rubygems.org/gems/%s-%s.gem' % (gem, up_pv)
|
||||||
ret.append((url, pv))
|
ret.append((url, pv, HANDLER_NAME, CONFIDENCE))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -37,6 +37,18 @@ _v_end = '((-|_)(pre|p|beta|b|alpha|a|rc|r)\d*)'
|
|||||||
_v = r'((\d+)((\.\d+)*)([a-zA-Z]*?)(' + _v_end + '*))'
|
_v = r'((\d+)((\.\d+)*)([a-zA-Z]*?)(' + _v_end + '*))'
|
||||||
|
|
||||||
|
|
||||||
|
def get_version_type(version):
|
||||||
|
types = []
|
||||||
|
gentoo_types = ("alpha", "beta", "pre", "rc", "p")
|
||||||
|
|
||||||
|
for token in re.findall("[\._-]([a-zA-Z]+)", version):
|
||||||
|
if token in gentoo_types:
|
||||||
|
types.append(token)
|
||||||
|
if types:
|
||||||
|
return types[0]
|
||||||
|
return "release"
|
||||||
|
|
||||||
|
|
||||||
# Stolen from g-pypi
|
# Stolen from g-pypi
|
||||||
def gentoo_mangle_version(up_pv):
|
def gentoo_mangle_version(up_pv):
|
||||||
"""Convert PV to MY_PV if needed
|
"""Convert PV to MY_PV if needed
|
||||||
@ -121,7 +133,7 @@ def gentoo_mangle_version(up_pv):
|
|||||||
pv = up_pv = rev_match.group(1)
|
pv = up_pv = rev_match.group(1)
|
||||||
replace_me = rev_match.group(2)
|
replace_me = rev_match.group(2)
|
||||||
rev = rev_match.group(3)
|
rev = rev_match.group(3)
|
||||||
additional_version = '.' + rev
|
additional_version = '_p' + rev
|
||||||
|
|
||||||
for this_suf in suf_matches.keys():
|
for this_suf in suf_matches.keys():
|
||||||
if rs_match:
|
if rs_match:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
from datetime import datetime
|
||||||
|
|
||||||
import portage
|
import portage
|
||||||
from portage.dbapi import porttree
|
from portage.dbapi import porttree
|
||||||
@ -10,8 +10,7 @@ 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, helpers, output
|
||||||
from euscan import helpers
|
|
||||||
from euscan.ebuild import package_from_ebuild
|
from euscan.ebuild import package_from_ebuild
|
||||||
|
|
||||||
import euscan
|
import euscan
|
||||||
@ -19,19 +18,27 @@ import euscan
|
|||||||
def filter_versions(cp, versions):
|
def filter_versions(cp, versions):
|
||||||
filtered = {}
|
filtered = {}
|
||||||
|
|
||||||
for url, version in versions:
|
for url, version, handler, confidence in versions:
|
||||||
|
|
||||||
''' Try to keep the most specific urls (determinted by the length) '''
|
# Try to keep the most specific urls (determinted by the length)
|
||||||
if version in filtered and len(url) < len(filtered[version]):
|
if version in filtered and len(url) < len(filtered[version]):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
''' Remove blacklisted versions '''
|
# Remove blacklisted versions
|
||||||
if helpers.version_blacklisted(cp, version):
|
if helpers.version_blacklisted(cp, version):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
filtered[version] = url
|
filtered[version] = {
|
||||||
|
"url": url,
|
||||||
|
"handler": handler,
|
||||||
|
"confidence": confidence
|
||||||
|
}
|
||||||
|
|
||||||
return [(cp, filtered[version], version) for version in filtered]
|
return [
|
||||||
|
(cp, filtered[version]["url"], version, filtered[version]["handler"],
|
||||||
|
filtered[version]["confidence"])
|
||||||
|
for version in filtered
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def scan_upstream_urls(cpv, urls):
|
def scan_upstream_urls(cpv, urls):
|
||||||
@ -39,22 +46,22 @@ def scan_upstream_urls(cpv, urls):
|
|||||||
|
|
||||||
for filename in urls:
|
for filename in urls:
|
||||||
for url in urls[filename]:
|
for url in urls[filename]:
|
||||||
if not CONFIG['quiet']:
|
if not CONFIG['quiet'] and not CONFIG['format']:
|
||||||
pp.uprint()
|
pp.uprint()
|
||||||
euscan.output.einfo("SRC_URI is '%s'" % url)
|
output.einfo("SRC_URI is '%s'" % url)
|
||||||
|
|
||||||
if '://' not in url:
|
if '://' not in url:
|
||||||
euscan.output.einfo("Invalid url '%s'" % url)
|
output.einfo("Invalid url '%s'" % url)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
''' Try normal scan '''
|
# Try normal scan
|
||||||
if CONFIG["scan-dir"]:
|
if CONFIG["scan-dir"]:
|
||||||
versions.extend(handlers.scan(cpv, url))
|
versions.extend(handlers.scan(cpv, url))
|
||||||
|
|
||||||
if versions and CONFIG['oneshot']:
|
if versions and CONFIG['oneshot']:
|
||||||
break
|
break
|
||||||
|
|
||||||
''' Brute Force '''
|
# Brute Force
|
||||||
if CONFIG["brute-force"] > 0:
|
if CONFIG["brute-force"] > 0:
|
||||||
versions.extend(handlers.brute_force(cpv, url))
|
versions.extend(handlers.brute_force(cpv, url))
|
||||||
|
|
||||||
@ -91,10 +98,10 @@ def scan_upstream(query):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
sys.stderr.write(
|
output.ewarn(
|
||||||
pp.warn("No package matching '%s'" % pp.pkgquery(query))
|
pp.warn("No package matching '%s'" % pp.pkgquery(query))
|
||||||
)
|
)
|
||||||
return []
|
return None
|
||||||
|
|
||||||
matches = sorted(matches)
|
matches = sorted(matches)
|
||||||
pkg = matches.pop()
|
pkg = matches.pop()
|
||||||
@ -103,29 +110,42 @@ def scan_upstream(query):
|
|||||||
pkg = matches.pop()
|
pkg = matches.pop()
|
||||||
|
|
||||||
if not pkg:
|
if not pkg:
|
||||||
sys.stderr.write(pp.warn("Package '%s' only have a dev version (9999)"
|
output.ewarn(
|
||||||
% pp.pkgquery(pkg.cp)))
|
pp.warn("Package '%s' only have a dev version (9999)"
|
||||||
return []
|
% 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 pkg.cp in BLACKLIST_PACKAGES:
|
if pkg.cp in BLACKLIST_PACKAGES:
|
||||||
sys.stderr.write(
|
output.ewarn(
|
||||||
pp.warn("Package '%s' is blacklisted" % pp.pkgquery(pkg.cp))
|
pp.warn("Package '%s' is blacklisted" % pp.pkgquery(pkg.cp))
|
||||||
)
|
)
|
||||||
return []
|
return None
|
||||||
|
|
||||||
if not CONFIG['quiet']:
|
if not CONFIG['quiet']:
|
||||||
|
if not CONFIG['format']:
|
||||||
pp.uprint(
|
pp.uprint(
|
||||||
" * %s [%s]" % (pp.cpv(pkg.cpv), pp.section(pkg.repo_name()))
|
" * %s [%s]" % (pp.cpv(pkg.cpv), pp.section(pkg.repo_name()))
|
||||||
)
|
)
|
||||||
pp.uprint()
|
pp.uprint()
|
||||||
|
else:
|
||||||
|
output.metadata("overlay", pp.section(pkg.repo_name()))
|
||||||
|
|
||||||
ebuild_path = pkg.ebuild_path()
|
ebuild_path = pkg.ebuild_path()
|
||||||
if ebuild_path:
|
if ebuild_path:
|
||||||
pp.uprint('Ebuild: ' + pp.path(os.path.normpath(ebuild_path)))
|
output.metadata(
|
||||||
|
"ebuild", pp.path(os.path.normpath(ebuild_path))
|
||||||
|
)
|
||||||
|
|
||||||
pp.uprint('Repository: ' + pkg.repo_name())
|
output.metadata("repository", pkg.repo_name())
|
||||||
pp.uprint('Homepage: ' + pkg.environment("HOMEPAGE"))
|
output.metadata("homepage", pkg.environment("HOMEPAGE"))
|
||||||
pp.uprint('Description: ' + pkg.environment("DESCRIPTION"))
|
output.metadata("description", pkg.environment("DESCRIPTION"))
|
||||||
|
|
||||||
cpv = pkg.cpv
|
cpv = pkg.cpv
|
||||||
metadata = {
|
metadata = {
|
||||||
@ -137,15 +157,19 @@ def scan_upstream(query):
|
|||||||
alist = porttree._parse_uri_map(cpv, metadata, use=use)
|
alist = porttree._parse_uri_map(cpv, metadata, use=use)
|
||||||
aalist = porttree._parse_uri_map(cpv, metadata)
|
aalist = porttree._parse_uri_map(cpv, metadata)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
sys.stderr.write(pp.warn("%s\n" % str(e)))
|
output.ewarn(pp.warn("%s\n" % str(e)))
|
||||||
sys.stderr.write(
|
output.ewarn(
|
||||||
pp.warn("Invalid SRC_URI for '%s'" % pp.pkgquery(cpv))
|
pp.warn("Invalid SRC_URI for '%s'" % pp.pkgquery(cpv))
|
||||||
)
|
)
|
||||||
return []
|
return None
|
||||||
|
|
||||||
if "mirror" in portage.settings.features:
|
if "mirror" in portage.settings.features:
|
||||||
urls = aalist
|
urls = aalist
|
||||||
else:
|
else:
|
||||||
urls = alist
|
urls = alist
|
||||||
|
|
||||||
|
# output scan time for formatted output
|
||||||
|
scan_time = (datetime.now() - start_time).total_seconds()
|
||||||
|
output.metadata("scan_time", scan_time, show=False)
|
||||||
|
|
||||||
return scan_upstream_urls(pkg.cpv, urls)
|
return scan_upstream_urls(pkg.cpv, urls)
|
||||||
|
Loading…
Reference in New Issue
Block a user