From: Zac Medico Date: Tue, 1 May 2012 02:26:52 +0000 (-0700) Subject: repoman: ignore false Service desktop entry error X-Git-Tag: v2.2.0_alpha102~15 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=aa63202838c5346692b49ae26fff16b6977fb56c;p=portage.git repoman: ignore false Service desktop entry error This will fix bug #414125. --- diff --git a/bin/repoman b/bin/repoman index 0163f8d30..1cdfcf674 100755 --- a/bin/repoman +++ b/bin/repoman @@ -76,6 +76,7 @@ from portage.output import bold, create_color_func, \ green, nocolor, red from portage.output import ConsoleStyleFile, StyleWriter from portage.util import cmp_sort_key, writemsg_level +from portage.util._desktop_entry import validate_desktop_entry from portage.package.ebuild.digestgen import digestgen from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use @@ -1565,15 +1566,14 @@ for x in effective_scanlist: (checkdir, y, m.group(0))) if desktop_file_validate and desktop_pattern.match(y): - status, cmd_output = subprocess_getstatusoutput( - "'%s' '%s'" % (desktop_file_validate, full_path)) - if os.WIFEXITED(status) and os.WEXITSTATUS(status) != os.EX_OK: + cmd_output = validate_desktop_entry(full_path) + if cmd_output: # Note: in the future we may want to grab the # warnings in addition to the errors. We're # just doing errors now since we don't want # to generate too much noise at first. error_re = re.compile(r'.*\s*error:\s*(.*)') - for line in cmd_output.splitlines(): + for line in cmd_output: error_match = error_re.match(line) if error_match is None: continue diff --git a/pym/portage/util/_desktop_entry.py b/pym/portage/util/_desktop_entry.py new file mode 100644 index 000000000..101965f6a --- /dev/null +++ b/pym/portage/util/_desktop_entry.py @@ -0,0 +1,70 @@ +# Copyright 2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import io +import subprocess + +try: + from configparser import Error as ConfigParserError, RawConfigParser +except ImportError: + from ConfigParser import Error as ConfigParserError, RawConfigParser + +from portage import _encodings, _unicode_encode, _unicode_decode + +def parse_desktop_entry(path): + """ + Parse the given file with RawConfigParser and return the + result. This may raise an IOError from io.open(), or a + ParsingError from RawConfigParser. + """ + parser = RawConfigParser() + + # use read_file/readfp in order to control decoding of unicode + try: + # Python >=3.2 + read_file = parser.read_file + except AttributeError: + read_file = parser.readfp + + with io.open(_unicode_encode(path, + encoding=_encodings['fs'], errors='strict'), + mode='r', encoding=_encodings['repo.content'], + errors='replace') as f: + read_file(f) + + return parser + +_ignored_service_errors = ( + 'error: required key "Name" in group "Desktop Entry" is not present', + 'error: key "Actions" is present in group "Desktop Entry", but the type is "Service" while this key is only valid for type "Application"', + 'error: key "MimeType" is present in group "Desktop Entry", but the type is "Service" while this key is only valid for type "Application"', +) + +def validate_desktop_entry(path): + proc = subprocess.Popen([b"desktop-file-validate", _unicode_encode(path)], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + output_lines = _unicode_decode(proc.communicate()[0]).splitlines() + proc.wait() + + if output_lines: + try: + desktop_entry = parse_desktop_entry(path) + except ConfigParserError: + pass + else: + if desktop_entry.has_section("Desktop Entry"): + try: + entry_type = desktop_entry.get("Desktop Entry", "Type") + except ConfigParserError: + pass + else: + if entry_type == "Service": + # Filter false errors for Type=Service (bug #414125). + filtered_output = [] + for line in output_lines: + if line[len(path)+2:] in _ignored_service_errors: + continue + filtered_output.append(line) + output_lines = filtered_output + + return output_lines