has/best_version: eqawarn if EAPI wrong for atom
authorZac Medico <zmedico@gentoo.org>
Mon, 11 Oct 2010 19:51:26 +0000 (12:51 -0700)
committerZac Medico <zmedico@gentoo.org>
Tue, 12 Oct 2010 01:51:12 +0000 (18:51 -0700)
Instead of calling die as in bug #340387, just call eqawarn for the
time being.

bin/portageq
pym/_emerge/AbstractEbuildProcess.py
pym/portage/package/ebuild/_ipc/QueryCommand.py

index b450c7a186168afe9550c03d8b56e968e56a58cc..d7ea72bf53c5db8ceb399528e9fc48bbb5e15942 100755 (executable)
@@ -21,7 +21,7 @@ except KeyboardInterrupt:
        sys.exit(1)
 
 import os
-
+import subprocess
 import types
 
 # Avoid sandbox violations after python upgrade.
@@ -79,8 +79,11 @@ def has_version(argv):
        if (len(argv) < 2):
                print("ERROR: insufficient parameters!")
                sys.exit(2)
+
+       warnings = []
+
        try:
-               atom = portage.dep.Atom(argv[1], eapi=eapi)
+               atom = portage.dep.Atom(argv[1])
        except portage.exception.InvalidAtom:
                if atom_validate_strict:
                        portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
@@ -89,8 +92,18 @@ def has_version(argv):
                else:
                        atom = argv[1]
        else:
+               if atom_validate_strict:
+                       try:
+                               atom = portage.dep.Atom(argv[1], eapi=eapi)
+                       except portage.exception.InvalidAtom as e:
+                               warnings.append(
+                                       portage._unicode_decode("QA Notice: %s: %s") % \
+                                       ('has_version', e))
                atom = eval_atom_use(atom)
 
+       if warnings:
+               elog('eqawarn', warnings)
+
        try:
                mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
                if mylist:
@@ -113,8 +126,11 @@ def best_version(argv):
        if (len(argv) < 2):
                print("ERROR: insufficient parameters!")
                sys.exit(2)
+
+       warnings = []
+
        try:
-               atom = portage.dep.Atom(argv[1], eapi=eapi)
+               atom = portage.dep.Atom(argv[1])
        except portage.exception.InvalidAtom:
                if atom_validate_strict:
                        portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
@@ -123,7 +139,18 @@ def best_version(argv):
                else:
                        atom = argv[1]
        else:
+               if atom_validate_strict:
+                       try:
+                               atom = portage.dep.Atom(argv[1], eapi=eapi)
+                       except portage.exception.InvalidAtom as e:
+                               warnings.append(
+                                       portage._unicode_decode("QA Notice: %s: %s") % \
+                                       ('best_version', e))
                atom = eval_atom_use(atom)
+
+       if warnings:
+               elog('eqawarn', warnings)
+
        try:
                mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
                print(portage.best(mylist))
@@ -578,7 +605,7 @@ list_preserved_libs.uses_root = True
 if not portage.const._ENABLE_PRESERVE_LIBS:
        del list_preserved_libs
 
-non_commands = frozenset(['eval_atom_use', 'exithandler', 'main',
+non_commands = frozenset(['elog', 'eval_atom_use', 'exithandler', 'main',
        'usage', 'writemsg', 'writemsg_stdout'])
 commands = sorted(k for k, v in globals().items() \
        if type(v) is types.FunctionType and k not in non_commands)
@@ -621,6 +648,17 @@ eapi = None
 if atom_validate_strict:
        eapi = os.environ.get('EAPI')
 
+       def elog(elog_funcname, lines):
+               cmd = "source '%s/isolated-functions.sh' ; " % \
+                       os.environ["PORTAGE_BIN_PATH"]
+               for line in lines:
+                       cmd += "%s %s ; " % (elog_funcname, portage._shell_quote(line))
+               subprocess.call([portage.const.BASH_BINARY, "-c", cmd])
+
+else:
+       def elog(elog_funcname, lines):
+               pass
+
 def main():
        if "-h" in sys.argv or "--help" in sys.argv:
                usage(sys.argv)
index d711c05857b41d1c5ac09645f433bef54dc32cee..b99f1df8a3a9e2e2131d6960d9b9d538788bbf19 100644 (file)
@@ -130,7 +130,7 @@ class AbstractEbuildProcess(SpawnProcess):
        def _start_ipc_daemon(self):
                self._exit_command = ExitCommand()
                self._exit_command.reply_hook = self._exit_command_callback
-               query_command = QueryCommand(self.settings)
+               query_command = QueryCommand(self.settings, self.phase)
                commands = {
                        'best_version' : query_command,
                        'exit'         : self._exit_command,
index 59663b1d966cc40c38954fd3660319034e882651..7d006acf0f0b7d0b00c56908444a7a281c54183a 100644 (file)
@@ -3,7 +3,11 @@
 
 import portage
 from portage import os
+from portage import StringIO
+from portage import _encodings
+from portage import _unicode_decode
 from portage.dep import Atom
+from portage.elog import messages as elog_messages
 from portage.exception import InvalidAtom
 from portage.package.ebuild._ipc.IpcCommand import IpcCommand
 from portage.util import normalize_path
@@ -11,25 +15,32 @@ from portage.versions import best
 
 class QueryCommand(IpcCommand):
 
-       __slots__ = ('settings',)
+       __slots__ = ('phase', 'settings',)
 
        _db = None
 
-       def __init__(self, settings):
+       def __init__(self, settings, phase):
                IpcCommand.__init__(self)
                self.settings = settings
+               self.phase = phase
 
        def __call__(self, argv):
                """
                @returns: tuple of (stdout, stderr, returncode)
                """
 
-               cmd, root, atom = argv
+               cmd, root, atom_str = argv
 
                try:
-                       atom = Atom(atom, eapi=self.settings.get('EAPI'))
+                       atom = Atom(atom_str)
                except InvalidAtom:
-                       return ('', 'invalid atom: %s\n' % atom, 2)
+                       return ('', 'invalid atom: %s\n' % atom_str, 2)
+
+               warnings = []
+               try:
+                       atom = Atom(atom_str, eapi=self.settings.get('EAPI'))
+               except InvalidAtom as e:
+                       warnings.append(_unicode_decode("QA Notice: %s: %s") % (cmd, e))
 
                use = self.settings.get('PORTAGE_BUILT_USE')
                if use is None:
@@ -42,6 +53,10 @@ class QueryCommand(IpcCommand):
                if db is None:
                        db = portage.db
 
+               warnings_str = ''
+               if warnings:
+                       warnings_str = self._elog('eqawarn', warnings)
+
                root = normalize_path(root).rstrip(os.path.sep) + os.path.sep
                if root not in db:
                        return ('', 'invalid ROOT: %s\n' % root, 2)
@@ -53,9 +68,32 @@ class QueryCommand(IpcCommand):
                                returncode = 0
                        else:
                                returncode = 1
-                       return ('', '', returncode)
+                       return ('', warnings_str, returncode)
                elif cmd == 'best_version':
                        m = best(vardb.match(atom))
-                       return ('%s\n' % m, '', 0)
+                       return ('%s\n' % m, warnings_str, 0)
                else:
                        return ('', 'invalid command: %s\n' % cmd, 2)
+
+       def _elog(self, elog_funcname, lines):
+               """
+               This returns a string, to be returned via ipc and displayed at the
+               appropriate place in the build output. We wouldn't want to open the
+               log here since it is already opened by AbstractEbuildProcess and we
+               don't want to corrupt it, especially if it is being written with
+               compression.
+               """
+               out = StringIO()
+               phase = self.phase
+               elog_func = getattr(elog_messages, elog_funcname)
+               global_havecolor = portage.output.havecolor
+               try:
+                       portage.output.havecolor = \
+                               self.settings.get('NOCOLOR', 'false').lower() in ('no', 'false')
+                       for line in lines:
+                               elog_func(line, phase=phase, key=self.settings.mycpv, out=out)
+               finally:
+                       portage.output.havecolor = global_havecolor
+               msg = _unicode_decode(out.getvalue(),
+                       encoding=_encodings['content'], errors='replace')
+               return msg