Lines 6-11
Functions used for determining the package the broken lib belongs to.
Link Here
|
6 |
|
6 |
|
7 |
from __future__ import print_function |
7 |
from __future__ import print_function |
8 |
|
8 |
|
|
|
9 |
import errno |
9 |
import os |
10 |
import os |
10 |
import io |
11 |
import io |
11 |
import re |
12 |
import re |
Lines 22-32
try:
Link Here
|
22 |
except NameError: |
23 |
except NameError: |
23 |
pass |
24 |
pass |
24 |
|
25 |
|
|
|
26 |
|
27 |
class _file_matcher(object): |
28 |
""" |
29 |
Compares files by basename and parent directory (device, inode), |
30 |
so comparisons work regardless of directory symlinks. If a |
31 |
parent directory does not exist, the realpath of the parent |
32 |
directory is used instead of the (device, inode). When multiple |
33 |
files share the same parent directory, stat is only called |
34 |
once per directory, and the result is cached internally. |
35 |
""" |
36 |
def __init__(self): |
37 |
self._file_ids = {} |
38 |
self._added = {} |
39 |
|
40 |
def _file_id(self, filename): |
41 |
try: |
42 |
return self._file_ids[filename] |
43 |
except KeyError: |
44 |
try: |
45 |
st = os.stat(filename) |
46 |
except OSError as e: |
47 |
if e.errno != errno.ENOENT: |
48 |
raise |
49 |
file_id = (os.path.realpath(filename),) |
50 |
else: |
51 |
file_id = (st.st_dev, st.st_ino) |
52 |
|
53 |
self._file_ids[filename] = file_id |
54 |
return file_id |
55 |
|
56 |
def _file_key(self, filename): |
57 |
head, tail = os.path.split(filename) |
58 |
key = self._file_id(head) + (tail,) |
59 |
return key |
60 |
|
61 |
def add(self, filename): |
62 |
self._added[self._file_key(filename)] = filename |
63 |
|
64 |
def intersection(self, other): |
65 |
for file_key in self._added: |
66 |
match = other._added.get(file_key) |
67 |
if match is not None: |
68 |
yield match |
69 |
|
70 |
|
25 |
def assign_packages(broken, logger, settings): |
71 |
def assign_packages(broken, logger, settings): |
26 |
''' Finds and returns packages that owns files placed in broken. |
72 |
''' Finds and returns packages that owns files placed in broken. |
27 |
Broken is list of files |
73 |
Broken is list of files |
28 |
''' |
74 |
''' |
29 |
stime = current_milli_time() |
75 |
stime = current_milli_time() |
|
|
76 |
|
77 |
broken_matcher = _file_matcher() |
78 |
for filename in broken: |
79 |
broken_matcher.add(filename) |
80 |
|
30 |
assigned_pkgs = set() |
81 |
assigned_pkgs = set() |
31 |
assigned_filenames = set() |
82 |
assigned_filenames = set() |
32 |
for group in os.listdir(settings['PKG_DIR']): |
83 |
for group in os.listdir(settings['PKG_DIR']): |
Lines 39-59
def assign_packages(broken, logger, settings):
Link Here
|
39 |
continue |
90 |
continue |
40 |
f = pkgpath + '/CONTENTS' |
91 |
f = pkgpath + '/CONTENTS' |
41 |
if os.path.exists(f): |
92 |
if os.path.exists(f): |
|
|
93 |
contents_matcher = _file_matcher() |
42 |
try: |
94 |
try: |
43 |
with io.open(f, 'r', encoding='utf_8') as cnt: |
95 |
with io.open(f, 'r', encoding='utf_8') as cnt: |
44 |
for line in cnt.readlines(): |
96 |
for line in cnt.readlines(): |
45 |
m = re.match('^obj (/[^ ]+)', line) |
97 |
m = re.match('^obj (/[^ ]+)', line) |
46 |
if m is not None: |
98 |
if m is not None: |
47 |
m = m.group(1) |
99 |
contents_matcher.add(m.group(1)) |
48 |
if m in broken: |
|
|
49 |
found = group+'/'+pkg |
50 |
assigned_pkgs.add(found) |
51 |
assigned_filenames.add(m) |
52 |
logger.info('\t' + green('* ') + m + |
53 |
' -> ' + bold(found)) |
54 |
except Exception as e: |
100 |
except Exception as e: |
55 |
logger.warning(red(' !! Failed to read ' + f)) |
101 |
logger.warning(red(' !! Failed to read ' + f)) |
56 |
logger.warning(red(' !! Error was:' + str(e))) |
102 |
logger.warning(red(' !! Error was:' + str(e))) |
|
|
103 |
else: |
104 |
for m in contents_matcher.intersection(broken_matcher): |
105 |
found = group+'/'+pkg |
106 |
assigned_pkgs.add(found) |
107 |
assigned_filenames.add(m) |
108 |
logger.info('\t' + green('* ') + m + |
109 |
' -> ' + bold(found)) |
57 |
|
110 |
|
58 |
broken_filenames = set(broken) |
111 |
broken_filenames = set(broken) |
59 |
orphaned = broken_filenames.difference(assigned_filenames) |
112 |
orphaned = broken_filenames.difference(assigned_filenames) |
60 |
- |
|
|