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.11"
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
53 PORTAGE_CONFIGROOT="/"
55 USER_CONFIG_PATH=PORTAGE_CONFIGROOT + USER_CONFIG_PATH
84 "r":"--removable-only",
93 overlays = [settings["PORTDIR_OVERLAY"]]
96 # Print full usage information for this tool to the console.
97 print ("\nUsage: " + portage.output.turquoise(__productname__) + portage.output.yellow(" command "))
98 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [ options ]") + portage.output.yellow(" command "))
99 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-c]") + portage.output.yellow(" [akmu]"))
100 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-r]") + portage.output.yellow(" [akmu]"))
101 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-f]") + portage.output.yellow(" [akmu]"))
102 print (" " + portage.output.turquoise(__productname__) + portage.output.green(" [-F]") + portage.output.yellow(" [akmu]"))
103 print (portage.output.yellow(" command ") + " can be ")
104 print (portage.output.yellow(" -a, --all") + " - show all matches")
105 print (portage.output.yellow(" -k, --keyword") + " - show matches from package.keywords and package.accept_keywords only")
106 print (portage.output.yellow(" -m, --mask") + " - show matches from package.mask only")
107 print (portage.output.yellow(" -u, --unmask") + " - show matched from package.unmask only")
109 print (portage.output.yellow(" -f, --fix") + " - will remove the stabled packages without asking for confirmation")
110 print (portage.output.yellow(" -h, --help") + " - display this message")
111 print (portage.output.yellow(" -d, --debug") + " - display more verbose output for debugging")
112 print (portage.output.yellow(" -V, --version") + " - display version info")
113 print (portage.output.green("options") + " are ")
114 print (portage.output.green(" -c, --changes-only") + \
115 " - show all matches that have upgrade option, use with " + \
116 "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
117 "|" + portage.output.yellow(" m ") + "|" + \
118 portage.output.yellow(" a ") + ">")
119 print (portage.output.green(" -n, --no-color") + \
120 " - suppress color output")
121 print (portage.output.green(" -r, --removable-only") + \
122 " - show all matches that can be removed from package files, use with " + \
123 "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
124 "|" + portage.output.yellow(" m ") + "|" + \
125 portage.output.yellow(" a ") + ">\n")
127 def get_keywords(package, var):
129 filtered_keywords = ""
131 keywords = package.environment("KEYWORDS").split()
132 except KeyError as error:
133 print ("!!! Portpeek caught Exception:", error)
134 print ("!!! This package/version seems to be no longer available, " + \
135 "please check and update/unmerge it")
136 return "Not Available/Deprecated"
138 #filtered_keywords = filter_keywords(keywords[0])
139 filtered_keywords = filter_keywords(keywords)
140 return filtered_keywords
144 # this is the main function for portpeek
145 # TODO comment this code!
146 def parse_line(line, filename):
147 global info,debug,using_gentoo_as_overlay
149 using_gentoo_as_overlay = False
153 not_installed_pkgs = 0
157 print_output(debug,portage.output.blue("Analyzing line: " + line))
158 # determine if we are also check ~ prefixed code
165 fields = line.replace("\t", " ").split(" ")
168 #if the line does not start with an atom such as (= or >), do not validate
169 #status as this tool is for check specific versions and not entire packages
170 # a ~cpv should be handled like an =cpv if requested bythe parameter -t
171 check_pkg = fields[0] # this should be one of <>=~
172 overlay_index = check_pkg.find("::")
173 if ( overlay_index >= 0):
174 overlay_list = check_pkg.rsplit("::")
175 if (len(overlay_list) > 0):
176 overlay_name = overlay_list[1]
177 if (overlay_name == "gentoo"):
178 using_gentoo_as_overlay = True
179 check_pkg = check_pkg[0:check_pkg.find("::")]
181 if check_pkg[0] not in atom_check:
184 if check_pkg[0] in "~":
185 check_tilde_masked_pkg(check_pkg, filename)
188 # determine if the package exists
190 package_exists = portage.portdb.xmatch("match-all", fields[0])
192 package_exists = False
195 # return a Package List based on the cpv
196 query = Query(check_pkg)
197 #query = Query(fields[0])
201 pkgs = query.smart_find(True,True,True,True,False,True)
202 except errors.GentoolkitException as err:
206 pkg_length = len(pkgs)
207 not_installed_pkgs = 0
210 # go through each package version for a specific version found above
211 for current_package in pkgs:
212 if not current_package.is_installed():
214 # we have found a package that is in our file, but not installed
215 not_installed_pkgs = not_installed_pkgs + 1
217 # check to see if specific version of pkg is not installed
218 # and display if true
219 check_pkg = fields[0]
220 if check_pkg[0] in atom_check:
221 check_pkg = check_pkg[1:]
223 if (check_pkg == str(current_package.cpv)):
224 if (not checking_package_mask):
225 # package is not instaleld
226 print_output(info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Not Installed") , current_package, filename)
227 if "package.keywords" in filename:
228 stable_list.append(str(current_package.cpv))
229 if "package.accept_keywords" in filename:
230 stable_listNg.append(str(current_package.cpv))
231 unmask_list.append(str(current_package.cpv))
233 # package is masked, and not installed, this is normal use of package.mask
234 print_output(info,portage.output.green("" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package, filename)
238 # package is installed
239 # retrieve the keywords for a file
240 keywords = "%s" % (get_keywords(current_package,"KEYWORDS").split())
241 if (keywords.find("Available/Deprecated") >= 0):
244 #retrieve the mask status of a specific package
245 pkgmask = _get_mask_status(current_package, False)
247 #determine if installed package is unmasked, if so, display keywords as green
248 stable = check_for_stable_release(current_package)
250 # do not display if keywords don't exist
255 ebuild_output = portage.output.green("Installed: ") + \
256 portage.output.turquoise(str(current_package.cpv)) + \
257 portage.output.green(" Keywords " + keywords)
258 if "package.unmask" in filename:
259 unmask_list.append(str(current_package.cpv))
260 if "package.keywords" in filename:
261 stable_list.append(str(current_package.cpv))
262 if "package.accept_keywords" in filename:
263 stable_listNg.append(str(current_package.cpv))
265 if (not show_removable_only_flag):
266 ebuild_output = portage.output.green("Installed: ") + \
267 portage.output.turquoise(str(current_package.cpv)) + \
268 portage.output.yellow(" Keywords " + keywords)
270 ebuild_output = portage.output.yellow(str(current_package.cpv))
272 # check package.unmask
273 if (checking_package_unmask):
274 if (not is_pkg_package_masked(str(current_package.cpv))):
276 # package is in package.unmask unnecessarily
277 ebuild_output = ebuild_output + ": " + portage.output.yellow("Not package masked")
278 if "package.unmask" in filename:
279 unmask_list.append(str(current_package.cpv))
280 print_output (info, "" + ebuild_output,None, filename)
284 ebuild_search_key_printed = False
287 ebuild_search_key_printed = True
288 print_output(info,"\n" + ebuild_output,current_package, filename)
289 elif not show_changes_only_flag and not show_removable_only_flag:
291 ebuild_search_key_printed = True
292 print_output(info,"\n" + ebuild_output,current_package)
294 # go through all versions of a package
295 query = Query(current_package.category + "/" + current_package.name)
300 all_pkgs = query.smart_find(True,True,True,True,False,True)
301 except errors.GentoolkitException as err:
302 print_output(debug,portage.output.blue("Package " + current_package.category + "/" + current_package.name + " not found."))
304 for a_package in all_pkgs:
305 if not a_package.is_installed():
306 # a_package is not installed
307 pkgmask = _get_mask_status(a_package, False)
308 # print status line of package we are now checking
309 print_output(debug,portage.output.blue("Checking package: " + str(a_package.cpv) +".pkgmask is " + str(pkgmask)))
310 # if package versions are different
311 if (VersionMatch(CPV(current_package.cpv)).match(CPV(a_package.cpv))):
313 keylist = a_package.environment("KEYWORDS")
314 keywords = "%s" % (filter_keywords(keylist)).split()
315 #if a_package is masked
316 if pkgmask > 0 and not show_removable_only_flag:
317 if show_changes_only_flag and not ebuild_search_key_printed:
318 print_output (info, "\n" + ebuild_output, current_package)
319 ebuild_search_key_printed = True
320 check_for_stable_release(current_package)
322 print_output (info,portage.output.red("Available: " + str(a_package.cpv) + " [M] Keywords: " + keywords),a_package)
324 print_output (info,portage.output.brown("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
326 if show_changes_only_flag and not ebuild_search_key_printed:
327 print_output (info,"\n" + ebuild_output,current_package)
328 ebuild_search_key_printed = True
329 print_output(info,portage.output.green("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
331 #print (portage.output.red ("\nCannot find package: " + check_pkg))
333 # if package does not exist, and current_package is None
334 # then make package using fields[0]
336 # display if pkg/cat is not installed (missing version)
337 if not_installed_pkgs == pkg_length:
339 if (not checking_package_mask):
340 print_output(info,portage.output.green("\n" + fields[0] + ": ") + portage.output.yellow("Not Installed"),current_package)
341 if "package.keywords" in filename:
342 stable_list.append(str(current_package.cpv))
343 if "package.accept_keywords" in filename:
344 stable_listNg.append(str(current_package.cpv))
345 unmask_list.append(str(current_package.cpv))
347 print_output (info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package)
350 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
351 if "package.keywords" in filename:
352 stable_list.append(fields[0])
353 if "package.accept_keywords" in filename:
354 stable_listNg.append(fields[0])
355 unmask_list.append(fields[0])
356 show_all_versions(fields[0], filename)
361 # adding support for etc/portage/package.keywords/<whatever>/package.keywords
362 def get_recursive_info(filename):
364 # determine if filename is a directory
365 if os.path.isdir(filename):
366 # get listing of directory
367 filenames = os.listdir(filename)
368 for file_name in filenames:
369 get_recursive_info(filename+os.path.sep+file_name)
373 def get_info(filename):
377 filedescriptor = None
380 filedescriptor = open(filename)
381 for line in filedescriptor.readlines():
385 elif line.find("#") >= 0:
386 # found '#' remove comment
387 if (skipFile(line,filename)):
389 line = line[0:line.find("#")]
393 if (processing_package_use == False):
394 diffs_found = parse_line(line, filename)
396 # process package.use
397 diffs_found = parse_package_use(line,filename)
399 print (portage.output.red("Could not find file " + filename))
402 if not diffs_found and no_file:
403 print (portage.output.brown("No ebuild options found."))
406 if (filedescriptor != None):
407 filedescriptor.close()
409 # parse the package.use file and look for packages
411 def parse_package_use(line, filename):
421 package_installed = False
422 fields = line.replace("\t", " ").split(" ")
425 check_pkg = fields[0] # this could be one of <>=
426 if check_pkg[0] not in atom_check:
429 check_pkg = check_pkg[1:]
432 # if there is a wildcard, check to make sure at least one
433 # of the packages is installed
434 if check_pkg.find("/*") >= 0:
435 query = Query(check_pkg)
438 pkgs = query.smart_find(True,True,True,True,False,True)
439 except errors.GentoolkitException as err:
440 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
444 pkg_length = len(pkgs)
445 for current_package in pkgs:
446 # on wildcard scenario, return False if one package is installed
447 if current_package.is_installed():
450 # look for any version of check_pkg installed as there is
451 # no version specified in package.use
452 package_exists = portage.portdb.xmatch("match-all", check_pkg)
454 # get all package versions
455 query = Query(check_pkg)
458 pkgs = query.smart_find(True,True,True,True,False,True)
459 except errors.GentoolkitException as err:
460 print_output(debug,portage.output.blue("Package " + check_pkg + " not found."))
463 pkg_length = len(pkgs)
465 # go through each package version for a specific version found above
466 if (has_atom == False):
467 for current_package in pkgs:
468 if current_package.is_installed():
469 package_installed = True
471 # go through each package version for a specific version found above
472 for current_package in pkgs:
473 if (str(current_package.cpv) == check_pkg):
474 if not current_package.is_installed():
475 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
476 if "package.keywords" in filename:
477 stable_list.append(check_pkg)
478 if "package.accept_keywords" in filename:
479 stable_listNg.append(check_pkg)
480 unmask_list.append(check_pkg)
485 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
486 if "package.keywords" in filename:
487 stable_list.append(check_pkg)
488 if "package.accept_keywords" in filename:
489 stable_listNg.append(check_pkg)
490 unmask_list.append(check_pkg)
492 if (package_installed == False):
493 # package does not exists
494 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
495 if "package.keywords" in filename:
496 stable_list.append(check_pkg)
497 if "package.accept_keywords" in filename:
498 stable_listNg.append(check_pkg)
499 unmask_list.append(check_pkg)
507 # skip the file if portpeek-skip found in a comment
508 # you can put this in the middle of a file and it will
509 #skip all entrie below it, this is useful to speed things
510 #up by not checking ~kde versions, for example
511 def skipFile (line, filename):
512 if ( (line == None) or (filename == None)):
515 if line.find("portpeek-skip") >= 0:
520 # parse the package.use file and look for packages
522 def parse_package_use(line, filename):
533 package_installed = False
534 fields = line.replace("\t", " ").split(" ")
537 check_pkg = fields[0] # this could be one of <>=
538 if check_pkg[0] not in atom_check:
541 check_pkg = check_pkg[1:]
543 # if there is a wildcard, check to make sure at least one
544 # of the packages is installed
545 if check_pkg.find("/*") >= 0:
546 query = Query(check_pkg)
549 pkgs = query.smart_find(True,True,True,True,False,True)
550 except errors.GentoolkitException as err:
551 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
555 pkg_length = len(pkgs)
556 for current_package in pkgs:
557 # on wildcard scenario, return False if one package is installed
558 if current_package.is_installed():
561 # look for any version of check_pkg installed as there is
562 # no version specified in package.use
564 package_exists = portage.portdb.xmatch("match-all", check_pkg)
566 # get all package versions
567 query = Query(check_pkg)
570 pkgs = query.smart_find(True,True,True,True,False,True)
571 except errors.GentoolkitException as err:
572 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
575 pkg_length = len(pkgs)
577 # go through each package version for a specific version found above
578 if (has_atom == False):
579 for current_package in pkgs:
580 if current_package.is_installed():
581 package_installed = True
583 # go through each package version for a specific version found above
584 for current_package in pkgs:
585 if (str(current_package.cpv) == check_pkg):
586 if not current_package.is_installed():
587 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
588 if "package.keywords" in filename:
589 stable_list.append(check_pkg)
590 if "package.accept_keywords" in filename:
591 stable_listNg.append(check_pkg)
592 unmask_list.append(check_pkg)
597 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
598 if "package.keywords" in filename:
599 stable_list.append(check_pkg)
600 if "package.accept_keywords" in filename:
601 stable_listNg.append(check_pkg)
602 unmask_list.append(check_pkg)
604 if (package_installed == False):
605 # package does not exists
606 print_output(info,portage.output.green("\n" + check_pkg + ": ") + portage.output.yellow("Not Installed"),current_package)
607 if "package.keywords" in filename:
608 stable_list.append(check_pkg)
609 if "package.accept_keywords" in filename:
610 stable_listNg.append(check_pkg)
611 unmask_list.append(check_pkg)
618 # parts blatantly stolen from equery
619 # if pure is true, then get "true" mask status that is
620 # not affected by entries in /etc/portage/package.*
621 def _get_mask_status(pkg, pure):
628 pkgmask = pkgmask + 3
632 keywords = portage.portdb.aux_get(str(pkg.cpv), ["KEYWORDS"])
633 keywords = keywords[0].split()
638 keywords = pkg.environment("KEYWORDS").split()
640 # first check for stable arch, stop there if it is found
641 if settings["ARCH"] in keywords:
644 if "~" + settings["ARCH"] in keywords:
645 pkgmask = pkgmask + 1
646 elif "-*" in keywords or "-" + settings["ARCH"] in keywords:
647 pkgmask = pkgmask + 2
651 def is_pkg_package_masked(cpv):
653 mysplit = catpkgsplit(cpv)
655 raise ValueError("invalid CPV: %s" % cpv)
656 if not portage.portdb.cpv_exists(cpv):
659 mycp = mysplit[0] + "/" + mysplit[1]
661 pmaskdict = settings._mask_manager._pmaskdict
662 if mycp in pmaskdict:
663 for package in pmaskdict[mycp]:
664 if cpv in portage.portdb.xmatch("match-all", package):
669 # filter out keywords for archs other than the current one
670 def filter_keywords(keywords):
671 filtered_keywords = ""
673 #for key in key_list:
675 key = key.replace("[", '')
676 key = key.replace("]", "")
677 key = key.replace(",", "")
678 arch=settings["ARCH"]
680 # remove '~' from key for comparison
681 key_comparison = key.lstrip('~')
682 if key_comparison == arch:
683 if len(filtered_keywords) != 0:
684 filtered_keywords = filtered_keywords + " "
685 filtered_keywords = filtered_keywords + key
687 if len(filtered_keywords) != 0:
688 filtered_keywords = filtered_keywords + " "
689 filtered_keywords = filtered_keywords + key
692 return filtered_keywords
694 # check to see if we have a stable release
695 # in our package.* files that we can remove
696 def check_for_stable_release(pkg):
697 if not is_pkg_package_masked(str(pkg.cpv)):
698 status = _get_mask_status(pkg, True)
705 # Print the version of this tool to the console.
706 print (__productname__ + "(" + __version__ + ") - " + \
708 print ("Author(s): " + __author__)
710 # function to go through a ~cp without a version
711 # and set for removal from file if no masked package version exists
712 def check_tilde_masked_pkg(package_name, filename):
714 variable_version = ""
716 orig_package_name = package_name
717 package_name = package_name.replace('~','')
719 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: orig_package-name is " + orig_package_name))
720 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: package_name is " + package_name))
722 query = Query(package_name+"*", True)
726 packages = query.smart_find(True,True,True,True,False,True)
727 except errors.GentoolkitException as err:
728 print_output(debug,portage.output.blue("Package " + package_name + " not found."))
730 no_versions_installed = True
731 for package in packages:
732 if package.is_installed():
733 no_versions_installed = False
735 if (no_versions_installed == True):
736 ebuild_output = portage.output.green("\n" + package_name + ": ") + portage.output.yellow("Not Installed")
737 if "package.unmask" in filename:
738 unmask_list.append(orig_package_name)
739 if "package.keywords" in filename:
740 stable_list.append(orig_package_name)
741 if "package.accept_keywords" in filename:
742 stable_listNg.append(orig_package_name)
743 print (ebuild_output + portage.output.brown(" : " + filename))
747 # get all packages matching cat/package
748 if (packages != None):
749 for current_package in packages:
750 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv)))
751 print_output(debug,portage.output.blue("comparing " + package_name + " to " + str(current_package.cpv)))
752 if (pkgcmp(pkgsplit(package_name),pkgsplit(str(current_package.cpv))) <=0 ):
753 #if (pkgcmp(package_name, str(current_package.cpv)) <= 0):
754 packageObj = gentoolkit.package.Package(str(current_package.cpv))
755 if (packageObj == None):
756 # we could not create a package object
758 pkgmask = _get_mask_status(packageObj, True)
760 print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv) + " and pkgmask is " + str(pkgmask)))
762 if "package.unmask" in filename:
763 if (is_pkg_package_masked(str(current_package.cpv))):
764 # package was found as masked
767 # package is not masked
768 unmask_list.append(str(current_package.cpv))
769 ebuild_output = portage.output.yellow(str(current_package.cpv)) + ": " + portage.output.yellow("Not package masked")
770 print_output(info,ebuild_output, package, filename)
774 # package was found as masked
777 # at this point we have no packages >= ~cpv that are masked, present for removal
778 # package does not have any masked versions
779 ebuild_output = portage.output.green(package_name + " has no masked versions")
781 if "package.unmask" in filename:
782 unmask_list.append(orig_package_name)
783 if "package.keywords" in filename:
784 stable_list.append(orig_package_name)
785 if "package.accept_keywords" in filename:
786 stable_listNg.append(orig_package_name)
787 print_output(info,ebuild_output, package, filename)
789 #helper function to print avail pks when version does not exist
790 def show_all_versions(pkg, filename):
793 is_package_masked = False
794 pkgArr = portage.pkgsplit(pkg)
796 if pkgArr is None or len(pkgArr) == 0:
799 # determine if category/package is masked
802 operator = portage.dep.Atom(pkg).operator
803 if operator is not None:
804 package = package[len(operator):]
806 # package is category/package and pkg is category/package-version
807 # is category/package-version we are checking package masked?
808 #if portage.settings.pmaskdict.has_key(package):
809 pmaskdict = settings._mask_manager._pmaskdict
810 if package in pmaskdict:
811 pkg_list = pmaskdict.get(package)
812 # iterate through list array looking for pkg
813 for pkg_check in pkg_list:
814 operator = portage.get_operator(pkg_check)
816 if pkg_check == package:
817 is_package_masked = True
819 query = Query(package)
824 all_pkgs = query.smart_find(True,True,True,True,False,True)
825 except errors.GentoolkitException as err:
826 print_output(debug,portage.output.blue("Package " + package + " not found."))
828 for current_package in all_pkgs:
829 keywords = "%s" % (current_package.environment("KEYWORDS").split())
830 keywords = filter_keywords(keywords)
831 keywords = "[%s]" % (keywords)
832 ebuild = current_package.ebuild_path()
834 pkgmask = _get_mask_status(current_package, True)
835 if is_package_masked:
836 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
838 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
839 elif pkgmask == 4 or pkgmask == 1:
840 print (portage.output.brown("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
842 print (portage.output.green("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
843 if "package.keywords" in filename:
844 stable_list.append(str(current_package.cpv))
845 if "package.accept_keywords" in filename:
846 stable_listNg.append(str(current_package.cpv))
848 def handle_if_overlay(package):
850 global print_overlay_flag,using_gentoo_as_overlay
852 if (using_gentoo_as_overlay):
855 print_overlay_flag = True
857 ebuild_path,overlay_path = porttree.dbapi.findname2(str(package.cpv))
860 index = overlay_list.index(overlay_path)
861 except ValueError as error:
862 overlay_list.append(overlay_path)
863 index = overlay_list.index(overlay_path)
865 overlay_text = " [%s]" % (str(index+1))
869 # if the overlay_text was displayed to the user
870 # we need to display the string at the end
871 # this array will store the overlays to be displayed
872 def print_overlay_text():
874 global print_overlay_flag
876 if (not print_overlay_flag):
879 if (len(overlay_list) <= 0):
883 for x in overlay_list:
884 print (portage.output.turquoise("[" + str(index) + "] ") + x)
889 #helper function to print output
890 def print_output(log_level,output_string, package=None, filename=None):
895 if (package.is_overlay()):
896 output_string = "%s%s" % (output_string,portage.output.turquoise(handle_if_overlay(package)))
897 #output_string = output_string + portage.output.turquoise(handle_if_overlay(package))
900 output_string = "%s%s" % (output_string,portage.output.brown(" : " + filename))
901 #output_string = output_string + portage.output.brown(" : " + filename)
903 if (log_level <= logLevel):
904 print (output_string)
906 # remove stabled files that are no longer needed from package.keywords
908 # includes support for etc/portage/package.keywords/<whatever>/package.keywords
909 def cleanFile (filename):
914 # if the file or directory does not exist
916 if (os.path.exists(filename) == False):
919 if "package.keywords" in filename:
920 if ( len(stable_list) == 0):
922 removeDups = stable_list
923 elif "package.accept_keywords" in filename:
924 if ( len(stable_listNg) == 0):
926 removeDups = stable_listNg
928 if ( len(unmask_list) == 0):
930 removeDups = unmask_list
935 # determine if filename is a directory
936 if os.path.isdir(filename):
937 # get listing of directory
938 filenames = os.listdir(filename)
939 for file_name in filenames:
940 cleanFile(filename+os.path.sep+file_name)
943 #go through stable array and remove line if found
944 for line in fileinput.input(filename,inplace =1):
948 # make sure line is not empty and do not remove commented out lines
951 elif line.find("#") == 0:
955 for item in removeDups:
957 removed_list.append(item)
958 removedDict[filename] = item
960 removeDups.pop(removeDups.index(item))
962 if (itemFound == False):
965 except OSError as error:
966 print (portage.output.red("Modify/Read access to file: " + filename + " failed: ") ,error)
968 if (len(removed_list) > 0):
970 for package in removed_list:
971 print (portage.output.red("Removing from: ") + portage.output.yellow(filename) + ": " + portage.output.green(package) + "\n")
974 if __name__ == "__main__":
976 if len(sys.argv) == 1:
980 # soooooo stolen from emerge
981 tmpcmdline = sys.argv[1:]
983 for cmd in tmpcmdline:
984 if cmd[0:1] == "-" and cmd[1:2] != "-":
985 for cmd_item in cmd[1:]:
986 if cmd_item in mappings:
987 if mappings[cmd_item] in cmdline:
989 print ("*** Warning: Redundant use of ", mappings[cmd_item])
991 cmdline.append(mappings[cmd_item])
993 print ("!!! Error: -"+cmd_item+" is an invalid option.")
1000 if len(cmd)>=2 and cmd[0:2]=="--":
1002 i = options.index(cmd)
1005 print ("!!! Error: -"+cmd+" is an invalid option.")
1008 if "--changes-only" in cmdline:
1009 cmdline.remove("--changes-only")
1010 show_changes_only_flag = True
1012 if "--removable-only" in cmdline:
1013 cmdline.remove("--removable-only")
1014 show_removable_only_flag = True
1016 if "--debug" in cmdline:
1019 if "--no-color" in cmdline:
1020 portage.output.nocolor()
1022 if "--tilde-check" in cmdline:
1025 if "--version" in cmdline:
1029 if "--all" in cmdline:
1030 tmpcmdline = ["--all"]
1031 if "--fix" in cmdline:
1032 tmpcmdline.append("--fix")
1033 elif "--fixwithall" in cmdline:
1034 tmpcmdline.append("--fixwithall")
1037 if "--help" in cmdline:
1041 if (show_changes_only_flag and show_removable_only_flag):
1042 print ("Please select only one of --show-removable (-r) or --changes-only")
1043 print ("Use --help for more info.")
1047 if cmd == "--keyword":
1048 print (portage.output.bold("\npackage.keywords:"))
1049 get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1050 if "--fix" in cmdline:
1051 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1052 print (portage.output.bold("Done\n"))
1053 print (portage.output.bold("\npackage.accept_keywords:"))
1054 get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1055 if "--fix" in cmdline:
1056 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1057 print (portage.output.bold("Done\n"))
1058 elif cmd == "--unmask":
1059 print (portage.output.bold("\npackage.unmask:"))
1060 checking_package_unmask = True
1061 get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1062 checking_package_unmask = False
1063 if "--fix" in cmdline:
1064 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1065 elif cmd == "--mask":
1066 checking_package_mask = True
1067 print (portage.output.bold("\npackage.mask:"))
1068 get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1069 print (portage.output.bold("Done\n"))
1070 checking_package_mask = False
1071 if "--fix" in cmdline:
1072 cleanFile(USER_CONFIG_PATH + "/package.mask")
1073 elif cmd == "--package-use":
1074 print (portage.output.bold("\npackage.use:"))
1075 processing_package_use = True
1076 get_recursive_info(USER_CONFIG_PATH + "/package.use")
1077 if "--fix" in cmdline:
1078 cleanFile(USER_CONFIG_PATH + "/package.use")
1079 print (portage.output.bold("Done\n"))
1080 elif cmd == "--all":
1081 print (portage.output.bold("\npackage.keywords:"))
1082 get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1083 print (portage.output.bold("\npackage.accept_keywords:"))
1084 get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1085 print (portage.output.bold("\npackage.unmask:"))
1086 checking_package_unmask = True
1087 get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1088 checking_package_unmask = False
1089 checking_package_mask = True
1090 print (portage.output.bold("\npackage.mask:"))
1091 get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1092 print (portage.output.bold("\npackage.use:"))
1093 processing_package_use = True
1094 get_recursive_info(USER_CONFIG_PATH + "/package.use")
1095 if "--fix" in cmdline:
1096 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1097 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1098 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1099 cleanFile(USER_CONFIG_PATH + "/package.use")
1100 cleanFile(USER_CONFIG_PATH + "/package.mask")
1101 print (portage.output.bold("\nDone\n"))
1103 print_overlay_text()
1105 if len(cmdline) == 0:
1106 if show_changes_only_flag or show_removable_only_flag:
1107 if (show_changes_only_flag):
1108 print (portage.output.green("-c") + " or " + portage.output.green("--changes-only") + " must be accompanied by one of the following:")
1110 print (portage.output.green("-r") + " or " + portage.output.green("--removable-only") + " must be accompanied by one of the following:")
1112 print (" " + portage.output.yellow("-k") + " or " + portage.output.yellow("--keyword"))
1113 print (" " + portage.output.yellow("-u") + " or " + portage.output.yellow("--unmask"))
1114 print (" " + portage.output.yellow("-m") + " or " + portage.output.yellow("--mask"))
1115 print (" " + portage.output.yellow("-a") + " or " + portage.output.yellow("--all"))