3 # Copyright 2006 Mike Pagano
4 # Distributed under the terms of the GNU General Public License v2
7 # Author: Mike Pagano <mpagano@gentoo.org>
9 # Portions written ripped from
10 # - equery, by Karl Trygve Kalleberg <karltk@gentoo.org>
11 # - gentoolkit.py, by Karl Trygve Kalleberg <karltk@gentoo.org>
17 __author__ = "Michael Pagano"
18 __email__ = "mpagano@gentoo.org"
19 __version__ = "2.0.12"
20 __productname__ = "portpeek"
21 __description__ = "Displays user unmasked ebuilds and installable options from the portage tree"
23 import sys, os, portage.output, fileinput
24 #import gentoolkit,gentoolkit.helpers,gentoolkit.package,gentoolkit.versionmatch,gentoolkit.query
25 from gentoolkit.versionmatch import VersionMatch,errors
26 from portage.const import USER_CONFIG_PATH
27 from portage.versions import catpkgsplit,pkgcmp,pkgsplit
28 from portage.exception import InvalidAtom
29 from gentoolkit.cpv import CPV
30 from gentoolkit.query import Query
32 porttree = portage.db[portage.root]["porttree"]
33 settings = portage.config(clone=portage.settings)
35 show_changes_only_flag = False
36 checking_package_unmask = False
37 checking_package_mask = False
38 print_overlay_flag = False
42 show_removable_only_flag = False
44 stable_listNg = [] # handle package.accept_keywords
47 processing_package_use = False
48 using_gentoo_as_overlay = False
54 PORTAGE_CONFIGROOT="/"
56 USER_CONFIG_PATH=PORTAGE_CONFIGROOT + USER_CONFIG_PATH
85 "r":"--removable-only",
94 overlays = [settings["PORTDIR_OVERLAY"]]
97 # Print full usage information for this tool to the console.
98 print ("\nUsage: " + portage.output.turquoise(__productname__) + portage.output.yellow(" command "))
99 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [ options ]") + portage.output.yellow(" command "))
100 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-c]") + portage.output.yellow(" [akmu]"))
101 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-r]") + portage.output.yellow(" [akmu]"))
102 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-f]") + portage.output.yellow(" [akmu]"))
103 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-F]") + portage.output.yellow(" [akmu]"))
104 print (portage.output.yellow(" command ") + " can be ")
105 print (portage.output.yellow(" -a, --all") + " - show all matches")
106 print (portage.output.yellow(" -k, --keyword") + " - show matches from package.keywords and package.accept_keywords only")
107 print (portage.output.yellow(" -m, --mask") + " - show matches from package.mask only")
108 print (portage.output.yellow(" -u, --unmask") + " - show matched from package.unmask only")
110 print (portage.output.yellow(" -f, --fix") + " - will remove the stabled packages without asking for confirmation")
111 print (portage.output.yellow(" -h, --help") + " - display this message")
112 print (portage.output.yellow(" -d, --debug") + " - display more verbose output for debugging")
113 print (portage.output.yellow(" -V, --version") + " - display version info")
114 print (portage.output.green("options") + " are ")
115 print (portage.output.green(" -c, --changes-only") + \
116 " - show all matches that have upgrade option, use with " + \
117 "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
118 "|" + portage.output.yellow(" m ") + "|" + \
119 portage.output.yellow(" a ") + ">")
120 print (portage.output.green(" -n, --no-color") + \
121 " - suppress color output")
122 print (portage.output.green(" -r, --removable-only") + \
123 " - show all matches that can be removed from package files, use with " + \
124 "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
125 "|" + portage.output.yellow(" m ") + "|" + \
126 portage.output.yellow(" a ") + ">\n")
128 def get_keywords(package, var):
130 filtered_keywords = ""
132 keywords = package.environment("KEYWORDS").split()
133 except KeyError as error:
134 print ("!!! Portpeek caught Exception:", error)
135 print ("!!! This package/version seems to be no longer available, " + \
136 "please check and update/unmerge it")
137 return "Not Available/Deprecated"
139 #filtered_keywords = filter_keywords(keywords[0])
140 filtered_keywords = filter_keywords(keywords)
141 return filtered_keywords
145 # this is the main function for portpeek
146 # TODO comment this code!
147 def parse_line(line, filename):
148 global info,debug,using_gentoo_as_overlay
150 using_gentoo_as_overlay = False
154 not_installed_pkgs = 0
158 print_output(debug,portage.output.blue("Analyzing line: " + line))
159 # determine if we are also check ~ prefixed code
166 fields = line.replace("\t", " ").split(" ")
169 #if the line does not start with an atom such as (= or >), do not validate
170 #status as this tool is for check specific versions and not entire packages
171 # a ~cpv should be handled like an =cpv if requested bythe parameter -t
172 check_pkg = fields[0] # this should be one of <>=~
173 overlay_index = check_pkg.find("::")
174 if ( overlay_index >= 0):
175 overlay_list = check_pkg.rsplit("::")
176 if (len(overlay_list) > 0):
177 overlay_name = overlay_list[1]
178 if (overlay_name == "gentoo"):
179 using_gentoo_as_overlay = True
180 check_pkg = check_pkg[0:check_pkg.find("::")]
182 if check_pkg[0] not in atom_check:
185 if check_pkg[0] in "~":
186 check_tilde_masked_pkg(check_pkg, filename)
189 # determine if the package exists
191 package_exists = portage.portdb.xmatch("match-all", fields[0])
193 package_exists = False
196 # return a Package List based on the cpv
197 query = Query(check_pkg)
198 #query = Query(fields[0])
202 pkgs = query.smart_find(True,True,True,True,False,True)
203 except errors.GentoolkitException as err:
207 pkg_length = len(pkgs)
208 not_installed_pkgs = 0
211 # go through each package version for a specific version found above
212 for current_package in pkgs:
213 if not current_package.is_installed():
215 # we have found a package that is in our file, but not installed
216 not_installed_pkgs = not_installed_pkgs + 1
218 # check to see if specific version of pkg is not installed
219 # and display if true
220 check_pkg = fields[0]
221 if check_pkg[0] in atom_check:
222 check_pkg = check_pkg[1:]
224 if (check_pkg == str(current_package.cpv)):
225 if (not checking_package_mask):
226 # package is not instaleld
227 print_output(info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Not Installed") , current_package, filename)
228 if "package.keywords" in filename:
229 stable_list.append(str(current_package.cpv))
230 if "package.accept_keywords" in filename:
231 stable_listNg.append(str(current_package.cpv))
232 unmask_list.append(str(current_package.cpv))
234 # package is masked, and not installed, this is normal use of package.mask
235 print_output(info,portage.output.green("" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package, filename)
239 # package is installed
240 # retrieve the keywords for a file
241 keywords = "%s" % (get_keywords(current_package,"KEYWORDS").split())
242 if (keywords.find("Available/Deprecated") >= 0):
245 #retrieve the mask status of a specific package
246 pkgmask = _get_mask_status(current_package, False)
248 #determine if installed package is unmasked, if so, display keywords as green
249 stable = check_for_stable_release(current_package)
251 # do not display if keywords don't exist
256 ebuild_output = portage.output.green("Installed: ") + \
257 portage.output.turquoise(str(current_package.cpv)) + \
258 portage.output.green(" Keywords " + keywords)
259 if "package.unmask" in filename:
260 unmask_list.append(str(current_package.cpv))
261 if "package.keywords" in filename:
262 stable_list.append(str(current_package.cpv))
263 if "package.accept_keywords" in filename:
264 stable_listNg.append(str(current_package.cpv))
266 if (not show_removable_only_flag):
267 ebuild_output = portage.output.green("Installed: ") + \
268 portage.output.turquoise(str(current_package.cpv)) + \
269 portage.output.yellow(" Keywords " + keywords)
271 ebuild_output = portage.output.yellow(str(current_package.cpv))
273 # check package.unmask
274 if (checking_package_unmask):
275 if (not is_pkg_package_masked(str(current_package.cpv))):
277 # package is in package.unmask unnecessarily
278 ebuild_output = ebuild_output + ": " + portage.output.yellow("Not package masked")
279 if "package.unmask" in filename:
280 unmask_list.append(str(current_package.cpv))
281 print_output (info, "" + ebuild_output,None, filename)
285 ebuild_search_key_printed = False
288 ebuild_search_key_printed = True
289 print_output(info,"\n" + ebuild_output,current_package, filename)
290 elif not show_changes_only_flag and not show_removable_only_flag:
292 ebuild_search_key_printed = True
293 print_output(info,"\n" + ebuild_output,current_package)
295 # go through all versions of a package
296 query = Query(current_package.category + "/" + current_package.name)
301 all_pkgs = query.smart_find(True,True,True,True,False,True)
302 except errors.GentoolkitException as err:
303 print_output(debug,portage.output.blue("Package " + current_package.category + "/" + current_package.name + " not found."))
305 for a_package in all_pkgs:
306 if not a_package.is_installed():
307 # a_package is not installed
308 pkgmask = _get_mask_status(a_package, False)
309 # print status line of package we are now checking
310 print_output(debug,portage.output.blue("Checking package: " + str(a_package.cpv) +".pkgmask is " + str(pkgmask)))
311 # if package versions are different
312 if (VersionMatch(CPV(current_package.cpv)).match(CPV(a_package.cpv))):
314 keylist = a_package.environment("KEYWORDS")
315 keywords = "%s" % (filter_keywords(keylist)).split()
316 #if a_package is masked
317 if pkgmask > 0 and not show_removable_only_flag:
318 if show_changes_only_flag and not ebuild_search_key_printed:
319 print_output (info, "\n" + ebuild_output, current_package)
320 ebuild_search_key_printed = True
321 check_for_stable_release(current_package)
323 print_output (info,portage.output.red("Available: " + str(a_package.cpv) + " [M] Keywords: " + keywords),a_package)
325 print_output (info,portage.output.brown("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
327 if show_changes_only_flag and not ebuild_search_key_printed:
328 print_output (info,"\n" + ebuild_output,current_package)
329 ebuild_search_key_printed = True
330 print_output(info,portage.output.green("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
332 #print (portage.output.red ("\nCannot find package: " + check_pkg))
334 # if package does not exist, and current_package is None
335 # then make package using fields[0]
337 # display if pkg/cat is not installed (missing version)
338 if not_installed_pkgs == pkg_length:
340 if (not checking_package_mask):
341 print_output(info,portage.output.green("\n" + fields[0] + ": ") + portage.output.yellow("Not Installed"),current_package)
342 if "package.keywords" in filename:
343 stable_list.append(str(current_package.cpv))
344 if "package.accept_keywords" in filename:
345 stable_listNg.append(str(current_package.cpv))
346 unmask_list.append(str(current_package.cpv))
348 print_output (info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package)
351 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
352 if "package.keywords" in filename:
353 stable_list.append(fields[0])
354 if "package.accept_keywords" in filename:
355 stable_listNg.append(fields[0])
356 unmask_list.append(fields[0])
357 show_all_versions(fields[0], filename)
362 # adding support for etc/portage/package.keywords/<whatever>/package.keywords
363 def get_recursive_info(filename):
365 # determine if filename is a directory
366 if os.path.isdir(filename):
367 # get listing of directory
368 filenames = os.listdir(filename)
369 for file_name in filenames:
370 get_recursive_info(filename+os.path.sep+file_name)
374 def get_info(filename):
378 filedescriptor = None
381 filedescriptor = open(filename)
382 for line in filedescriptor.readlines():
386 elif line.find("#") >= 0:
387 # found '#' remove comment
388 if (skipFile(line,filename)):
390 line = line[0:line.find("#")]
394 if (processing_package_use == False):
395 diffs_found = parse_line(line, filename)
397 # process package.use
398 diffs_found = parse_package_use(line,filename)
400 print (portage.output.red("Could not find file " + filename))
403 if not diffs_found and no_file:
404 print (portage.output.brown("No ebuild options found."))
407 if (filedescriptor != None):
408 filedescriptor.close()
410 # parse the package.use file and look for packages
412 def parse_package_use(line, filename):
422 package_installed = False
423 fields = line.replace("\t", " ").split(" ")
426 check_pkg = fields[0] # this could be one of <>=
427 if check_pkg[0] not in atom_check:
430 check_pkg = check_pkg[1:]
433 # if there is a wildcard, check to make sure at least one
434 # of the packages is installed
435 if check_pkg.find("/*") >= 0:
436 query = Query(check_pkg)
439 pkgs = query.smart_find(True,True,True,True,False,True)
440 except errors.GentoolkitException as err:
441 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
445 pkg_length = len(pkgs)
446 for current_package in pkgs:
447 # on wildcard scenario, return False if one package is installed
448 if current_package.is_installed():
451 # look for any version of check_pkg installed as there is
452 # no version specified in package.use
453 package_exists = portage.portdb.xmatch("match-all", check_pkg)
455 # get all package versions
456 query = Query(check_pkg)
459 pkgs = query.smart_find(True,True,True,True,False,True)
460 except errors.GentoolkitException as err:
461 print_output(debug,portage.output.blue("Package " + check_pkg + " not found."))
464 pkg_length = len(pkgs)
466 # go through each package version for a specific version found above
467 if (has_atom == False):
468 for current_package in pkgs:
469 if current_package.is_installed():
470 package_installed = True
472 # go through each package version for a specific version found above
473 for current_package in pkgs:
474 if (str(current_package.cpv) == check_pkg):
475 if not current_package.is_installed():
476 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
477 if "package.keywords" in filename:
478 stable_list.append(check_pkg)
479 if "package.accept_keywords" in filename:
480 stable_listNg.append(check_pkg)
481 unmask_list.append(check_pkg)
486 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
487 if "package.keywords" in filename:
488 stable_list.append(check_pkg)
489 if "package.accept_keywords" in filename:
490 stable_listNg.append(check_pkg)
491 unmask_list.append(check_pkg)
493 if (package_installed == False):
494 # package does not exists
495 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
496 if "package.keywords" in filename:
497 stable_list.append(check_pkg)
498 if "package.accept_keywords" in filename:
499 stable_listNg.append(check_pkg)
500 unmask_list.append(check_pkg)
508 # skip the file if portpeek-skip found in a comment
509 # you can put this in the middle of a file and it will
510 #skip all entrie below it, this is useful to speed things
511 #up by not checking ~kde versions, for example
512 def skipFile (line, filename):
513 if ( (line == None) or (filename == None)):
516 if line.find("portpeek-skip") >= 0:
521 # parse the package.use file and look for packages
523 def parse_package_use(line, filename):
534 package_installed = False
535 fields = line.replace("\t", " ").split(" ")
538 check_pkg = fields[0] # this could be one of <>=
539 if check_pkg[0] not in atom_check:
542 check_pkg = check_pkg[1:]
544 # if there is a wildcard, check to make sure at least one
545 # of the packages is installed
546 if check_pkg.find("/*") >= 0:
547 query = Query(check_pkg)
550 pkgs = query.smart_find(True,True,True,True,False,True)
551 except errors.GentoolkitException as err:
552 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
556 pkg_length = len(pkgs)
557 for current_package in pkgs:
558 # on wildcard scenario, return False if one package is installed
559 if current_package.is_installed():
562 # look for any version of check_pkg installed as there is
563 # no version specified in package.use
565 package_exists = portage.portdb.xmatch("match-all", check_pkg)
567 # get all package versions
568 query = Query(check_pkg)
571 pkgs = query.smart_find(True,True,True,True,False,True)
572 except errors.GentoolkitException as err:
573 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
576 pkg_length = len(pkgs)
578 # go through each package version for a specific version found above
579 if (has_atom == False):
580 for current_package in pkgs:
581 if current_package.is_installed():
582 package_installed = True
584 # go through each package version for a specific version found above
585 for current_package in pkgs:
586 if (str(current_package.cpv) == check_pkg):
587 if not current_package.is_installed():
588 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
589 if "package.keywords" in filename:
590 stable_list.append(check_pkg)
591 if "package.accept_keywords" in filename:
592 stable_listNg.append(check_pkg)
593 unmask_list.append(check_pkg)
598 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
599 if "package.keywords" in filename:
600 stable_list.append(check_pkg)
601 if "package.accept_keywords" in filename:
602 stable_listNg.append(check_pkg)
603 unmask_list.append(check_pkg)
605 if (package_installed == False):
606 # package does not exists
607 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
608 if "package.keywords" in filename:
609 stable_list.append(check_pkg)
610 if "package.accept_keywords" in filename:
611 stable_listNg.append(check_pkg)
612 unmask_list.append(check_pkg)
619 # parts blatantly stolen from equery
620 # if pure is true, then get "true" mask status that is
621 # not affected by entries in /etc/portage/package.*
622 def _get_mask_status(pkg, pure):
629 pkgmask = pkgmask + 3
633 keywords = portage.portdb.aux_get(str(pkg.cpv), ["KEYWORDS"])
634 keywords = keywords[0].split()
639 keywords = pkg.environment("KEYWORDS").split()
641 # first check for stable arch, stop there if it is found
642 if settings["ARCH"] in keywords:
645 if "~" + settings["ARCH"] in keywords:
646 pkgmask = pkgmask + 1
647 elif "-*" in keywords or "-" + settings["ARCH"] in keywords:
648 pkgmask = pkgmask + 2
652 def is_pkg_package_masked(cpv):
654 mysplit = catpkgsplit(cpv)
656 raise ValueError("invalid CPV: %s" % cpv)
657 if not portage.portdb.cpv_exists(cpv):
660 mycp = mysplit[0] + "/" + mysplit[1]
662 pmaskdict = settings._mask_manager._pmaskdict
663 if mycp in pmaskdict:
664 for package in pmaskdict[mycp]:
665 if cpv in portage.portdb.xmatch("match-all", package):
670 # filter out keywords for archs other than the current one
671 def filter_keywords(keywords):
672 filtered_keywords = ""
674 #for key in key_list:
676 key = key.replace("[", '')
677 key = key.replace("]", "")
678 key = key.replace(",", "")
679 arch=settings["ARCH"]
681 # remove '~' from key for comparison
682 key_comparison = key.lstrip('~')
683 if key_comparison == arch:
684 if len(filtered_keywords) != 0:
685 filtered_keywords = filtered_keywords + " "
686 filtered_keywords = filtered_keywords + key
688 if len(filtered_keywords) != 0:
689 filtered_keywords = filtered_keywords + " "
690 filtered_keywords = filtered_keywords + key
693 return filtered_keywords
695 # check to see if we have a stable release
696 # in our package.* files that we can remove
697 def check_for_stable_release(pkg):
698 if not is_pkg_package_masked(str(pkg.cpv)):
699 status = _get_mask_status(pkg, True)
706 # Print the version of this tool to the console.
707 print (__productname__ + "(" + __version__ + ") - " + \
709 print ("Author(s): " + __author__)
711 # function to go through a ~cp without a version
712 # and set for removal from file if no masked package version exists
713 def check_tilde_masked_pkg(package_name, filename):
715 variable_version = ""
717 orig_package_name = package_name
718 package_name = package_name.replace('~','')
720 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: orig_package-name is " + orig_package_name))
721 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: package_name is " + package_name))
723 query = Query(package_name+"*", True)
727 packages = query.smart_find(True,True,True,True,False,True)
728 except errors.GentoolkitException as err:
729 print_output(debug,portage.output.blue("Package " + package_name + " not found."))
731 no_versions_installed = True
732 for package in packages:
733 if package.is_installed():
734 no_versions_installed = False
736 if (no_versions_installed == True):
737 ebuild_output = portage.output.green("\n" + package_name + ": ") + portage.output.yellow("Not Installed")
738 if "package.unmask" in filename:
739 unmask_list.append(orig_package_name)
740 if "package.keywords" in filename:
741 stable_list.append(orig_package_name)
742 if "package.accept_keywords" in filename:
743 stable_listNg.append(orig_package_name)
744 print (ebuild_output + portage.output.brown(" : " + filename))
748 # get all packages matching cat/package
749 if (packages != None):
750 for current_package in packages:
751 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv)))
752 print_output(debug,portage.output.blue("comparing " + package_name + " to " + str(current_package.cpv)))
753 if (pkgcmp(pkgsplit(package_name),pkgsplit(str(current_package.cpv))) <=0 ):
754 #if (pkgcmp(package_name, str(current_package.cpv)) <= 0):
755 packageObj = gentoolkit.package.Package(str(current_package.cpv))
756 if (packageObj == None):
757 # we could not create a package object
759 pkgmask = _get_mask_status(packageObj, True)
761 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv) + " and pkgmask is " + str(pkgmask)))
763 if "package.unmask" in filename:
764 if (is_pkg_package_masked(str(current_package.cpv))):
765 # package was found as masked
768 # package is not masked
769 unmask_list.append(str(current_package.cpv))
770 ebuild_output = portage.output.yellow(str(current_package.cpv)) + ": " + portage.output.yellow("Not package masked")
771 print_output(info,ebuild_output, package, filename)
775 # package was found as masked
778 # at this point we have no packages >= ~cpv that are masked, present for removal
779 # package does not have any masked versions
780 ebuild_output = portage.output.green(package_name + " has no masked versions")
782 if "package.unmask" in filename:
783 unmask_list.append(orig_package_name)
784 if "package.keywords" in filename:
785 stable_list.append(orig_package_name)
786 if "package.accept_keywords" in filename:
787 stable_listNg.append(orig_package_name)
788 print_output(info,ebuild_output, package, filename)
790 #helper function to print avail pks when version does not exist
791 def show_all_versions(pkg, filename):
794 is_package_masked = False
795 pkgArr = portage.pkgsplit(pkg)
797 if pkgArr is None or len(pkgArr) == 0:
800 # determine if category/package is masked
803 operator = portage.dep.Atom(pkg).operator
804 if operator is not None:
805 package = package[len(operator):]
807 # package is category/package and pkg is category/package-version
808 # is category/package-version we are checking package masked?
809 #if portage.settings.pmaskdict.has_key(package):
810 pmaskdict = settings._mask_manager._pmaskdict
811 if package in pmaskdict:
812 pkg_list = pmaskdict.get(package)
813 # iterate through list array looking for pkg
814 for pkg_check in pkg_list:
815 operator = portage.get_operator(pkg_check)
817 if pkg_check == package:
818 is_package_masked = True
820 query = Query(package)
825 all_pkgs = query.smart_find(True,True,True,True,False,True)
826 except errors.GentoolkitException as err:
827 print_output(debug,portage.output.blue("Package " + package + " not found."))
829 for current_package in all_pkgs:
830 keywords = "%s" % (current_package.environment("KEYWORDS").split())
831 keywords = filter_keywords(keywords)
832 keywords = "[%s]" % (keywords)
833 ebuild = current_package.ebuild_path()
835 pkgmask = _get_mask_status(current_package, True)
836 if is_package_masked:
837 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
839 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
840 elif pkgmask == 4 or pkgmask == 1:
841 print (portage.output.brown("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
843 print (portage.output.green("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
844 if "package.keywords" in filename:
845 stable_list.append(str(current_package.cpv))
846 if "package.accept_keywords" in filename:
847 stable_listNg.append(str(current_package.cpv))
849 def handle_if_overlay(package):
851 global print_overlay_flag,using_gentoo_as_overlay
853 if (using_gentoo_as_overlay):
856 print_overlay_flag = True
858 ebuild_path,overlay_path = porttree.dbapi.findname2(str(package.cpv))
861 index = overlay_list.index(overlay_path)
862 except ValueError as error:
863 overlay_list.append(overlay_path)
864 index = overlay_list.index(overlay_path)
866 overlay_text = " [%s]" % (str(index+1))
870 # if the overlay_text was displayed to the user
871 # we need to display the string at the end
872 # this array will store the overlays to be displayed
873 def print_overlay_text():
875 global print_overlay_flag
877 if (not print_overlay_flag):
880 if (len(overlay_list) <= 0):
884 for x in overlay_list:
885 print (portage.output.turquoise("[" + str(index) + "] ") + x)
890 #helper function to print output
891 def print_output(log_level,output_string, package=None, filename=None):
896 if (package.is_overlay()):
897 output_string = "%s%s" % (output_string,portage.output.turquoise(handle_if_overlay(package)))
898 #output_string = output_string + portage.output.turquoise(handle_if_overlay(package))
901 output_string = "%s%s" % (output_string,portage.output.brown(" : " + filename))
902 #output_string = output_string + portage.output.brown(" : " + filename)
904 if (log_level <= logLevel):
905 print (output_string)
907 # remove stabled files that are no longer needed from package.keywords
909 # includes support for etc/portage/package.keywords/<whatever>/package.keywords
910 def cleanFile (filename):
915 # if the file or directory does not exist
917 if (os.path.exists(filename) == False):
920 if "package.keywords" in filename:
921 if ( len(stable_list) == 0):
923 removeDups = stable_list
924 elif "package.accept_keywords" in filename:
925 if ( len(stable_listNg) == 0):
927 removeDups = stable_listNg
929 if ( len(unmask_list) == 0):
931 removeDups = unmask_list
936 # determine if filename is a directory
937 if os.path.isdir(filename):
938 # get listing of directory
939 filenames = os.listdir(filename)
940 for file_name in filenames:
941 cleanFile(filename+os.path.sep+file_name)
944 #go through stable array and remove line if found
945 for line in fileinput.input(filename,inplace =1):
949 # make sure line is not empty and do not remove commented out lines
952 elif line.find("#") == 0:
956 for item in removeDups:
958 removed_list.append(item)
959 removedDict[filename] = item
961 removeDups.pop(removeDups.index(item))
963 if (itemFound == False):
966 except OSError as error:
967 print (portage.output.red("Modify/Read access to file: " + filename + " failed: ") ,error)
969 if (len(removed_list) > 0):
971 for package in removed_list:
972 print (portage.output.red("Removing from: ") + portage.output.yellow(filename) + ": " + portage.output.green(package) + "\n")
975 if __name__ == "__main__":
977 if len(sys.argv) == 1:
981 # soooooo stolen from emerge
982 tmpcmdline = sys.argv[1:]
984 for cmd in tmpcmdline:
985 if cmd[0:1] == "-" and cmd[1:2] != "-":
986 for cmd_item in cmd[1:]:
987 if cmd_item in mappings:
988 if mappings[cmd_item] in cmdline:
990 print ("*** Warning: Redundant use of ", mappings[cmd_item])
992 cmdline.append(mappings[cmd_item])
994 print ("!!! Error: -"+cmd_item+" is an invalid option.")
1001 if len(cmd)>=2 and cmd[0:2]=="--":
1003 i = options.index(cmd)
1006 print ("!!! Error: -"+cmd+" is an invalid option.")
1009 if "--changes-only" in cmdline:
1010 cmdline.remove("--changes-only")
1011 show_changes_only_flag = True
1013 if "--removable-only" in cmdline:
1014 cmdline.remove("--removable-only")
1015 show_removable_only_flag = True
1017 if "--debug" in cmdline:
1020 if "--no-color" in cmdline:
1021 portage.output.nocolor()
1023 if "--tilde-check" in cmdline:
1026 if "--version" in cmdline:
1030 if "--all" in cmdline:
1031 tmpcmdline = ["--all"]
1032 if "--fix" in cmdline:
1033 tmpcmdline.append("--fix")
1034 elif "--fixwithall" in cmdline:
1035 tmpcmdline.append("--fixwithall")
1038 if "--help" in cmdline:
1042 if (show_changes_only_flag and show_removable_only_flag):
1043 print ("Please select only one of --show-removable (-r) or --changes-only")
1044 print ("Use --help for more info.")
1048 if cmd == "--keyword":
1049 print (portage.output.bold("\npackage.keywords:"))
1050 get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1051 if "--fix" in cmdline:
1052 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1053 print (portage.output.bold("Done\n"))
1054 print (portage.output.bold("\npackage.accept_keywords:"))
1055 get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1056 if "--fix" in cmdline:
1057 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1058 print (portage.output.bold("Done\n"))
1059 elif cmd == "--unmask":
1060 print (portage.output.bold("\npackage.unmask:"))
1061 checking_package_unmask = True
1062 get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1063 checking_package_unmask = False
1064 if "--fix" in cmdline:
1065 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1066 elif cmd == "--mask":
1067 checking_package_mask = True
1068 print (portage.output.bold("\npackage.mask:"))
1069 get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1070 print (portage.output.bold("Done\n"))
1071 checking_package_mask = False
1072 if "--fix" in cmdline:
1073 cleanFile(USER_CONFIG_PATH + "/package.mask")
1074 elif cmd == "--package-use":
1075 print (portage.output.bold("\npackage.use:"))
1076 processing_package_use = True
1077 get_recursive_info(USER_CONFIG_PATH + "/package.use")
1078 if "--fix" in cmdline:
1079 cleanFile(USER_CONFIG_PATH + "/package.use")
1080 print (portage.output.bold("Done\n"))
1081 elif cmd == "--all":
1082 print (portage.output.bold("\npackage.keywords:"))
1083 get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1084 print (portage.output.bold("\npackage.accept_keywords:"))
1085 get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1086 print (portage.output.bold("\npackage.unmask:"))
1087 checking_package_unmask = True
1088 get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1089 checking_package_unmask = False
1090 checking_package_mask = True
1091 print (portage.output.bold("\npackage.mask:"))
1092 get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1093 print (portage.output.bold("\npackage.use:"))
1094 processing_package_use = True
1095 get_recursive_info(USER_CONFIG_PATH + "/package.use")
1096 if "--fix" in cmdline:
1097 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1098 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1099 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1100 cleanFile(USER_CONFIG_PATH + "/package.use")
1101 cleanFile(USER_CONFIG_PATH + "/package.mask")
1102 print (portage.output.bold("\nDone\n"))
1104 print_overlay_text()
1106 if len(cmdline) == 0:
1107 if show_changes_only_flag or show_removable_only_flag:
1108 if (show_changes_only_flag):
1109 print (portage.output.green("-c") + " or " + portage.output.green("--changes-only") + " must be accompanied by one of the following:")
1111 print (portage.output.green("-r") + " or " + portage.output.green("--removable-only") + " must be accompanied by one of the following:")
1113 print (" " + portage.output.yellow("-k") + " or " + portage.output.yellow("--keyword"))
1114 print (" " + portage.output.yellow("-u") + " or " + portage.output.yellow("--unmask"))
1115 print (" " + portage.output.yellow("-m") + " or " + portage.output.yellow("--mask"))
1116 print (" " + portage.output.yellow("-a") + " or " + portage.output.yellow("--all"))