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 try:
669 mydep = mybuffer.pop()
670 except ValueError:
671 mydep = None
672
673 open_db = self.open_repository
674 am = self.atom_match
675 while mydep:
676
677 if mydep in depcache:
678 try:
679 mydep = mybuffer.pop()
680 except ValueError:
681 break
682 continue
683 depcache.add(mydep)
684
685 idpackage, repoid = am(mydep)
686 if (idpackage, repoid) in matchfilter:
687 try:
688 mydep = mybuffer.pop()
689 except ValueError:
690 break
691 continue
692
693 if idpackage != -1:
694
695
696 matchfilter.add((idpackage, repoid))
697
698
699 if idpackage == -1:
700 idpackage, repoid = am(mydep, packagesFilter = False)
701 if idpackage != -1:
702 treelevel += 1
703 if not maskedtree.has_key(treelevel) and not flat:
704 maskedtree[treelevel] = {}
705 dbconn = open_db(repoid)
706 vidpackage, idreason = dbconn.idpackageValidator(idpackage)
707 if atoms:
708 mydict = {dbconn.retrieveAtom(idpackage): idreason}
709 else:
710 mydict = {(idpackage,repoid): idreason}
711 if flat: maskedtree.update(mydict)
712 else: maskedtree[treelevel].update(mydict)
713
714
715 if idpackage != -1:
716 matchfilter.add((idpackage, repoid))
717 dbconn = open_db(repoid)
718 owndeps = dbconn.retrieveDependencies(idpackage)
719 for owndep in owndeps:
720 mybuffer.push(owndep)
721
722 try:
723 mydep = mybuffer.pop()
724 except ValueError:
725 break
726
727 return maskedtree
728
729
730 - def generate_dependency_tree(self,
731 matched_atom, empty_deps = False, deep_deps = False, matchfilter = None,
732 flat = False, filter_unsat_cache = None, treecache = None, keyslotcache = None):
733
734 if not isinstance(matchfilter,set):
735 matchfilter = set()
736 if not isinstance(filter_unsat_cache,dict):
737 filter_unsat_cache = {}
738 if not isinstance(treecache,set):
739 treecache = set()
740 if not isinstance(keyslotcache,set):
741 keyslotcache = set()
742
743 mydbconn = self.open_repository(matched_atom[1])
744 myatom = mydbconn.retrieveAtom(matched_atom[0])
745
746
747
748 deps_not_found = set()
749 conflicts = set()
750
751 mydep = (1,myatom)
752 mybuffer = Lifo()
753 deptree = set()
754 if matched_atom not in matchfilter:
755 deptree.add((1,matched_atom))
756
757 virgin = True
758 open_repo = self.open_repository
759 atom_match = self.atom_match
760 cdb_atom_match = self.clientDbconn.atomMatch
761 lookup_conflict_replacement = self._lookup_conflict_replacement
762 lookup_library_breakages = self._lookup_library_breakages
763 lookup_inverse_dependencies = self._lookup_inverse_dependencies
764 get_unsatisfied_deps = self.get_unsatisfied_dependencies
765
766 def my_dep_filter(x):
767 if x in treecache: return False
768 if tuple(x.split(":")) in keyslotcache: return False
769 return True
770
771 while mydep:
772
773 const_debug_write(__name__,
774 "generate_dependency_tree analyzing => %s" % (
775 mydep,))
776
777 dep_level, dep_atom = mydep
778
779
780 if dep_atom in treecache:
781 const_debug_write(__name__,
782 "generate_dependency_tree already in treecache => %s" % (
783 dep_atom,))
784 try:
785 mydep = mybuffer.pop()
786 except ValueError:
787 const_debug_write(__name__, "---empty--")
788 break
789 const_debug_write(__name__, "---")
790 continue
791 treecache.add(dep_atom)
792
793 if dep_atom is None:
794 const_debug_write(__name__,
795 "generate_dependency_tree broken entry in DB => %s" % (
796 mydep,))
797 try:
798 mydep = mybuffer.pop()
799 except ValueError:
800 const_debug_write(__name__, "---empty2--")
801 break
802 const_debug_write(__name__, "---")
803 continue
804
805
806 if dep_atom[0] == "!":
807 c_idpackage, xst = cdb_atom_match(dep_atom[1:])
808 if c_idpackage != -1:
809 myreplacement = lookup_conflict_replacement(dep_atom[1:],
810 c_idpackage, deep_deps = deep_deps)
811
812 const_debug_write(__name__,
813 "generate_dependency_tree conflict replacement => %s" % (
814 myreplacement,))
815
816 if (myreplacement != None) and (myreplacement not in treecache):
817 mybuffer.push((dep_level+1,myreplacement))
818 else:
819 conflicts.add(c_idpackage)
820 try:
821 mydep = mybuffer.pop()
822 except ValueError:
823 const_debug_write(__name__, "---empty3---")
824 break
825 const_debug_write(__name__, "---")
826 continue
827
828
829 if virgin:
830
831 virgin = False
832 m_idpackage, m_repo = matched_atom
833 dbconn = open_repo(m_repo)
834 myidpackage, idreason = dbconn.idpackageValidator(m_idpackage)
835
836 const_debug_write(__name__,
837 "generate_dependency_tree virgin match masked? => %s - %s" % (
838 myidpackage, idreason,))
839
840 if myidpackage == -1:
841 m_idpackage = -1
842
843 else:
844 m_idpackage, m_repo = atom_match(dep_atom)
845 const_debug_write(__name__,
846 "generate_dependency_tree matching %s => (%s, %s)" % (
847 dep_atom, m_idpackage, m_repo,))
848
849 if m_idpackage == -1:
850
851 const_debug_write(__name__,
852 "generate_dependency_tree dep not found => %s" % (
853 dep_atom,))
854
855 deps_not_found.add(dep_atom)
856 try:
857 mydep = mybuffer.pop()
858 except ValueError:
859 const_debug_write(__name__, "---empty3---")
860 break
861 const_debug_write(__name__, "---")
862 continue
863
864
865 matchdb = open_repo(m_repo)
866 matchatom = matchdb.retrieveAtom(m_idpackage)
867 matchkey, matchslot = matchdb.retrieveKeySlot(m_idpackage)
868
869 const_debug_write(__name__,
870 "generate_dependency_tree idpackage %s => %s - %s:%s" % (
871 m_idpackage, matchatom, matchkey, matchslot))
872
873 if (dep_atom != matchatom) and (matchatom in treecache):
874 try:
875 mydep = mybuffer.pop()
876 except ValueError:
877 const_debug_write(__name__, "---empty4---")
878 break
879 const_debug_write(__name__,
880 "generate_dependency_tree matchatom %s already in cache" % (
881 matchatom,))
882 const_debug_write(__name__, "---")
883 continue
884
885 treecache.add(matchatom)
886
887 const_debug_write(__name__,
888 "generate_dependency_tree check if key + slot cache => %s" % (
889 (matchslot, matchkey),))
890
891
892 if (matchslot, matchkey) in keyslotcache:
893 try:
894 mydep = mybuffer.pop()
895 except ValueError:
896 const_debug_write(__name__, "---empty5---")
897 break
898 const_debug_write(__name__, "---")
899 continue
900 else:
901 keyslotcache.add((matchslot, matchkey))
902
903 const_debug_write(__name__,
904 "generate_dependency_tree not in key + slot cache => %s" % (
905 (matchslot, matchkey),))
906
907 match = (m_idpackage, m_repo,)
908
909 if match in matchfilter:
910 try:
911 mydep = mybuffer.pop()
912 except ValueError:
913 const_debug_write(__name__, "---empty6---")
914 break
915 const_debug_write(__name__, "---")
916 continue
917
918 const_debug_write(__name__,
919 "generate_dependency_tree match NOT already analyzed => %s" % (
920 match,))
921
922
923 matchfilter.add(match)
924 treedepth = dep_level+1
925 deptree.add((dep_level,match))
926
927
928 cm_idpackage, cm_result = cdb_atom_match(matchkey,
929 matchSlot = matchslot)
930 if cm_idpackage != -1:
931
932 broken_atoms = lookup_library_breakages(match,
933 (cm_idpackage, cm_result,), deep_deps = deep_deps)
934 const_debug_write(__name__,
935 "generate_dependency_tree lib broken atoms for %s => %s" % (
936 matchkey+":"+matchslot, broken_atoms,))
937
938 inverse_deps = lookup_inverse_dependencies(match,
939 (cm_idpackage, cm_result,))
940 const_debug_write(__name__,
941 "generate_dependency_tree inverse deps for %s => %s" % (
942 matchkey+":"+matchslot, inverse_deps,))
943
944 if inverse_deps:
945 deptree.remove((dep_level,match))
946 for ikey,islot in inverse_deps:
947 iks_str = '%s:%s' % (ikey,islot,)
948 if ((ikey,islot) not in keyslotcache) and (iks_str not in treecache):
949 mybuffer.push((dep_level,iks_str))
950 keyslotcache.add((ikey,islot))
951 deptree.add((treedepth,match))
952 treedepth += 1
953
954 for x in broken_atoms:
955 if (tuple(x.split(":")) not in keyslotcache) and (x not in treecache):
956 mybuffer.push((treedepth,x))
957
958 m_deplist = matchdb.retrieveDependenciesList(m_idpackage)
959
960 const_debug_write(__name__,
961 "generate_dependency_tree dependency list for %s => %s" % (
962 m_idpackage, m_deplist,))
963
964 myundeps = filter(my_dep_filter, m_deplist)
965
966 const_debug_write(__name__,
967 "generate_dependency_tree filtered dependency list => %s" % (
968 myundeps,))
969
970 if not empty_deps:
971
972 m_unsat_deplist = get_unsatisfied_deps(myundeps, deep_deps,
973 depcache = filter_unsat_cache)
974
975 const_debug_write(__name__,
976 "generate_dependency_tree unsatisfied dependencies (deep: %s) => %s" % (
977 deep_deps, m_unsat_deplist,))
978
979 myundeps = filter(my_dep_filter, m_unsat_deplist)
980
981 const_debug_write(__name__,
982 "generate_dependency_tree filtered UNSATISFIED dependencies => %s" % (
983 myundeps,))
984
985
986 if myundeps:
987
988 post_deps = [x for x in \
989 matchdb.retrievePostDependencies(m_idpackage) if x \
990 in myundeps]
991
992 const_debug_write(__name__,
993 "generate_dependency_tree POST dependencies => %s" % (
994 post_deps,))
995
996 if post_deps:
997
998
999
1000 myundeps = [x for x in myundeps if x not in post_deps]
1001
1002 const_debug_write(__name__,
1003 "generate_dependency_tree POST dependencies ADDED => %s" % (
1004 myundeps,))
1005
1006 for x in post_deps:
1007 mybuffer.push((-1, x))
1008
1009 for x in myundeps:
1010 mybuffer.push((treedepth, x))
1011
1012 try:
1013 mydep = mybuffer.pop()
1014 except ValueError:
1015 const_debug_write(__name__, "---empty7---")
1016 break
1017 const_debug_write(__name__, "---")
1018
1019 if deps_not_found:
1020 return list(deps_not_found), -2
1021
1022 if flat:
1023 return [x[1] for x in deptree], 0
1024
1025 newdeptree = {}
1026 for key, item in deptree:
1027 if key >= 0:
1028
1029 key += 1
1030 obj = newdeptree.setdefault(key, set())
1031 obj.add(item)
1032
1033 newdeptree[0] = conflicts
1034
1035 return newdeptree,0
1036
1037
1039
1040 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1041 data = client_settings['repositories']['system_mask']
1042
1043 if not data:
1044 return []
1045 mydata = []
1046 cached_items = set()
1047 for atom in data:
1048 mymatch = self.atom_match(atom)
1049 if mymatch[0] == -1:
1050 continue
1051 if mymatch in cached_items:
1052 continue
1053 if mymatch not in mydata:
1054
1055 myaction = self.get_package_action(mymatch)
1056
1057 if myaction == 1: mydata.append(mymatch)
1058 cached_items.add(mymatch)
1059 return mydata
1060
1062 if self.entropyTools.isjustname(conflict_atom):
1063 return None
1064 conflict_match = self.atom_match(conflict_atom)
1065 mykey, myslot = self.clientDbconn.retrieveKeySlot(client_idpackage)
1066 new_match = self.atom_match(mykey, matchSlot = myslot)
1067 if (conflict_match == new_match) or (new_match[1] == 1):
1068 return None
1069 action = self.get_package_action(new_match)
1070 if (action == 0) and (not deep_deps):
1071 return None
1072 return "%s:%s" % (mykey,myslot,)
1073
1075
1076 cmpstat = self.get_package_action(match)
1077 if cmpstat == 0: return set()
1078
1079 keyslots = set()
1080 mydepends = self.clientDbconn.retrieveDepends(clientmatch[0])
1081 am = self.atom_match
1082 cdb_rdeps = self.clientDbconn.retrieveDependencies
1083 cdb_rks = self.clientDbconn.retrieveKeySlot
1084 gpa = self.get_package_action
1085 keyslots_cache = set()
1086 match_cache = {}
1087
1088 for idpackage in mydepends:
1089 try:
1090 key, slot = cdb_rks(idpackage)
1091 except TypeError:
1092 continue
1093 if (key,slot) in keyslots_cache: continue
1094 keyslots_cache.add((key,slot))
1095 if (key,slot) in keyslots: continue
1096
1097 mydeps = cdb_rdeps(idpackage)
1098 found = False
1099 for mydep in mydeps:
1100 mymatch = match_cache.get(mydep, 0)
1101 if mymatch == 0:
1102 mymatch = am(mydep)
1103 match_cache[mydep] = mymatch
1104 if mymatch == match:
1105 found = True
1106 break
1107 if not found:
1108 mymatch = am(key, matchSlot = slot)
1109 if mymatch[0] == -1: continue
1110 cmpstat = gpa(mymatch)
1111 if cmpstat == 0: continue
1112 keyslots.add((key,slot))
1113
1114 return keyslots
1115
1117 repo_needed = match_db.retrieveNeeded(match_idpackage, extended = True, format = True)
1118 client_needed = self.clientDbconn.retrieveNeeded(client_idpackage, extended = True, format = True)
1119 repo_split = [x.split(".so")[0] for x in repo_needed]
1120 client_split = [x.split(".so")[0] for x in client_needed]
1121 client_side = [x for x in client_needed if (x not in repo_needed) and (x.split(".so")[0] in repo_split)]
1122 repo_side = [x for x in repo_needed if (x not in client_needed) and (x.split(".so")[0] in client_split)]
1123 return repo_needed, client_side, repo_side
1124
1126
1127
1128
1129
1130 c_hash = "%s|%s|%s" % (
1131 tuple(match),
1132 deep_deps,
1133 tuple(clientmatch),
1134 )
1135 c_hash = "%s%s" % (etpCache['library_breakage'], hash(c_hash),)
1136 if self.xcache:
1137 cached = self.Cacher.pop(c_hash)
1138 if cached != None: return cached
1139
1140
1141 repo_atoms = set()
1142
1143 client_atoms = set()
1144
1145 matchdb = self.open_repository(match[1])
1146 reponeeded, client_side, repo_side = self.__get_lib_breaks_client_and_repo_side(matchdb,
1147 match[0], clientmatch[0])
1148
1149
1150 client_idpackages = set()
1151 for needed in client_side: client_idpackages |= self.clientDbconn.searchNeeded(needed)
1152
1153 client_keyslots = set()
1154 def mymf(idpackage):
1155 if idpackage == clientmatch[0]:
1156 return 0
1157 ks = self.clientDbconn.retrieveKeySlot(idpackage)
1158 if ks is None:
1159 return 0
1160 return ks
1161 client_keyslots = set([x for x in map(mymf,client_idpackages) if x != 0])
1162
1163
1164 repodata = {}
1165 for needed in repo_side:
1166 repodata[needed] = reponeeded[needed]
1167 del repo_side,reponeeded
1168
1169 repo_dependencies = matchdb.retrieveDependencies(match[0])
1170 matched_deps = set()
1171 matched_repos = set()
1172 for dependency in repo_dependencies:
1173 depmatch = self.atom_match(dependency)
1174 if depmatch[0] == -1:
1175 continue
1176 matched_repos.add(depmatch[1])
1177 matched_deps.add(depmatch)
1178
1179 matched_repos = [x for x in self.SystemSettings['repositories']['order'] \
1180 if x in matched_repos]
1181 found_matches = set()
1182 for needed in repodata:
1183 for myrepo in matched_repos:
1184 mydbc = self.open_repository(myrepo)
1185 solved_needed = mydbc.resolveNeeded(needed,
1186 repodata[needed])
1187 found = False
1188 for idpackage in solved_needed:
1189 x = (idpackage, myrepo)
1190 if x in matched_deps:
1191 found_matches.add(x)
1192 found = True
1193 break
1194 if found:
1195 break
1196
1197 for idpackage,repo in found_matches:
1198 if not deep_deps:
1199 cmpstat = self.get_package_action((idpackage,repo))
1200 if cmpstat == 0:
1201 continue
1202 mydbc = self.open_repository(repo)
1203 repo_atoms.add(mydbc.retrieveAtom(idpackage))
1204
1205 for key, slot in client_keyslots:
1206 idpackage, repo = self.atom_match(key, matchSlot = slot)
1207 if idpackage == -1:
1208 continue
1209 if not deep_deps:
1210 cmpstat = self.get_package_action((idpackage, repo))
1211 if cmpstat == 0:
1212 continue
1213 mydbc = self.open_repository(repo)
1214 client_atoms.add(mydbc.retrieveAtom(idpackage))
1215
1216 client_atoms |= repo_atoms
1217
1218 if self.xcache:
1219 self.Cacher.push(c_hash,client_atoms)
1220
1221 return client_atoms
1222
1223
1225
1226 c_hash = "%s%s" % (
1227 etpCache['dep_tree'],
1228 hash("%s|%s|%s|%s|%s" % (
1229 hash(frozenset(sorted(matched_atoms))),
1230 empty_deps,
1231 deep_deps,
1232 self.clientDbconn.database_checksum(),
1233
1234
1235 self.SystemSettings['repositories']['branch'],
1236 )),)
1237 if self.xcache:
1238 cached = self.Cacher.pop(c_hash)
1239 if cached != None: return cached
1240
1241 deptree = {}
1242 deptree[0] = set()
1243
1244 atomlen = len(matched_atoms); count = 0
1245 error_generated = 0
1246 error_tree = set()
1247
1248
1249 forced_matches = self._lookup_system_mask_repository_deps()
1250 if forced_matches:
1251 if isinstance(matched_atoms, list):
1252 matched_atoms = forced_matches + [x for x in matched_atoms if x not in forced_matches]
1253 elif isinstance(matched_atoms, set):
1254 matched_atoms |= set(forced_matches)
1255
1256 sort_dep_text = _("Sorting dependencies")
1257 filter_unsat_cache = {}
1258 treecache = set()
1259 keyslotcache = set()
1260 matchfilter = set()
1261 for matched_atom in matched_atoms:
1262 const_debug_write(__name__,
1263 "get_required_packages matched_atom => %s" % (matched_atom,))
1264
1265 if not quiet:
1266 count += 1
1267 if (count%10 == 0) or (count == atomlen) or (count == 1):
1268 self.updateProgress(sort_dep_text, importance = 0, type = "info",
1269 back = True, header = ":: ", footer = " ::",
1270 percent = True, count = (count,atomlen))
1271
1272 if matched_atom in matchfilter: continue
1273 newtree, result = self.generate_dependency_tree(
1274 matched_atom, empty_deps, deep_deps,
1275 matchfilter = matchfilter, filter_unsat_cache = filter_unsat_cache, treecache = treecache,
1276 keyslotcache = keyslotcache
1277 )
1278
1279 const_debug_write(__name__,
1280 "get_required_packages deptree => %s -- %s" % (
1281 newtree, result,))
1282
1283 if result == -2:
1284 error_generated = -2
1285 error_tree |= set(newtree)
1286 elif (result != 0):
1287 return newtree, result
1288 elif newtree:
1289
1290 max_parent_key = max(deptree)
1291 deptree[0] |= newtree.pop(0)
1292 levelcount = 0
1293 for mylevel in sorted(newtree.keys(), reverse = True):
1294 levelcount += 1
1295 deptree[max_parent_key+levelcount] = newtree.get(mylevel)
1296
1297 if error_generated != 0:
1298 return error_tree,error_generated
1299
1300 if self.xcache:
1301 self.Cacher.push(c_hash,(deptree,0))
1302
1303 return deptree,0
1304
1306 remove_depends = set()
1307 for d_idpackage in depends:
1308 mydeps = self.clientDbconn.retrieveDependencies(d_idpackage)
1309 for mydep in mydeps:
1310 matches, rslt = self.clientDbconn.atomMatch(mydep, multiMatch = True)
1311 if rslt == 1: continue
1312 if idpackage in matches and len(matches) > 1:
1313
1314 for mymatch in matches:
1315 if mymatch not in depends and mymatch not in monotree:
1316 remove_depends.add(d_idpackage)
1317 break
1318 depends -= remove_depends
1319 return depends
1320
1321
1323
1324 c_hash = "%s%s" % (
1325 etpCache['depends_tree'],
1326 hash("%s|%s" % (
1327 tuple(sorted(idpackages)),
1328 deep,
1329 ),
1330 ),
1331 )
1332 if self.xcache:
1333 cached = self.Cacher.pop(c_hash)
1334 if cached != None: return cached
1335
1336 dependscache = set()
1337 treeview = set(idpackages)
1338 treelevel = set(idpackages)
1339 tree = {}
1340
1341 treedepth = 0
1342 tree[treedepth] = set(idpackages)
1343 monotree = set(idpackages)
1344
1345
1346 pdepend_id = etpConst['spm']['pdepend_id']
1347
1348 self.clientDbconn.retrieveDepends(idpackages[0])
1349 count = 0
1350
1351 rem_dep_text = _("Calculating inverse dependencies for")
1352 while 1:
1353 treedepth += 1
1354 tree[treedepth] = set()
1355 for idpackage in treelevel:
1356
1357 count += 1
1358 p_atom = self.clientDbconn.retrieveAtom(idpackage)
1359 self.updateProgress(
1360 blue(rem_dep_text + " %s" % (red(p_atom),)),
1361 importance = 0,
1362 type = "info",
1363 back = True,
1364 header = '|/-\\'[count%4]+" "
1365 )
1366
1367 systempkg = not self.validate_package_removal(idpackage)
1368 if (idpackage in dependscache) or systempkg:
1369 if idpackage in treeview:
1370 treeview.remove(idpackage)
1371 continue
1372
1373
1374 depends = self.clientDbconn.retrieveDepends(idpackage,
1375 exclude_deptypes = (pdepend_id,))
1376
1377 depends = set([x for x in depends if x not in monotree])
1378 depends = set([x for x in depends if \
1379 self.validate_package_removal(x)])
1380 if depends:
1381 depends = self._filter_depends_multimatched_atoms(
1382 idpackage, depends, monotree)
1383 if depends:
1384 tree[treedepth] |= depends
1385 monotree |= depends
1386 treeview |= depends
1387 elif deep:
1388
1389 mydeps = set()
1390 for x in self.clientDbconn.retrieveDependencies(idpackage):
1391 match = self.clientDbconn.atomMatch(x)
1392 if match[0] != -1:
1393 mydeps.add(match[0])
1394
1395
1396 mydeps = [x for x in mydeps if x not in monotree and not \
1397 (self.clientDbconn.isSystemPackage(x) or \
1398 self.is_installed_idpackage_in_system_mask(x) )]
1399 for x in mydeps:
1400 mydepends = self.clientDbconn.retrieveDepends(x)
1401 mydepends -= set([y for y in mydepends if y \
1402 not in monotree])
1403 if not mydepends:
1404 tree[treedepth].add(x)
1405 monotree.add(x)
1406 treeview.add(x)
1407
1408 dependscache.add(idpackage)
1409 if idpackage in treeview:
1410 treeview.remove(idpackage)
1411
1412 treelevel = treeview.copy()
1413 if not treelevel:
1414 if not tree[treedepth]:
1415 del tree[treedepth]
1416 break
1417
1418
1419 for count in sorted(tree.keys(), reverse = True):
1420 x = 0
1421 while x < count:
1422 tree[x] -= tree[count]
1423 x += 1
1424
1425 if self.xcache:
1426 self.Cacher.push(c_hash,(tree,0))
1427
1428
1429 return tree,0
1430
1432
1433 c_hash = self.get_available_packages_chash()
1434 if use_cache and self.xcache:
1435 cached = self.get_available_packages_cache(myhash = c_hash)
1436 if cached != None:
1437 return cached
1438
1439 available = []
1440 self.setTotalCycles(len(self.validRepositories))
1441 avail_dep_text = _("Calculating available packages for")
1442 for repo in self.validRepositories:
1443 try:
1444 dbconn = self.open_repository(repo)
1445 dbconn.validateDatabase()
1446 except (RepositoryError,SystemDatabaseError):
1447 self.cycleDone()
1448 continue
1449 idpackages = [x for x in dbconn.listAllIdpackages(
1450 order_by = 'atom') if dbconn.idpackageValidator(x)[0] != -1]
1451 count = 0
1452 maxlen = len(idpackages)
1453 myavailable = []
1454 do_break = False
1455 for idpackage in idpackages:
1456 if do_break:
1457 break
1458 count += 1
1459 if (count % 10 == 0) or (count == 1) or (count == maxlen):
1460 self.updateProgress(
1461 avail_dep_text + " %s" % (repo,),
1462 importance = 0,
1463 type = "info",
1464 back = True,
1465 header = "::",
1466 count = (count,maxlen),
1467 percent = True,
1468 footer = " ::"
1469 )
1470
1471 try:
1472 key, slot = dbconn.retrieveKeySlot(idpackage)
1473 matches = self.clientDbconn.searchKeySlot(key, slot)
1474 except (self.dbapi2.DatabaseError,self.dbapi2.IntegrityError,self.dbapi2.OperationalError,):
1475 self.cycleDone()
1476 do_break = True
1477 continue
1478 if not matches: myavailable.append((idpackage,repo))
1479 available += myavailable[:]
1480 self.cycleDone()
1481
1482 if self.xcache:
1483 self.Cacher.push("%s%s" % (
1484 etpCache['world_available'], c_hash), available)
1485 return available
1486
1488
1489 db_digest = self.all_repositories_checksum()
1490 if use_cache and self.xcache:
1491 cached = self.get_critical_updates_cache(db_digest = db_digest)
1492 if cached != None:
1493 return cached
1494
1495 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1496 critical_data = client_settings['repositories']['critical_updates']
1497
1498 atoms = set()
1499 atom_matches = {}
1500 for repoid in critical_data:
1501 for atom in critical_data[repoid]:
1502 match_id, match_repo = self.atom_match(atom)
1503 if match_repo == 1:
1504 continue
1505 atom_matches[atom] = (match_id, match_repo,)
1506 atoms.add(atom)
1507
1508 atoms = self.get_unsatisfied_dependencies(atoms)
1509 matches = [atom_matches.get(atom) for atom in atoms]
1510 data = (atoms, matches)
1511
1512 if self.xcache:
1513 c_hash = self.get_critical_update_cache_hash(db_digest)
1514 self.Cacher.push("%s%s" % (etpCache['critical_update'], c_hash,),
1515 data, async = False)
1516
1517 return data
1518
1519
1522
1523 cl_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1524 misc_settings = cl_settings['misc']
1525 update = []
1526 remove = []
1527 fine = []
1528 spm_fine = []
1529
1530
1531
1532 if misc_settings.get('forcedupdates') and critical_updates:
1533 upd_atoms, upd_matches = self.calculate_critical_updates(
1534 use_cache = use_cache)
1535 if upd_atoms:
1536 return upd_matches, remove, fine, spm_fine
1537
1538 db_digest = self.all_repositories_checksum()
1539 if use_cache and self.xcache:
1540 cached = self.get_world_update_cache(empty_deps = empty_deps,
1541 db_digest = db_digest)
1542 if cached != None:
1543 return cached
1544
1545
1546 ignore_spm_downgrades = misc_settings['ignore_spm_downgrades']
1547
1548
1549 idpackages = self.clientDbconn.listAllIdpackages(order_by = 'atom')
1550 maxlen = len(idpackages)
1551 count = 0
1552 mytxt = _("Calculating world packages")
1553 for idpackage in idpackages:
1554
1555 count += 1
1556 if (count%10 == 0) or (count == maxlen) or (count == 1):
1557 self.updateProgress(
1558 mytxt,
1559 importance = 0,
1560 type = "info",
1561 back = True,
1562 header = ":: ",
1563 count = (count,maxlen),
1564 percent = True,
1565 footer = " ::"
1566 )
1567
1568 try:
1569 cl_pkgkey, cl_slot, cl_version, \
1570 cl_tag, cl_revision, \
1571 cl_atom = self.clientDbconn.getStrictData(idpackage)
1572 except TypeError:
1573
1574 continue
1575 use_match_cache = True
1576 do_continue = False
1577 while 1:
1578 try:
1579 match = self.atom_match(
1580 cl_pkgkey,
1581 matchSlot = cl_slot,
1582 extendedResults = True,
1583 useCache = use_match_cache
1584 )
1585 except self.dbapi2.OperationalError:
1586
1587 do_continue = True
1588 break
1589 try:
1590 m_idpackage = match[0][0]
1591 except TypeError:
1592 if not use_match_cache: raise
1593 use_match_cache = False
1594 continue
1595 break
1596 if do_continue: continue
1597
1598
1599
1600
1601 if (m_idpackage != -1):
1602 repoid = match[1]
1603 version = match[0][1]
1604 tag = match[0][2]
1605 revision = match[0][3]
1606 if empty_deps:
1607 if (m_idpackage,repoid) not in update:
1608 update.append((m_idpackage,repoid))
1609 continue
1610 elif (cl_revision != revision):
1611
1612 if cl_revision == 9999 and ignore_spm_downgrades:
1613
1614 fine.append(cl_atom)
1615 if (m_idpackage,repoid) not in update:
1616 spm_fine.append((m_idpackage,repoid))
1617 continue
1618 else:
1619 if (m_idpackage,repoid) not in update:
1620 update.append((m_idpackage,repoid))
1621 continue
1622 elif (cl_version != version):
1623
1624 if (m_idpackage,repoid) not in update:
1625 update.append((m_idpackage,repoid))
1626 continue
1627 elif (cl_tag != tag):
1628
1629 if (m_idpackage,repoid) not in update:
1630 update.append((m_idpackage,repoid))
1631 continue
1632 else:
1633
1634 fine.append(cl_atom)
1635 continue
1636
1637
1638 maskedresults = self.atom_match(cl_pkgkey, matchSlot = cl_slot,
1639 packagesFilter = False)
1640 if maskedresults[0] == -1:
1641 remove.append(idpackage)
1642
1643
1644 matchresults = self.atom_match(cl_pkgkey)
1645 if matchresults[0] != -1:
1646 m_action = self.get_package_action(matchresults)
1647 if m_action > 0 and (matchresults not in update):
1648 update.append(matchresults)
1649
1650 if self.xcache:
1651 c_hash = self.get_world_update_cache_hash(db_digest, empty_deps,
1652 ignore_spm_downgrades)
1653 data = (update, remove, fine, spm_fine,)
1654 self.Cacher.push("%s%s" % (etpCache['world_update'],c_hash,),
1655 data, async = False)
1656
1657 return update, remove, fine, spm_fine
1658
1660
1661 c_hash = "%s%s" % (etpCache['check_package_update'],
1662 hash("%s%s" % (atom, deep,)
1663 ),
1664 )
1665 if self.xcache:
1666 cached = self.Cacher.pop(c_hash)
1667 if cached != None:
1668 return cached
1669
1670 found = False
1671 match = self.clientDbconn.atomMatch(atom)
1672 matched = None
1673 if match[0] != -1:
1674 myatom = self.clientDbconn.retrieveAtom(match[0])
1675 mytag = self.entropyTools.dep_gettag(myatom)
1676 myatom = self.entropyTools.remove_tag(myatom)
1677 myrev = self.clientDbconn.retrieveRevision(match[0])
1678 pkg_match = "="+myatom+"~"+str(myrev)
1679 if mytag != None:
1680 pkg_match += "#%s" % (mytag,)
1681 pkg_unsatisfied = self.get_unsatisfied_dependencies([pkg_match], deep_deps = deep)
1682 if pkg_unsatisfied:
1683
1684 pkg_key = self.entropyTools.dep_getkey(myatom)
1685 pkg_id, pkg_repo = self.atom_match(pkg_key)
1686 if pkg_id != -1:
1687 found = True
1688 del pkg_unsatisfied
1689 matched = self.atom_match(pkg_match)
1690 del match
1691
1692 if self.xcache:
1693 self.Cacher.push(c_hash,(found, matched))
1694 return found, matched
1695
1697
1698 pkgatom = self.clientDbconn.retrieveAtom(idpackage)
1699 pkgkey = self.entropyTools.dep_getkey(pkgatom)
1700 client_settings = self.SystemSettings[self.sys_settings_client_plugin_id]
1701 mask_installed_keys = client_settings['system_mask']['repos_installed_keys']
1702
1703 if self.is_installed_idpackage_in_system_mask(idpackage):
1704 idpackages = mask_installed_keys.get(pkgkey)
1705 if not idpackages: return False
1706 if len(idpackages) > 1:
1707 return True
1708 return False
1709
1710
1711 system_pkg = self.clientDbconn.isSystemPackage(idpackage)
1712 if not system_pkg: return True
1713
1714 matches, rc = self.clientDbconn.atomMatch(pkgkey, multiMatch = True)
1715 if len(matches) < 2:
1716 return False
1717 return True
1718
1719
1721 queue = []
1722 if not idpackages:
1723 return queue
1724 treeview, status = self.generate_depends_tree(idpackages, deep = deep)
1725 if status == 0:
1726 for x in range(len(treeview))[::-1]: queue.extend(treeview[x])
1727 return queue
1728
1730
1731 install = []
1732 removal = []
1733 treepackages, result = self.get_required_packages(matched_atoms,
1734 empty_deps, deep_deps, quiet = quiet)
1735
1736 if result == -2:
1737 return treepackages,removal,result
1738
1739
1740 removal = treepackages.pop(0, set())
1741 for dep_level in sorted(treepackages):
1742 install.extend(treepackages[dep_level])
1743
1744
1745 if install and removal:
1746 myremmatch = {}
1747 for rm_idpackage in removal:
1748 keyslot = self.clientDbconn.retrieveKeySlot(rm_idpackage)
1749
1750
1751 if keyslot is None:
1752 continue
1753 myremmatch[keyslot] = rm_idpackage
1754
1755 for pkg_id, pkg_repo in install:
1756 dbconn = self.open_repository(pkg_repo)
1757 testtuple = dbconn.retrieveKeySlot(pkg_id)
1758 removal.discard(myremmatch.get(testtuple))
1759
1760 return install, sorted(removal), 0
1761