Gentoo Archives: gentoo-commits

From: "André Erdmann" <dywi@×××××××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/db/
Date: Fri, 30 Aug 2013 14:49:41
Message-Id: 1377866538.bec81d9137f5b68398401e79df094207680eb006.dywi@gentoo
1 commit: bec81d9137f5b68398401e79df094207680eb006
2 Author: André Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Fri Aug 30 12:42:18 2013 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Fri Aug 30 12:42:18 2013 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=bec81d91
7
8 distmap: add_distfile_owner()
9
10 This commit also includes a stub for detecting/handling file collisions.
11
12 ---
13 roverlay/db/distmap.py | 97 +++++++++++++++++++++++++++++++++++++++++---------
14 1 file changed, 80 insertions(+), 17 deletions(-)
15
16 diff --git a/roverlay/db/distmap.py b/roverlay/db/distmap.py
17 index ca3d236..b3b285c 100644
18 --- a/roverlay/db/distmap.py
19 +++ b/roverlay/db/distmap.py
20 @@ -4,17 +4,17 @@
21 # Distributed under the terms of the GNU General Public License;
22 # either version 2 of the License, or (at your option) any later version.
23
24 -import errno
25 -
26 import bz2
27 import gzip
28
29 +import errno
30 import os.path
31 +import logging
32 import shutil
33
34 -
35 import roverlay.digest
36 import roverlay.util
37 +import roverlay.util.objects
38 import roverlay.stats.collector
39
40
41 @@ -30,6 +30,14 @@ class DistMapInfo ( object ):
42 RESTORE_FROM_DISTFILE = '_'
43 UNSET = 'U'
44
45 + @classmethod
46 + def from_package_info ( cls, p_info, allow_digest_create=True ):
47 + key, value = p_info.get_distmap_value (
48 + allow_digest_create=allow_digest_create
49 + )
50 + return key, cls ( *value )
51 + # --- end of from_package_info (...) ---
52 +
53 def __init__ ( self, distfile, repo_name, repo_file, sha256 ):
54 """Distmap entry constructor.
55
56 @@ -44,12 +52,26 @@ class DistMapInfo ( object ):
57 self.repo_name = repo_name if repo_name is not None else self.UNSET
58 self.sha256 = sha256
59
60 + # references to objects that "own" (use, ...) this distfile
61 + self.backrefs = set()
62 + self.add_backref = self.backrefs.add
63 +
64 if repo_file == self.RESTORE_FROM_DISTFILE:
65 self.repo_file = distfile
66 else:
67 self.repo_file = repo_file if repo_file is not None else self.UNSET
68 # --- end of __init__ (...) ---
69
70 + #def add_backref ( self, ref ): self.backrefs.add ( ref )
71 +
72 + def has_backref_to ( self, obj ):
73 + return any ( ( ref.deref_unsafe() is obj ) for ref in self.backrefs )
74 + # --- end of has_backref_to (...) ---
75 +
76 + def has_backrefs ( self ):
77 + return bool ( self.backrefs )
78 + # --- end of has_backrefs (...) ---
79 +
80 @property
81 def digest ( self ):
82 return self.sha256
83 @@ -139,16 +161,16 @@ def get_distmap ( distmap_file, distmap_compression, ignore_missing=False ):
84 class _DistMapBase ( object ):
85
86 # { attr[, as_attr] }
87 - DISTMAP_BIND_ATTR = frozenset ({ 'get', 'keys', 'items', 'values', })
88 -
89 - class AbstractMethod ( NotImplementedError ):
90 - pass
91 - # --- end of AbstractMethod ---
92 + DISTMAP_BIND_ATTR = frozenset ({
93 + 'get', 'keys', 'items', 'values', ( 'get', 'get_entry' ),
94 + })
95
96 def __init__ ( self ):
97 super ( _DistMapBase, self ).__init__()
98 + self.logger = logging.getLogger ( self.__class__.__name__ )
99 self.dirty = False
100 self._distmap = dict()
101 +
102 self.stats = roverlay.stats.collector.static.distmap
103
104 self._rebind_distmap()
105 @@ -202,9 +224,33 @@ class _DistMapBase ( object ):
106 if isinstance ( attr, str ):
107 setattr ( self, attr, getattr ( self._distmap, attr ) )
108 else:
109 - setattr ( self, attr [1], getattr ( self._distmap, attr[0] ) )
110 + setattr ( self, attr[1], getattr ( self._distmap, attr[0] ) )
111 # --- end of _rebind_distmap (...) ---
112
113 + def add_distfile_owner ( self, backref, distfile, distfilepath=None ):
114 + entry = self.get_entry ( distfile )
115 + if entry is not None:
116 + entry.add_backref ( backref )
117 + else:
118 + new_entry = self.add_dummy_entry (
119 + distfile, distfilepath=distfilepath, log_level=True
120 + )
121 + # ^ raises: ? if distfile is missing
122 + new_entry.add_backref ( backref )
123 + # --- end of add_distfile_owner (...) ---
124 +
125 + def get_distfile_slot ( self, backref, distfile ):
126 + entry = self.get_entry ( distfile )
127 + if entry is None:
128 + raise NotImplementedError ( "backref gets new 'slot'." )
129 + return 1
130 + elif entry.has_backref_to ( backref.deref_safe() ):
131 + return 2
132 + else:
133 + raise NotImplementedError ( "handle file collision." )
134 + return 0
135 + # --- end of get_distfile_slot (...) ---
136 +
137 def check_revbump_necessary ( self, package_info ):
138 """Tries to find package_info's distfile in the distmap and returns
139 whether a revbump is necessary (True) or not (False).
140 @@ -351,6 +397,8 @@ class _DistMapBase ( object ):
141 arguments:
142 * distfile -- distfile path relative to the distroot
143 * distmap_info -- distmap entry
144 +
145 + Returns: distmap_info
146 """
147 if self.update_only:
148 entry = self._distmap.get ( distfile, None )
149 @@ -362,7 +410,7 @@ class _DistMapBase ( object ):
150 self._distmap [distfile] = distmap_info
151 self._file_added ( distfile )
152
153 - return True
154 + return distmap_info
155 # --- end of add_entry (...) ---
156
157 def add_entry_for ( self, p_info ):
158 @@ -370,14 +418,16 @@ class _DistMapBase ( object ):
159
160 arguments:
161 * p_info --
162 +
163 + Returns: created entry
164 """
165 - key = p_info.get_distmap_key()
166 - return self.add_entry (
167 - key, DistMapInfo ( key, *p_info.get_distmap_value() )
168 - )
169 + key, value = DistMapInfo.from_package_info ( p_info )
170 + return self.add_entry ( key, value )
171 # --- end of add_entry_for (...) ---
172
173 - def add_dummy_entry ( self, distfile, distfilepath=None, hashdict=None ):
174 + def add_dummy_entry (
175 + self, distfile, distfilepath=None, hashdict=None, log_level=None
176 + ):
177 """Adds a dummy entry.
178 Such an entry contains a checksum and a distfile, but no information
179 about its origin (repo name/file).
180 @@ -386,7 +436,18 @@ class _DistMapBase ( object ):
181 * distfile -- distfile path relative to the distroot
182 * distfilepath -- absolute path to the distfile
183 * hashdict -- dict with already calculated hashes
184 + * log_level -- if not None: log entry creation with the given log
185 + level (or INFO if log_level is True)
186 +
187 + Returns: created entry
188 """
189 + if log_level is None or log_level is False:
190 + pass
191 + elif log_level is True:
192 + self.logger.info ( "adding dummy entry for " + distfile )
193 + else:
194 + self.logger.log ( log_level, "adding dummy entry for " + distfile )
195 +
196 if hashdict and DistMapInfo.DIGEST_TYPE in hashdict:
197 digest = hashdict [DistMapInfo.DIGEST_TYPE]
198 else:
199 @@ -523,15 +584,17 @@ class _FileDistMapBase ( _DistMapBase ):
200 return False
201 # --- end of _read_header (...) ---
202
203 + @roverlay.util.objects.abstractmethod
204 def read ( self, filepath=None ):
205 """Reads the distmap.
206
207 arguments:
208 * filepath -- path to the distmap file (defaults to self.dbfile)
209 """
210 - raise self.__class__.AbstractMethod()
211 + pass
212 # --- end of read (...) ---
213
214 + @roverlay.util.objects.abstractmethod
215 def write ( self, filepath=None, force=False ):
216 """Writes the distmap.
217
218 @@ -539,7 +602,7 @@ class _FileDistMapBase ( _DistMapBase ):
219 * filepath -- path to the distmap file (defaults to self.dbfile)
220 * force -- enforce writing even if distmap not modified
221 """
222 - raise self.__class__.AbstractMethod()
223 + pass
224 # --- end of write (...) ---
225
226 # --- end of _FileDistMapBase ---