flake8 cleanups
This commit is contained in:
parent
b2bc56a5c6
commit
543a05f084
|
@ -21,9 +21,12 @@ import Config
|
|||
# Note: do not add any capturing parentheses here
|
||||
macro_regex = re.compile('%+[{(]?[a-zA-Z_]\w{2,}[)}]?')
|
||||
|
||||
|
||||
class _HeadRequest(urllib2.Request):
|
||||
def get_method(self):
|
||||
return "HEAD"
|
||||
|
||||
|
||||
class _HeadRedirectHandler(urllib2.HTTPRedirectHandler):
|
||||
def redirect_request(*args):
|
||||
res = urllib2.HTTPRedirectHandler.redirect_request(*args)
|
||||
|
@ -31,6 +34,7 @@ class _HeadRedirectHandler(urllib2.HTTPRedirectHandler):
|
|||
res = _HeadRequest(res.get_full_url())
|
||||
return res
|
||||
|
||||
|
||||
class AbstractCheck:
|
||||
known_checks = {}
|
||||
|
||||
|
@ -86,17 +90,18 @@ class AbstractCheck:
|
|||
res.close()
|
||||
return info
|
||||
|
||||
|
||||
class AbstractFilesCheck(AbstractCheck):
|
||||
def __init__(self, name, file_regexp):
|
||||
self.__files_re = re.compile(file_regexp)
|
||||
AbstractCheck.__init__(self, name)
|
||||
|
||||
def check_binary(self, pkg):
|
||||
ghosts = pkg.ghostFiles()
|
||||
for filename in (x for x in pkg.files() if x not in ghosts):
|
||||
if self.__files_re.match(filename):
|
||||
self.check_file(pkg, filename)
|
||||
|
||||
|
||||
def check_file(self, pkg, filename):
|
||||
"""Virtual method called for each file that match the regexp passed
|
||||
to the constructor.
|
||||
|
|
|
@ -24,12 +24,14 @@ DEFAULT_SYSTEM_LIB_PATHS = (
|
|||
'/lib', '/usr/lib', '/usr/X11R6/lib',
|
||||
'/lib64', '/usr/lib64', '/usr/X11R6/lib64')
|
||||
|
||||
|
||||
def create_regexp_call(call):
|
||||
if type(call) == type([]):
|
||||
call = '(?:' + '|'.join(call) + ')'
|
||||
r = "\s+FUNC\s+.*?\s+(%s(?:@GLIBC\S+)?)(?:\s|$)" % call
|
||||
return re.compile(r)
|
||||
|
||||
|
||||
class BinaryInfo:
|
||||
|
||||
needed_regex = re.compile('\s+\(NEEDED\).*\[(\S+)\]')
|
||||
|
@ -45,11 +47,11 @@ class BinaryInfo:
|
|||
exit_call_regex = create_regexp_call('_?exit')
|
||||
fork_call_regex = create_regexp_call('fork')
|
||||
# regexp for setgid setegid setresgid set(?:res|e)?gid
|
||||
setgid_call_regex = create_regexp_call(['setresgid','setegid','setgid'])
|
||||
setuid_call_regex = create_regexp_call(['setresuid','seteuid','setuid'])
|
||||
setgroups_call_regex = create_regexp_call(['initgroups','setgroups'])
|
||||
setgid_call_regex = create_regexp_call(['setresgid', 'setegid', 'setgid'])
|
||||
setuid_call_regex = create_regexp_call(['setresuid', 'seteuid', 'setuid'])
|
||||
setgroups_call_regex = create_regexp_call(['initgroups', 'setgroups'])
|
||||
chroot_call_regex = create_regexp_call('chroot')
|
||||
chdir_call_regex = create_regexp_call('chdir')
|
||||
chdir_call_regex = create_regexp_call('chdir')
|
||||
mktemp_call_regex = create_regexp_call('mktemp')
|
||||
|
||||
def __init__(self, pkg, path, file, is_ar, is_shlib):
|
||||
|
@ -165,7 +167,7 @@ class BinaryInfo:
|
|||
# call is for x86 32 bits, callq for x86_64
|
||||
if l.find('callq ') >= 0 or l.find('call ') >= 0:
|
||||
call.append(l.rpartition(' ')[2])
|
||||
for index,c in enumerate(call):
|
||||
for index, c in enumerate(call):
|
||||
if c.find('chroot@plt') >= 0:
|
||||
for i in call[index-2:index+2]:
|
||||
if i.find('chdir@plt'):
|
||||
|
@ -247,6 +249,7 @@ srcname_regex = re.compile('(.*?)-[0-9]')
|
|||
invalid_dir_ref_regex = re.compile('/(home|tmp)(\W|$)')
|
||||
ocaml_mixed_regex = re.compile('^Caml1999X0\d\d$')
|
||||
|
||||
|
||||
def dir_base(path):
|
||||
res = path_regex.search(path)
|
||||
if res:
|
||||
|
@ -254,6 +257,7 @@ def dir_base(path):
|
|||
else:
|
||||
return '', path
|
||||
|
||||
|
||||
class BinariesCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -423,7 +427,8 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
|
|||
continue
|
||||
|
||||
if not bin_info.needed and not (
|
||||
bin_info.soname and ldso_soname_regex.search(bin_info.soname)):
|
||||
bin_info.soname and
|
||||
ldso_soname_regex.search(bin_info.soname)):
|
||||
if is_shobj:
|
||||
printError(pkg,
|
||||
'shared-lib-without-dependency-information',
|
||||
|
@ -434,9 +439,9 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
|
|||
else:
|
||||
# linked against libc ?
|
||||
if "libc." not in fname and \
|
||||
(not bin_info.soname or \
|
||||
("libc." not in bin_info.soname and \
|
||||
not ldso_soname_regex.search(bin_info.soname))):
|
||||
(not bin_info.soname or
|
||||
("libc." not in bin_info.soname and
|
||||
not ldso_soname_regex.search(bin_info.soname))):
|
||||
|
||||
found_libc = False
|
||||
for lib in bin_info.needed:
|
||||
|
@ -456,8 +461,9 @@ class BinariesCheck(AbstractCheck.AbstractCheck):
|
|||
if bin_info.exec_stack:
|
||||
printWarning(pkg, 'executable-stack', fname)
|
||||
elif not bin_info.readelf_error and (
|
||||
pkg.arch.endswith("86") or pkg.arch.startswith("pentium") or
|
||||
pkg.arch in ("athlon", "x86_64")):
|
||||
pkg.arch.endswith("86") or
|
||||
pkg.arch.startswith("pentium") or
|
||||
pkg.arch in ("athlon", "x86_64")):
|
||||
printError(pkg, 'missing-PT_GNU_STACK-section', fname)
|
||||
|
||||
if bin_info.setgid and bin_info.setuid and not bin_info.setgroups:
|
||||
|
|
20
Config.py
20
Config.py
|
@ -56,20 +56,24 @@ no_exception = False
|
|||
_checks = []
|
||||
_checks.extend(DEFAULT_CHECKS)
|
||||
|
||||
|
||||
def addCheck(check):
|
||||
check = re.sub('\.py[co]?$', '', check)
|
||||
if check not in _checks:
|
||||
_checks.append(check)
|
||||
|
||||
|
||||
def allChecks():
|
||||
if _checks == []:
|
||||
defaultChecks()
|
||||
return _checks
|
||||
|
||||
|
||||
def defaultChecks():
|
||||
resetChecks()
|
||||
_checks.extend(DEFAULT_CHECKS)
|
||||
|
||||
|
||||
def resetChecks():
|
||||
global _checks
|
||||
|
||||
|
@ -79,11 +83,13 @@ def resetChecks():
|
|||
|
||||
_dirs = ["/usr/share/rpmlint"]
|
||||
|
||||
|
||||
def addCheckDir(dir):
|
||||
d = os.path.expanduser(dir)
|
||||
if d not in _dirs:
|
||||
_dirs.insert(0, d)
|
||||
|
||||
|
||||
def checkDirs():
|
||||
return _dirs
|
||||
|
||||
|
@ -91,10 +97,12 @@ def checkDirs():
|
|||
|
||||
_options = {}
|
||||
|
||||
|
||||
def setOption(name, value):
|
||||
_options[name] = value
|
||||
|
||||
def getOption(name, default = ""):
|
||||
|
||||
def getOption(name, default=""):
|
||||
try:
|
||||
return _options[name]
|
||||
except:
|
||||
|
@ -104,12 +112,14 @@ def getOption(name, default = ""):
|
|||
_filters = []
|
||||
_filters_re = None
|
||||
|
||||
|
||||
def addFilter(s):
|
||||
global _filters_re
|
||||
|
||||
_filters.append(s)
|
||||
_filters_re = None
|
||||
|
||||
|
||||
def removeFilter(s):
|
||||
global _filters_re
|
||||
|
||||
|
@ -122,17 +132,21 @@ def removeFilter(s):
|
|||
|
||||
_scoring = {}
|
||||
|
||||
|
||||
def setBadness(s, score):
|
||||
_scoring[s] = score
|
||||
|
||||
|
||||
def badness(s):
|
||||
return _scoring.get(s, 0)
|
||||
|
||||
_non_named_group_re = re.compile('[^\\](\()[^:]')
|
||||
|
||||
|
||||
def isFiltered(s):
|
||||
global _filters_re
|
||||
|
||||
if _filters_re == None:
|
||||
if _filters_re is None:
|
||||
# no filter
|
||||
if len(_filters) == 0:
|
||||
return False
|
||||
|
@ -144,7 +158,7 @@ def isFiltered(s):
|
|||
# version only supports 100 named groups
|
||||
if '(' in _filters[idx]:
|
||||
_non_named_group_re.subn('(:?', _filters[idx])
|
||||
_filters_re = _filters_re + '|(?:' + _filters[idx] +')'
|
||||
_filters_re = _filters_re + '|(?:' + _filters[idx] + ')'
|
||||
_filters_re = re.compile(_filters_re)
|
||||
|
||||
if not no_exception:
|
||||
|
|
|
@ -22,8 +22,8 @@ vendor = Config.getOption("Vendor")
|
|||
distribution = Config.getOption("Distribution")
|
||||
compress_ext = Config.getOption("CompressExtension", "bz2")
|
||||
|
||||
class DistributionCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
class DistributionCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
AbstractCheck.AbstractCheck.__init__(self, "DistributionCheck")
|
||||
|
@ -65,7 +65,7 @@ addDetails(
|
|||
automatically when the package is rebuilt, make sure that you have the
|
||||
appropriate rpm helper and/or config packages for your target distribution
|
||||
installed and try rebuilding again; if it still does not happen automatically,
|
||||
you can compress this file in the %%install section of the spec file.''' \
|
||||
you can compress this file in the %%install section of the spec file.'''
|
||||
% (compress_ext, compress_ext),
|
||||
|
||||
'infopage-not-compressed',
|
||||
|
@ -74,7 +74,7 @@ you can compress this file in the %%install section of the spec file.''' \
|
|||
automatically when the package is rebuilt, make sure that you have the
|
||||
appropriate rpm helper and/or config packages for your target distribution
|
||||
installed and try rebuilding again; if it still does not happen automatically,
|
||||
you can compress this file in the %%install section of the spec file.''' \
|
||||
you can compress this file in the %%install section of the spec file.'''
|
||||
% (compress_ext, compress_ext),
|
||||
)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class DocFilesCheck(AbstractCheck.AbstractCheck):
|
|||
reqs[fname] = [x[0] for x in pkgfile.requires]
|
||||
|
||||
core_reqs = {} # dependencies of non-doc files
|
||||
doc_reqs = {} # dependencies of doc files
|
||||
doc_reqs = {} # dependencies of doc files
|
||||
|
||||
for dep in pkg.header.dsFromHeader():
|
||||
# skip deps which were found by find-requires
|
||||
|
@ -51,7 +51,7 @@ class DocFilesCheck(AbstractCheck.AbstractCheck):
|
|||
|
||||
for i in files:
|
||||
if not reqs[i]:
|
||||
continue # skip empty dependencies
|
||||
continue # skip empty dependencies
|
||||
if i in doc_files:
|
||||
target = doc_reqs
|
||||
else:
|
||||
|
|
|
@ -161,9 +161,9 @@ DEFAULT_DANGLING_EXCEPTIONS = (['consolehelper$', 'usermode-consoleonly'],
|
|||
)
|
||||
|
||||
# Standard users and groups from LSB Core 4.0.0: 21.2 User & Group Names
|
||||
DEFAULT_STANDARD_USERS = ('root', 'bin', 'daemon', 'adm', 'lp', 'sync',
|
||||
'shutdown', 'halt', 'mail', 'news', 'uucp',
|
||||
'operator', 'man', 'nobody',)
|
||||
DEFAULT_STANDARD_USERS = ('root', 'bin', 'daemon', 'adm', 'lp', 'sync',
|
||||
'shutdown', 'halt', 'mail', 'news', 'uucp',
|
||||
'operator', 'man', 'nobody',)
|
||||
DEFAULT_STANDARD_GROUPS = ('root', 'bin', 'daemon', 'adm', 'lp', 'sync',
|
||||
'shutdown', 'halt', 'mail', 'news', 'uucp',
|
||||
'man', 'nobody',)
|
||||
|
@ -217,7 +217,7 @@ sourced_script_regex = re.compile('^/etc/(bash_completion\.d|profile\.d)/')
|
|||
use_utf8 = Config.getOption('UseUTF8', Config.USEUTF8_DEFAULT)
|
||||
skipdocs_regex = re.compile(Config.getOption('SkipDocsRegexp', '\.(?:rtf|x?html?|svg|ml[ily]?)$'), re.IGNORECASE)
|
||||
meta_package_regex = re.compile(Config.getOption('MetaPackageRegexp', '^(bundle|task)-'))
|
||||
filesys_packages = ['filesystem'] # TODO: make configurable?
|
||||
filesys_packages = ['filesystem'] # TODO: make configurable?
|
||||
quotes_regex = re.compile('[\'"]+')
|
||||
start_certificate_regex = re.compile('^-----BEGIN CERTIFICATE-----$')
|
||||
start_private_key_regex = re.compile('^----BEGIN PRIVATE KEY-----$')
|
||||
|
@ -261,6 +261,7 @@ else:
|
|||
# Python 3 means bytes accepts integer input directly
|
||||
printable_extended_ascii += bytes(range(32, 256))
|
||||
|
||||
|
||||
def peek(filename, pkg, length=1024):
|
||||
"""Peek into a file, return a chunk from its beginning and a flag if it
|
||||
seems to be a text file."""
|
||||
|
@ -270,7 +271,7 @@ def peek(filename, pkg, length=1024):
|
|||
fobj = open(filename, 'rb')
|
||||
chunk = fobj.read(length)
|
||||
fobj.close()
|
||||
except IOError: # eg. https://bugzilla.redhat.com/209876
|
||||
except IOError: # eg. https://bugzilla.redhat.com/209876
|
||||
e = sys.exc_info()[1]
|
||||
printWarning(pkg, 'read-error', e)
|
||||
if fobj:
|
||||
|
@ -316,6 +317,7 @@ _python_magic_values = {
|
|||
'3.4': 3310,
|
||||
}
|
||||
|
||||
|
||||
def get_expected_pyc_magic(path):
|
||||
""".pyc/.pyo files embed a 4-byte magic value identifying which version of
|
||||
the python bytecode ABI they are for. Given a path to a .pyc/.pyo file,
|
||||
|
@ -347,6 +349,7 @@ def get_expected_pyc_magic(path):
|
|||
|
||||
return (expected_magic_value, ver_from_path)
|
||||
|
||||
|
||||
def py_demarshal_long(b):
|
||||
"""Counterpart to Python's PyMarshal_ReadLongFromFile, operating on the
|
||||
bytes in a string."""
|
||||
|
@ -357,6 +360,7 @@ def py_demarshal_long(b):
|
|||
+ (b[2] << 16)
|
||||
+ (b[3] << 24))
|
||||
|
||||
|
||||
def python_bytecode_to_script(path):
|
||||
"""Given a python bytecode path, give the path of the .py file
|
||||
(or None if not python bytecode)."""
|
||||
|
@ -371,6 +375,7 @@ def python_bytecode_to_script(path):
|
|||
|
||||
return None
|
||||
|
||||
|
||||
class FilesCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -452,8 +457,8 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
|||
is_kernel_package:
|
||||
printError(pkg, "kernel-modules-not-in-kernel-packages", f)
|
||||
|
||||
for i in ['mnt','opt','usr-local','var-local','home']:
|
||||
if f.startswith('/%s/' % i.replace('-','/')):
|
||||
for i in ('mnt', 'opt', 'usr-local', 'var-local', 'home'):
|
||||
if f.startswith('/%s/' % i.replace('-', '/')):
|
||||
printError(pkg, 'dir-or-file-in-%s' % i, f)
|
||||
|
||||
if tmp_regex.search(f):
|
||||
|
@ -644,8 +649,8 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
|||
bindir_exes.setdefault(exe, []).append(f)
|
||||
|
||||
if not devel_pkg and not is_doc and \
|
||||
(includefile_regex.search(f) or \
|
||||
develfile_regex.search(f) or is_buildconfig):
|
||||
(includefile_regex.search(f) or develfile_regex.search(f) or
|
||||
is_buildconfig):
|
||||
printWarning(pkg, 'devel-file-in-non-devel-package', f)
|
||||
if mode & int("444", 8) != int("444", 8) and \
|
||||
perm & int("7000", 8) == 0:
|
||||
|
@ -844,7 +849,7 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
|||
|
||||
# normal dir check
|
||||
elif stat.S_ISDIR(mode):
|
||||
if mode & int("1002", 8) == 2: # world writable w/o sticky bit
|
||||
if mode & int("1002", 8) == 2: # world writable w/o sticky bit
|
||||
printError(pkg, 'world-writable', f, oct(perm))
|
||||
if perm != int("755", 8):
|
||||
printError(pkg, 'non-standard-dir-perm', f, oct(perm))
|
||||
|
@ -853,7 +858,6 @@ class FilesCheck(AbstractCheck.AbstractCheck):
|
|||
if hidden_file_regex.search(f):
|
||||
printWarning(pkg, 'hidden-file-or-dir', f)
|
||||
|
||||
|
||||
# symbolic link check
|
||||
elif stat.S_ISLNK(mode):
|
||||
|
||||
|
|
15
Filter.py
15
Filter.py
|
@ -21,7 +21,7 @@ except ImportError:
|
|||
_rawout = None
|
||||
_diagnostic = list()
|
||||
_badness_score = 0
|
||||
printed_messages = { "I": 0, "W": 0, "E": 0 }
|
||||
printed_messages = {"I": 0, "W": 0, "E": 0}
|
||||
|
||||
if sys.stdout.isatty():
|
||||
def __print(s):
|
||||
|
@ -32,15 +32,19 @@ else:
|
|||
s = s.encode(locale.getpreferredencoding(), "replace")
|
||||
print(s)
|
||||
|
||||
|
||||
def printInfo(pkg, reason, *details):
|
||||
_print("I", pkg, reason, details)
|
||||
|
||||
|
||||
def printWarning(pkg, reason, *details):
|
||||
_print("W", pkg, reason, details)
|
||||
|
||||
|
||||
def printError(pkg, reason, *details):
|
||||
_print("E", pkg, reason, details)
|
||||
|
||||
|
||||
def _print(msgtype, pkg, reason, details):
|
||||
global _badness_score
|
||||
|
||||
|
@ -85,6 +89,7 @@ def _print(msgtype, pkg, reason, details):
|
|||
|
||||
return False
|
||||
|
||||
|
||||
def printDescriptions(reason):
|
||||
try:
|
||||
d = _details[reason]
|
||||
|
@ -94,17 +99,19 @@ def printDescriptions(reason):
|
|||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def _diag_sortkey(x):
|
||||
xs = x.split()
|
||||
return (xs[2], xs[1])
|
||||
|
||||
|
||||
def printAllReasons():
|
||||
threshold = badnessThreshold()
|
||||
if threshold < 0:
|
||||
return False
|
||||
|
||||
global _diagnostic
|
||||
_diagnostic.sort(key = _diag_sortkey, reverse = True)
|
||||
_diagnostic.sort(key=_diag_sortkey, reverse=True)
|
||||
last_reason = ''
|
||||
for diag in _diagnostic:
|
||||
if Config.info:
|
||||
|
@ -122,17 +129,21 @@ def printAllReasons():
|
|||
|
||||
_details = {}
|
||||
|
||||
|
||||
def addDetails(*details):
|
||||
for idx in range(int(len(details)/2)):
|
||||
if not details[idx*2] in _details:
|
||||
_details[details[idx*2]] = details[idx*2+1]
|
||||
|
||||
|
||||
def badnessScore():
|
||||
return _badness_score
|
||||
|
||||
|
||||
def badnessThreshold():
|
||||
return Config.getOption("BadnessThreshold", -1)
|
||||
|
||||
|
||||
def setRawOut(file):
|
||||
global _rawout
|
||||
if _rawout:
|
||||
|
|
|
@ -26,7 +26,7 @@ INCORRECT_LOCALES = {
|
|||
'gr_GR': 'el_GR',
|
||||
'cz': 'cs',
|
||||
'cz_CZ': 'cs_CZ',
|
||||
'lug': 'lg', # 'lug' is valid, but we standardize on 2 letter codes
|
||||
'lug': 'lg', # 'lug' is valid, but we standardize on 2 letter codes
|
||||
'en_UK': 'en_GB'}
|
||||
|
||||
package_regex = re.compile('-(' + '|'.join(LANGUAGES) + ')$')
|
||||
|
@ -46,6 +46,7 @@ EXCEPTION_DIRS = ('C', 'POSIX', 'CP1251', 'CP1255', 'CP1256',
|
|||
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15',
|
||||
'KOI8-R', 'KOI8-U', 'UTF-8', 'default')
|
||||
|
||||
|
||||
def is_valid_lang(lang):
|
||||
# TODO: @Foo and charset handling
|
||||
lang = re.sub("[@.].*$", "", lang)
|
||||
|
@ -69,6 +70,7 @@ def is_valid_lang(lang):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
class I18NCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -150,6 +152,7 @@ class I18NCheck(AbstractCheck.AbstractCheck):
|
|||
if locales not in (x[0] for x in pkg.requires()):
|
||||
printError(pkg, 'no-dependency-on', locales)
|
||||
|
||||
|
||||
def is_prefix(p, s):
|
||||
return len(p) <= len(s) and p == s[:len(p)]
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
# Project : Mandriva Linux
|
||||
# Module : rpmlint
|
||||
# File : InitScriptCheck.py
|
||||
# Author : Frederic Lepied
|
||||
# Created On : Fri Aug 25 09:26:37 2000
|
||||
# Purpose : check init scripts (files in /etc/rc.d/init.d)
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import re
|
||||
|
@ -36,6 +36,7 @@ LSB_KEYWORDS = ('Provides', 'Required-Start', 'Required-Stop', 'Should-Start',
|
|||
RECOMMENDED_LSB_KEYWORDS = ('Provides', 'Required-Start', 'Required-Stop',
|
||||
'Default-Stop', 'Short-Description')
|
||||
|
||||
|
||||
class InitScriptCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -90,7 +91,7 @@ class InitScriptCheck(AbstractCheck.AbstractCheck):
|
|||
continue
|
||||
content_str = "".join(content)
|
||||
for line in content:
|
||||
line = line[:-1] # chomp
|
||||
line = line[:-1] # chomp
|
||||
# TODO check if there is only one line like this
|
||||
if line.startswith('### BEGIN INIT INFO'):
|
||||
in_lsb_tag = True
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
# Project : Mandriva Linux
|
||||
# Module : rpmlint
|
||||
# File : LSBCheck.py
|
||||
# Author : Frederic Lepied
|
||||
# Created On : Tue Jan 30 14:44:37 2001
|
||||
# Purpose : LSB non compliance checks
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import re
|
||||
|
||||
import rpm
|
||||
|
||||
from Filter import addDetails, printError
|
||||
from Pkg import b2s
|
||||
import AbstractCheck
|
||||
|
||||
|
||||
version_regex = re.compile('^[a-zA-Z0-9.+]+$')
|
||||
name_regex = re.compile('^[a-z0-9.+-]+$')
|
||||
|
||||
|
||||
class LSBCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
# Project : Mandriva Linux
|
||||
# Module : rpmlint
|
||||
# File : MenuCheck.py
|
||||
# Author : Frederic Lepied
|
||||
# Created On : Mon Mar 20 07:43:37 2000
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import re
|
||||
import stat
|
||||
|
@ -154,6 +154,7 @@ for l in launchers:
|
|||
l[0] = re.compile(l[0])
|
||||
del l
|
||||
|
||||
|
||||
class MenuCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -302,7 +303,7 @@ class MenuCheck(AbstractCheck.AbstractCheck):
|
|||
if res:
|
||||
grp = res.groups()
|
||||
needs = (grp[1] or grp[2]).lower()
|
||||
if needs in ('x11', 'text' ,'wm'):
|
||||
if needs in ('x11', 'text', 'wm'):
|
||||
res = section_regex.search(line)
|
||||
if res:
|
||||
grp = res.groups()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
# Project : Mandriva Linux
|
||||
# Module : rpmlint
|
||||
# File : NamingPolicyCheck.py
|
||||
# Author : Michael Scherer
|
||||
# Created On : Mon May 19 11:25:37 2003
|
||||
# Purpose : Check package names according to their content.
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import re
|
||||
|
||||
|
@ -28,9 +28,11 @@ import AbstractCheck
|
|||
|
||||
simple_naming_policy_re = re.compile('\^[a-zA-Z1-9-_]*$')
|
||||
|
||||
|
||||
class NamingPolicyNotAppliedException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NamingPolicyCheck(AbstractCheck.AbstractCheck):
|
||||
checks_ = []
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
# Project : Mandriva Linux
|
||||
# Module : rpmlint
|
||||
# File : PamCheck.py
|
||||
# Author : Michael Scherer
|
||||
# Created On : 31/01/2006
|
||||
# Purpose : Apply pam policy
|
||||
#---------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import re
|
||||
|
||||
|
@ -16,6 +16,7 @@ import AbstractCheck
|
|||
|
||||
pam_stack_re = re.compile('^\s*[^#].*pam_stack\.so\s*service')
|
||||
|
||||
|
||||
class PamCheck(AbstractCheck.AbstractFilesCheck):
|
||||
def __init__(self):
|
||||
AbstractCheck.AbstractFilesCheck.__init__(self, "PamCheck",
|
||||
|
|
56
Pkg.py
56
Pkg.py
|
@ -37,6 +37,7 @@ if sys.version_info[0] > 2:
|
|||
# Blows up with Python < 3 without the exec() hack
|
||||
exec('def warn(s): print (s, file=sys.stderr)')
|
||||
long = int
|
||||
|
||||
def b2s(b):
|
||||
if b is None:
|
||||
return None
|
||||
|
@ -44,7 +45,9 @@ if sys.version_info[0] > 2:
|
|||
return [b2s(x) for x in b]
|
||||
return b.decode(errors='replace')
|
||||
else:
|
||||
def warn(s): print >> sys.stderr, s
|
||||
def warn(s):
|
||||
print >> sys.stderr, s
|
||||
|
||||
def b2s(b):
|
||||
return b
|
||||
|
||||
|
@ -61,6 +64,7 @@ PREREQ_FLAG = (rpm.RPMSENSE_PREREQ or 64) | \
|
|||
|
||||
var_regex = re.compile('^(.*)\${?(\w+)}?(.*)$')
|
||||
|
||||
|
||||
def shell_var_value(var, script):
|
||||
assign_regex = re.compile('\\b' + re.escape(var) + '\s*=\s*(.+)\s*(#.*)*$',
|
||||
re.MULTILINE)
|
||||
|
@ -68,12 +72,13 @@ def shell_var_value(var, script):
|
|||
if res:
|
||||
res2 = var_regex.search(res.group(1))
|
||||
if res2:
|
||||
if res2.group(2) == var: # infinite loop
|
||||
if res2.group(2) == var: # infinite loop
|
||||
return None
|
||||
return substitute_shell_vars(res.group(1), script)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def substitute_shell_vars(val, script):
|
||||
res = var_regex.search(val)
|
||||
if res:
|
||||
|
@ -85,7 +90,8 @@ def substitute_shell_vars(val, script):
|
|||
else:
|
||||
return val
|
||||
|
||||
def getstatusoutput(cmd, stdoutonly = False, shell = False):
|
||||
|
||||
def getstatusoutput(cmd, stdoutonly=False, shell=False):
|
||||
'''A version of commands.getstatusoutput() which can take cmd as a
|
||||
sequence, thus making it potentially more secure.'''
|
||||
if stdoutonly:
|
||||
|
@ -107,6 +113,7 @@ def getstatusoutput(cmd, stdoutonly = False, shell = False):
|
|||
bz2_regex = re.compile('\.t?bz2?$')
|
||||
xz_regex = re.compile('\.(t[xl]z|xz|lzma)$')
|
||||
|
||||
|
||||
def catcmd(fname):
|
||||
"""Get a 'cat' command that handles possibly compressed files."""
|
||||
cat = 'gzip -dcf'
|
||||
|
@ -116,12 +123,14 @@ def catcmd(fname):
|
|||
cat = 'xz -dc'
|
||||
return cat
|
||||
|
||||
|
||||
def is_utf8(fname):
|
||||
(sts, text) = getstatusoutput(catcmd(fname).split() + [fname])
|
||||
return not sts and is_utf8_str(text)
|
||||
|
||||
REPLACEMENT_CHAR = unicodedata.lookup('REPLACEMENT CHARACTER')
|
||||
|
||||
|
||||
def is_utf8_str(s):
|
||||
if hasattr(s, 'decode'):
|
||||
# byte string
|
||||
|
@ -133,6 +142,7 @@ def is_utf8_str(s):
|
|||
# unicode string
|
||||
return REPLACEMENT_CHAR not in s
|
||||
|
||||
|
||||
# TODO: PY3
|
||||
def to_utf8(string):
|
||||
if string is None:
|
||||
|
@ -160,6 +170,7 @@ def to_utf8(string):
|
|||
newstring = newstring + char
|
||||
return newstring
|
||||
|
||||
|
||||
def readlines(path):
|
||||
fobj = open(path, 'rb')
|
||||
try:
|
||||
|
@ -168,8 +179,9 @@ def readlines(path):
|
|||
finally:
|
||||
fobj.close()
|
||||
|
||||
|
||||
def mktemp():
|
||||
tmpfd, tmpname = tempfile.mkstemp(prefix = 'rpmlint.')
|
||||
tmpfd, tmpname = tempfile.mkstemp(prefix='rpmlint.')
|
||||
tmpfile = os.fdopen(tmpfd, 'w')
|
||||
return tmpfile, tmpname
|
||||
|
||||
|
@ -177,6 +189,7 @@ slash_regex = re.compile('/+')
|
|||
slashdot_regex = re.compile('/(\.(/|$))+')
|
||||
slashend_regex = re.compile('([^/])/+$')
|
||||
|
||||
|
||||
def safe_normpath(path):
|
||||
"""Like os.path.normpath but normalizes less aggressively thus being
|
||||
potentially safer for paths containing symlinks."""
|
||||
|
@ -185,7 +198,8 @@ def safe_normpath(path):
|
|||
ret = slashend_regex.sub('\\1', ret)
|
||||
return ret
|
||||
|
||||
def get_default_valid_rpmgroups(filename = None):
|
||||
|
||||
def get_default_valid_rpmgroups(filename=None):
|
||||
"""Get default rpm groups from filename, or try to look them up from
|
||||
the rpm package (if installed) if no filename is given"""
|
||||
groups = []
|
||||
|
@ -206,11 +220,12 @@ def get_default_valid_rpmgroups(filename = None):
|
|||
fobj.close()
|
||||
if 'Development/Debug' not in groups:
|
||||
groups.append('Development/Debug')
|
||||
if 'Unspecified' not in groups: # auto-added by rpm >= 4.6.0
|
||||
if 'Unspecified' not in groups: # auto-added by rpm >= 4.6.0
|
||||
groups.append('Unspecified')
|
||||
groups.sort()
|
||||
return groups
|
||||
|
||||
|
||||
# from yum 3.2.27, rpmUtils.miscutils, with rpmlint modifications
|
||||
def compareEVR(evr1, evr2):
|
||||
(e1, v1, r1) = evr1
|
||||
|
@ -230,6 +245,7 @@ def compareEVR(evr1, evr2):
|
|||
rc = rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
|
||||
return rc
|
||||
|
||||
|
||||
# from yum 3.2.27, rpmUtils.miscutils, with rpmlint modifications
|
||||
def rangeCompare(reqtuple, provtuple):
|
||||
"""returns true if provtuple satisfies reqtuple"""
|
||||
|
@ -253,7 +269,7 @@ def rangeCompare(reqtuple, provtuple):
|
|||
# "Requires: foo < 1.0" should not be satisfied by "Provides: foo = 1:0.5"
|
||||
#if reqe is None:
|
||||
# e = None
|
||||
if reqv is None: # just for the record if ver is None then we're going to segfault
|
||||
if reqv is None: # just for the record if ver is None then we're going to segfault
|
||||
v = None
|
||||
|
||||
# if we just require foo-version, then foo-version-* will match
|
||||
|
@ -307,6 +323,7 @@ def rangeCompare(reqtuple, provtuple):
|
|||
|
||||
return 0
|
||||
|
||||
|
||||
# from yum 3.2.23, rpmUtils.miscutils, with rpmlint modifications
|
||||
def formatRequire(name, flags, evr):
|
||||
s = name
|
||||
|
@ -324,6 +341,7 @@ def formatRequire(name, flags, evr):
|
|||
s = "%s %s" % (s, versionToString(evr))
|
||||
return s
|
||||
|
||||
|
||||
def versionToString(evr):
|
||||
if not isinstance(evr, (list, tuple)):
|
||||
# assume string
|
||||
|
@ -337,6 +355,7 @@ def versionToString(evr):
|
|||
ret += "-" + evr[2]
|
||||
return ret
|
||||
|
||||
|
||||
# from yum 3.2.23, rpmUtils.miscutils, with some rpmlint modifications
|
||||
def stringToVersion(verstring):
|
||||
if verstring in (None, ''):
|
||||
|
@ -365,6 +384,7 @@ def stringToVersion(verstring):
|
|||
release = None
|
||||
return (epoch, version, release)
|
||||
|
||||
|
||||
def parse_deps(line):
|
||||
'''Parse provides/requires/conflicts/obsoletes line to list of
|
||||
(name, flags, (epoch, version, release)) tuples.'''
|
||||
|
@ -434,7 +454,7 @@ class Pkg:
|
|||
|
||||
_magic_from_compressed_re = re.compile('\([^)]+\s+compressed\s+data\\b')
|
||||
|
||||
def __init__(self, filename, dirname, header = None, is_source = False):
|
||||
def __init__(self, filename, dirname, header=None, is_source=False):
|
||||
self.filename = filename
|
||||
self.extracted = False
|
||||
self.dirname = dirname
|
||||
|
@ -508,8 +528,8 @@ class Pkg:
|
|||
return None
|
||||
else:
|
||||
self.dirname = tempfile.mkdtemp(
|
||||
prefix = 'rpmlint.%s.' % os.path.basename(self.filename),
|
||||
dir = self.dirname)
|
||||
prefix='rpmlint.%s.' % os.path.basename(self.filename),
|
||||
dir=self.dirname)
|
||||
# TODO: better shell escaping or sequence based command invocation
|
||||
command_str = \
|
||||
'rpm2cpio "%s" | (cd "%s"; cpio -id); chmod -R +rX "%s"' % \
|
||||
|
@ -629,7 +649,7 @@ class Pkg:
|
|||
provides = [b2s(x) for x in self.header[rpm.RPMTAG_FILEPROVIDE]]
|
||||
files = [b2s(x) for x in self.header[rpm.RPMTAG_FILENAMES]]
|
||||
magics = [b2s(x) for x in self.header[rpm.RPMTAG_FILECLASS]]
|
||||
try: # rpm >= 4.7.0
|
||||
try: # rpm >= 4.7.0
|
||||
filecaps = self.header[rpm.RPMTAG_FILECAPS]
|
||||
except:
|
||||
filecaps = None
|
||||
|
@ -732,7 +752,7 @@ class Pkg:
|
|||
|
||||
# internal function to gather dependency info used by the above ones
|
||||
def _gather_aux(self, header, list, nametag, flagstag, versiontag,
|
||||
prereq = None):
|
||||
prereq=None):
|
||||
names = header[nametag]
|
||||
flags = header[flagstag]
|
||||
versions = header[versiontag]
|
||||
|
@ -784,6 +804,7 @@ class Pkg:
|
|||
prog = b' '.join(prog)
|
||||
return b2s(prog)
|
||||
|
||||
|
||||
def getInstalledPkgs(name):
|
||||
"""Get list of installed package objects by name."""
|
||||
|
||||
|
@ -800,9 +821,10 @@ def getInstalledPkgs(name):
|
|||
|
||||
return pkgs
|
||||
|
||||
|
||||
# Class to provide an API to an installed package
|
||||
class InstalledPkg(Pkg):
|
||||
def __init__(self, name, hdr = None):
|
||||
def __init__(self, name, hdr=None):
|
||||
if not hdr:
|
||||
ts = rpm.TransactionSet()
|
||||
mi = ts.dbMatch('name', name)
|
||||
|
@ -827,6 +849,7 @@ class InstalledPkg(Pkg):
|
|||
def checkSignature(self):
|
||||
return (0, 'fake: pgp md5 OK')
|
||||
|
||||
|
||||
# Class to provide an API to a "fake" package, eg. for specfile-only checks
|
||||
class FakePkg:
|
||||
def __init__(self, name):
|
||||
|
@ -837,6 +860,7 @@ class FakePkg:
|
|||
def cleanup(self):
|
||||
pass
|
||||
|
||||
|
||||
# Class for files in packages
|
||||
class PkgFile(object):
|
||||
|
||||
|
@ -862,10 +886,10 @@ class PkgFile(object):
|
|||
|
||||
# TODO: decompression support
|
||||
|
||||
is_config = property(lambda self: self.flags & rpm.RPMFILE_CONFIG)
|
||||
is_doc = property(lambda self: self.flags & rpm.RPMFILE_DOC)
|
||||
is_config = property(lambda self: self.flags & rpm.RPMFILE_CONFIG)
|
||||
is_doc = property(lambda self: self.flags & rpm.RPMFILE_DOC)
|
||||
is_noreplace = property(lambda self: self.flags & rpm.RPMFILE_NOREPLACE)
|
||||
is_ghost = property(lambda self: self.flags & rpm.RPMFILE_GHOST)
|
||||
is_ghost = property(lambda self: self.flags & rpm.RPMFILE_GHOST)
|
||||
is_missingok = property(lambda self: self.flags & rpm.RPMFILE_MISSINGOK)
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ menu_regex = re.compile('^/usr/lib/menu/|^/etc/menu-methods/|^/usr/share/applica
|
|||
bogus_var_regex = re.compile('(\${?RPM_BUILD_(ROOT|DIR)}?)')
|
||||
|
||||
prereq_assoc = (
|
||||
# ['chkconfig', ('chkconfig', '/sbin/chkconfig')],
|
||||
#['chkconfig', ('chkconfig', '/sbin/chkconfig')],
|
||||
['chkfontpath', ('chkfontpath', '/usr/sbin/chkfontpath')],
|
||||
['rpm-helper', ('rpm-helper',)],
|
||||
)
|
||||
|
@ -72,11 +72,14 @@ script_tags = [
|
|||
(rpm.RPMTAG_VERIFYSCRIPT, rpm.RPMTAG_VERIFYSCRIPTPROG, '%verifyscript'),
|
||||
]
|
||||
|
||||
|
||||
def incorrect_shell_script(prog, shellscript):
|
||||
return check_syntax_script(prog,'-n', shellscript)
|
||||
return check_syntax_script(prog, '-n', shellscript)
|
||||
|
||||
|
||||
def incorrect_perl_script(prog, perlscript):
|
||||
return check_syntax_script(prog,'-wc', perlscript)
|
||||
return check_syntax_script(prog, '-wc', perlscript)
|
||||
|
||||
|
||||
def check_syntax_script(prog, commandline, script):
|
||||
if not script:
|
||||
|
|
|
@ -20,8 +20,8 @@ source_regex = re.compile('\\.(tar|patch|tgz|diff)$')
|
|||
compress_ext = Config.getOption("CompressExtension", "bz2")
|
||||
valid_src_perms = Config.getOption("ValidSrcPerms", DEFAULT_VALID_SRC_PERMS)
|
||||
|
||||
class SourceCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
class SourceCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
AbstractCheck.AbstractCheck.__init__(self, 'SourceCheck')
|
||||
|
|
29
SpecCheck.py
29
SpecCheck.py
|
@ -11,7 +11,7 @@ import re
|
|||
import unicodedata
|
||||
try:
|
||||
from urlparse import urlparse
|
||||
except ImportError: # Python 3
|
||||
except ImportError: # Python 3
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import rpm
|
||||
|
@ -31,24 +31,23 @@ DEFAULT_BIARCH_PACKAGES = '^(gcc|glibc)'
|
|||
# be installed on biarch systems
|
||||
DEFAULT_HARDCODED_LIB_PATH_EXCEPTIONS = '/lib/(modules|cpp|perl5|rpm|hotplug|firmware)($|[\s/,])'
|
||||
|
||||
|
||||
def re_tag_compile(tag):
|
||||
if type(tag) == type([]):
|
||||
tag = '(?:' + '|'.join(tag) + ')'
|
||||
r = "^%s\s*:\s*(\S.*?)\s*$" % tag
|
||||
return re.compile(r, re.IGNORECASE)
|
||||
|
||||
|
||||
|
||||
patch_regex = re_tag_compile('Patch(\d*)')
|
||||
applied_patch_regex = re.compile("^%patch(\d*)")
|
||||
applied_patch_p_regex = re.compile("\s-P\s+(\d+)\\b")
|
||||
applied_patch_pipe_regex = re.compile(r'\s%\{PATCH(\d+)\}\s*\|\s*(%\{?__)?patch\b')
|
||||
source_dir_regex = re.compile("^[^#]*(\$RPM_SOURCE_DIR|%{?_sourcedir}?)")
|
||||
obsolete_tags_regex = re_tag_compile(['Serial','Copyright'])
|
||||
obsolete_tags_regex = re_tag_compile(['Serial', 'Copyright'])
|
||||
buildroot_regex = re_tag_compile('BuildRoot')
|
||||
prefix_regex = re_tag_compile('Prefix')
|
||||
packager_regex = re_tag_compile('Packager')
|
||||
buildarch_regex = re_tag_compile(['BuildArch','BuildArchitectures'])
|
||||
buildarch_regex = re_tag_compile(['BuildArch', 'BuildArchitectures'])
|
||||
buildprereq_regex = re_tag_compile('BuildPreReq')
|
||||
prereq_regex = re_tag_compile('PreReq(\(.*\))')
|
||||
|
||||
|
@ -82,7 +81,7 @@ hardcoded_library_path_regex = re.compile('^[^#]*((^|\s+|\.\./\.\.|\${?RPM_BUILD
|
|||
# https://bugzilla.redhat.com/118780 and bugs linked to that one.
|
||||
scriptlet_requires_regex = re.compile('^(PreReq|Requires)\([^\)]*,', re.IGNORECASE)
|
||||
|
||||
DEFINE_RE='(^|\s)%(define|global)\s+'
|
||||
DEFINE_RE = '(^|\s)%(define|global)\s+'
|
||||
depscript_override_regex = re.compile(DEFINE_RE + '__find_(requires|provides)\s')
|
||||
depgen_disable_regex = re.compile(DEFINE_RE + '_use_internal_dependency_generator\s+0')
|
||||
patch_fuzz_override_regex = re.compile(DEFINE_RE + '_default_patch_fuzz\s+(\d+)')
|
||||
|
@ -110,18 +109,20 @@ tarball_regex = re.compile('\.(?:t(?:ar|[glx]z|bz2?)|zip)\\b', re.IGNORECASE)
|
|||
|
||||
UNICODE_NBSP = unicodedata.lookup('NO-BREAK SPACE')
|
||||
|
||||
|
||||
def unversioned(deps):
|
||||
'''Yield unversioned dependency names from the given list.'''
|
||||
for dep in deps:
|
||||
if not dep[1]:
|
||||
yield dep[0]
|
||||
|
||||
|
||||
def contains_buildroot(line):
|
||||
'''Check if the given line contains use of rpm buildroot.'''
|
||||
res = rpm_buildroot_regex.search(line)
|
||||
if res and \
|
||||
(not res.group(1) or len(res.group(1)) % 2 == 0) and \
|
||||
(not res.group(2) or len(res.group(2)) % 2 != 0):
|
||||
(not res.group(1) or len(res.group(1)) % 2 == 0) and \
|
||||
(not res.group(2) or len(res.group(2)) % 2 != 0):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -171,7 +172,7 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
|||
if_depth = 0
|
||||
ifarch_depth = -1
|
||||
current_section = 'package'
|
||||
buildroot_clean = {'clean': False, 'install' : False}
|
||||
buildroot_clean = {'clean': False, 'install': False}
|
||||
depscript_override = False
|
||||
depgen_disabled = False
|
||||
patch_fuzz_override = False
|
||||
|
@ -337,7 +338,7 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
|||
if current_section != 'changelog' and res and not \
|
||||
(biarch_package_regex.match(pkg.name) or
|
||||
hardcoded_lib_path_exceptions_regex.search(
|
||||
res.group(1).lstrip())):
|
||||
res.group(1).lstrip())):
|
||||
printError(pkg, "hardcoded-library-path", "in",
|
||||
res.group(1).lstrip())
|
||||
|
||||
|
@ -482,7 +483,7 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
|||
# If not checking spec file only, we're checking one inside a
|
||||
# SRPM -> skip this check to avoid duplicate warnings (#167)
|
||||
if spec_only and VALID_GROUPS and \
|
||||
line.lower().startswith("group:"):
|
||||
line.lower().startswith("group:"):
|
||||
group = line[6:].strip()
|
||||
if group not in VALID_GROUPS:
|
||||
printWarning(pkg, 'non-standard-group', group)
|
||||
|
@ -491,7 +492,7 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
|||
if hashPos != -1 and \
|
||||
(hashPos == 0 or line[hashPos-1] in (" ", "\t")):
|
||||
for match in AbstractCheck.macro_regex.findall(
|
||||
line[hashPos+1:]):
|
||||
line[hashPos+1:]):
|
||||
res = re.match('%+', match)
|
||||
if len(res.group(0)) % 2:
|
||||
printWarning(pkg, 'macro-in-comment', match)
|
||||
|
@ -577,7 +578,7 @@ class SpecCheck(AbstractCheck.AbstractCheck):
|
|||
for src in sources:
|
||||
(url, num, flags) = src
|
||||
(scheme, netloc) = urlparse(url)[0:2]
|
||||
if flags & 1: # rpmspec.h, rpm.org ticket #123
|
||||
if flags & 1: # rpmspec.h, rpm.org ticket #123
|
||||
srctype = "Source"
|
||||
else:
|
||||
srctype = "Patch"
|
||||
|
@ -835,7 +836,7 @@ intended contents.''',
|
|||
|
||||
'patch-fuzz-is-changed',
|
||||
'''The internal patch fuzz value was changed, and could hide patchs issues, or
|
||||
could lead to applying a patch at the wrong location. Usually, this is often the
|
||||
could lead to applying a patch at the wrong location. Usually, this is often the
|
||||
sign that someone didn't check if a patch is still needed and do not want to rediff
|
||||
it. It is usually better to rediff the patch and try to send it upstream.'''
|
||||
)
|
||||
|
|
41
TagsCheck.py
41
TagsCheck.py
|
@ -13,7 +13,7 @@ import re
|
|||
import time
|
||||
try:
|
||||
from urlparse import urlparse
|
||||
except ImportError: # Python 3
|
||||
except ImportError: # Python 3
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import rpm
|
||||
|
@ -42,8 +42,8 @@ DEFAULT_VALID_LICENSES = (
|
|||
# the full name). Updated 2010-02-01.
|
||||
'Academic Free License',
|
||||
'Adaptive Public License',
|
||||
'AGPLv3', # Affero GNU Public License
|
||||
'AGPLv3+', # Affero GNU Public License
|
||||
'AGPLv3', # Affero GNU Public License
|
||||
'AGPLv3+', # Affero GNU Public License
|
||||
'Apache License',
|
||||
'Apache Software License',
|
||||
'Apple Public Source License',
|
||||
|
@ -52,7 +52,7 @@ DEFAULT_VALID_LICENSES = (
|
|||
'BSD',
|
||||
'Boost Software License',
|
||||
'Computer Associates Trusted Open Source License',
|
||||
'CDDL', # Common Development and Distribution License
|
||||
'CDDL', # Common Development and Distribution License
|
||||
'Common Public Attribution License',
|
||||
'CUA Office Public License',
|
||||
'EU DataGrid Software License',
|
||||
|
@ -83,7 +83,7 @@ DEFAULT_VALID_LICENSES = (
|
|||
'MirOS License',
|
||||
'MIT',
|
||||
'Motosoto License',
|
||||
'MPL', # Mozilla Public License
|
||||
'MPL', # Mozilla Public License
|
||||
'Multics License',
|
||||
'NASA Open Source Agreement',
|
||||
'Naumen Public License',
|
||||
|
@ -92,13 +92,13 @@ DEFAULT_VALID_LICENSES = (
|
|||
'Non-profit Open Software License',
|
||||
'NTP License',
|
||||
'OCLC Research Public License',
|
||||
'OFL', # Open Font License
|
||||
'OFL', # Open Font License
|
||||
'Open Group Test Suite License',
|
||||
'Open Software License',
|
||||
'PHP License',
|
||||
'Python license', # CNRI Python License
|
||||
'Python license', # CNRI Python License
|
||||
'Python Software Foundation License',
|
||||
'QPL', # Qt Public License
|
||||
'QPL', # Qt Public License
|
||||
'RealNetworks Public Source License',
|
||||
'Reciprocal Public License',
|
||||
'Ricoh Source Code Public License',
|
||||
|
@ -121,8 +121,8 @@ DEFAULT_VALID_LICENSES = (
|
|||
'Creative Commons Attribution-NonCommercial-ShareAlike',
|
||||
'Creative Commons Attribution-ShareAlike',
|
||||
# Others:
|
||||
'Design Public License', # ???
|
||||
'GFDL', # GNU Free Documentation License
|
||||
'Design Public License', # ???
|
||||
'GFDL', # GNU Free Documentation License
|
||||
'LaTeX Project Public License',
|
||||
'OpenContent License',
|
||||
'Open Publication License',
|
||||
|
@ -400,7 +400,7 @@ BAD_WORDS = {
|
|||
DEFAULT_INVALID_REQUIRES = ('^is$', '^not$', '^owned$', '^by$', '^any$', '^package$', '^libsafe\.so\.')
|
||||
|
||||
VALID_GROUPS = Config.getOption('ValidGroups', None)
|
||||
if VALID_GROUPS is None: # get defaults from rpm package only if it's not set
|
||||
if VALID_GROUPS is None: # get defaults from rpm package only if it's not set
|
||||
VALID_GROUPS = Pkg.get_default_valid_rpmgroups()
|
||||
VALID_LICENSES = Config.getOption('ValidLicenses', DEFAULT_VALID_LICENSES)
|
||||
INVALID_REQUIRES = map(re.compile, Config.getOption('InvalidRequires', DEFAULT_INVALID_REQUIRES))
|
||||
|
@ -440,6 +440,8 @@ for path in ('%perl_archlib', '%perl_vendorarch', '%perl_sitearch',
|
|||
private_so_paths.add(re.sub(r'/lib(?=/|$)', '/lib64', epath))
|
||||
|
||||
_enchant_checkers = {}
|
||||
|
||||
|
||||
def spell_check(pkg, str, fmt, lang, ignored):
|
||||
|
||||
dict_found = True
|
||||
|
@ -452,9 +454,9 @@ def spell_check(pkg, str, fmt, lang, ignored):
|
|||
if not checker and lang not in _enchant_checkers:
|
||||
try:
|
||||
checker = enchant.checker.SpellChecker(
|
||||
lang, filters = [ enchant.tokenize.EmailFilter,
|
||||
enchant.tokenize.URLFilter,
|
||||
enchant.tokenize.WikiWordFilter ])
|
||||
lang, filters=[enchant.tokenize.EmailFilter,
|
||||
enchant.tokenize.URLFilter,
|
||||
enchant.tokenize.WikiWordFilter])
|
||||
except enchant.DictNotFoundError:
|
||||
printInfo(pkg, 'enchant-dictionary-not-found', lang)
|
||||
pass
|
||||
|
@ -738,7 +740,7 @@ class TagsCheck(AbstractCheck.AbstractCheck):
|
|||
# only check when source name correspond to name
|
||||
if srpm[0:-8] == '%s-%s-%s' % (name, version, release):
|
||||
expected = [version + '-' + release]
|
||||
if epoch is not None: # regardless of use_epoch
|
||||
if epoch is not None: # regardless of use_epoch
|
||||
expected[0] = str(epoch) + ':' + expected[0]
|
||||
# Allow EVR in changelog without release extension,
|
||||
# the extension is often a macro or otherwise dynamic.
|
||||
|
@ -758,13 +760,13 @@ class TagsCheck(AbstractCheck.AbstractCheck):
|
|||
|
||||
clt = pkg[rpm.RPMTAG_CHANGELOGTIME][0]
|
||||
if clt:
|
||||
clt -= clt % (24*3600) # roll back to 00:00:00, see #246
|
||||
clt -= clt % (24*3600) # roll back to 00:00:00, see #246
|
||||
if clt < oldest_changelog_timestamp:
|
||||
printWarning(pkg, 'changelog-time-overflow',
|
||||
time.strftime("%Y-%m-%d", time.gmtime(clt)))
|
||||
elif clt > time.time():
|
||||
printError(pkg, 'changelog-time-in-future',
|
||||
time.strftime("%Y-%m-%d", time.gmtime(clt)))
|
||||
time.strftime("%Y-%m-%d", time.gmtime(clt)))
|
||||
|
||||
# for provide_name in (x[0] for x in pkg.provides()):
|
||||
# if name == provide_name:
|
||||
|
@ -794,12 +796,12 @@ class TagsCheck(AbstractCheck.AbstractCheck):
|
|||
for tag in ('URL', 'DistURL', 'BugURL'):
|
||||
if hasattr(rpm, 'RPMTAG_%s' % tag.upper()):
|
||||
url = Pkg.b2s(pkg[getattr(rpm, 'RPMTAG_%s' % tag.upper())])
|
||||
self._unexpanded_macros(pkg, tag, url, is_url = True)
|
||||
self._unexpanded_macros(pkg, tag, url, is_url=True)
|
||||
if url:
|
||||
(scheme, netloc) = urlparse(url)[0:2]
|
||||
if not scheme or not netloc or "." not in netloc or \
|
||||
scheme not in ('http', 'https', 'ftp') or \
|
||||
(Config.getOption('InvalidURL') and \
|
||||
(Config.getOption('InvalidURL') and
|
||||
invalid_url_regex.search(url)):
|
||||
printWarning(pkg, 'invalid-url', tag, url)
|
||||
else:
|
||||
|
@ -867,7 +869,6 @@ class TagsCheck(AbstractCheck.AbstractCheck):
|
|||
printWarning(pkg, "private-shared-object-provides",
|
||||
fname, Pkg.formatRequire(*prov))
|
||||
|
||||
|
||||
def check_description(self, pkg, lang, ignored_words):
|
||||
description = pkg.langtag(rpm.RPMTAG_DESCRIPTION, lang)
|
||||
self._unexpanded_macros(pkg, '%%description -l %s' % lang, description)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#------------------------------------------------------------------------------
|
||||
#############################################################################
|
||||
# File : ZipCheck.py
|
||||
# Package : rpmlint
|
||||
# Author : Ville Skyttä
|
||||
# Created on : Thu Oct 30 00:14:45 EET 2003
|
||||
# Purpose : Verify Zip/Jar file correctness
|
||||
#------------------------------------------------------------------------------
|
||||
#############################################################################
|
||||
|
||||
import os
|
||||
import re
|
||||
|
@ -24,6 +24,7 @@ classpath_regex = re.compile('^\s*Class-Path\s*:', re.M | re.I)
|
|||
|
||||
want_indexed_jars = Config.getOption('UseIndexedJars', True)
|
||||
|
||||
|
||||
class ZipCheck(AbstractCheck.AbstractCheck):
|
||||
|
||||
def __init__(self):
|
||||
|
@ -33,8 +34,8 @@ class ZipCheck(AbstractCheck.AbstractCheck):
|
|||
for fname, pkgfile in pkg.files().items():
|
||||
path = pkgfile.path
|
||||
if zip_regex.search(fname) and os.path.exists(path) and \
|
||||
stat.S_ISREG(os.lstat(path)[stat.ST_MODE]) and \
|
||||
zipfile.is_zipfile(path):
|
||||
stat.S_ISREG(os.lstat(path)[stat.ST_MODE]) and \
|
||||
zipfile.is_zipfile(path):
|
||||
z = None
|
||||
try:
|
||||
z = zipfile.ZipFile(path, 'r')
|
||||
|
|
16382
__isocodes__.py
16382
__isocodes__.py
File diff suppressed because it is too large
Load Diff
20
rpmlint
20
rpmlint
|
@ -30,7 +30,7 @@ sys.path.insert(1, '/usr/share/rpmlint')
|
|||
# place for those variables.
|
||||
|
||||
from Filter import badnessScore, badnessThreshold, printAllReasons, \
|
||||
printDescriptions, printInfo, printed_messages, setRawOut
|
||||
printDescriptions, printInfo, printed_messages, setRawOut
|
||||
import AbstractCheck
|
||||
import Config
|
||||
import Pkg
|
||||
|
@ -39,6 +39,7 @@ import Pkg
|
|||
_default_user_conf = '%s/rpmlint' % \
|
||||
(os.environ.get('XDG_CONFIG_HOME') or '~/.config')
|
||||
|
||||
|
||||
# Print usage information
|
||||
def usage(name):
|
||||
print ('''usage: %s [<options>] <rpm files|installed packages|specfiles|dirs>
|
||||
|
@ -55,13 +56,15 @@ def usage(name):
|
|||
\t[-n|--noexception]
|
||||
\t[ --rawout <file>]
|
||||
\t[-f|--file <user config file to use instead of %s]
|
||||
\t[-o|--option <key value>]''' \
|
||||
% (name, _default_user_conf))
|
||||
\t[-o|--option <key value>]'''
|
||||
% (name, _default_user_conf))
|
||||
|
||||
|
||||
# Print version information
|
||||
def printVersion():
|
||||
print ('rpmlint version %s Copyright (C) 1999-2007 Frederic Lepied, Mandriva' % Config.__version__)
|
||||
|
||||
|
||||
def loadCheck(name):
|
||||
'''Load a (check) module by its name, unless it is already loaded.'''
|
||||
# Avoid loading more than once (initialization costs)
|
||||
|
@ -74,6 +77,7 @@ def loadCheck(name):
|
|||
finally:
|
||||
fobj.close()
|
||||
|
||||
|
||||
#############################################################################
|
||||
# main program
|
||||
#############################################################################
|
||||
|
@ -135,8 +139,8 @@ def main():
|
|||
Pkg.warn(
|
||||
'(none): E: no installed packages by name %s' % arg)
|
||||
else:
|
||||
ipkgs.sort(key = lambda x: locale.strxfrm(
|
||||
x.header.sprintf("%{NAME}.%{ARCH}")))
|
||||
ipkgs.sort(key=lambda x: locale.strxfrm(
|
||||
x.header.sprintf("%{NAME}.%{ARCH}")))
|
||||
pkgs.extend(ipkgs)
|
||||
except KeyboardInterrupt:
|
||||
if isfile:
|
||||
|
@ -194,7 +198,7 @@ def main():
|
|||
sys.exit(66)
|
||||
|
||||
finally:
|
||||
print("%d packages and %d specfiles checked; %d errors, %d warnings." \
|
||||
print("%d packages and %d specfiles checked; %d errors, %d warnings."
|
||||
% (packages_checked, specfiles_checked,
|
||||
printed_messages["E"], printed_messages["W"]))
|
||||
|
||||
|
@ -202,6 +206,7 @@ def main():
|
|||
sys.exit(64)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def runChecks(pkg):
|
||||
|
||||
try:
|
||||
|
@ -218,6 +223,7 @@ def runChecks(pkg):
|
|||
finally:
|
||||
pkg.cleanup()
|
||||
|
||||
|
||||
def runSpecChecks(pkg, fname):
|
||||
|
||||
try:
|
||||
|
@ -228,7 +234,7 @@ def runSpecChecks(pkg, fname):
|
|||
check = AbstractCheck.AbstractCheck.known_checks.get(name)
|
||||
if check:
|
||||
check.verbose = verbose
|
||||
check.check_spec(pkg,fname)
|
||||
check.check_spec(pkg, fname)
|
||||
else:
|
||||
Pkg.warn('(none): W: unknown check %s, skipping' % name)
|
||||
finally:
|
||||
|
|
|
@ -10,27 +10,33 @@ import Pkg
|
|||
currently_testing = 0
|
||||
output = []
|
||||
|
||||
|
||||
def isTest():
|
||||
return currently_testing
|
||||
|
||||
|
||||
def startTest():
|
||||
global currently_testing
|
||||
global output
|
||||
output = []
|
||||
currently_testing = 1
|
||||
|
||||
|
||||
def addOutput(s):
|
||||
global output
|
||||
output.append(s)
|
||||
|
||||
|
||||
def getOutput():
|
||||
global output
|
||||
return output
|
||||
|
||||
|
||||
def getTestedPackage(name):
|
||||
pkg_path = glob.glob(os.environ['TESTPATH'] + '/' + name + '-*.rpm')[0]
|
||||
return Pkg.Pkg(pkg_path, tempfile.gettempdir())
|
||||
|
||||
|
||||
def getTestedSpecPackage(name):
|
||||
pkg_path = glob.glob(os.environ['TESTPATH'] + '/' + name + '.spec')[0]
|
||||
return Pkg.FakePkg(pkg_path)
|
||||
|
|
|
@ -11,12 +11,12 @@ langs = set()
|
|||
countries = set()
|
||||
|
||||
# 2-letter country codes
|
||||
tree = ElementTree(file = "/usr/share/xml/iso-codes/iso_3166.xml")
|
||||
tree = ElementTree(file="/usr/share/xml/iso-codes/iso_3166.xml")
|
||||
for entry in tree.findall("iso_3166_entry"):
|
||||
countries.add(entry.get("alpha_2_code"))
|
||||
|
||||
# 2-letter codes
|
||||
tree = ElementTree(file = "/usr/share/xml/iso-codes/iso_639.xml")
|
||||
tree = ElementTree(file="/usr/share/xml/iso-codes/iso_639.xml")
|
||||
for entry in tree.findall("iso_639_entry"):
|
||||
for attr in ("iso_639_1_code", "iso_639_2T_code"):
|
||||
code = entry.get(attr)
|
||||
|
@ -25,7 +25,7 @@ for entry in tree.findall("iso_639_entry"):
|
|||
break
|
||||
|
||||
# Remaining 2-letter codes plus 3-letter ones for which we have no 2-letter one
|
||||
tree = ElementTree(file = "/usr/share/xml/iso-codes/iso_639_3.xml")
|
||||
tree = ElementTree(file="/usr/share/xml/iso-codes/iso_639_3.xml")
|
||||
for entry in tree.findall("iso_639_3_entry"):
|
||||
code = entry.get("part1_code")
|
||||
if code:
|
||||
|
@ -38,11 +38,11 @@ print ""
|
|||
print "LANGUAGES = set(("
|
||||
for code in sorted(langs):
|
||||
if code:
|
||||
print "\t\"%s\"," % code
|
||||
print " \"%s\"," % code
|
||||
print "))"
|
||||
print ""
|
||||
print "COUNTRIES = set(("
|
||||
for code in sorted(countries):
|
||||
if code:
|
||||
print "\t\"%s\"," % code
|
||||
print " \"%s\"," % code
|
||||
print "))"
|
||||
|
|
Loading…
Reference in New Issue