forked from openSUSE/rpmlint-checks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDuplicatesCheck.py
102 lines (79 loc) · 3.19 KB
/
DuplicatesCheck.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
# vim:sw=4:et
#############################################################################
# File : DuplicatesCheck.py
# Package : rpmlint
# Author : Stephan Kulow
# Purpose : Check for duplicate files being packaged separately
#############################################################################
import AbstractCheck
import Filter
import os
import stat
def get_prefix(file):
pathlist = str.split(file, '/')
if len(pathlist) == 3:
return "/".join(pathlist[0:2])
return "/".join(pathlist[0:3])
class DuplicatesCheck(AbstractCheck.AbstractCheck):
def __init__(self):
self.map = []
AbstractCheck.AbstractCheck.__init__(self, "DuplicatesCheck")
def check(self, pkg):
if pkg.isSource():
return
md5s = {}
sizes = {}
files = pkg.files()
configFiles = pkg.configFiles()
for f, pkgfile in files.items():
if f in pkg.ghostFiles():
continue
if not stat.S_ISREG(pkgfile.mode):
continue
md5s.setdefault(pkgfile.md5, set()).add(f)
sizes[pkgfile.md5] = pkgfile.size
sum = 0
for f in md5s:
duplicates = md5s[f]
if len(duplicates) == 1:
continue
one = duplicates.pop()
one_is_config = False
if one in configFiles:
one_is_config = True
partition = get_prefix(one)
st = os.stat(pkg.dirName() + '/' + one)
diff = 1 + len(duplicates) - st[stat.ST_NLINK]
if diff <= 0:
for dupe in duplicates:
if partition != get_prefix(dupe):
Filter.printError(pkg, "hardlink-across-partition",
one, dupe)
if one_is_config and dupe in configFiles:
Filter.printError(pkg, "hardlink-across-config-files",
one, dupe)
continue
for dupe in duplicates:
if partition != get_prefix(dupe):
diff = diff - 1
sum += sizes[f] * diff
if sizes[f] and diff > 0:
Filter.printWarning(pkg, 'files-duplicate', one,
":".join(sorted(duplicates)))
if sum > 100000:
Filter.printError(pkg, 'files-duplicated-waste', sum)
check = DuplicatesCheck()
Filter.addDetails(
'files-duplicated-waste',
"""Your package contains duplicated files that are not hard- or symlinks.
You should use the %fdupes macro to link the files to one.""",
'hardlink-across-partition',
"""Your package contains two files that are apparently hardlinked and
that are likely on different partitions. Installation of such an RPM will fail
due to RPM being unable to unpack the hardlink. do not hardlink across
the first two levels of a path, e.g. between /srv/ftp and /srv/www or
/etc and /usr. """,
'hardlink-across-config-files',
"""Your package contains two config files that are apparently hardlinked.
Hardlinking a config file is probably not what you want. Please double
check and report false positives.""")