238 lines
9.0 KiB
Python
238 lines
9.0 KiB
Python
#---------------------------------------------------------------
|
|
# Project : Mandrake
|
|
# Module : rpmlint
|
|
# File : MenuCheck.py
|
|
# Version : $Id$
|
|
# Author : Frederic Lepied
|
|
# Created On : Mon Mar 20 07:43:37 2000
|
|
#---------------------------------------------------------------
|
|
|
|
from Filter import *
|
|
import AbstractCheck
|
|
import rpm
|
|
import re
|
|
import commands
|
|
import string
|
|
import sys
|
|
import stat
|
|
import Pkg
|
|
|
|
DEFAULT_VALID_SECTIONS=(
|
|
"Configuration/Hardware",
|
|
"Configuration/Packaging",
|
|
"Configuration/Networking",
|
|
"Configuration/Printing",
|
|
"Configuration/Boot and Init",
|
|
"Configuration/Other",
|
|
"Applications/Development/Interpreters",
|
|
"Applications/Development/Code generators",
|
|
"Applications/Development/Development environments",
|
|
"Applications/Development/Tools",
|
|
"Applications/Sciences/Astronomy",
|
|
"Applications/Sciences/Biology",
|
|
"Applications/Sciences/Chemistry",
|
|
"Applications/Sciences/Computer science",
|
|
"Applications/Sciences/Geosciences",
|
|
"Applications/Sciences/Mathematics",
|
|
"Applications/Sciences/Physics",
|
|
"Applications/Sciences/Other",
|
|
"Applications/Communications",
|
|
"Applications/Editors",
|
|
"Applications/Emulators",
|
|
"Applications/Archiving/Compression",
|
|
"Applications/Archiving/Cd burning",
|
|
"Applications/Archiving/Backup",
|
|
"Applications/Archiving/Other",
|
|
"Applications/Monitoring",
|
|
"Applications/Publishing",
|
|
"Terminals",
|
|
"Applications/Shells",
|
|
"Applications/File tools",
|
|
"Applications/Text tools",
|
|
"Documentation",
|
|
"Office",
|
|
"Networking/File transfer",
|
|
"Networking/IRC",
|
|
"Networking/ICQ",
|
|
"Networking/Chat",
|
|
"Networking/News",
|
|
"Networking/Mail",
|
|
"Networking/WWW",
|
|
"Networking/Remote access",
|
|
"Networking/Other",
|
|
"Amusement/Adventure",
|
|
"Amusement/Arcade",
|
|
"Amusement/Boards",
|
|
"Amusement/Cards",
|
|
"Amusement/Puzzles",
|
|
"Amusement/Sports",
|
|
"Amusement/Strategy",
|
|
"Amusement/Other",
|
|
"Amusement/Toys",
|
|
"Multimedia/Sound",
|
|
"Multimedia/Graphics",
|
|
"Multimedia/Video",
|
|
"Session/Windowmanagers"
|
|
)
|
|
|
|
DEFAULT_EXTRA_MENU_NEEDS = (
|
|
"gnome",
|
|
"icewm",
|
|
"kde",
|
|
"wmaker"
|
|
)
|
|
|
|
DEFAULT_ICON_PATH = "/usr/share/icons/"
|
|
|
|
class MenuCheck(AbstractCheck.AbstractCheck):
|
|
menu_file=re.compile("^/usr/lib/menu/([^/]+)$")
|
|
old_menu_file=re.compile("^/usr/share/(gnome/apps|applnk)/([^/]+)$")
|
|
package=re.compile("\?package\((.*)\):")
|
|
needs=re.compile("needs=(\"([^\"]+)\"|([^ \t\"]+))")
|
|
section=re.compile("section=(\"([^\"]+)\"|([^ \t\"]+))")
|
|
title=re.compile("title=(\"([^\"]+)\"|([^ \t\"]+))")
|
|
command=re.compile("command=\"?([^\" ]+)")
|
|
kdesu_command=re.compile("command=\"?kdesu -c \"?([^\" ]+)")
|
|
icon=re.compile("icon=\"?([^\" ]+)")
|
|
valid_sections=Config.getOption("ValidMenuSections", DEFAULT_VALID_SECTIONS)
|
|
update_menus=re.compile("^[^#]*update-menus",re.MULTILINE)
|
|
standard_needs=Config.getOption("ExtraMenuNeeds", DEFAULT_EXTRA_MENU_NEEDS)
|
|
xpm_icon_paths=Config.getOption("XpmIconPath", DEFAULT_ICON_PATH)
|
|
xpm_ext=re.compile(xpm_icon_paths + ".*\.xpm$")
|
|
|
|
def __init__(self):
|
|
AbstractCheck.AbstractCheck.__init__(self, "MenuCheck")
|
|
|
|
def check(self, pkg, verbose):
|
|
# Check only binary package
|
|
if pkg.isSource():
|
|
return
|
|
|
|
files=pkg.files()
|
|
pkgname=pkg[rpm.RPMTAG_NAME]
|
|
menus=[]
|
|
dirname=pkg.dirName()
|
|
|
|
for f in files.keys():
|
|
# Check menu files
|
|
res=MenuCheck.menu_file.search(f)
|
|
if res:
|
|
basename=res.group(1)
|
|
mode=files[f][0]
|
|
if not stat.S_ISREG(mode):
|
|
printError(pkg, "non-file-in-menu-dir", f)
|
|
else:
|
|
if basename != pkgname:
|
|
printWarning(pkg, "non-coherent-menu-filename", f)
|
|
menus.append(f)
|
|
else:
|
|
# Check old menus from KDE and GNOME
|
|
res=MenuCheck.old_menu_file.search(f)
|
|
if res:
|
|
mode=files[f][0]
|
|
if stat.S_ISREG(mode):
|
|
printError(pkg, "old-menu-entry", f)
|
|
else:
|
|
# Check non transparent xpm files
|
|
res=MenuCheck.xpm_ext.search(f)
|
|
if res:
|
|
mode=files[f][0]
|
|
if stat.S_ISREG(mode) and not Pkg.grep("None\",", dirname + "/" + f):
|
|
printWarning(pkg, "non-transparent-xpm", f)
|
|
pass
|
|
if len(menus) > 0:
|
|
dir=pkg.dirName()
|
|
if menus != []:
|
|
postin=pkg[rpm.RPMTAG_POSTIN] or pkg[rpm.RPMTAG_POSTINPROG]
|
|
if not postin:
|
|
printError(pkg, "menu-without-postin")
|
|
else:
|
|
if not MenuCheck.update_menus.search(postin):
|
|
printError(pkg, "postin-without-update-menus")
|
|
|
|
postun=pkg[rpm.RPMTAG_POSTUN] or pkg[rpm.RPMTAG_POSTUNPROG]
|
|
if not postun:
|
|
printError(pkg, "menu-without-postun")
|
|
else:
|
|
if not MenuCheck.update_menus.search(postun):
|
|
printError(pkg, "postun-without-update-menus")
|
|
|
|
for f in menus:
|
|
# remove comments and handle cpp continuation lines
|
|
str="/lib/cpp %s%s | grep ^\?" % (dir, f)
|
|
cmd=commands.getoutput(str)
|
|
for line in string.split(cmd, "\n"):
|
|
res=MenuCheck.package.search(line)
|
|
if res:
|
|
package=res.group(1)
|
|
if package != pkgname:
|
|
printWarning(pkg, "incoherent-package-value-in-menu", package, f)
|
|
else:
|
|
printInfo(pkg, "unable-to-parse-menu-entry", line)
|
|
|
|
command=1
|
|
res=MenuCheck.command.search(line)
|
|
if res:
|
|
command=res.group(1)
|
|
try:
|
|
if command[:5] == 'kdesu':
|
|
res2=MenuCheck.kdesu_command.search(line)
|
|
command2=res2.group(1)
|
|
files[command2]
|
|
else:
|
|
if command[0] == '/':
|
|
files[command]
|
|
else:
|
|
if not (files.has_key("/bin/" + command) or
|
|
files.has_key("/usr/bin/" + command) or
|
|
files.has_key("/usr/X11R6/bin/" + command)):
|
|
raise KeyError, command
|
|
except KeyError:
|
|
printWarning(pkg, "menu-command-not-in-package", command)
|
|
else:
|
|
command=0
|
|
|
|
res=MenuCheck.title.search(line)
|
|
if res:
|
|
grp=res.groups()
|
|
title=grp[1] or grp[2]
|
|
else:
|
|
printError(pkg, "no-title-in-menu", f)
|
|
title=None
|
|
|
|
res=MenuCheck.needs.search(line)
|
|
if res:
|
|
grp=res.groups()
|
|
needs=string.lower(grp[1] or grp[2])
|
|
if needs in ("x11", "text" ,"wm"):
|
|
res=MenuCheck.section.search(line)
|
|
if res:
|
|
grp=res.groups()
|
|
section=grp[1] or grp[2]
|
|
# don't warn entries for sections
|
|
if command:
|
|
if section not in MenuCheck.valid_sections:
|
|
printError(pkg, "invalid-menu-section", section, f)
|
|
else:
|
|
printInfo(pkg, "unable-to-parse-menu-section", line)
|
|
elif needs not in MenuCheck.standard_needs:
|
|
printInfo(pkg, "strange-needs", needs, f)
|
|
else:
|
|
printInfo(pkg, "unable-to-parse-menu-needs", line)
|
|
|
|
res=MenuCheck.icon.search(line)
|
|
if res:
|
|
icon=res.group(1)
|
|
try:
|
|
if icon[0] == '/':
|
|
files[icon]
|
|
except KeyError:
|
|
printError(pkg, "specified-icon-not-in-package", icon, f)
|
|
else:
|
|
printWarning(pkg, "no-icon-in-menu", title)
|
|
|
|
# Create an object to enable the auto registration of the test
|
|
check=MenuCheck()
|
|
|
|
# MenuCheck.py ends here
|