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 import os
23 import stat
24 import sys
25 import shutil
26 import tempfile
27 from entropy.const import etpConst, etpUi
28 from entropy.exceptions import *
29 from entropy.output import darkred, darkgreen, brown, darkblue, purple, red, \
30 bold
31 from entropy.i18n import _
32 from entropy.core import SystemSettings, Singleton
35
37
38 if not hasattr(OutputInterface,'updateProgress'):
39 mytxt = _("OutputInterface does not have an updateProgress method")
40 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
41 elif not callable(OutputInterface.updateProgress):
42 mytxt = _("OutputInterface does not have an updateProgress method")
43 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
44
45 self.spm_backend = etpConst['spm']['backend']
46 self.valid_backends = etpConst['spm']['available_backends']
47 if self.spm_backend not in self.valid_backends:
48 mytxt = "%s: %s" % (_("Invalid backend"),self.spm_backend,)
49 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,))
50
51 if self.spm_backend == "portage":
52 self.intf = PortagePlugin(OutputInterface)
53
54 @staticmethod
59
61 """Base class for Source Package Manager plugins"""
62
64 """Take a dependency structure as returned by paren_reduce or use_reduce
65 and generate an equivalent structure that has no redundant lists."""
67 list.__init__(self)
68 self._zap_parens(src, self)
69
71 if not src:
72 return dest
73 i = iter(src)
74 for x in i:
75 if isinstance(x, basestring):
76 if x == '||':
77 x = self._zap_parens(i.next(), [], disjunction=True)
78 if len(x) == 1:
79 dest.append(x[0])
80 else:
81 dest.append("||")
82 dest.append(x)
83 elif x.endswith("?"):
84 dest.append(x)
85 dest.append(self._zap_parens(i.next(), []))
86 else:
87 dest.append(x)
88 else:
89 if disjunction:
90 x = self._zap_parens(x, [])
91 if len(x) == 1:
92 dest.append(x[0])
93 else:
94 dest.append(x)
95 else:
96 self._zap_parens(x, dest)
97 return dest
98
100 """
101 Source Package Manager Plugin singleton method.
102 This method must be reimplemented by subclasses.
103
104 @param output_interface: Entropy output interface
105 @type output_interface: entropy.output.TextInterface based instances
106 @raise NotImplementedError: when method is not reimplemented
107 """
108 raise NotImplementedError
109
111 """
112 Service function that returns an Entropy SPM interface instance.
113
114 @param output_interface: Entropy Output Interface instance
115 @type output_interface: entropy.output.TextInterface based instance
116 @return: currently selected SPM interface
117 @rtype: entropy.spm.SpmPlugin instance
118 """
119 spmintf = Spm.get_spm_interface()
120 return spmintf(output_interface)
121
123
124 import entropy.tools as entropyTools
126
127 if not hasattr(OutputInterface,'updateProgress'):
128 mytxt = _("OutputInterface does not have an updateProgress method")
129 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
130 elif not callable(OutputInterface.updateProgress):
131 mytxt = _("OutputInterface does not have an updateProgress method")
132 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
133
134
135 self.updateProgress = OutputInterface.updateProgress
136 self.askQuestion = OutputInterface.askQuestion
137 sys.path.append("/usr/lib/gentoolkit/pym")
138
139 from entropy.misc import LogFile
140 self.LogFile = LogFile
141
142
143 import portage
144 self.portage = portage
145 self.EAPI = 1
146 try:
147 import portage.const as portage_const
148 except ImportError:
149 import portage_const
150 if hasattr(portage_const,"EAPI"):
151 self.EAPI = portage_const.EAPI
152 self.portage_const = portage_const
153
154 from portage.versions import best
155 self.portage_best = best
156
157 try:
158 import portage.util as portage_util
159 except ImportError:
160 import portage_util
161 self.portage_util = portage_util
162
163 try:
164 import portage.sets as portage_sets
165 self.portage_sets = portage_sets
166 except ImportError:
167 self.portage_sets = None
168
169 try:
170 import glsa
171 self.glsa = glsa
172 except ImportError:
173 self.glsa = None
174
175 if hasattr(self.portage,'exception'):
176 self.portage_exception = self.portage.exception
177 else:
178 self.portage_exception = Exception
179
180 self.builtin_pkg_sets = [
181 "system","world","installed","module-rebuild",
182 "security","preserved-rebuild","live-rebuild",
183 "downgrade","unavailable"
184 ]
185
187 spmLog = self.LogFile(
188 level = etpConst['spmloglevel'],
189 filename = etpConst['spmlogfile'],
190 header = "[spm]"
191 )
192 spmLog.write(message)
193 spmLog.flush()
194 spmLog.close()
195
205
207
208 if not self.glsa: return
209 if command not in ['new','all','affected']: return
210
211 glsaconfig = self.glsa.checkconfig(self.portage.config(clone=self.portage.settings))
212 completelist = self.glsa.get_glsa_list(glsaconfig["GLSA_DIR"], glsaconfig)
213
214 glsalist = []
215 if command == "new":
216 checklist = []
217 if os.access(glsaconfig["CHECKFILE"], os.R_OK):
218 checklist = [line.strip() for line in open(glsaconfig["CHECKFILE"], "r").readlines()]
219 glsalist = [e for e in completelist if e not in checklist]
220 elif command == "all":
221 glsalist = completelist
222 elif command == "affected":
223
224 for x in completelist:
225 try:
226 myglsa = self.glsa.Glsa(x, glsaconfig)
227 except (self.glsa.GlsaTypeException, self.glsa.GlsaFormatException), e:
228 continue
229 if not myglsa.isVulnerable():
230 continue
231 glsalist.append(x)
232
233 return glsalist
234
275
277 if myroot == None:
278 myroot = etpConst['systemroot']+"/"
279 mydb = {}
280 mydb[myroot] = {}
281 mydb[myroot]['vartree'] = self._get_portage_vartree(myroot)
282 mydb[myroot]['porttree'] = self._get_portage_portagetree(myroot)
283 mydb[myroot]['bintree'] = self._get_portage_binarytree(myroot)
284 mydb[myroot]['virtuals'] = self.portage.settings.getvirtuals(myroot)
285 if etpUi['mute']:
286 pid = os.fork()
287 if pid > 0:
288 os.waitpid(pid, 0)
289 else:
290 f = open("/dev/null","w")
291 old_stdout = sys.stdout
292 old_stderr = sys.stderr
293 sys.stdout = f
294 sys.stderr = f
295 self.portage._global_updates(mydb, {})
296 sys.stdout = old_stdout
297 sys.stderr = old_stderr
298 f.close()
299 os._exit(0)
300 else:
301 self.portage._global_updates(mydb, {})
302
304 return os.path.join(etpConst['systemroot'],"/",self.portage_const.WORLD_FILE)
305
307 x = []
308 if self.portage.thirdpartymirrors.has_key(mirrorname):
309 x = self.portage.thirdpartymirrors[mirrorname]
310 return x
311
313 return self.portage.settings[var]
314
316 config_protect = self.portage.settings['CONFIG_PROTECT']
317 config_protect = config_protect.split()
318 config_protect_mask = self.portage.settings['CONFIG_PROTECT_MASK']
319 config_protect_mask = config_protect_mask.split()
320
321 protect = []
322 for x in config_protect:
323 x = os.path.expandvars(x)
324 protect.append(x)
325 mask = []
326 for x in config_protect_mask:
327 x = os.path.expandvars(x)
328 mask.append(x)
329 return ' '.join(protect),' '.join(mask)
330
332
333 if not etpConst['spm']['cache'].has_key('portage'):
334 etpConst['spm']['cache']['portage'] = {}
335 if not etpConst['spm']['cache']['portage'].has_key('vartree'):
336 etpConst['spm']['cache']['portage']['vartree'] = {}
337
338 cached = etpConst['spm']['cache']['portage']['vartree'].get(root)
339 if cached != None:
340 return cached
341
342 try:
343 mytree = self.portage.vartree(root=root)
344 except Exception, e:
345 raise SPMError("SPMError: %s: %s" % (Exception,e,))
346 etpConst['spm']['cache']['portage']['vartree'][root] = mytree
347 return mytree
348
350
351 if not etpConst['spm']['cache'].has_key('portage'):
352 etpConst['spm']['cache']['portage'] = {}
353 if not etpConst['spm']['cache']['portage'].has_key('portagetree'):
354 etpConst['spm']['cache']['portage']['portagetree'] = {}
355
356 cached = etpConst['spm']['cache']['portage']['portagetree'].get(root)
357 if cached != None:
358 return cached
359
360 try:
361 mytree = self.portage.portagetree(root=root)
362 except Exception, e:
363 raise SPMError("SPMError: %s: %s" % (Exception,e,))
364 etpConst['spm']['cache']['portage']['portagetree'][root] = mytree
365 return mytree
366
368
369 if not etpConst['spm']['cache'].has_key('portage'):
370 etpConst['spm']['cache']['portage'] = {}
371 if not etpConst['spm']['cache']['portage'].has_key('binarytree'):
372 etpConst['spm']['cache']['portage']['binarytree'] = {}
373
374 cached = etpConst['spm']['cache']['portage']['binarytree'].get(root)
375 if cached != None:
376 return cached
377
378 pkgdir = root+self.portage.settings['PKGDIR']
379 try:
380 mytree = self.portage.binarytree(root,pkgdir)
381 except Exception, e:
382 raise SPMError("SPMError: %s: %s" % (Exception,e,))
383 etpConst['spm']['cache']['portage']['binarytree'][root] = mytree
384 return mytree
385
387
388 if use_cache:
389 if not etpConst['spm']['cache'].has_key('portage'):
390 etpConst['spm']['cache']['portage'] = {}
391 if not etpConst['spm']['cache']['portage'].has_key('config'):
392 etpConst['spm']['cache']['portage']['config'] = {}
393
394 cached = etpConst['spm']['cache']['portage']['config'].get((config_root,root))
395 if cached != None:
396 return cached
397
398 try:
399 mysettings = self.portage.config(config_root = config_root, target_root = root, config_incrementals = self.portage_const.INCREMENTALS)
400 except Exception, e:
401 raise SPMError("SPMError: %s: %s" % (Exception,e,))
402 if use_cache:
403 etpConst['spm']['cache']['portage']['config'][(config_root,root)] = mysettings
404 return mysettings
405
406
407
409 try:
410 return self.portage.portdb.xmatch(match,str(atom))
411 except ValueError:
412 return None
413
414
416 atoms = self.portage.portdb.xmatch("match-all",str(atom))
417 return self.portage_best(atoms)
418
420 from xml.dom import minidom
421 data = {}
422 portdir = self.portage.settings['PORTDIR']
423 myfile = os.path.join(portdir,category,"metadata.xml")
424 if os.access(myfile,os.R_OK) and os.path.isfile(myfile):
425 doc = minidom.parse(myfile)
426 longdescs = doc.getElementsByTagName("longdescription")
427 for longdesc in longdescs:
428 data[longdesc.getAttribute("lang").strip()] = ' '.join([x.strip() for x in longdesc.firstChild.data.strip().split("\n")])
429 return data
430
432 try:
433 return self.portage.portdb.xmatch("match-all",str(atom))[0].split("/")[0]
434 except:
435 return None
436
437
439 system = self.portage.settings.packages
440 sysoutput = []
441 for x in system:
442 y = self.get_installed_atoms(x)
443 if (y != None):
444 for z in y:
445 sysoutput.append(z)
446 sysoutput.extend(etpConst['spm']['system_packages'])
447 return sysoutput
448
450 mypath = etpConst['systemroot']+"/"
451 mytree = self._get_portage_vartree(mypath)
452 rc = mytree.dep_match(str(atom))
453 if rc: return rc[-1]
454
456 if atom.startswith("="): atom = atom[1:]
457 return self.portage.portdb.aux_get(atom,['DESCRIPTION'])[0]
458
460 if atom.startswith("="): atom = atom[1:]
461 return self.portage.portdb.findname(atom)
462
464 if atom.startswith("="): atom = atom[1:]
465 ebuild_path = self.get_package_ebuild_path(atom)
466 if isinstance(ebuild_path,basestring):
467 cp = os.path.join(os.path.dirname(ebuild_path),"ChangeLog")
468 if os.path.isfile(cp) and os.access(cp,os.R_OK):
469 f = open(cp,"r")
470 txt = f.read()
471 f.close()
472 return txt
473
475 mypath = etpConst['systemroot']+"/"
476 mytree = self._get_portage_vartree(mypath)
477 if atom.startswith("="): atom = atom[1:]
478 rc = mytree.dbapi.aux_get(atom, ["DESCRIPTION"])[0]
479 if rc: return rc
480
482 if atom.startswith("="): atom = atom[1:]
483 return self.portage.portdb.aux_get(atom,['SLOT'])[0]
484
486 mypath = etpConst['systemroot']+"/"
487 mytree = self._get_portage_vartree(mypath)
488 if atom.startswith("="): atom = atom[1:]
489 rc = mytree.getslot(atom)
490 if rc: return rc
491
493 mypath = etpConst['systemroot']+"/"
494 mytree = self._get_portage_vartree(mypath)
495 rc = mytree.dep_match(str(atom))
496 if rc: return rc
497
499 key_split = key.split("/")
500 cat = key_split[0]
501 name = key_split[1]
502 cat_dir = os.path.join(self.get_vdb_path(),cat)
503 if not os.path.isdir(cat_dir):
504 return []
505 return [os.path.join(cat,x) for x in os.listdir(cat_dir) if \
506 x.startswith(name)]
507
508
510
511
512 pkgname = atom.split("/")[1]
513 pkgcat = atom.split("/")[0]
514
515 if not os.path.isdir(dirpath):
516 os.makedirs(dirpath)
517 dirpath += "/"+pkgname+etpConst['packagesext']
518 dbdir = self.get_vdb_path()+"/"+pkgcat+"/"+pkgname+"/"
519
520 import tarfile
521 import stat
522 trees = self.portage.db["/"]
523 vartree = trees["vartree"]
524 dblnk = self.portage.dblink(pkgcat, pkgname, "/", vartree.settings, treetype="vartree", vartree=vartree)
525 dblnk.lockdb()
526 tar = tarfile.open(dirpath,"w:bz2")
527
528 contents = dblnk.getcontents()
529 paths = sorted(contents.keys())
530
531 for path in paths:
532 try:
533 exist = os.lstat(path)
534 except OSError:
535 continue
536 ftype = contents[path][0]
537 lpath = path
538 arcname = path[1:]
539 if 'dir' == ftype and \
540 not stat.S_ISDIR(exist.st_mode) and \
541 os.path.isdir(lpath):
542 lpath = os.path.realpath(lpath)
543 tarinfo = tar.gettarinfo(lpath, arcname)
544
545 if stat.S_ISREG(exist.st_mode):
546 tarinfo.mode = stat.S_IMODE(exist.st_mode)
547 tarinfo.type = tarfile.REGTYPE
548 f = open(path)
549 try:
550 tar.addfile(tarinfo, f)
551 finally:
552 f.close()
553 else:
554 tar.addfile(tarinfo)
555
556 tar.close()
557
558
559 import entropy.xpak as xpak
560 tbz2 = xpak.tbz2(dirpath)
561 tbz2.recompose(dbdir)
562
563 dblnk.unlockdb()
564
565 if os.path.isfile(dirpath):
566 return dirpath
567 else:
568 raise FileNotFound("FileNotFound: Spm:quickpkg %s: %s %s" % (
569 _("error"),
570 dirpath,
571 _("not found"),
572 )
573 )
574
576 return os.path.join(self.portage_const.USER_CONFIG_PATH,'package.use')
577
579 result = self.unset_package_useflags(atom, useflags)
580 if not result: return False
581 return self._handle_new_useflags(atom, useflags, "")
582
584 result = self.unset_package_useflags(atom, useflags)
585 if not result: return False
586 return self._handle_new_useflags(atom, useflags, "-")
587
589 matched_atom = self.get_best_atom(atom)
590 if not matched_atom:
591 return False
592 use_file = self.get_package_use_file()
593
594 if not (os.path.isfile(use_file) and os.access(use_file,os.W_OK)):
595 return False
596 f = open(use_file,"r")
597 content = [x.strip() for x in f.readlines()]
598 f.close()
599
600 def handle_line(line, useflags):
601
602 data = line.split()
603 if len(data) < 2:
604 return False, line
605
606 myatom = data[0]
607 if matched_atom != self.get_best_atom(myatom):
608 return False, line
609
610 flags = data[1:]
611 base_flags = []
612 added_flags = []
613 for flag in flags:
614 myflag = flag
615 if myflag.startswith("+"):
616 myflag = myflag[1:]
617 elif myflag.startswith("-"):
618 myflag = myflag[1:]
619 if not myflag:
620 continue
621 base_flags.append(myflag)
622
623 for useflag in useflags:
624 if mark+useflag in base_flags:
625 continue
626 added_flags.append(mark+useflag)
627
628 new_line = "%s %s" % (myatom, ' '.join(flags+added_flags))
629 return True, new_line
630
631
632 atom_found = False
633 new_content = []
634 for line in content:
635
636 changed, elaborated_line = handle_line(line, useflags)
637 if changed: atom_found = True
638 new_content.append(elaborated_line)
639
640 if not atom_found:
641 myline = "%s %s" % (atom, ' '.join([mark+x for x in useflags]))
642 new_content.append(myline)
643
644
645 f = open(use_file+".tmp","w")
646 for line in new_content:
647 f.write(line+"\n")
648 f.flush()
649 f.close()
650 os.rename(use_file+".tmp", use_file)
651 return True
652
654 matched_atom = self.get_best_atom(atom)
655 if not matched_atom:
656 return False
657
658 use_file = self.get_package_use_file()
659 if not (os.path.isfile(use_file) and os.access(use_file,os.W_OK)):
660 return False
661
662 f = open(use_file,"r")
663 content = [x.strip() for x in f.readlines()]
664 f.close()
665
666 new_content = []
667 for line in content:
668
669 data = line.split()
670 if len(data) < 2:
671 new_content.append(line)
672 continue
673
674 myatom = data[0]
675 if matched_atom != self.get_best_atom(myatom):
676 new_content.append(line)
677 continue
678
679 flags = data[1:]
680 new_flags = []
681 for flag in flags:
682 myflag = flag
683
684 if myflag.startswith("+"):
685 myflag = myflag[1:]
686 elif myflag.startswith("-"):
687 myflag = myflag[1:]
688
689 if myflag in useflags:
690 continue
691 elif not flag:
692 continue
693
694 new_flags.append(flag)
695
696 if new_flags:
697 new_line = "%s %s" % (myatom, ' '.join(new_flags))
698 new_content.append(new_line)
699
700 f = open(use_file+".tmp","w")
701 for line in new_content:
702 f.write(line+"\n")
703 f.flush()
704 f.close()
705 os.rename(use_file+".tmp", use_file)
706 return True
707
709 matched_atom = self.get_best_atom(atom)
710 if not matched_atom:
711 return {}
712 global_useflags = self.get_useflags()
713 use_force = self.get_useflags_force()
714 use_mask = self.get_useflags_mask()
715 package_use_useflags = self.get_package_use_useflags(atom)
716
717 data = {}
718 data['use_force'] = use_force.copy()
719 data['use_mask'] = use_mask.copy()
720 data['global_use'] = global_useflags.split()
721
722 iuse = self.get_package_setting(atom, "IUSE")
723 if not isinstance(iuse, basestring):
724 iuse = ''
725 data['iuse'] = iuse.split()[:]
726 iuse = set()
727 for myiuse in data['iuse']:
728 if myiuse.startswith("+"):
729 myiuse = myiuse[1:]
730 iuse.add(myiuse)
731
732 use = [f for f in data['global_use']+list(package_use_useflags['enabled']) if (f in iuse) and (f not in use_mask) and (f not in package_use_useflags['disabled'])]
733 use_disabled = [f for f in iuse if (f not in data['global_use']) and (f not in use_mask) and (f not in package_use_useflags['enabled'])]
734 data['use'] = use[:]
735 data['use_disabled'] = use_disabled[:]
736
737 matched_slot = self.get_package_slot(matched_atom)
738 try:
739 installed_atom = self.get_installed_atom("%s:%s" % (self.entropyTools.dep_getkey(atom),matched_slot,))
740 except self.portage_exception:
741 installed_atom = None
742
743 if installed_atom:
744
745
746 previous_iuse = self.get_installed_package_setting(installed_atom, "IUSE").split()
747 previous_use = self.get_installed_package_setting(installed_atom, "USE").split()
748
749 new_previous_iuse = set()
750 for myuse in previous_iuse:
751 if myuse.startswith("+"):
752 myuse = myuse[1:]
753 new_previous_iuse.add(myuse)
754 previous_iuse = list(new_previous_iuse)
755
756 inst_use = [f for f in previous_iuse if (f in previous_use) and (f not in use_mask)]
757
758
759
760 use_removed = []
761 for myuse in inst_use:
762 if myuse not in use:
763 use_removed.append(myuse)
764
765
766 use_not_avail = []
767 for myuse in previous_iuse:
768 if (myuse not in iuse) and (myuse not in use_removed):
769 use_not_avail.append(myuse)
770
771
772 t_use = []
773 for myuse in use:
774 if myuse not in inst_use:
775 myuse = "+%s*" % (myuse,)
776 t_use.append(myuse)
777 use = t_use
778
779
780 t_use_disabled = []
781 for myuse in use_disabled:
782 if myuse in inst_use:
783 if myuse in use_removed+use_not_avail:
784 continue
785 myuse = "-%s*" % (myuse,)
786 else:
787 myuse = "-%s" % (myuse,)
788 t_use_disabled.append(myuse)
789 use_disabled = t_use_disabled
790
791 for myuse in use_removed:
792 use_disabled.append("(-%s*)" % (myuse,))
793 for myuse in use_not_avail:
794 use_disabled.append("(-%s)" % (myuse,))
795 else:
796 use_disabled = ["-"+x for x in use_disabled]
797
798 data['use_string'] = ' '.join(sorted(use)+sorted([x for x in use_disabled]))
799 data['use_string_colored'] = ' '.join(
800 sorted([darkred(x) for x in use if not x.startswith("+")] + \
801 [darkgreen(x) for x in use if x.startswith("+")]) + \
802 sorted([darkblue(x) for x in use_disabled if x.startswith("-")] + \
803 [brown(x) for x in use_disabled if x.startswith("(") and (x.find("*") == -1)] + \
804 [purple(x) for x in use_disabled if x.startswith("(") and (x.find("*") != -1)]
805 )
806 )
807 return data
808
810
811 matched_atom = self.get_installed_atom(atom)
812 if not matched_atom:
813 return {}
814
815 global_use = self.get_installed_package_setting(matched_atom, "USE")
816 use_mask = self.get_useflags_mask()
817
818 data = {}
819 data['use_mask'] = use_mask.copy()
820 data['global_use'] = global_use.split()
821
822 iuse = self.get_installed_package_setting(matched_atom, "IUSE")
823 if not isinstance(iuse,basestring): iuse = ''
824 data['iuse'] = iuse.split()[:]
825 iuse = set()
826 for myiuse in data['iuse']:
827 if myiuse.startswith("+"):
828 myiuse = myiuse[1:]
829 iuse.add(myiuse)
830
831 use = [f for f in data['global_use'] if (f in iuse) and (f not in use_mask)]
832 use_disabled = [f for f in iuse if (f not in data['global_use']) and (f not in use_mask)]
833 data['use'] = use[:]
834 data['use_disabled'] = use_disabled[:]
835
836 data['use_string'] = ' '.join(sorted(use)+sorted([x for x in use_disabled]))
837 data['use_string_colored'] = ' '.join(
838 sorted([darkred(x) for x in use if not x.startswith("+")] + \
839 [darkgreen(x) for x in use if x.startswith("+")]) + \
840 sorted([darkblue(x) for x in use_disabled if x.startswith("-")] + \
841 [brown(x) for x in use_disabled if x.startswith("(") and (x.find("*") == -1)] + \
842 [purple(x) for x in use_disabled if x.startswith("(") and (x.find("*") != -1)]
843 )
844 )
845 return data
846
847
849
850 data = {
851 'enabled': set(),
852 'disabled': set(),
853 }
854
855 matched_atom = self.get_best_atom(atom)
856 if not matched_atom:
857 return data
858
859 use_file = self.get_package_use_file()
860 if not (os.path.isfile(use_file) and os.access(use_file,os.W_OK)):
861 return data
862
863 use_data = self.portage_util.grabdict(use_file)
864 for myatom in use_data:
865 mymatch = self.get_best_atom(myatom)
866 if mymatch != matched_atom:
867 continue
868 for flag in use_data[myatom]:
869 if flag.startswith("-"):
870 myflag = flag[1:]
871 data['enabled'].discard(myflag)
872 data['disabled'].add(myflag)
873 else:
874 myflag = flag
875 if myflag.startswith("+"):
876 myflag = myflag[1:]
877 data['disabled'].discard(myflag)
878 data['enabled'].add(myflag)
879
880 return data
881
883 return self.portage.settings['USE']
884
886 return self.portage.settings.useforce
887
889 return self.portage.settings.usemask
890
892 mypath = etpConst['systemroot']+"/"
893 mytree = self._get_portage_vartree(mypath)
894 if atom.startswith("="): atom = atom[1:]
895 return mytree.dbapi.aux_get(atom, [setting])[0]
896
898 if atom.startswith("="): atom = atom[1:]
899 return self.portage.portdb.aux_get(atom,[setting])[0]
900
902 mypath = etpConst['systemroot']+"/"
903 mysplit = atom.split("/")
904 content = self.portage.dblink(mysplit[0], mysplit[1], mypath, self.portage.settings).getcontents()
905 return content.keys()
906
908 mypath = etpConst['systemroot']+"/"
909 mytree = self._get_portage_vartree(mypath)
910 packages = mytree.dbapi.cpv_all()
911 matches = set()
912 for package in packages:
913 mysplit = package.split("/")
914 content = self.portage.dblink(mysplit[0], mysplit[1], mypath, self.portage.settings).getcontents()
915 if not like:
916 if filename in content:
917 matches.add(package)
918 else:
919 for myfile in content:
920 if myfile.find(filename) != -1:
921 matches.add(package)
922 return matches
923
925 mypath = etpConst['systemroot']+"/"
926 mytree = self._get_portage_vartree(mypath)
927 packages = mytree.dbapi.cpv_all()
928 matches = {}
929 filenames = filenames.copy()
930 for package in packages:
931 cat, pkgv = package.split("/")
932 content = self.portage.dblink(cat, pkgv, mypath, self.portage.settings).getcontents()
933 if not like:
934 for filename in filenames:
935 if filename in content:
936 myslot = self.get_installed_package_slot(package)
937 if not matches.has_key((package,myslot)):
938 matches[(package,myslot)] = set()
939 matches[(package,myslot)].add(filename)
940 else:
941 for filename in filenames:
942 for myfile in content:
943 if myfile.find(filename) != -1:
944 myslot = self.get_installed_package_slot(package)
945 if not matches.has_key((package,myslot)):
946 matches[(package,myslot)] = set()
947 matches[(package,myslot)].add(filename)
948 return matches
949
951 use = set()
952 use_mask = self.get_useflags_mask()
953 use_force = self.get_useflags_force()
954 for myiuse in iuse_list:
955 if myiuse[0] in ("+", "-",):
956 myiuse = myiuse[1:]
957 if ((myiuse in use_list) or (myiuse in use_force)) and \
958 (myiuse not in use_mask):
959 use.add(myiuse)
960 return use
961
962 - def calculate_dependencies(self, my_iuse, my_use, my_license, my_depend, my_rdepend, my_pdepend, my_provide, my_src_uri):
963
964 metadata = {
965 'LICENSE': my_license,
966 'DEPEND': my_depend,
967 'PDEPEND': my_pdepend,
968 'RDEPEND': my_rdepend,
969 'PROVIDE': my_provide,
970 'SRC_URI': my_src_uri,
971 'USE_MASK': sorted(self.get_useflags_mask()),
972 'USE_FORCE': sorted(self.get_useflags_force()),
973 }
974
975
976 raw_use = my_use.split()
977 enabled_use = sorted(self._resolve_enabled_useflags(
978 my_iuse.split(), raw_use))
979
980 metadata['ENABLED_USE'] = enabled_use
981 use = raw_use + [x for x in metadata['USE_FORCE'] if x not in raw_use]
982 metadata['USE'] = sorted([unicode(x) for x in use if x not in \
983 metadata['USE_MASK']])
984
985 for k in "LICENSE", "RDEPEND", "DEPEND", "PDEPEND", "PROVIDE", "SRC_URI":
986 try:
987 if k == "SRC_URI":
988 deps = self.src_uri_paren_reduce(metadata[k])
989 else:
990 deps = self.paren_reduce(metadata[k])
991 deps = self.use_reduce(deps, uselist = raw_use)
992 deps = self.paren_normalize(deps)
993 if k == "LICENSE":
994 deps = self.paren_license_choose(deps)
995 else:
996 deps = self.paren_choose(deps)
997 if k.endswith("DEPEND"):
998 deps = self.usedeps_reduce(deps, enabled_use)
999 deps = ' '.join(deps)
1000 except Exception, e:
1001 self.entropyTools.print_traceback()
1002 self.updateProgress(
1003 darkred("%s: %s: %s :: %s") % (
1004 _("Error calculating dependencies"),
1005 str(Exception),
1006 k,
1007 e,
1008 ),
1009 importance = 1,
1010 type = "error",
1011 header = red(" !!! ")
1012 )
1013 deps = ''
1014 continue
1015 metadata[k] = deps
1016 return metadata
1017
1019 src_uris = self.paren_reduce(src_uris)
1020 newlist = []
1021 skip_next = False
1022 for src_uri in src_uris:
1023 if skip_next:
1024 skip_next = False
1025 continue
1026 if src_uri == "->":
1027 skip_next = True
1028 continue
1029 newlist.append(src_uri)
1030 return newlist
1031
1033 newlist = []
1034
1035 def strip_use(xuse):
1036 myuse = xuse[:]
1037 if myuse[0] == "!":
1038 myuse = myuse[1:]
1039 if myuse[-1] in ("=","?",):
1040 myuse = myuse[:-1]
1041 return myuse
1042
1043 for dependency in dependencies:
1044 use_deps = self.entropyTools.dep_getusedeps(dependency)
1045 if use_deps:
1046 new_use_deps = []
1047 for use in use_deps:
1048 """
1049 explicitly support only specific types
1050 """
1051 if (use[0] == "!") and (use[-1] not in ("=","?",)):
1052
1053 continue
1054 elif use[-1] == "=":
1055 if use[0] == "!":
1056
1057 s_use = strip_use(use)
1058 if s_use in enabled_useflags:
1059 new_use_deps.append("-%s" % (s_use,))
1060 else:
1061 new_use_deps.append(s_use)
1062 continue
1063 else:
1064
1065 s_use = strip_use(use)
1066 if s_use in enabled_useflags:
1067 new_use_deps.append(s_use)
1068 else:
1069 new_use_deps.append("-%s" % (s_use,))
1070 continue
1071 elif use[-1] == "?":
1072 if use[0] == "!":
1073
1074 s_use = strip_use(use)
1075 if s_use not in enabled_useflags:
1076 new_use_deps.append("-%s" % (s_use,))
1077 continue
1078 else:
1079
1080 s_use = strip_use(use)
1081 if s_use in enabled_useflags:
1082 new_use_deps.append(s_use)
1083 continue
1084 new_use_deps.append(use)
1085
1086 if new_use_deps:
1087 dependency = "%s[%s]" % (
1088 self.entropyTools.remove_usedeps(dependency),
1089 ','.join(new_use_deps),
1090 )
1091 else:
1092 dependency = self.entropyTools.remove_usedeps(dependency)
1093
1094 newlist.append(dependency)
1095 return newlist
1096
1098 """
1099
1100 # deps.py -- Portage dependency resolution functions
1101 # Copyright 2003-2004 Gentoo Foundation
1102 # Distributed under the terms of the GNU General Public License v2
1103 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
1104
1105 Take a string and convert all paren enclosed entities into sublists, optionally
1106 futher splitting the list elements by spaces.
1107
1108 Example usage:
1109 >>> paren_reduce('foobar foo ( bar baz )',1)
1110 ['foobar', 'foo', ['bar', 'baz']]
1111 >>> paren_reduce('foobar foo ( bar baz )',0)
1112 ['foobar foo ', [' bar baz ']]
1113
1114 @param mystr: The string to reduce
1115 @type mystr: String
1116 @rtype: Array
1117 @return: The reduced string in an array
1118 """
1119 mylist = []
1120 while mystr:
1121 left_paren = mystr.find("(")
1122 has_left_paren = left_paren != -1
1123 right_paren = mystr.find(")")
1124 has_right_paren = right_paren != -1
1125 if not has_left_paren and not has_right_paren:
1126 freesec = mystr
1127 subsec = None
1128 tail = ""
1129 elif mystr[0] == ")":
1130 return [mylist,mystr[1:]]
1131 elif has_left_paren and not has_right_paren:
1132 raise InvalidDependString(
1133 "InvalidDependString: %s: '%s'" % (_("missing right parenthesis"),mystr,))
1134 elif has_left_paren and left_paren < right_paren:
1135 freesec,subsec = mystr.split("(",1)
1136 subsec,tail = self.paren_reduce(subsec)
1137 else:
1138 subsec,tail = mystr.split(")",1)
1139 subsec = self.strip_empty(subsec.split(" "))
1140 return [mylist+subsec,tail]
1141 mystr = tail
1142 if freesec:
1143 mylist = mylist + self.strip_empty(freesec.split(" "))
1144 if subsec is not None:
1145 mylist = mylist + [subsec]
1146 return mylist
1147
1149 """
1150
1151 # deps.py -- Portage dependency resolution functions
1152 # Copyright 2003-2004 Gentoo Foundation
1153 # Distributed under the terms of the GNU General Public License v2
1154 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
1155
1156 Strip all empty elements from an array
1157
1158 @param myarr: The list of elements
1159 @type myarr: List
1160 @rtype: Array
1161 @return: The array with empty elements removed
1162 """
1163 for x in range(len(myarr)-1, -1, -1):
1164 if not myarr[x]:
1165 del myarr[x]
1166 return myarr
1167
1168 - def use_reduce(self, deparray, uselist=[], masklist=[], matchall=0, excludeall=[]):
1169 """
1170
1171 # deps.py -- Portage dependency resolution functions
1172 # Copyright 2003-2004 Gentoo Foundation
1173 # Distributed under the terms of the GNU General Public License v2
1174 # $Id: portage_dep.py 9174 2008-01-11 05:49:02Z zmedico $
1175
1176 Takes a paren_reduce'd array and reduces the use? conditionals out
1177 leaving an array with subarrays
1178
1179 @param deparray: paren_reduce'd list of deps
1180 @type deparray: List
1181 @param uselist: List of use flags
1182 @type uselist: List
1183 @param masklist: List of masked flags
1184 @type masklist: List
1185 @param matchall: Resolve all conditional deps unconditionally. Used by repoman
1186 @type matchall: Integer
1187 @rtype: List
1188 @return: The use reduced depend array
1189 """
1190
1191 for x in range(len(deparray)):
1192 if deparray[x] in ["||","&&"]:
1193 if len(deparray) - 1 == x or not isinstance(deparray[x+1], list):
1194 mytxt = _("missing atom list in")
1195 raise InvalidDependString(deparray[x]+" "+mytxt+" \""+str(deparray)+"\"")
1196 if deparray and deparray[-1] and deparray[-1][-1] == "?":
1197 mytxt = _("Conditional without target in")
1198 raise InvalidDependString("InvalidDependString: "+mytxt+" \""+str(deparray)+"\"")
1199
1200
1201
1202
1203
1204 _dep_check_strict = False
1205
1206 mydeparray = deparray[:]
1207 rlist = []
1208 while mydeparray:
1209 head = mydeparray.pop(0)
1210
1211 if isinstance(head,list):
1212 additions = self.use_reduce(head, uselist, masklist, matchall, excludeall)
1213 if additions:
1214 rlist.append(additions)
1215 elif rlist and rlist[-1] == "||":
1216
1217
1218 rlist.append([])
1219 else:
1220 if head[-1] == "?":
1221
1222 newdeparray = [head]
1223 while isinstance(newdeparray[-1], basestring) and newdeparray[-1][-1] == "?":
1224 if mydeparray:
1225 newdeparray.append(mydeparray.pop(0))
1226 else:
1227 raise ValueError, _("Conditional with no target")
1228
1229
1230 warned = 0
1231 if len(newdeparray[-1]) == 0:
1232 mytxt = "%s. (%s)" % (_("Empty target in string"),_("Deprecated"),)
1233 self.updateProgress(
1234 darkred("PortagePlugin.use_reduce(): %s" % (mytxt,)),
1235 importance = 0,
1236 type = "error",
1237 header = bold(" !!! ")
1238 )
1239 warned = 1
1240 if len(newdeparray) != 2:
1241 mytxt = "%s. (%s)" % (_("Nested use flags without parenthesis"),_("Deprecated"),)
1242 self.updateProgress(
1243 darkred("PortagePlugin.use_reduce(): %s" % (mytxt,)),
1244 importance = 0,
1245 type = "error",
1246 header = bold(" !!! ")
1247 )
1248 warned = 1
1249 if warned:
1250 self.updateProgress(
1251 darkred("PortagePlugin.use_reduce(): "+" ".join(map(str,[head]+newdeparray))),
1252 importance = 0,
1253 type = "error",
1254 header = bold(" !!! ")
1255 )
1256
1257
1258 ismatch = True
1259 missing_flag = False
1260 for head in newdeparray[:-1]:
1261 head = head[:-1]
1262 if not head:
1263 missing_flag = True
1264 break
1265 if head.startswith("!"):
1266 head_key = head[1:]
1267 if not head_key:
1268 missing_flag = True
1269 break
1270 if not matchall and head_key in uselist or \
1271 head_key in excludeall:
1272 ismatch = False
1273 break
1274 elif head not in masklist:
1275 if not matchall and head not in uselist:
1276 ismatch = False
1277 break
1278 else:
1279 ismatch = False
1280 if missing_flag:
1281 mytxt = _("Conditional without flag")
1282 raise InvalidDependString(
1283 "InvalidDependString: "+mytxt+": \"" + \
1284 str([head+"?", newdeparray[-1]])+"\"")
1285
1286
1287 if ismatch:
1288 target = newdeparray[-1]
1289 if isinstance(target, list):
1290 additions = self.use_reduce(target, uselist, masklist, matchall, excludeall)
1291 if additions:
1292 rlist.append(additions)
1293 elif not _dep_check_strict:
1294
1295 rlist.append(target)
1296 else:
1297 mytxt = _("Conditional without parenthesis")
1298 raise InvalidDependString(
1299 "InvalidDependString: "+mytxt+": '%s?'" % head)
1300
1301 else:
1302 rlist += [head]
1303 return rlist
1304
1306 newlist = []
1307 do_skip = False
1308 for idx in range(len(dep_list)):
1309
1310 if do_skip:
1311 do_skip = False
1312 continue
1313
1314 item = dep_list[idx]
1315 if item == "||":
1316 next_item = dep_list[idx+1]
1317 if not next_item:
1318 do_skip = True
1319 continue
1320 item = self.dep_or_select(next_item)
1321 if not item:
1322
1323 newlist.append(str(next_item))
1324 else:
1325 newlist += item
1326 do_skip = True
1327 elif isinstance(item, list):
1328 item = self.dep_and_select(item)
1329 newlist += item
1330 else:
1331 newlist.append(item)
1332
1333 return newlist
1334
1336 do_skip = False
1337 newlist = []
1338 for idx in range(len(and_list)):
1339
1340 if do_skip:
1341 do_skip = False
1342 continue
1343
1344 x = and_list[idx]
1345 if x == "||":
1346 x = self.dep_or_select(and_list[idx+1])
1347 do_skip = True
1348 if not x:
1349 x = str(and_list[idx+1])
1350 else:
1351 newlist += x
1352 elif isinstance(x, list):
1353 x = self.dep_and_select(x)
1354 newlist += x
1355 else:
1356 newlist.append(x)
1357
1358
1359 for x in newlist:
1360 match = self.get_installed_atom(x)
1361 if match == None:
1362 return []
1363
1364 return newlist
1365
1367 do_skip = False
1368 for idx in range(len(or_list)):
1369 if do_skip:
1370 do_skip = False
1371 continue
1372 x = or_list[idx]
1373 if x == "||":
1374 x = self.dep_or_select(or_list[idx+1])
1375 do_skip = True
1376 elif isinstance(x, list):
1377 x = self.dep_and_select(x)
1378 if not x:
1379 continue
1380
1381 return x
1382 else:
1383 x = [x]
1384
1385 for y in x:
1386 match = self.get_installed_atom(y)
1387 if match != None:
1388 return [y]
1389
1390 return []
1391
1393
1394 newlist = set()
1395 for item in dep_list:
1396
1397 if isinstance(item, list):
1398
1399 data = set(self.paren_license_choose(item))
1400 newlist.update(data)
1401 else:
1402 if item not in ["||"]:
1403 newlist.add(item)
1404
1405 return list(newlist)
1406
1408 rc = etpConst['systemroot']+"/"+self.portage_const.VDB_PATH
1409 if (not rc.endswith("/")):
1410 return rc+"/"
1411 return rc
1412
1414 mypath = etpConst['systemroot']+"/"
1415 mysettings = self._get_portage_config("/",mypath)
1416 portdb = self.portage.portdbapi(mysettings["PORTDIR"], mysettings = mysettings)
1417 cps = portdb.cp_all()
1418 visibles = set()
1419 for cp in cps:
1420 if categories and cp.split("/")[0] not in categories:
1421 continue
1422
1423 slots = set()
1424 atoms = self.get_best_atom(cp, "match-visible")
1425 if atoms:
1426 for atom in atoms:
1427 slots.add(portdb.aux_get(atom, ["SLOT"])[0])
1428 for slot in slots:
1429 visibles.add(cp+":"+slot)
1430 del cps
1431
1432
1433 available = set()
1434 for visible in visibles:
1435 match = self.get_best_atom(visible)
1436 if match == None:
1437 continue
1438 if filter_reinstalls:
1439 installed = self.get_installed_atom(visible)
1440
1441 if installed != match:
1442 available.add(match)
1443 else:
1444 available.add(match)
1445 del visibles
1446
1447 return available
1448
1449
1451 if not dbdir:
1452 appDbDir = self.get_vdb_path()
1453 else:
1454 appDbDir = dbdir
1455 dbDirs = os.listdir(appDbDir)
1456 installedAtoms = set()
1457 for pkgsdir in dbDirs:
1458 if os.path.isdir(appDbDir+pkgsdir):
1459 pkgdir = os.listdir(appDbDir+pkgsdir)
1460 for pdir in pkgdir:
1461 pkgcat = pkgsdir.split("/")[-1]
1462 if categories and (pkgcat not in categories):
1463 continue
1464 pkgatom = pkgcat+"/"+pdir
1465 if pkgatom.find("-MERGING-") == -1:
1466 installedAtoms.add(pkgatom)
1467 return sorted(list(installedAtoms)), len(installedAtoms)
1468
1470 if not dbdir:
1471 appDbDir = self.get_vdb_path()
1472 else:
1473 appDbDir = dbdir
1474 installedAtoms = set()
1475
1476 for current_dirpath, subdirs, files in os.walk(appDbDir):
1477 pvs = os.listdir(current_dirpath)
1478 for mypv in pvs:
1479 if mypv.startswith("-MERGING-"):
1480 continue
1481 mypvpath = current_dirpath+"/"+mypv
1482 if not os.path.isdir(mypvpath):
1483 continue
1484 mycounter_file = mypvpath+"/"+etpConst['spm']['xpak_entries']['counter']
1485 if not os.access(mycounter_file,os.R_OK):
1486 continue
1487 f = open(mycounter_file)
1488 try:
1489 counter = int(f.readline().strip())
1490 except (IOError, ValueError):
1491 f.close()
1492 continue
1493 installedAtoms.add((os.path.basename(current_dirpath)+"/"+mypv,counter))
1494 return installedAtoms
1495
1497
1498
1499 setconfigpaths = [os.path.join(self.portage_const.GLOBAL_CONFIG_PATH, etpConst['setsconffilename'])]
1500 setconfigpaths.append(os.path.join(settings["PORTDIR"], etpConst['setsconffilename']))
1501 setconfigpaths += [os.path.join(x, etpConst['setsconffilename']) for x in settings["PORTDIR_OVERLAY"].split()]
1502 setconfigpaths.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
1503 self.portage_const.USER_CONFIG_PATH.lstrip(os.path.sep), etpConst['setsconffilename']))
1504 return self.portage_sets.SetConfig(setconfigpaths, settings, trees)
1505
1507
1508 if self.portage_sets == None: return
1509 myroot = etpConst['systemroot']+"/"
1510 return self._load_sets_config(
1511 self.portage.settings,
1512 self.portage.db[myroot]
1513 )
1514
1516 config = self.get_set_config()
1517 if config == None: return {}
1518 mysets = config.getSets()
1519 if not builtin_sets:
1520 builtin_pkg_sets = [x for x in self.builtin_pkg_sets if x in mysets]
1521 for pkg_set in builtin_pkg_sets: mysets.pop(pkg_set)
1522 return mysets
1523
1525 config = self.get_set_config()
1526 if config == None: return []
1527 return config.getSetAtoms(pkgset_obj).copy()
1528
1530 config = self.get_set_config()
1531 if config == None: return {}
1532 mysets = {}
1533 sets = config.getSets()
1534 if not builtin_sets:
1535 builtin_pkg_sets = [x for x in self.builtin_pkg_sets if x in sets]
1536 for pkg_set in builtin_pkg_sets: sets.pop(pkg_set)
1537 for myset in sorted(sets):
1538 try: atoms = config.getSetAtoms(myset).copy()
1539 except: continue
1540 mysets[myset] = atoms
1541 return mysets
1542
1544 if not dbdir:
1545 appDbDir = self.get_vdb_path()
1546 else:
1547 appDbDir = dbdir
1548 counters = set()
1549 for catdir in os.listdir(appDbDir):
1550 catdir = appDbDir+catdir
1551 if not os.path.isdir(catdir):
1552 continue
1553 for pkgdir in os.listdir(catdir):
1554 pkgdir = catdir+"/"+pkgdir
1555 if not os.path.isdir(pkgdir):
1556 continue
1557 counterfile = pkgdir+"/"+etpConst['spm']['xpak_entries']['counter']
1558 if not os.path.isfile(pkgdir+"/"+etpConst['spm']['xpak_entries']['counter']):
1559 continue
1560 try:
1561 f = open(counterfile,"r")
1562 counter = int(f.readline().strip())
1563 counters.add(counter)
1564 f.close()
1565 except:
1566 continue
1567 if counters:
1568 newcounter = max(counters)
1569 else:
1570 newcounter = 0
1571 if not os.path.isdir(os.path.dirname(etpConst['edbcounter'])):
1572 os.makedirs(os.path.dirname(etpConst['edbcounter']))
1573 try:
1574 f = open(etpConst['edbcounter'],"w")
1575 except IOError, e:
1576 if e[0] == 21:
1577 shutil.rmtree(etpConst['edbcounter'],True)
1578 try:
1579 os.rmdir(etpConst['edbcounter'])
1580 except:
1581 pass
1582 f = open(etpConst['edbcounter'],"w")
1583 f.write(str(newcounter))
1584 f.flush()
1585 f.close()
1586 del counters
1587 return newcounter
1588
1589
1590 - def spm_doebuild(self, myebuild, mydo, tree, cpv, portage_tmpdir = None, licenses = [], fork = False):
1591 if fork:
1592
1593 return self.entropyTools.spawn_function(
1594 self._portage_doebuild, myebuild,
1595 mydo, tree, cpv,
1596 portage_tmpdir, licenses
1597 )
1598 return self._portage_doebuild(myebuild, mydo, tree, cpv, portage_tmpdir, licenses)
1599
1600 - def _portage_doebuild(self, myebuild, mydo, tree, cpv, portage_tmpdir = None, licenses = []):
1601
1602
1603
1604
1605
1606
1607 oldsystderr = sys.stderr
1608 f = open("/dev/null","w")
1609 if not etpUi['debug']:
1610 sys.stderr = f
1611
1612
1613
1614 domute = False
1615 if etpUi['mute']:
1616 domute = True
1617 oldsysstdout = sys.stdout
1618 sys.stdout = f
1619
1620 mypath = etpConst['systemroot']+"/"
1621
1622
1623 os.environ["SKIP_EQUO_SYNC"] = "1"
1624
1625
1626 myebuilddir = os.path.dirname(myebuild)
1627 keys = self.portage.auxdbkeys
1628 metadata = {}
1629
1630 for key in keys:
1631 mykeypath = os.path.join(myebuilddir,key)
1632 if os.path.isfile(mykeypath) and os.access(mykeypath,os.R_OK):
1633 f = open(mykeypath,"r")
1634 metadata[key] = f.readline().strip()
1635 f.close()
1636
1637
1638
1639
1640 mysettings = self._get_portage_config("/",mypath)
1641 mysettings['EBUILD_PHASE'] = mydo
1642
1643
1644
1645
1646
1647
1648 mysettings['LICENSE'] = str(' '.join(licenses))
1649 if licenses:
1650
1651 mysettings["ACCEPT_LICENSE"] = mysettings['LICENSE']
1652 mysettings.backup_changes("ACCEPT_LICENSE")
1653
1654 mysettings['EAPI'] = "0"
1655 if metadata.has_key('EAPI'):
1656 mysettings['EAPI'] = metadata['EAPI']
1657
1658
1659 mysettings['ROOT'] = mypath
1660 mysettings['CD_ROOT'] = "/tmp"
1661
1662 mysettings.backup_changes("EAPI")
1663 mysettings.backup_changes("LICENSE")
1664 mysettings.backup_changes("EBUILD_PHASE")
1665 mysettings.backup_changes("ROOT")
1666 mysettings.backup_changes("CD_ROOT")
1667
1668 try:
1669 mysettings._environ_whitelist = set(mysettings._environ_whitelist)
1670
1671 mysettings._environ_whitelist.add("SKIP_EQUO_SYNC")
1672 mysettings._environ_whitelist.add("ACCEPT_LICENSE")
1673 mysettings._environ_whitelist.add("CD_ROOT")
1674 mysettings._environ_whitelist.add("ROOT")
1675 mysettings._environ_whitelist = frozenset(mysettings._environ_whitelist)
1676 except:
1677 self.write_traceback_to_log()
1678
1679 cpv = str(cpv)
1680 mysettings.setcpv(cpv)
1681 portage_tmpdir_created = False
1682 if portage_tmpdir:
1683 if not os.path.isdir(portage_tmpdir):
1684 os.makedirs(portage_tmpdir)
1685 portage_tmpdir_created = True
1686 mysettings['PORTAGE_TMPDIR'] = str(portage_tmpdir)
1687 mysettings.backup_changes("PORTAGE_TMPDIR")
1688
1689 mydbapi = self.portage.fakedbapi(settings=mysettings)
1690 mydbapi.cpv_inject(cpv, metadata = metadata)
1691
1692
1693 vartree = self._get_portage_vartree(mypath)
1694
1695 try:
1696 rc = self.portage.doebuild(
1697 myebuild = str(myebuild),
1698 mydo = str(mydo),
1699 myroot = mypath,
1700 tree = tree,
1701 mysettings = mysettings,
1702 mydbapi = mydbapi,
1703 vartree = vartree,
1704 use_cache = 0
1705 )
1706 except:
1707 self.write_traceback_to_log()
1708 raise
1709
1710
1711 if domute:
1712 sys.stdout = oldsysstdout
1713
1714 sys.stderr = oldsystderr
1715 f.close()
1716
1717 if portage_tmpdir_created:
1718 shutil.rmtree(portage_tmpdir,True)
1719
1720 del mydbapi
1721 del metadata
1722 del keys
1723 return rc
1724
1809
1811
1812 pkg_content = {}
1813
1814 if os.path.isfile(content_file):
1815
1816 f = open(content_file,"r")
1817 content = [x.decode('raw_unicode_escape') for x in f.readlines()]
1818 f.close()
1819 outcontent = set()
1820 for line in content:
1821 line = line.strip().split()
1822 try:
1823 datatype = line[0]
1824 datafile = line[1:]
1825 if datatype == 'obj':
1826 datafile = datafile[:-2]
1827 datafile = ' '.join(datafile)
1828 elif datatype == 'dir':
1829 datafile = ' '.join(datafile)
1830 elif datatype == 'sym':
1831 datafile = datafile[:-3]
1832 datafile = ' '.join(datafile)
1833 else:
1834 myexc = "InvalidData: %s %s. %s." % (
1835 datafile,
1836 _("not supported"),
1837 _("Probably Portage API has changed"),
1838 )
1839 raise InvalidData(myexc)
1840 outcontent.add((datafile,datatype))
1841 except:
1842 pass
1843
1844 outcontent = sorted(outcontent)
1845 for datafile, datatype in outcontent:
1846 pkg_content[datafile] = datatype
1847
1848 else:
1849
1850
1851
1852 mytempdir = etpConst['packagestmpdir']+"/"+os.path.basename(package_path)+".inject"
1853 if os.path.isdir(mytempdir):
1854 shutil.rmtree(mytempdir)
1855 if not os.path.isdir(mytempdir):
1856 os.makedirs(mytempdir)
1857
1858 self.entropyTools.uncompress_tar_bz2(package_path, extractPath = mytempdir, catchEmpty = True)
1859 tmpdir_len = len(mytempdir)
1860 for currentdir, subdirs, files in os.walk(mytempdir):
1861 pkg_content[currentdir[tmpdir_len:]] = u"dir"
1862 for item in files:
1863 item = currentdir+"/"+item
1864 if os.path.islink(item):
1865 pkg_content[item[tmpdir_len:]] = u"sym"
1866 else:
1867 pkg_content[item[tmpdir_len:]] = u"obj"
1868
1869
1870 shutil.rmtree(mytempdir,True)
1871 try:
1872 os.rmdir(mytempdir)
1873 except (OSError,):
1874 pass
1875
1876 return pkg_content
1877
1902
1920
1954
1980
1994
2005
2006
2252