1
2 '''
3 # DESCRIPTION:
4 # Entropy Object Oriented Interface
5
6 Copyright (C) 2007-2009 Fabio Erculiani
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 '''
22 from __future__ import with_statement
23 from entropy.misc import Lifo
24 from entropy.const import *
25 from entropy.exceptions import *
26 from entropy.output import bold, darkgreen, darkred, blue, red
27 from entropy.i18n import _
28
30
32
33 if dbconn == None:
34 dbconn = self.clientDbconn
35
36 installed_packages = dbconn.listAllIdpackages()
37
38 pdepend_id = etpConst['spm']['pdepend_id']
39 deps_not_matched = set()
40
41 length = len(installed_packages)
42 count = 0
43 for idpackage in installed_packages:
44 count += 1
45
46 if (count%150 == 0) or (count == length) or (count == 1):
47 atom = dbconn.retrieveAtom(idpackage)
48 self.updateProgress(
49 darkgreen(_("Checking %s") % (bold(atom),)),
50 importance = 0,
51 type = "info",
52 back = True,
53 count = (count,length),
54 header = darkred(" @@ ")
55 )
56
57 xdeps = dbconn.retrieveDependencies(idpackage,
58 exclude_deptypes = (pdepend_id,))
59 needed_deps = [(x,dbconn.atomMatch(x),) for x in xdeps]
60 deps_not_matched |= set([x for x,(y,z,) in needed_deps if y == -1])
61
62 return deps_not_matched
63
79
81
82 packageInformation = {}
83 versionInformation = {}
84
85
86 tbz2repos = [x for x in results if x.endswith(etpConst['packagesext'])]
87 if tbz2repos:
88 del tbz2repos
89 newrepos = results.copy()
90 for x in newrepos:
91 if x.endswith(etpConst['packagesext']):
92 continue
93 del results[x]
94
95 version_duplicates = set()
96 versions = set()
97 for repo in results:
98 packageInformation[repo] = {}
99 if extended_results:
100 version = results[repo][1]
101 packageInformation[repo]['versiontag'] = results[repo][2]
102 packageInformation[repo]['revision'] = results[repo][3]
103 else:
104 dbconn = self.__atom_match_open_db(repo, server_inst)
105 packageInformation[repo]['versiontag'] = dbconn.retrieveVersionTag(results[repo])
106 packageInformation[repo]['revision'] = dbconn.retrieveRevision(results[repo])
107 version = dbconn.retrieveVersion(results[repo])
108 packageInformation[repo]['version'] = version
109 versionInformation[version] = repo
110 if version in versions:
111 version_duplicates.add(version)
112 versions.add(version)
113
114 newerVersion = self.entropyTools.get_newer_version(list(versions))[0]
115
116 if (not version_duplicates) or (newerVersion not in version_duplicates):
117 reponame = versionInformation.get(newerVersion)
118 return (results[reponame],reponame)
119
120
121
122
123 conflictingEntries = {}
124 tags_duplicates = set()
125 tags = set()
126 tagsInfo = {}
127 for repo in packageInformation:
128 if packageInformation[repo]['version'] != newerVersion:
129 continue
130 conflictingEntries[repo] = {}
131 versiontag = packageInformation[repo]['versiontag']
132 if versiontag in tags:
133 tags_duplicates.add(versiontag)
134 tags.add(versiontag)
135 tagsInfo[versiontag] = repo
136 conflictingEntries[repo]['versiontag'] = versiontag
137 conflictingEntries[repo]['revision'] = packageInformation[repo]['revision']
138
139
140 newerTag = sorted(list(tags), reverse = True)[0]
141 if newerTag not in tags_duplicates:
142 reponame = tagsInfo.get(newerTag)
143 return (results[reponame],reponame)
144
145
146
147
148 conflictingRevisions = {}
149 revisions = set()
150 revisions_duplicates = set()
151 revisionInfo = {}
152 for repo in conflictingEntries:
153 if conflictingEntries[repo]['versiontag'] == newerTag:
154 conflictingRevisions[repo] = {}
155 versionrev = conflictingEntries[repo]['revision']
156 if versionrev in revisions:
157 revisions_duplicates.add(versionrev)
158 revisions.add(versionrev)
159 revisionInfo[versionrev] = repo
160 conflictingRevisions[repo]['revision'] = versionrev
161
162 newerRevision = max(revisions)
163 if newerRevision not in revisions_duplicates:
164 reponame = revisionInfo.get(newerRevision)
165 return (results[reponame],reponame)
166
167
168
169
170 for reponame in valid_repos:
171 if reponame in conflictingRevisions:
172 return (results[reponame],reponame)
173
175
176 data, rc = cached_obj
177 if rc == 1: return cached_obj
178
179 if multiRepo or multiMatch:
180 matches = data
181 if extendedResults:
182
183 matches = [(x[0][0],x[1],) for x in data]
184 for m_id, m_repo in matches:
185 m_db = self.__atom_match_open_db(m_repo, server_inst)
186 if not m_db.isIDPackageAvailable(m_id): return None
187 else:
188 m_id, m_repo = cached_obj
189 if extendedResults:
190
191 m_id, m_repo = cached_obj[0][0],cached_obj[1]
192 m_db = self.__atom_match_open_db(m_repo, server_inst)
193 if not m_db.isIDPackageAvailable(m_id): return None
194
195 return cached_obj
196
198 if server_inst != None:
199 dbconn = server_inst.open_server_repository(just_reading = True,
200 repo = repoid, do_treeupdates = False)
201 else:
202 dbconn = self.open_repository(repoid)
203 return dbconn
204
205 - def atom_match(self, atom, caseSensitive = True, matchSlot = None,
206 matchBranches = (), matchTag = None, packagesFilter = True,
207 multiMatch = False, multiRepo = False, matchRevision = None,
208 matchRepo = None, server_repos = [], serverInstance = None,
209 extendedResults = False, useCache = True):
210
211
212
213 atom, repos = self.entropyTools.dep_get_match_in_repos(atom)
214 if (matchRepo == None) and (repos != None):
215 matchRepo = repos
216
217 u_hash = ""
218 m_hash = ""
219 k_ms = "//"
220 k_mt = "@#@"
221 k_mr = "-1"
222 if isinstance(matchRepo,(list,tuple,set,)): u_hash = hash(frozenset(matchRepo))
223 if isinstance(matchBranches,(list,tuple,set,)): m_hash = hash(frozenset(matchBranches))
224 if isinstance(matchSlot,basestring): k_ms = matchSlot
225 if isinstance(matchTag,basestring): k_mt = matchTag
226 if isinstance(matchRevision,basestring): k_mr = matchRevision
227
228 c_hash = "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s" % (
229 atom,k_ms,k_mt,hash(packagesFilter),
230 hash(frozenset(self.validRepositories)),
231 hash(frozenset(self.SystemSettings['repositories']['available'])),
232 hash(multiMatch),hash(multiRepo),hash(caseSensitive),
233 k_mr,hash(extendedResults),
234 u_hash, m_hash
235 )
236 c_hash = "%s%s" % (self.atomMatchCacheKey,hash(c_hash),)
237
238 if self.xcache and useCache:
239 cached = self.Cacher.pop(c_hash)
240 if cached != None:
241 try:
242 cached = self.__validate_atom_match_cache(cached, multiMatch, extendedResults, multiRepo, serverInstance)
243 except (TypeError,ValueError,IndexError,KeyError,):
244 cached = None
245 if cached != None:
246 return cached
247
248 if server_repos:
249 if not serverInstance:
250 t = _("server_repos needs serverInstance")
251 raise IncorrectParameter("IncorrectParameter: %s" % (t,))
252 valid_repos = server_repos[:]
253 else:
254 valid_repos = self.validRepositories
255 if matchRepo and (type(matchRepo) in (list,tuple,set)):
256 valid_repos = list(matchRepo)
257
258 repoResults = {}
259 for repo in valid_repos:
260
261
262 dbconn = self.__atom_match_open_db(repo, serverInstance)
263 use_cache = useCache
264 while 1:
265 try:
266 query_data, query_rc = dbconn.atomMatch(
267 atom,
268 caseSensitive = caseSensitive,
269 matchSlot = matchSlot,
270 matchBranches = matchBranches,
271 matchTag = matchTag,
272 packagesFilter = packagesFilter,
273 matchRevision = matchRevision,
274 extendedResults = extendedResults,
275 useCache = use_cache
276 )
277 if query_rc == 0:
278
279 if extendedResults:
280 repoResults[repo] = (query_data[0],query_data[2],query_data[3],query_data[4])
281 else:
282 repoResults[repo] = query_data
283 except TypeError:
284 if not use_cache:
285 raise
286 use_cache = False
287 continue
288 break
289
290 dbpkginfo = (-1,1)
291 if extendedResults:
292 dbpkginfo = ((-1,None,None,None),1)
293
294 if multiRepo and repoResults:
295
296 data = set()
297 for repoid in repoResults:
298 data.add((repoResults[repoid],repoid))
299 dbpkginfo = (data,0)
300
301 elif len(repoResults) == 1:
302
303 repo = repoResults.keys()[0]
304 dbpkginfo = (repoResults[repo],repo)
305
306 elif len(repoResults) > 1:
307
308
309 mypkginfo = self.__handle_multi_repo_matches(repoResults, extendedResults, valid_repos, serverInstance)
310 if mypkginfo != None: dbpkginfo = mypkginfo
311
312
313 if multiMatch:
314
315 if dbpkginfo[1] == 1:
316 dbpkginfo = (set(), 1)
317 else:
318 if multiRepo:
319 data = set()
320 for q_id,q_repo in dbpkginfo[0]:
321 dbconn = self.__atom_match_open_db(q_repo, serverInstance)
322 query_data, query_rc = dbconn.atomMatch(
323 atom,
324 caseSensitive = caseSensitive,
325 matchSlot = matchSlot,
326 matchBranches = matchBranches,
327 matchTag = matchTag,
328 packagesFilter = packagesFilter,
329 multiMatch = True,
330 extendedResults = extendedResults
331 )
332 if extendedResults:
333 for item in query_data:
334 data.add(((item[0],item[2],item[3],item[4]),q_repo))
335 else:
336 for x in query_data: data.add((x,q_repo))
337 dbpkginfo = (data,0)
338 else:
339 dbconn = self.__atom_match_open_db(dbpkginfo[1], serverInstance)
340 query_data, query_rc = dbconn.atomMatch(
341 atom,
342 caseSensitive = caseSensitive,
343 matchSlot = matchSlot,
344 matchBranches = matchBranches,
345 matchTag = matchTag,
346 packagesFilter = packagesFilter,
347 multiMatch = True,
348 extendedResults = extendedResults
349 )
350 if extendedResults:
351 dbpkginfo = (set([((x[0],x[2],x[3],x[4]),dbpkginfo[1]) for x in query_data]),0)
352 else:
353 dbpkginfo = (set([(x,dbpkginfo[1]) for x in query_data]),0)
354
355 if self.xcache and useCache:
356 self.Cacher.push(c_hash,dbpkginfo)
357
358 return dbpkginfo
359
360
362 new_packages = []
363
364 for pkg_id in range(len(packages)):
365 package = packages[pkg_id]
366
367
368 if package.startswith(etpConst['packagesetprefix']):
369 set_pkgs = sorted(list(self.package_set_expand(package, raise_exceptions = False)))
370 new_packages.extend([x for x in set_pkgs if x not in packages])
371 else:
372 new_packages.append(package)
373
374 return new_packages
375
377
378 max_recursion_level = 50
379 recursion_level = 0
380
381 def do_expand(myset, recursion_level, max_recursion_level):
382 recursion_level += 1
383 if recursion_level > max_recursion_level:
384 raise InvalidPackageSet('InvalidPackageSet: corrupted, too many recursions: %s' % (myset,))
385 set_data, set_rc = self.package_set_match(myset[len(etpConst['packagesetprefix']):])
386 if not set_rc:
387 raise InvalidPackageSet('InvalidPackageSet: not found: %s' % (myset,))
388 (set_from, package_set, mydata,) = set_data
389
390 mypkgs = set()
391 for fset in mydata:
392 if fset.startswith(etpConst['packagesetprefix']):
393 mypkgs |= do_expand(fset, recursion_level, max_recursion_level)
394 else:
395 mypkgs.add(fset)
396
397 return mypkgs
398
399 if not package_set.startswith(etpConst['packagesetprefix']):
400 package_set = "%s%s" % (etpConst['packagesetprefix'],package_set,)
401
402 try:
403 mylist = do_expand(package_set, recursion_level, max_recursion_level)
404 except InvalidPackageSet:
405 if raise_exceptions: raise
406 mylist = set()
407
408 return mylist
409
410 - def package_set_list(self, server_repos = [], serverInstance = None, matchRepo = None):
411 return self.package_set_match('', matchRepo = matchRepo, server_repos = server_repos, serverInstance = serverInstance, search = True)[0]
412
413 - def package_set_search(self, package_set, server_repos = [], serverInstance = None, matchRepo = None):
414
415 if package_set == '*': package_set = ''
416 return self.package_set_match(package_set, matchRepo = matchRepo, server_repos = server_repos, serverInstance = serverInstance, search = True)[0]
417
424
425 - def package_set_match(self, package_set, multiMatch = False, matchRepo = None, server_repos = [], serverInstance = None, search = False):
426
427
428
429 package_set, repos = self.entropyTools.dep_get_match_in_repos(package_set)
430 if (matchRepo == None) and (repos != None):
431 matchRepo = repos
432
433 if server_repos:
434 if not serverInstance:
435 t = _("server_repos needs serverInstance")
436 raise IncorrectParameter("IncorrectParameter: %s" % (t,))
437 valid_repos = server_repos[:]
438 else:
439 valid_repos = self.validRepositories
440
441 if matchRepo and (type(matchRepo) in (list,tuple,set)):
442 valid_repos = list(matchRepo)
443
444
445 if search: multiMatch = True
446
447 set_data = []
448
449 while 1:
450
451
452 if not server_repos:
453 if search:
454 mysets = [x for x in self.SystemSettings['system_package_sets'].keys() if (x.find(package_set) != -1)]
455 for myset in mysets:
456 mydata = self.SystemSettings['system_package_sets'].get(myset)
457 set_data.append((etpConst['userpackagesetsid'], unicode(myset), mydata.copy(),))
458 else:
459 mydata = self.SystemSettings['system_package_sets'].get(package_set)
460 if mydata != None:
461 set_data.append((etpConst['userpackagesetsid'], unicode(package_set), mydata,))
462 if not multiMatch: break
463
464 for repoid in valid_repos:
465 dbconn = self.__package_set_match_open_db(repoid, serverInstance)
466 if search:
467 mysets = dbconn.searchSets(package_set)
468 for myset in mysets:
469 mydata = dbconn.retrievePackageSet(myset)
470 set_data.append((repoid, myset, mydata.copy(),))
471 else:
472 mydata = dbconn.retrievePackageSet(package_set)
473 if mydata: set_data.append((repoid, package_set, mydata,))
474 if not multiMatch: break
475
476 break
477
478 if not set_data: return (),False
479 if multiMatch: return set_data,True
480 return set_data.pop(0),True
481
483
484 if self.xcache:
485 c_data = sorted(dependencies)
486 client_checksum = self.clientDbconn.database_checksum()
487 c_hash = hash("%s|%s|%s" % (c_data,deep_deps,client_checksum,))
488 c_hash = "%s%s" % (etpCache['filter_satisfied_deps'],c_hash,)
489 cached = self.Cacher.pop(c_hash)
490 if cached != None: return cached
491
492 const_debug_write(__name__,
493 "get_unsatisfied_dependencies (not cached, deep: %s) for => %s" % (
494 deep_deps, dependencies,))
495
496 if not isinstance(depcache,dict):
497 depcache = {}
498
499
500
501 satisfied_kw = '__%s__satisfied_ids' % (__name__,)
502 satisfied_data = self.SystemSettings.get(satisfied_kw)
503 if satisfied_data is None:
504 satisfied_list = self.SystemSettings['satisfied']
505 tmp_satisfied_data = set()
506 for atom in satisfied_list:
507 matches, m_res = self.atom_match(atom, multiMatch = True,
508 packagesFilter = False, multiRepo = True)
509 if m_res == 0:
510 tmp_satisfied_data |= matches
511 satisfied_data = tmp_satisfied_data
512 self.SystemSettings[satisfied_kw] = satisfied_data
513
514 cdb_am = self.clientDbconn.atomMatch
515 am = self.atom_match
516 open_repo = self.open_repository
517 intf_error = self.dbapi2.InterfaceError
518 cdb_getversioning = self.clientDbconn.getVersioningData
519 etp_cmp = self.entropyTools.entropy_compare_versions
520 etp_get_rev = self.entropyTools.dep_get_entropy_revision
521
522 def fm_dep(dependency):
523
524 cached = depcache.get(dependency)
525 if cached != None:
526 const_debug_write(__name__,
527 "get_unsatisfied_dependencies control cached for => %s" % (
528 dependency,))
529 const_debug_write(__name__, "...")
530 return cached
531
532
533 if dependency.startswith("!"):
534 idpackage,rc = cdb_am(dependency[1:])
535 if idpackage != -1:
536 depcache[dependency] = dependency
537 const_debug_write(__name__,
538 "get_unsatisfied_dependencies conflict not found on system for => %s" % (
539 dependency,))
540 const_debug_write(__name__, "...")
541 return dependency
542 depcache[dependency] = 0
543 const_debug_write(__name__, "...")
544 return 0
545
546 c_ids, c_rc = cdb_am(dependency, multiMatch = True)
547 if c_rc != 0:
548 depcache[dependency] = dependency
549 const_debug_write(__name__,
550 "get_unsatisfied_dependencies not satisfied on system for => %s" % (
551 dependency,))
552 const_debug_write(__name__, "...")
553 return dependency
554
555 r_id, r_repo = am(dependency)
556 if r_id == -1:
557 depcache[dependency] = dependency
558 const_debug_write(__name__,
559 "get_unsatisfied_dependencies repository match not found for => %s" % (
560 dependency,))
561 const_debug_write(__name__, "...")
562 return dependency
563
564
565
566 if (r_id, r_repo,) in satisfied_data:
567 return 0
568
569 dbconn = open_repo(r_repo)
570 try:
571 repo_pkgver, repo_pkgtag, repo_pkgrev = dbconn.getVersioningData(r_id)
572 except (intf_error,TypeError,):
573
574 const_debug_write(__name__,
575 "get_unsatisfied_dependencies repository entry broken for match => %s" % (
576 (r_id, r_repo),))
577 const_debug_write(__name__, "...")
578 return dependency
579
580 client_data = set()
581 for c_id in c_ids:
582 try:
583 installedVer, installedTag, installedRev = cdb_getversioning(c_id)
584 except TypeError:
585 installedVer = "0"
586 installedTag = ''
587 installedRev = 0
588 client_data.add((installedVer, installedTag, installedRev,))
589
590
591
592 do_deep = deep_deps
593 if not do_deep:
594 string_rev = etp_get_rev(dependency)
595 if string_rev == -1:
596 do_deep = True
597
598
599
600 for installedVer, installedTag, installedRev in client_data:
601 vcmp = etp_cmp((repo_pkgver,repo_pkgtag,repo_pkgrev,),
602 (installedVer,installedTag,installedRev,))
603 if vcmp == 0:
604 const_debug_write(__name__,
605 "get_unsatisfied_dependencies SATISFIED equals (not cached, deep: %s) => %s" % (
606 deep_deps, dependency,))
607 depcache[dependency] = 0
608 const_debug_write(__name__, "...")
609 return 0
610 ver_tag_repo = (repo_pkgver, repo_pkgtag,)
611 ver_tag_inst = (installedVer, installedTag,)
612 rev_match = repo_pkgrev != installedRev
613
614 if not do_deep and (ver_tag_repo == ver_tag_inst) and rev_match:
615
616 depcache[dependency] = 0
617 const_debug_write(__name__,
618 "get_unsatisfied_dependencies SATISFIED w/o rev (not cached, deep: %s) => %s" % (
619 deep_deps, dependency,))
620 const_debug_write(__name__, "...")
621 return 0
622
623
624 const_debug_write(__name__,
625 "get_unsatisfied_dependencies NOT SATISFIED (not cached, deep: %s) => %s" % (
626 deep_deps, dependency,))
627
628 depcache[dependency] = dependency
629 const_debug_write(__name__, "...")
630 return dependency
631
632 unsatisfied = map(fm_dep,dependencies)
633 unsatisfied = set([x for x in unsatisfied if x != 0])
634
635 if self.xcache:
636 self.Cacher.push(c_hash,unsatisfied)
637
638 return unsatisfied
639
641
642 if not isinstance(matchfilter,set):
643 matchfilter = set()
644
645 maskedtree = {}
646 mybuffer = Lifo()
647 depcache = set()
648 treelevel = -1
649
650 match_id, match_repo = match
651
652 mydbconn = self.open_repository(match_repo)
653 myatom = mydbconn.retrieveAtom(match_id)
654 idpackage, idreason = mydbconn.idpackageValidator(match_id)
655 if idpackage == -1:
656 treelevel += 1
657 if atoms:
658 mydict = {myatom: idreason,}
659 else:
660 mydict = {match: idreason,}
661 if flat:
662 maskedtree.update(mydict)
663 else:
664 maskedtree[treelevel] = mydict
665
666 mydeps = mydbconn.retrieveDependencies(match_id)
667 for mydep in mydeps: mybuffer.push(mydep)
668 mydep = mybuffer.pop()
669
670 open_db = self.open_repository
671 am = self.atom_match
672 while mydep:
673
674 if mydep in depcache:
675 mydep = mybuffer.pop()
676 continue
677 depcache.add(mydep)
678
679 idpackage, repoid = am(mydep)
680 if (idpackage, repoid) in matchfilter:
681 mydep = mybuffer.pop()
682 continue
683
684 if idpackage != -1:
685
686
687 matchfilter.add((idpackage, repoid))
688
689
690 if idpackage == -1:
691 idpackage, repoid = am(mydep, packagesFilter = False)
692 if idpackage != -1:
693 treelevel += 1
694 if not maskedtree.has_key(treelevel) and not flat:
695 maskedtree[treelevel] = {}
696 dbconn = open_db(repoid)
697 vidpackage, idreason = dbconn.idpackageValidator(idpackage)
698 if atoms:
699 mydict = {dbconn.retrieveAtom(idpackage): idreason}
700 else:
701 mydict = {(idpackage,repoid): idreason}
702 if flat: maskedtree.update(mydict)
703 else: maskedtree[treelevel].update(mydict)
704
705
706 if idpackage != -1:
707 matchfilter.add((idpackage, repoid))
708 dbconn = open_db(repoid)
709 owndeps = dbconn.retrieveDependencies(idpackage)
710 for owndep in owndeps:
711 mybuffer.push(owndep)
712
713 mydep = mybuffer.pop()
714
715 return maskedtree
716
717
718 - def generate_dependency_tree(self,
719 matched_atom, empty_deps = False, deep_deps = False, matchfilter = None,
720 flat = False, filter_unsat_cache = None, treecache = None, keyslotcache = None):
721
722 if not isinstance(matchfilter,set):
723 matchfilter = set()
724 if not isinstance(filter_unsat_cache,dict):
725 filter_unsat_cache = {}
726 if not isinstance(treecache,set):
727 treecache = set()
728 if not isinstance(keyslotcache,set):
729 keyslotcache = set()
730
731 mydbconn = self.open_repository(matched_atom[1])
732 myatom = mydbconn.retrieveAtom(matched_atom[0])
733
734
735
736 deps_not_found = set()
737 conflicts = set()
738
739 mydep = (1,myatom)
740 mybuffer = Lifo()
741 deptree = set()
742 if matched_atom not in matchfilter:
743 deptree.add((1,matched_atom))
744
745 virgin = True
746 open_repo = self.open_repository
747 atom_match = self.atom_match
748 cdb_atom_match = self.clientDbconn.atomMatch
749 lookup_conflict_replacement = self._lookup_conflict_replacement
750 lookup_library_breakages = self._lookup_library_breakages
751 lookup_inverse_dependencies = self._lookup_inverse_dependencies
752 get_unsatisfied_deps = self.get_unsatisfied_dependencies
753
754 def my_dep_filter(x):
755 if x in treecache: return False
756 if tuple(x.split(":")) in keyslotcache: return False
757 return True
758
759 while mydep:
760
761 const_debug_write(__name__,
762 "generate_dependency_tree analyzing => %s" % (
763 mydep,))
764
765 dep_level, dep_atom = mydep
766
767
768 if dep_atom in treecache:
769 const_debug_write(__name__,
770 "generate_dependency_tree already in treecache => %s" % (
771 dep_atom,))
772 mydep = mybuffer.pop()
773 const_debug_write(__name__, "---")
774 continue
775 treecache.add(dep_atom)
776
777 if dep_atom is None:
778 const_debug_write(__name__,
779 "generate_dependency_tree broken entry in DB => %s" % (
780 mydep,))
781 mydep = mybuffer.pop()
782 const_debug_write(__name__, "---")
783 continue
784
785
786 if dep_atom[0] == "!":
787 c_idpackage, xst = cdb_atom_match(dep_atom[1:])
788 if c_idpackage != -1:
789 myreplacement = lookup_conflict_replacement(dep_atom[1:],
790 c_idpackage, deep_deps = deep_deps)
791
792 const_debug_write(__name__,
793 "generate_dependency_tree conflict replacement => %s" % (
794 myreplacement,))
795
796 if (myreplacement != None) and (myreplacement not in treecache):
797 mybuffer.push((dep_level+1,myreplacement))
798 else:
799 conflicts.add(c_idpackage)
800 mydep = mybuffer.pop()
801 const_debug_write(__name__, "---")
802 continue
803
804
805 if virgin:
806
807 virgin = False
808 m_idpackage, m_repo = matched_atom
809 dbconn = open_repo(m_repo)
810 myidpackage, idreason = dbconn.idpackageValidator(m_idpackage)
811
812 const_debug_write(__name__,
813 "generate_dependency_tree virgin match masked? => %s - %s" % (
814 myidpackage, idreason,))
815
816 if myidpackage == -1:
817 m_idpackage = -1
818
819 else:
820 m_idpackage, m_repo = atom_match(dep_atom)
821 const_debug_write(__name__,
822 "generate_dependency_tree matching %s => (%s, %s)" % (
823 dep_atom, m_idpackage, m_repo,))
824
825 if m_idpackage == -1:
826
827 const_debug_write(__name__,
828 "generate_dependency_tree dep not found => %s" % (
829 dep_atom,))
830
831 deps_not_found.add(dep_atom)
832 mydep = mybuffer.pop()
833 const_debug_write(__name__, "---")
834 continue
835
836
837 matchdb = open_repo(m_repo)
838 matchatom = matchdb.retrieveAtom(m_idpackage)
839 matchkey, matchslot = matchdb.retrieveKeySlot(m_idpackage)
840
841 const_debug_write(__name__,
842 "generate_dependency_tree idpackage %s => %s - %s:%s" % (
843 m_idpackage, matchatom, matchkey, matchslot))
844
845 if (dep_atom != matchatom) and (matchatom in treecache):
846 mydep = mybuffer.pop()
847 const_debug_write(__name__,
848 "generate_dependency_tree matchatom %s already in cache" % (
849 matchatom,))
850 const_debug_write(__name__, "---")
851 continue
852
853 treecache.add(matchatom)
854
855 const_debug_write(__name__,
856 "generate_dependency_tree check if key + slot cache => %s" % (
857 (matchslot, matchkey),))
858
859
860 if (matchslot, matchkey) in keyslotcache:
861 mydep = mybuffer.pop()
862 const_debug_write(__name__, "---")
863 continue
864 else:
865 keyslotcache.add((matchslot, matchkey))
866
867 const_debug_write(__name__,
868 "generate_dependency_tree not in key + slot cache => %s" % (
869 (matchslot, matchkey),))
870
871 match = (m_idpackage, m_repo,)
872
873 if match in matchfilter:
874 mydep = mybuffer.pop()
875 const_debug_write(__name__, "---")
876 continue
877
878 const_debug_write(__name__,
879 "generate_dependency_tree match NOT already analyzed => %s" % (
880 match,))
881
882
883 matchfilter.add(match)
884 treedepth = dep_level+1
885 deptree.add((dep_level,match))
886
887
888 cm_idpackage, cm_result = cdb_atom_match(matchkey,
889 matchSlot = matchslot)
890 if cm_idpackage != -1:
891
892 broken_atoms = lookup_library_breakages(match,
893 (cm_idpackage, cm_result,), deep_deps = deep_deps)
894 const_debug_write(__name__,
895 "generate_dependency_tree lib broken atoms for %s => %s" % (
896 matchkey+":"+matchslot, broken_atoms,))
897
898 inverse_deps = lookup_inverse_dependencies(match,
899 (cm_idpackage, cm_result,))
900 const_debug_write(__name__,
901 "generate_dependency_tree inverse deps for %s => %s" % (
902 matchkey+":"+matchslot, inverse_deps,))
903
904 if inverse_deps:
905 deptree.remove((dep_level,match))
906 for ikey,islot in inverse_deps:
907 iks_str = '%s:%s' % (ikey,islot,)
908 if ((ikey,islot) not in keyslotcache) and (iks_str not in treecache):
909 mybuffer.push((dep_level,iks_str))
910 keyslotcache.add((ikey,islot))
911 deptree.add((treedepth,match))
912 treedepth += 1
913
914 for x in broken_atoms:
915 if (tuple(x.split(":")) not in keyslotcache) and (x not in treecache):
916 mybuffer.push((treedepth,x))
917
918 m_deplist = matchdb.retrieveDependenciesList(m_idpackage)
919
920 const_debug_write(__name__,
921 "generate_dependency_tree dependency list for %s => %s" % (
922 m_idpackage, m_deplist,))
923
924 myundeps = filter(my_dep_filter, m_deplist)
925
926 const_debug_write(__name__,
927 "generate_dependency_tree filtered dependency list => %s" % (
928 myundeps,))
929
930 if not empty_deps:
931
932 m_unsat_deplist = get_unsatisfied_deps(myundeps, deep_deps,
933 depcache = filter_unsat_cache)
934
935 const_debug_write(__name__,
936 "generate_dependency_tree unsatisfied dependencies (deep: %s) => %s" % (
937 deep_deps, m_unsat_deplist,))
938
939 myundeps = filter(my_dep_filter, m_unsat_deplist)
940
941 const_debug_write(__name__,
942 "generate_dependency_tree filtered UNSATISFIED dependencies => %s" % (
943 myundeps,))
944
945
946 if myundeps:
947
948 post_deps = [x for x in \
949 matchdb.retrievePostDependencies(m_idpackage) if x \
950 in myundeps]
951
952 const_debug_write(__name__,
953 "generate_dependency_tree POST dependencies => %s" % (
954 post_deps,))
955
956 if post_deps:
957
958
959
960 myundeps = [x for x in myundeps if x not in post_deps]
961
962 const_debug_write(__name__,
963 "generate_dependency_tree POST dependencies ADDED => %s" % (
964 myundeps,))
965
966 for x in post_deps:
967 mybuffer.push((-1, x))
968
969 for x in myundeps:
970 mybuffer.push((treedepth, x))
971
972 mydep = mybuffer.pop()
973 const_debug_write(__name__, "---")
974
975 if deps_not_found:
976 return list(deps_not_found),-2
977
978 if flat: return [x[1] for x in deptree],0
979
980 newdeptree = {}
981 for key, item in deptree:
982 if key >= 0:
983
984 key += 1
985 obj = newdeptree.setdefault(key, set())
986 obj.add(item)
987
988 newdeptree[0] = conflicts
989
990 return newdeptree,0
991
992
994
995 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
996 data = client_settings['repositories']['system_mask']
997
998 if not data:
999 return []
1000 mydata = []
1001 cached_items = set()
1002 for atom in data:
1003 mymatch = self.atom_match(atom)
1004 if mymatch[0] == -1:
1005 continue
1006 if mymatch in cached_items:
1007 continue
1008 if mymatch not in mydata:
1009
1010 myaction = self.get_package_action(mymatch)
1011
1012 if myaction == 1: mydata.append(mymatch)
1013 cached_items.add(mymatch)
1014 return mydata
1015
1017 if self.entropyTools.isjustname(conflict_atom):
1018 return None
1019 conflict_match = self.atom_match(conflict_atom)
1020 mykey, myslot = self.clientDbconn.retrieveKeySlot(client_idpackage)
1021 new_match = self.atom_match(mykey, matchSlot = myslot)
1022 if (conflict_match == new_match) or (new_match[1] == 1):
1023 return None
1024 action = self.get_package_action(new_match)
1025 if (action == 0) and (not deep_deps):
1026 return None
1027 return "%s:%s" % (mykey,myslot,)
1028
1030
1031 cmpstat = self.get_package_action(match)
1032 if cmpstat == 0: return set()
1033
1034 keyslots = set()
1035 mydepends = self.clientDbconn.retrieveDepends(clientmatch[0])
1036 am = self.atom_match
1037 cdb_rdeps = self.clientDbconn.retrieveDependencies
1038 cdb_rks = self.clientDbconn.retrieveKeySlot
1039 gpa = self.get_package_action
1040 keyslots_cache = set()
1041 match_cache = {}
1042
1043 for idpackage in mydepends:
1044 try:
1045 key, slot = cdb_rks(idpackage)
1046 except TypeError:
1047 continue
1048 if (key,slot) in keyslots_cache: continue
1049 keyslots_cache.add((key,slot))
1050 if (key,slot) in keyslots: continue
1051
1052 mydeps = cdb_rdeps(idpackage)
1053 found = False
1054 for mydep in mydeps:
1055 mymatch = match_cache.get(mydep, 0)
1056 if mymatch == 0:
1057 mymatch = am(mydep)
1058 match_cache[mydep] = mymatch
1059 if mymatch == match:
1060 found = True
1061 break
1062 if not found:
1063 mymatch = am(key, matchSlot = slot)
1064 if mymatch[0] == -1: continue
1065 cmpstat = gpa(mymatch)
1066 if cmpstat == 0: continue
1067 keyslots.add((key,slot))
1068
1069 return keyslots
1070
1072 repo_needed = match_db.retrieveNeeded(match_idpackage, extended = True, format = True)
1073 client_needed = self.clientDbconn.retrieveNeeded(client_idpackage, extended = True, format = True)
1074 repo_split = [x.split(".so")[0] for x in repo_needed]
1075 client_split = [x.split(".so")[0] for x in client_needed]
1076 client_side = [x for x in client_needed if (x not in repo_needed) and (x.split(".so")[0] in repo_split)]
1077 repo_side = [x for x in repo_needed if (x not in client_needed) and (x.split(".so")[0] in client_split)]
1078 return repo_needed, client_side, repo_side
1079
1081
1082
1083
1084
1085 c_hash = "%s|%s|%s" % (
1086 tuple(match),
1087 deep_deps,
1088 tuple(clientmatch),
1089 )
1090 c_hash = "%s%s" % (etpCache['library_breakage'], hash(c_hash),)
1091 if self.xcache:
1092 cached = self.Cacher.pop(c_hash)
1093 if cached != None: return cached
1094
1095
1096 repo_atoms = set()
1097
1098 client_atoms = set()
1099
1100 matchdb = self.open_repository(match[1])
1101 reponeeded, client_side, repo_side = self.__get_lib_breaks_client_and_repo_side(matchdb,
1102 match[0], clientmatch[0])
1103
1104
1105 client_idpackages = set()
1106 for needed in client_side: client_idpackages |= self.clientDbconn.searchNeeded(needed)
1107
1108 client_keyslots = set()
1109 def mymf(idpackage):
1110 if idpackage == clientmatch[0]:
1111 return 0
1112 ks = self.clientDbconn.retrieveKeySlot(idpackage)
1113 if ks is None:
1114 return 0
1115 return ks
1116 client_keyslots = set([x for x in map(mymf,client_idpackages) if x != 0])
1117
1118
1119 repodata = {}
1120 for needed in repo_side:
1121 repodata[needed] = reponeeded[needed]
1122 del repo_side,reponeeded
1123
1124 repo_dependencies = matchdb.retrieveDependencies(match[0])
1125 matched_deps = set()
1126 matched_repos = set()
1127 for dependency in repo_dependencies:
1128 depmatch = self.atom_match(dependency)
1129 if depmatch[0] == -1:
1130 continue
1131 matched_repos.add(depmatch[1])
1132 matched_deps.add(depmatch)
1133
1134 matched_repos = [x for x in self.SystemSettings['repositories']['order'] \
1135 if x in matched_repos]
1136 found_matches = set()
1137 for needed in repodata:
1138 for myrepo in matched_repos:
1139 mydbc = self.open_repository(myrepo)
1140 solved_needed = mydbc.resolveNeeded(needed,
1141 repodata[needed])
1142 found = False
1143 for idpackage in solved_needed:
1144 x = (idpackage, myrepo)
1145 if x in matched_deps:
1146 found_matches.add(x)
1147 found = True
1148 break
1149 if found:
1150 break
1151
1152 for idpackage,repo in found_matches:
1153 if not deep_deps:
1154 cmpstat = self.get_package_action((idpackage,repo))
1155 if cmpstat == 0:
1156 continue
1157 mydbc = self.open_repository(repo)
1158 repo_atoms.add(mydbc.retrieveAtom(idpackage))
1159
1160 for key, slot in client_keyslots:
1161 idpackage, repo = self.atom_match(key, matchSlot = slot)
1162 if idpackage == -1:
1163 continue
1164 if not deep_deps:
1165 cmpstat = self.get_package_action((idpackage, repo))
1166 if cmpstat == 0:
1167 continue
1168 mydbc = self.open_repository(repo)
1169 client_atoms.add(mydbc.retrieveAtom(idpackage))
1170
1171 client_atoms |= repo_atoms
1172
1173 if self.xcache:
1174 self.Cacher.push(c_hash,client_atoms)
1175
1176 return client_atoms
1177
1178
1180
1181 c_hash = "%s%s" % (
1182 etpCache['dep_tree'],
1183 hash("%s|%s|%s|%s|%s" % (
1184 hash(frozenset(sorted(matched_atoms))),
1185 empty_deps,
1186 deep_deps,
1187 self.clientDbconn.database_checksum(),
1188
1189
1190 self.SystemSettings['repositories']['branch'],
1191 )),)
1192 if self.xcache:
1193 cached = self.Cacher.pop(c_hash)
1194 if cached != None: return cached
1195
1196 deptree = {}
1197 deptree[0] = set()
1198
1199 atomlen = len(matched_atoms); count = 0
1200 error_generated = 0
1201 error_tree = set()
1202
1203
1204 forced_matches = self._lookup_system_mask_repository_deps()
1205 if forced_matches:
1206 if isinstance(matched_atoms, list):
1207 matched_atoms = forced_matches + [x for x in matched_atoms if x not in forced_matches]
1208 elif isinstance(matched_atoms, set):
1209 matched_atoms |= set(forced_matches)
1210
1211 sort_dep_text = _("Sorting dependencies")
1212 filter_unsat_cache = {}
1213 treecache = set()
1214 keyslotcache = set()
1215 matchfilter = set()
1216 for matched_atom in matched_atoms:
1217 const_debug_write(__name__,
1218 "get_required_packages matched_atom => %s" % (matched_atom,))
1219
1220 if not quiet:
1221 count += 1
1222 if (count%10 == 0) or (count == atomlen) or (count == 1):
1223 self.updateProgress(sort_dep_text, importance = 0, type = "info",
1224 back = True, header = ":: ", footer = " ::",
1225 percent = True, count = (count,atomlen))
1226
1227 if matched_atom in matchfilter: continue
1228 newtree, result = self.generate_dependency_tree(
1229 matched_atom, empty_deps, deep_deps,
1230 matchfilter = matchfilter, filter_unsat_cache = filter_unsat_cache, treecache = treecache,
1231 keyslotcache = keyslotcache
1232 )
1233
1234 const_debug_write(__name__,
1235 "get_required_packages deptree => %s -- %s" % (
1236 newtree, result,))
1237
1238 if result == -2:
1239 error_generated = -2
1240 error_tree |= set(newtree)
1241 elif (result != 0):
1242 return newtree, result
1243 elif newtree:
1244
1245 max_parent_key = max(deptree)
1246 deptree[0] |= newtree.pop(0)
1247 levelcount = 0
1248 for mylevel in sorted(newtree.keys(), reverse = True):
1249 levelcount += 1
1250 deptree[max_parent_key+levelcount] = newtree.get(mylevel)
1251
1252 if error_generated != 0:
1253 return error_tree,error_generated
1254
1255 if self.xcache:
1256 self.Cacher.push(c_hash,(deptree,0))
1257
1258 return deptree,0
1259
1261 remove_depends = set()
1262 for d_idpackage in depends:
1263 mydeps = self.clientDbconn.retrieveDependencies(d_idpackage)
1264 for mydep in mydeps:
1265 matches, rslt = self.clientDbconn.atomMatch(mydep, multiMatch = True)
1266 if rslt == 1: continue
1267 if idpackage in matches and len(matches) > 1:
1268
1269 for mymatch in matches:
1270 if mymatch not in depends and mymatch not in monotree:
1271 remove_depends.add(d_idpackage)
1272 break
1273 depends -= remove_depends
1274 return depends
1275
1276
1278
1279 c_hash = "%s%s" % (
1280 etpCache['depends_tree'],
1281 hash("%s|%s" % (
1282 tuple(sorted(idpackages)),
1283 deep,
1284 ),
1285 ),
1286 )
1287 if self.xcache:
1288 cached = self.Cacher.pop(c_hash)
1289 if cached != None: return cached
1290
1291 dependscache = set()
1292 treeview = set(idpackages)
1293 treelevel = set(idpackages)
1294 tree = {}
1295
1296 treedepth = 0
1297 tree[treedepth] = set(idpackages)
1298 monotree = set(idpackages)
1299
1300
1301 pdepend_id = etpConst['spm']['pdepend_id']
1302
1303 self.clientDbconn.retrieveDepends(idpackages[0])
1304 count = 0
1305
1306 rem_dep_text = _("Calculating inverse dependencies for")
1307 while 1:
1308 treedepth += 1
1309 tree[treedepth] = set()
1310 for idpackage in treelevel:
1311
1312 count += 1
1313 p_atom = self.clientDbconn.retrieveAtom(idpackage)
1314 self.updateProgress(
1315 blue(rem_dep_text + " %s" % (red(p_atom),)),
1316 importance = 0,
1317 type = "info",
1318 back = True,
1319 header = '|/-\\'[count%4]+" "
1320 )
1321
1322 systempkg = not self.validate_package_removal(idpackage)
1323 if (idpackage in dependscache) or systempkg:
1324 if idpackage in treeview:
1325 treeview.remove(idpackage)
1326 continue
1327
1328
1329 depends = self.clientDbconn.retrieveDepends(idpackage,
1330 exclude_deptypes = (pdepend_id,))
1331
1332 depends = set([x for x in depends if x not in monotree])
1333 depends = set([x for x in depends if \
1334 self.validate_package_removal(x)])
1335 if depends:
1336 depends = self._filter_depends_multimatched_atoms(
1337 idpackage, depends, monotree)
1338 if depends:
1339 tree[treedepth] |= depends
1340 monotree |= depends
1341 treeview |= depends
1342 elif deep:
1343
1344 mydeps = set()
1345 for x in self.clientDbconn.retrieveDependencies(idpackage):
1346 match = self.clientDbconn.atomMatch(x)
1347 if match[0] != -1:
1348 mydeps.add(match[0])
1349
1350
1351 mydeps = [x for x in mydeps if x not in monotree and not \
1352 (self.clientDbconn.isSystemPackage(x) or \
1353 self.is_installed_idpackage_in_system_mask(x) )]
1354 for x in mydeps:
1355 mydepends = self.clientDbconn.retrieveDepends(x)
1356 mydepends -= set([y for y in mydepends if y \
1357 not in monotree])
1358 if not mydepends:
1359 tree[treedepth].add(x)
1360 monotree.add(x)
1361 treeview.add(x)
1362
1363 dependscache.add(idpackage)
1364 if idpackage in treeview:
1365 treeview.remove(idpackage)
1366
1367 treelevel = treeview.copy()
1368 if not treelevel:
1369 if not tree[treedepth]:
1370 del tree[treedepth]
1371 break
1372
1373
1374 for count in sorted(tree.keys(), reverse = True):
1375 x = 0
1376 while x < count:
1377 tree[x] -= tree[count]
1378 x += 1
1379
1380 if self.xcache:
1381 self.Cacher.push(c_hash,(tree,0))
1382
1383
1384 return tree,0
1385
1387
1388 c_hash = self.get_available_packages_chash()
1389 if use_cache and self.xcache:
1390 cached = self.get_available_packages_cache(myhash = c_hash)
1391 if cached != None:
1392 return cached
1393
1394 available = []
1395 self.setTotalCycles(len(self.validRepositories))
1396 avail_dep_text = _("Calculating available packages for")
1397 for repo in self.validRepositories:
1398 try:
1399 dbconn = self.open_repository(repo)
1400 dbconn.validateDatabase()
1401 except (RepositoryError,SystemDatabaseError):
1402 self.cycleDone()
1403 continue
1404 idpackages = [x for x in dbconn.listAllIdpackages(
1405 order_by = 'atom') if dbconn.idpackageValidator(x)[0] != -1]
1406 count = 0
1407 maxlen = len(idpackages)
1408 myavailable = []
1409 do_break = False
1410 for idpackage in idpackages:
1411 if do_break:
1412 break
1413 count += 1
1414 if (count % 10 == 0) or (count == 1) or (count == maxlen):
1415 self.updateProgress(
1416 avail_dep_text + " %s" % (repo,),
1417 importance = 0,
1418 type = "info",
1419 back = True,
1420 header = "::",
1421 count = (count,maxlen),
1422 percent = True,
1423 footer = " ::"
1424 )
1425
1426 try:
1427 key, slot = dbconn.retrieveKeySlot(idpackage)
1428 matches = self.clientDbconn.searchKeySlot(key, slot)
1429 except (self.dbapi2.DatabaseError,self.dbapi2.IntegrityError,self.dbapi2.OperationalError,):
1430 self.cycleDone()
1431 do_break = True
1432 continue
1433 if not matches: myavailable.append((idpackage,repo))
1434 available += myavailable[:]
1435 self.cycleDone()
1436
1437 if self.xcache:
1438 self.Cacher.push("%s%s" % (
1439 etpCache['world_available'], c_hash), available)
1440 return available
1441
1443
1444 db_digest = self.all_repositories_checksum()
1445 if use_cache and self.xcache:
1446 cached = self.get_critical_updates_cache(db_digest = db_digest)
1447 if cached != None:
1448 return cached
1449
1450 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1451 critical_data = client_settings['repositories']['critical_updates']
1452
1453 atoms = set()
1454 atom_matches = {}
1455 for repoid in critical_data:
1456 for atom in critical_data[repoid]:
1457 match_id, match_repo = self.atom_match(atom)
1458 if match_repo == 1:
1459 continue
1460 atom_matches[atom] = (match_id, match_repo,)
1461 atoms.add(atom)
1462
1463 atoms = self.get_unsatisfied_dependencies(atoms)
1464 matches = [atom_matches.get(atom) for atom in atoms]
1465 data = (atoms, matches)
1466
1467 if self.xcache:
1468 c_hash = self.get_critical_update_cache_hash(db_digest)
1469 self.Cacher.push("%s%s" % (etpCache['critical_update'], c_hash,),
1470 data, async = False)
1471
1472 return data
1473
1474
1477
1478 cl_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1479 misc_settings = cl_settings['misc']
1480 update = []
1481 remove = []
1482 fine = []
1483 spm_fine = []
1484
1485
1486
1487 if misc_settings.get('forcedupdates') and critical_updates:
1488 upd_atoms, upd_matches = self.calculate_critical_updates(
1489 use_cache = use_cache)
1490 if upd_atoms:
1491 return upd_matches, remove, fine, spm_fine
1492
1493 db_digest = self.all_repositories_checksum()
1494 if use_cache and self.xcache:
1495 cached = self.get_world_update_cache(empty_deps = empty_deps,
1496 db_digest = db_digest)
1497 if cached != None:
1498 return cached
1499
1500
1501 ignore_spm_downgrades = misc_settings['ignore_spm_downgrades']
1502
1503
1504 idpackages = self.clientDbconn.listAllIdpackages(order_by = 'atom')
1505 maxlen = len(idpackages)
1506 count = 0
1507 mytxt = _("Calculating world packages")
1508 for idpackage in idpackages:
1509
1510 count += 1
1511 if (count%10 == 0) or (count == maxlen) or (count == 1):
1512 self.updateProgress(
1513 mytxt,
1514 importance = 0,
1515 type = "info",
1516 back = True,
1517 header = ":: ",
1518 count = (count,maxlen),
1519 percent = True,
1520 footer = " ::"
1521 )
1522
1523 try:
1524 cl_pkgkey, cl_slot, cl_version, \
1525 cl_tag, cl_revision, \
1526 cl_atom = self.clientDbconn.getStrictData(idpackage)
1527 except TypeError:
1528
1529 continue
1530 use_match_cache = True
1531 do_continue = False
1532 while 1:
1533 try:
1534 match = self.atom_match(
1535 cl_pkgkey,
1536 matchSlot = cl_slot,
1537 extendedResults = True,
1538 useCache = use_match_cache
1539 )
1540 except self.dbapi2.OperationalError:
1541
1542 do_continue = True
1543 break
1544 try:
1545 m_idpackage = match[0][0]
1546 except TypeError:
1547 if not use_match_cache: raise
1548 use_match_cache = False
1549 continue
1550 break
1551 if do_continue: continue
1552
1553
1554
1555
1556 if (m_idpackage != -1):
1557 repoid = match[1]
1558 version = match[0][1]
1559 tag = match[0][2]
1560 revision = match[0][3]
1561 if empty_deps:
1562 if (m_idpackage,repoid) not in update:
1563 update.append((m_idpackage,repoid))
1564 continue
1565 elif (cl_revision != revision):
1566
1567 if cl_revision == 9999 and ignore_spm_downgrades:
1568
1569 fine.append(cl_atom)
1570 if (m_idpackage,repoid) not in update:
1571 spm_fine.append((m_idpackage,repoid))
1572 continue
1573 else:
1574 if (m_idpackage,repoid) not in update:
1575 update.append((m_idpackage,repoid))
1576 continue
1577 elif (cl_version != version):
1578
1579 if (m_idpackage,repoid) not in update:
1580 update.append((m_idpackage,repoid))
1581 continue
1582 elif (cl_tag != tag):
1583
1584 if (m_idpackage,repoid) not in update:
1585 update.append((m_idpackage,repoid))
1586 continue
1587 else:
1588
1589 fine.append(cl_atom)
1590 continue
1591
1592
1593 maskedresults = self.atom_match(cl_pkgkey, matchSlot = cl_slot,
1594 packagesFilter = False)
1595 if maskedresults[0] == -1:
1596 remove.append(idpackage)
1597
1598
1599 matchresults = self.atom_match(cl_pkgkey)
1600 if matchresults[0] != -1:
1601 m_action = self.get_package_action(matchresults)
1602 if m_action > 0 and (matchresults not in update):
1603 update.append(matchresults)
1604
1605 if self.xcache:
1606 c_hash = self.get_world_update_cache_hash(db_digest, empty_deps,
1607 ignore_spm_downgrades)
1608 data = {
1609 'r': (update, remove, fine, spm_fine,),
1610 'empty_deps': empty_deps,
1611 }
1612 self.Cacher.push("%s%s" % (etpCache['world_update'],c_hash,),
1613 data, async = False)
1614
1615 return update, remove, fine, spm_fine
1616
1618
1619 c_hash = "%s%s" % (etpCache['check_package_update'],
1620 hash("%s%s" % (atom, deep,)
1621 ),
1622 )
1623 if self.xcache:
1624 cached = self.Cacher.pop(c_hash)
1625 if cached != None:
1626 return cached
1627
1628 found = False
1629 match = self.clientDbconn.atomMatch(atom)
1630 matched = None
1631 if match[0] != -1:
1632 myatom = self.clientDbconn.retrieveAtom(match[0])
1633 mytag = self.entropyTools.dep_gettag(myatom)
1634 myatom = self.entropyTools.remove_tag(myatom)
1635 myrev = self.clientDbconn.retrieveRevision(match[0])
1636 pkg_match = "="+myatom+"~"+str(myrev)
1637 if mytag != None:
1638 pkg_match += "#%s" % (mytag,)
1639 pkg_unsatisfied = self.get_unsatisfied_dependencies([pkg_match], deep_deps = deep)
1640 if pkg_unsatisfied:
1641
1642 pkg_key = self.entropyTools.dep_getkey(myatom)
1643 pkg_id, pkg_repo = self.atom_match(pkg_key)
1644 if pkg_id != -1:
1645 found = True
1646 del pkg_unsatisfied
1647 matched = self.atom_match(pkg_match)
1648 del match
1649
1650 if self.xcache:
1651 self.Cacher.push(c_hash,(found, matched))
1652 return found, matched
1653
1655
1656 pkgatom = self.clientDbconn.retrieveAtom(idpackage)
1657 pkgkey = self.entropyTools.dep_getkey(pkgatom)
1658 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1659 mask_installed_keys = client_settings['system_mask']['repos_installed_keys']
1660
1661 if self.is_installed_idpackage_in_system_mask(idpackage):
1662 idpackages = mask_installed_keys.get(pkgkey)
1663 if not idpackages: return False
1664 if len(idpackages) > 1:
1665 return True
1666 return False
1667
1668
1669 system_pkg = self.clientDbconn.isSystemPackage(idpackage)
1670 if not system_pkg: return True
1671
1672 matches, rc = self.clientDbconn.atomMatch(pkgkey, multiMatch = True)
1673 if len(matches) < 2:
1674 return False
1675 return True
1676
1677
1679 queue = []
1680 if not idpackages:
1681 return queue
1682 treeview, status = self.generate_depends_tree(idpackages, deep = deep)
1683 if status == 0:
1684 for x in range(len(treeview))[::-1]: queue.extend(treeview[x])
1685 return queue
1686
1688
1689 install = []
1690 removal = []
1691 treepackages, result = self.get_required_packages(matched_atoms,
1692 empty_deps, deep_deps, quiet = quiet)
1693
1694 if result == -2:
1695 return treepackages,removal,result
1696
1697
1698 removal = treepackages.pop(0, set())
1699 for dep_level in sorted(treepackages):
1700 install.extend(treepackages[dep_level])
1701
1702
1703 if install and removal:
1704 myremmatch = {}
1705 for rm_idpackage in removal:
1706 keyslot = self.clientDbconn.retrieveKeySlot(rm_idpackage)
1707
1708
1709 if keyslot is None:
1710 continue
1711 myremmatch[keyslot] = rm_idpackage
1712
1713 for pkg_id, pkg_repo in install:
1714 dbconn = self.open_repository(pkg_repo)
1715 testtuple = dbconn.retrieveKeySlot(pkg_id)
1716 removal.discard(myremmatch.get(testtuple))
1717
1718 return install, sorted(removal), 0
1719