Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 611808
Collapse All | Expand All

(-)a/pym/gentoolkit/revdep_rebuild/assign.py (-8 / +60 lines)
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
- 

Return to bug 611808