forked from rpm-software-management/rpmlint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MenuXDGCheck.py
118 lines (101 loc) · 4.2 KB
/
MenuXDGCheck.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# -*- coding: utf-8 -*-
#
# check xdg file format violation
#
# http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
#
import codecs
import os
try:
import ConfigParser as cfgparser
except ImportError:
import configparser as cfgparser
import AbstractCheck
from Filter import addDetails, printError, printWarning
from Pkg import getstatusoutput, is_utf8
STANDARD_BIN_DIRS = ('/bin', '/sbin', '/usr/bin', '/usr/sbin')
class MenuXDGCheck(AbstractCheck.AbstractFilesCheck):
def __init__(self):
# desktop file need to be in $XDG_DATA_DIRS
# $ echo $XDG_DATA_DIRS/applications
# /var/lib/menu-xdg:/usr/share
AbstractCheck.AbstractFilesCheck.__init__(
self, "MenuXDGCheck", r'(?:/usr|/etc/opt|/opt/.*)/share/applications/.*\.desktop$')
def parse_desktop_file(self, pkg, root, f, filename):
cfp = cfgparser.RawConfigParser()
try:
with codecs.open(f, encoding='utf-8') as inputf:
cfp.readfp(inputf, filename)
except cfgparser.DuplicateSectionError as e:
printError(
pkg, 'desktopfile-duplicate-section', filename,
'[%s]' % e.section)
except cfgparser.MissingSectionHeaderError:
printError(
pkg, 'desktopfile-missing-header', filename)
except cfgparser.Error as e:
# Only in Python >= 3.2
if (hasattr(cfgparser, 'DuplicateOptionError') and
isinstance(e, cfgparser.DuplicateOptionError)):
printError(
pkg, 'desktopfile-duplicate-option', filename,
'[%s]/%s' % (e.section, e.option))
else:
printWarning(
pkg, 'invalid-desktopfile', filename,
e.message.partition(':')[0])
except UnicodeDecodeError as e:
printWarning(
pkg, 'invalid-desktopfile', filename, 'No valid Unicode')
else:
binary = None
if cfp.has_option('Desktop Entry', 'Exec'):
binary = cfp.get('Desktop Entry', 'Exec').partition(' ')[0]
if binary:
found = False
if binary.startswith('/'):
found = os.path.exists(root + binary)
else:
for i in STANDARD_BIN_DIRS:
if os.path.exists(root + i + '/' + binary):
# no need to check if the binary is +x, rpmlint does it
# in another place
found = True
break
if not found:
printWarning(
pkg, 'desktopfile-without-binary', filename, binary)
def check_file(self, pkg, filename):
root = pkg.dirName()
f = root + filename
st = getstatusoutput(('desktop-file-validate', f), True)
if st[0]:
error_printed = False
for line in st[1].splitlines():
if 'error: ' in line:
printError(pkg, 'invalid-desktopfile', filename,
line.split('error: ')[1])
error_printed = True
if not error_printed:
printError(pkg, 'invalid-desktopfile', filename)
if not is_utf8(f):
printError(pkg, 'non-utf8-desktopfile', filename)
self.parse_desktop_file(pkg, root, f, filename)
check = MenuXDGCheck()
addDetails(
'invalid-desktopfile',
'''.desktop file is not valid, check with desktop-file-validate''',
'non-utf8-desktopfile',
'''.desktop file is not encoded in UTF-8''',
'desktopfile-without-binary',
'''the .desktop file is for a file not present in the package. You
should check the requires or see if this is not a error''',
'desktopfile-duplicate-section',
'''The .desktop file contains the mentioned section name twice, which
can trigger parsing ambiguities. Remove the duplicate.''',
'desktopfile-duplicate-option',
'''The .desktop file contains the mentioned option key twice,
which can trigger parsing ambiguities. Remove the duplicate.''',
'desktopfile-missing-header',
'''The .desktop file should start with a section header.''',
)