1e4f2169369d996adf94fb5e4d1177dafb48571a
[portpeek.git] / portpeek
1 #!/usr/bin/python
2 #
3 # Copyright 2006 Mike Pagano
4 # Distributed under the terms of the GNU General Public License v2
5 #
6 # $Header$
7 # Author: Mike Pagano <mpagano@gentoo.org>
8 #
9 # Portions written ripped from 
10 # - equery, by Karl Trygve Kalleberg <karltk@gentoo.org>
11 # - gentoolkit.py, by Karl Trygve Kalleberg <karltk@gentoo.org>
12 # - portage.py
13 # - emerge
14 #
15 #
16
17 __author__ = "Michael Pagano"
18 __email__ = "mpagano@gentoo.org"
19 __version__ = "2.1.7"
20 __productname__ = "portpeek"
21 __description__ = "Displays user unmasked ebuilds and installable options from the portage tree"
22
23 import sys, os, portage, fileinput, re, gentoolkit
24 from gentoolkit.versionmatch import VersionMatch,errors
25 from portage.const import USER_CONFIG_PATH
26 from portage.versions import catpkgsplit,pkgcmp,pkgsplit
27 from portage.exception import InvalidAtom
28 from gentoolkit.cpv import CPV
29 from gentoolkit.query import Query
30 from gentoolkit.flag import get_iuse
31
32 # support python 2
33 try:
34     input = raw_input
35 except NameError:
36     pass
37
38 porttree = portage.db[portage.root]["porttree"]
39 settings = portage.config(clone=portage.settings)
40 #settings = portage.config(local_config=False)
41
42 show_changes_only_flag = False
43 checking_package_unmask = False
44 checking_package_mask = False
45 print_overlay_flag = False
46 info = 0
47 debug = 1
48 logLevel = info
49 show_removable_only_flag = False
50 stable_list = []
51 stable_listNg = [] # handle package.accept_keywords
52 unmask_list = []
53 tilde = 0
54 processing_package_use = False
55 using_gentoo_as_overlay = False
56 overlay_list = []
57 fix_confirm = True
58 fix_asked = False
59 use_flag_dict = {}
60 useremove_display = ""
61 invalid_flag_found = False
62
63 try:
64     PORTAGE_CONFIGROOT
65 except NameError:
66     PORTAGE_CONFIGROOT="/"
67
68 USER_CONFIG_PATH=PORTAGE_CONFIGROOT + USER_CONFIG_PATH
69
70 #parameters
71 options = [
72 "--keyword",
73 "--unmask",
74 "--mask",
75 "--all",
76 "--changes-only",
77 "--version",
78 "--version",
79 "--help",
80 "--removable-only",
81 "--debug",
82 "--fix", 
83 "--tilde-check",
84 "--no-color",
85 "--package-use",
86 "--fix-confirm"
87 ]
88
89 mappings = {
90 "k":"--keyword",
91 "u":"--unmask",
92 "m":"--mask",
93 "a":"--all",
94 "c":"--changes-only",
95 "V":"--version",
96 "v":"--version",
97 "h":"--help",
98 "r":"--removable-only",
99 "d":"--debug",
100 "f":"--fix", 
101 "t":"--tilde-check",
102 "n":"--no-color",
103 "s":"--package-use",
104 "q":"--fix-confirm"
105 }
106
107 cmdline = []
108 overlays = [settings["PORTDIR_OVERLAY"]]
109
110 def print_usage():
111     # Print full usage information for this tool to the console.
112     print ("\nUsage: " + portage.output.turquoise(__productname__) +  portage.output.yellow(" command "))
113     print ("       " + portage.output.turquoise(__productname__) + portage.output.green(" [ options ]") +  portage.output.yellow(" command "))
114     print ("       " + portage.output.turquoise(__productname__) + portage.output.green(" [-c]") + portage.output.yellow(" [akmu]"))
115     print ("       " + portage.output.turquoise(__productname__) + portage.output.green(" [-r]") + portage.output.yellow(" [akmu]"))
116     print ("       " + portage.output.turquoise(__productname__) + portage.output.green(" [-f]") + portage.output.yellow(" [akmu]"))
117     print ("       " + portage.output.turquoise(__productname__) + portage.output.green(" [-F]") + portage.output.yellow(" [akmu]"))
118     print (portage.output.yellow(" command ") + " can be ")
119     print (portage.output.yellow(" -a, --all") + "       - show all matches")
120     print (portage.output.yellow(" -k, --keyword") + "       - show matches from package.keywords and package.accept_keywords only")
121     print (portage.output.yellow(" -m, --mask") + "      - show matches from package.mask only")
122     print (portage.output.yellow(" -u, --unmask") + "        - show matched from package.unmask only")
123     print (portage.output.yellow(" -s, --package.use") + "   - show matches from package.use only")
124     
125     print (portage.output.yellow(" -f, --fix") + "       - will remove the stabled and invalid packages without asking for confirmation")
126     print (portage.output.yellow(" -q, --confirm-fix") +"    - will remove the stabled and invalid packages asking for confirmation before doing so")
127     print (portage.output.yellow(" -h, --help") + "      - display this message")
128     print (portage.output.yellow(" -d, --debug") + "         - display more verbose output for debugging")
129     print (portage.output.yellow(" -V, --version") + "       - display version info")
130     print (portage.output.green("options") + " are ")
131     print (portage.output.green(" -c, --changes-only") + \
132         "   - show all matches that have upgrade option, use with " + \
133         "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
134         "|" + portage.output.yellow(" m ") + "|" + \
135         portage.output.yellow(" a ") + ">")
136     print (portage.output.green(" -n, --no-color") + \
137         "   - suppress color output")
138     print (portage.output.green(" -r, --removable-only") + \
139         "   - show all matches that can be removed from package files, use with " + \
140         "<" + portage.output.yellow(" k ") + "|" + portage.output.yellow(" u ") + \
141         "|" + portage.output.yellow(" m ") + "|" + \
142         portage.output.yellow(" a ") + ">\n")
143
144 def get_keywords(package, var):
145     mytree = porttree
146     filtered_keywords = ""
147     try:
148         keywords = package.environment("KEYWORDS").split()
149     except KeyError as error:
150         print ("!!! Portpeek caught Exception:" + format(error))
151         print ("!!! This package/version seems to be no longer available, " + \
152         "please check and update/unmerge it") 
153         return "Not Available/Deprecated"
154     
155     #filtered_keywords = filter_keywords(keywords[0])
156     filtered_keywords = filter_keywords(keywords)
157     return filtered_keywords
158
159
160
161 # this is the main function for portpeek
162 # TODO comment this code!
163 def parse_line(line, filename):     
164     global info,debug,using_gentoo_as_overlay
165
166     using_gentoo_as_overlay = False
167     pkgs = None
168     ebuild_output = ""
169     check_pkg = ""
170     not_installed_pkgs = 0
171     pkg_length = 0
172     atom_check="<>=~"
173     original_line = line
174
175     # if the line has special characters, we need to make sure the original line is used for matching
176     special_line = False
177
178     if ( (re.match('[><:\*]',line) != None) ):
179         special_line = True
180
181     print_output(debug,portage.output.blue("Analyzing line: " + line))
182
183     diffs_found = False
184     display_done = False
185
186     fields = line.replace("\t", " ").split(" ")
187
188     if len(fields) > 0:
189         #if the line does not start with an atom such as (= or >), do not validate 
190         #status as this tool is for check specific versions and not entire packages 
191         # a ~cpv should be handled like an =cpv if requested bythe parameter -t
192         check_pkg = fields[0] # this should be one of <>=~
193         overlay_index = check_pkg.find("::")
194         if ( overlay_index >= 0):
195             overlay_list = check_pkg.rsplit("::")
196             if (len(overlay_list) > 0):
197                 overlay_name = overlay_list[1]
198                 if (overlay_name == "gentoo"):
199                     using_gentoo_as_overlay = True
200             check_pkg = check_pkg[0:check_pkg.find("::")]
201
202         if check_pkg[0] not in atom_check:
203
204             # if this is package_unmask, then check the non-atom containing package to see if any version is masked
205
206             if (checking_package_unmask == True):
207                 
208                 print_output(debug,portage.output.blue("check_pkg is " + check_pkg + " found"))
209                 if (is_any_cpv_masked(check_pkg) == False):
210                     print_output(info,portage.output.red("No masked versions of " + check_pkg + " found. Tagged for removal."))
211                     unmask_list.append(str(check_pkg))
212             return
213         if (tilde == 1):
214             if check_pkg[0] in "~":
215                 check_tilde_masked_pkg(check_pkg, filename)
216                 return
217
218         # determine if the package exists
219         try:
220             package_exists = portage.portdb.xmatch("match-all", fields[0])
221         except InvalidAtom:
222             package_exists = False
223
224         if package_exists:
225             # return a Package List based on the cpv
226             query = Query(check_pkg)
227             #query = Query(fields[0])
228             pkgs = []
229
230             try:
231                 pkgs = query.smart_find(True,True,True,True,False,True)
232             except errors.GentoolkitException as err:
233                 pass
234
235             if (pkgs != None):
236                 pkg_length = len(pkgs)
237                 not_installed_pkgs = 0
238                 display_done = False
239
240                                 # go through each package version for a specific version found above
241                 for current_package in pkgs:
242                     if not current_package.is_installed():
243
244                                                 # we have found a package that is in our file, but not installed
245                         not_installed_pkgs = not_installed_pkgs + 1
246
247                         # check to see if specific version of pkg is not installed 
248                         # and display if true
249                         check_pkg = fields[0]
250                         if check_pkg[0] in atom_check:
251                             check_pkg = check_pkg[1:]
252
253                         if (check_pkg == str(current_package.cpv)):
254                             if (not checking_package_mask):
255                                                                 # package is not instaleld
256                                 print_output(info,portage.output.yellow("\n" + str(current_package.cpv) + ": ") + portage.output.red("Not Installed") , current_package, filename)
257                                 if "package.keywords" in filename:
258                                     stable_list.append(str(current_package.cpv))
259                                 if "package.accept_keywords" in filename:
260                                     stable_listNg.append(str(current_package.cpv))
261                                 unmask_list.append(str(current_package.cpv))
262                             else:
263                                                                 # package is masked, and not installed, this is normal use of package.mask
264                                 print_output(info,portage.output.green("" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package, filename)
265                             display_done = True
266                         continue
267
268                                         # package is installed
269                                         # retrieve the keywords for a file
270                     keywords = "%s" % (get_keywords(current_package,"KEYWORDS").split())
271                     if (keywords.find("Available/Deprecated") >= 0):
272                         continue
273
274                                         #retrieve the mask status of a specific package
275                     pkgmask = _get_mask_status(current_package, False)
276
277                     #determine if installed package is unmasked, if so, display keywords as green
278                     stable = check_for_stable_release(current_package)
279
280                     # do not display if keywords don't exist
281                     if keywords == "[]":
282                         continue
283
284                     if stable:
285                         ebuild_output = portage.output.green("Installed: ") + \
286                             portage.output.turquoise(str(current_package.cpv)) + \
287                             portage.output.green("  Keywords " + keywords)
288                         if "package.unmask" in filename:
289                             unmask_list.append(str(current_package.cpv))
290                         if "package.keywords" in filename:
291                             stable_list.append(str(current_package.cpv))
292                         if "package.accept_keywords" in filename:
293                             stable_listNg.append(str(current_package.cpv))
294                     else:
295                         if (not show_removable_only_flag):
296                             if (not checking_package_unmask):
297                                 ebuild_output = portage.output.green("Installed: ") + \
298                                 portage.output.turquoise(str(current_package.cpv)) + \
299                                 portage.output.yellow("  Keywords " + keywords) 
300                         else:
301                             ebuild_output = portage.output.yellow(str(current_package.cpv))
302
303                                         # check package.unmask
304                     if (checking_package_unmask):
305                         if (not is_pkg_package_masked(str(current_package.cpv))):
306
307                                                         # package is in package.unmask unnecessarily
308                             ebuild_output = ebuild_output + ": " + portage.output.yellow("Not package masked")
309                             if "package.unmask" in filename:
310                                 unmask_list.append(str(current_package.cpv))
311                                 print_output (info, "" +  ebuild_output,None, filename)
312                                 continue
313
314                                         # print once
315                     ebuild_search_key_printed = False
316                     if stable:
317                         diffs_found = False
318                         ebuild_search_key_printed = True
319                         print_output(info,"\n" + ebuild_output,current_package, filename)
320                     elif not show_changes_only_flag and not show_removable_only_flag:
321                         diffs_found = False
322                         ebuild_search_key_printed = True
323                         print_output(info,"\n" + ebuild_output,current_package)
324
325                                         # go through all versions of a package
326                     query = Query(current_package.category + "/" + current_package.name)
327
328                     all_pkgs = []
329
330                     try:
331                         all_pkgs = query.smart_find(True,True,True,True,False,True)
332                     except errors.GentoolkitException as err:
333                         print_output(debug,portage.output.blue("Package " + current_package.category + "/" + current_package.name + " not found."))
334
335                     for a_package in all_pkgs:
336                         if not a_package.is_installed():
337                                                         # a_package is not installed
338                             pkgmask = _get_mask_status(a_package, False)
339                                                         # print status line of package we are now checking
340                             print_output(debug,portage.output.blue("Checking package: " + str(a_package.cpv) +".pkgmask is " + str(pkgmask)))
341                                                         # if package versions are different
342                             if (VersionMatch(CPV(current_package.cpv)).match(CPV(a_package.cpv))):
343                                 diffs_found = True
344                                 keylist = a_package.environment("KEYWORDS")
345                                 keywords = "%s" % (filter_keywords(keylist)).split()
346                                 #if a_package is masked
347                                 if pkgmask > 0 and not show_removable_only_flag:
348                                     if show_changes_only_flag and not ebuild_search_key_printed:
349                                         print_output (info, "\n" +  ebuild_output, current_package)
350                                         ebuild_search_key_printed = True
351                                         check_for_stable_release(current_package)
352                                     if (pkgmask >= 3):
353                                         print_output (info,portage.output.red("Available: " + str(a_package.cpv) + " [M] Keywords: " + keywords),a_package)
354                                     else:
355                                         print_output (info,portage.output.brown("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
356                                 else:
357                                     if show_changes_only_flag and not ebuild_search_key_printed:
358                                         print_output (info,"\n" + ebuild_output,current_package)
359                                         ebuild_search_key_printed = True
360                                         print_output(info,portage.output.green("Available: " + str(a_package.cpv) + " Keywords: " + keywords),a_package)
361                 #else:
362                     #print (portage.output.red ("\nCannot find package: " + check_pkg))
363
364                 # if package does not exist, and current_package is None
365                 # then make package using fields[0]
366
367                 # display if pkg/cat is not installed (missing version)
368                 if not_installed_pkgs ==  pkg_length:
369                     if not display_done:
370                         if (not checking_package_mask):
371                             print_output(info,portage.output.yellow("\n" + fields[0] + ": ") + portage.output.red("Not Installed"),current_package)
372                             if "package.keywords" in filename:
373                                 if (special_line == False):
374                                     stable_list.append(str(current_package.cpv))
375                                 else:
376                                     stable_list.append(original_line)
377                             if "package.accept_keywords" in filename:
378                                 if (special_line == False):
379                                     stable_listNg.append(str(current_package.cpv))
380                                 else:
381                                     stable_listNg.append(original_line)
382                             if (special_line == False):
383                                 unmask_list.append(str(current_package.cpv))
384                             else:
385                                 unmask_list.append(original_line)
386                         else:
387                             print_output (info,portage.output.green("\n" + str(current_package.cpv) + ": ") + portage.output.yellow("Package Masked"),current_package)
388         else:
389             diffs_found = True
390             print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
391             if "package.keywords" in filename:
392                 stable_list.append(fields[0])
393             if "package.accept_keywords" in filename:
394                 stable_listNg.append(fields[0])
395             unmask_list.append(fields[0])
396             show_all_versions(fields[0], filename)
397     current_package = ""
398
399     return diffs_found
400
401 # adding support for etc/portage/package.keywords/<whatever>/package.keywords
402 def get_recursive_info(filename):
403
404     # determine if filename is a directory
405     if os.path.isdir(filename):
406         # get listing of directory
407         filenames = os.listdir(filename)
408         for file_name in filenames:
409             get_recursive_info(filename+os.path.sep+file_name)
410     else:   
411         get_info(filename)
412
413 def get_info(filename):
414
415     diffs_found = False
416     no_file = False
417     filedescriptor = None
418
419     try:
420         filedescriptor = open(filename)
421         for line in filedescriptor.readlines():
422             line = line.strip()
423             if len(line) <= 0:
424                 continue
425             elif line.find("#") >= 0:
426                 # found '#' remove comment
427                 if (skipFile(line,filename)):
428                     return
429                 line = line[0:line.find("#")]
430                 line = line.strip()
431                 if len(line) <= 0:
432                     continue
433             if (processing_package_use == False):
434                 diffs_found = parse_line(line, filename)
435             else:
436                 # process package.use
437                 diffs_found = parse_package_use(line,filename)
438     except IOError:
439         print (portage.output.red("Could not find file " + filename))
440         no_file = True
441
442     if not diffs_found and no_file:
443         print (portage.output.brown("No ebuild options found."))
444
445     # close file
446     if (filedescriptor != None):
447         filedescriptor.close()
448
449 # parse the package.use file and look for packages
450 # not installed
451 def parse_package_use(line, filename):
452
453     global info,debug
454     print_output(debug,portage.output.blue("parse_package_use: Line: " + line))
455     pkgs = None
456     check_pkg = ""
457     pkg_length = 0
458     atom_check="<>="
459     any_version = False
460     has_atom = True
461
462     diffs_found = False
463     package_installed = False
464     fields = line.replace("\t", " ").split(" ")
465
466     if len(fields) > 0:
467         check_pkg = fields[0] # this could be one of <>=
468         if check_pkg[0] not in atom_check:
469             has_atom = False
470         else:
471             check_pkg = check_pkg[1:]
472             if check_pkg[0] in atom_check:
473                 check_pkg = check_pkg[1:]
474
475
476         # if there is a wildcard, check to make sure at least one
477         # of the packages is installed
478         if check_pkg.find("/*") >= 0:
479             query = Query(check_pkg)
480             pkgs = []
481             try:
482                 pkgs = query.smart_find(True,True,True,True,False,True)
483             except errors.GentoolkitException as err:
484                 print_output(debug,portage.output.blue("parse_package_use: Package " + check_pkg + " not found."))
485                 return False
486
487             if (pkgs != None):
488                 pkg_length = len(pkgs)
489             for current_package in pkgs:
490                 # on wildcard scenario, return False if one package is installed
491                 if current_package.is_installed():
492                     check_useflags(current_package,line)
493                     return False
494         else:
495             # look for any version of check_pkg installed as there is 
496             # no version specified in package.use
497             package_exists = portage.portdb.xmatch("match-all", check_pkg)
498             if package_exists:
499                 # get all package versions
500                 query = Query(check_pkg)
501                 pkgs = []
502                 try:
503                     pkgs = query.smart_find(True,True,True,True,False,True)
504                 except errors.GentoolkitException as err:
505                     print_output(debug,portage.output.blue("Package " + check_pkg + " not found."))
506     
507                 if (pkgs != None):
508                     pkg_length = len(pkgs)
509     
510                     # go through each package version for a specific 
511                     # version found above
512                     # if one line check returns all ok, we don't need 
513                     #to check the rest. One slot could have different 
514                     #use flags than another
515                     if (has_atom == False):
516                         check_useflags_all_versions(pkgs, line, check_pkg)
517                         package_installed = check_for_any_installed_version(pkgs)
518                         current_package = None
519
520                         #for current_package in pkgs:
521                         #    if current_package.is_installed():
522                         #        check_useflags(current_package,line)
523                         #        package_installed = True
524                         #        if (invalid_flag_found == False):
525                         #            break;
526                     else: 
527                         # go through each package version for a specific version found above
528                         for current_package in pkgs:
529                             if (str(current_package.cpv) == check_pkg):
530                                 if not current_package.is_installed():
531                                     print_output(info,portage.output.yellow("\n" + check_pkg + ": ") + portage.output.red("Not Installed"),current_package)
532                                     if "package.keywords" in filename:
533                                         stable_list.append(check_pkg)
534                                     if "package.accept_keywords" in filename:
535                                         stable_listNg.append(check_pkg)
536                                     unmask_list.append(check_pkg)
537                                     if "package.use" in filename:
538                                         valid_flag_list = []
539                                         valid_flag_list.insert(0,current_package);
540                                         use_flag_dict[line] = valid_flag_list
541                                         check_for_change = use_flag_dict[line]
542                                     return True
543                                 else:
544                                     check_useflags(current_package,line)
545                                     return False
546             else:
547                 print (portage.output.red ("\nPackage: " + fields[0] + " not found. Please check " + filename + " to validate entry"))
548                 if "package.keywords" in filename:
549                     stable_list.append(check_pkg)
550                 if "package.accept_keywords" in filename:
551                     stable_listNg.append(check_pkg)
552                 unmask_list.append(check_pkg)
553                 if "package.use" in filename:
554                     valid_flag_list = []
555                     #valid_flag_list.insert(0,current_package);
556                     valid_flag_list.insert(0,fields[0]);
557                     use_flag_dict[line] = valid_flag_list
558                     check_for_change = use_flag_dict[line]
559                 return True
560
561     if (package_installed == False):
562         # package does not exists
563         print_output(info,portage.output.yellow("\n" + check_pkg + ": ") + portage.output.red("Not Installed"),current_package)
564         if "package.keywords" in filename:
565             stable_list.append(check_pkg)
566         if "package.accept_keywords" in filename:
567             stable_listNg.append(check_pkg)
568         if "package.use" in filename:
569             valid_flag_list = []
570             valid_flag_list.insert(0,current_package);
571             use_flag_dict[line] = valid_flag_list
572             check_for_change = use_flag_dict[line]
573
574         unmask_list.append(check_pkg)
575         return True
576
577     return False
578
579
580
581
582 # skip the file if portpeek-skip found in a comment
583 # you can put this in the middle of a file and it will
584 #skip all entrie below it, this is useful to speed things
585 #up by not checking ~kde versions, for example
586 def skipFile (line, filename):
587     if ( (line == None) or (filename == None)):
588         return False
589
590     if line.find("portpeek-skip") >= 0:
591         return True
592
593     return False
594
595 # parts blatantly stolen from equery
596 # if pure is true, then get "true" mask status that is
597 # not affected by entries in /etc/portage/package.*
598 def _get_mask_status(pkg, pure):
599     pkgmask = 0
600
601     if (pkg == None):
602         return 0
603
604     if pkg.is_masked():
605         pkgmask = pkgmask + 3
606
607     if pure:
608         try:
609             keywords = portage.portdb.aux_get(str(pkg.cpv), ["KEYWORDS"])
610             keywords = keywords[0].split()
611         except KeyError:
612             # cpv does not exist
613             return 0
614     else:
615         keywords = pkg.environment("KEYWORDS").split()
616
617     # first check for stable arch, stop there if it is found
618     if settings["ARCH"] in keywords:
619         return 0
620
621     if "~" + settings["ARCH"] in keywords:
622         pkgmask = pkgmask + 1
623     elif "-*" in keywords or "-" + settings["ARCH"] in keywords:
624         pkgmask = pkgmask + 2
625     
626     return pkgmask
627
628 def is_pkg_package_masked(cpv):
629
630     print_output(debug,portage.output.blue("is_pkg_package_masked called: " + cpv))
631     settings2 = portage.config(local_config=False)
632     portdb2 = portage.portdbapi(None, settings)
633
634     mask_reason_list = None
635     
636     try:
637         for mask_reason_list in portage.getmaskingstatus(cpv, settings2, portdb=portdb2):
638             return True
639     except:
640         return False
641
642     return False
643
644 # filter out keywords for archs other than the current one
645 def filter_keywords(keywords):
646     filtered_keywords = ""
647
648     #for key in key_list:
649     for key in keywords:
650         key = key.replace("[", '')
651         key = key.replace("]", "")
652         key = key.replace(",", "")
653         arch=settings["ARCH"]
654
655         # remove '~' from key for comparison
656         key_comparison = key.lstrip('~')
657         if key_comparison == arch:
658             if len(filtered_keywords) != 0:
659                 filtered_keywords = filtered_keywords + " "
660             filtered_keywords = filtered_keywords + key
661         elif "-*" in key:
662             if len(filtered_keywords) != 0:
663                 filtered_keywords = filtered_keywords + " "
664             filtered_keywords = filtered_keywords + key
665
666
667     return filtered_keywords
668
669
670 # this function takes in a package with no cpv
671 # and returns True if any version is masked
672 def is_any_cpv_masked(package_name):
673     print_output(debug,portage.output.blue("inside is_any_cpv_masked: " + package_name))
674
675     query = Query(package_name, True)
676
677     packages = []
678     try:
679         packages = query.smart_find(True,True,True,True,False,True)
680     except errors.GentoolkitException as err:
681         print_output(debug,portage.output.blue("Package " + package_name + " not found."))
682
683     for package in packages:
684         if is_pkg_package_masked(package.cpv):
685             print_output(debug,portage.output.blue("Package " + package.cpv + " is masked."))
686             return True
687
688     print_output(debug,portage.output.blue("Package " + package_name + ". No masked versions."))
689     return False
690
691
692 # check to see if we have a stable release
693 # in our package.* files that we can remove
694 def check_for_stable_release(pkg):
695     if not is_pkg_package_masked(str(pkg.cpv)):
696         status = _get_mask_status(pkg, True)
697         if status == 0:
698             return True
699     return False
700
701 #print version info
702 def print_version():
703     # Print the version of this tool to the console.
704     print (__productname__ + "(" + __version__ + ") - " + \
705         __description__)
706     print ("Author(s): " + __author__)
707
708 # function to go through a ~cp without a version
709 # and set for removal from file if no masked package version exists
710 def check_tilde_masked_pkg(package_name, filename):
711     ebuild_output=""
712     variable_version = ""
713
714     orig_package_name = package_name
715     package_name = package_name.replace('~','')
716
717     print_output(debug,portage.output.blue("check_tilde_maskd_pkg: orig_package-name is " + orig_package_name))
718     print_output(debug,portage.output.blue("check_tilde_maskd_pkg: package_name is " + package_name))
719
720     query = Query(package_name, True)
721
722     packages = []
723     try:
724         packages = query.smart_find(True,True,True,True,False,True)
725     except errors.GentoolkitException as err:
726         print_output(debug,portage.output.blue("Package " + package_name + " not found."))
727
728     no_versions_installed = True
729     for package in packages:
730         if package.is_installed():
731             no_versions_installed = False
732
733     if (no_versions_installed == True):
734         ebuild_output = portage.output.yellow("\n" + package_name + ": ") + portage.output.red("Not Installed")
735         if "package.unmask" in filename:
736             unmask_list.append(orig_package_name)
737         if "package.keywords" in filename:
738             stable_list.append(orig_package_name)
739         if "package.accept_keywords" in filename:
740             stable_listNg.append(orig_package_name)
741         print (ebuild_output + portage.output.brown(" : " + filename))
742
743         return
744
745     # get all packages matching cat/package
746     if (packages != None):
747         for current_package in packages:
748             print_output(debug,portage.output.blue("check_tilde_maskd_pkg: current_package is " + str(current_package.cpv)))
749             print_output(debug,portage.output.blue("comparing " + package_name + " to " + str(current_package.cpv)))
750             if (pkgcmp(pkgsplit(package_name),pkgsplit(str(current_package.cpv))) <=0 ):
751             #if (pkgcmp(package_name, str(current_package.cpv)) <= 0):
752                 packageObj = gentoolkit.package.Package(str(current_package.cpv))
753                 if (packageObj == None):
754                     # we could not create a package object
755                     return
756
757                 if "package.unmask" in filename:
758                     if (is_pkg_package_masked(str(current_package.cpv))):
759                         # package was found as masked
760                         return
761                     else:
762                         # package is not masked
763                         unmask_list.append(str(current_package.cpv))
764                         ebuild_output = portage.output.yellow(str(current_package.cpv)) + ": " + portage.output.yellow("Not package masked")
765                         print_output(info,ebuild_output, package, filename)
766                         return
767                 else:
768                     if (is_pkg_package_masked(str(current_package.cpv))):
769                         # package was found as masked
770                         return 
771         else:
772             # at this point we have no packages >= ~cpv that are masked, present for removal
773             # package does not have any masked versions
774             ebuild_output = portage.output.green(package_name + " has no masked versions")
775             
776             if "package.unmask" in filename:
777                 unmask_list.append(orig_package_name)
778             if "package.keywords" in filename:
779                 stable_list.append(orig_package_name)
780             if "package.accept_keywords" in filename:
781                 stable_listNg.append(orig_package_name)
782             print_output(info,ebuild_output, package, filename)
783
784 #helper function to print avail pks when version does not exist
785 def show_all_versions(pkg, filename):
786
787     # is package masked
788     is_package_masked = False
789     pkgArr = portage.pkgsplit(pkg)
790
791     if pkgArr is None or len(pkgArr) == 0:
792         return
793
794     # determine if category/package is masked 
795     package = pkgArr[0]
796
797     operator = portage.dep.Atom(pkg).operator
798     if operator is not None:
799         package = package[len(operator):]
800
801     # package is category/package and pkg is category/package-version
802     # is category/package-version we are checking package masked?
803     #if portage.settings.pmaskdict.has_key(package):
804     pmaskdict = settings._mask_manager._pmaskdict
805     if package in pmaskdict:
806         pkg_list = pmaskdict.get(package)
807         # iterate through list array looking for pkg
808         for pkg_check in pkg_list:
809             operator = portage.get_operator(pkg_check)
810             if operator is None:
811                 if pkg_check == package:
812                     is_package_masked = True
813
814     query = Query(package)
815
816     all_pkgs = []
817
818     try:
819         all_pkgs = query.smart_find(True,True,True,True,False,True)
820     except errors.GentoolkitException as err:
821         print_output(debug,portage.output.blue("Package " + package + " not found."))
822
823     for current_package in all_pkgs:
824         keywords = "%s" % (current_package.environment("KEYWORDS").split())
825         keywords = filter_keywords(keywords)
826         keywords = "[%s]" % (keywords)
827         ebuild = current_package.ebuild_path()
828         if ebuild:
829             pkgmask = _get_mask_status(current_package, True)
830             if is_package_masked:
831                 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
832             elif pkgmask > 4:
833                 print (portage.output.red("Available: " + str(current_package.cpv) + " [M] Keywords: " + keywords))
834             elif pkgmask == 4 or pkgmask == 1:
835                 print (portage.output.brown("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
836             else:
837                 print (portage.output.green("Available: " + str(current_package.cpv) + " Keywords: " + keywords))
838                 if "package.keywords" in filename:
839                     stable_list.append(str(current_package.cpv))
840                 if "package.accept_keywords" in filename:
841                     stable_listNg.append(str(current_package.cpv))
842
843
844 def get_useflags(package):
845     iuse = get_iuse(package.cpv)
846     return iuse
847
848 def check_useflags_all_versions(pkgs, line, check_pkgs):
849
850     global useremove_display, invalid_flag_found 
851     invalid_flag_found = False
852    
853     print_output(debug,portage.output.blue("ENTERED check_useflags_all_versions: " + check_pkgs))
854
855     potential_invalid_flag = []
856     valid_flag_list = []
857     for package in pkgs:
858
859         # if package not installed, move on
860         if (not package.is_installed()):
861             continue;
862
863         print_output(debug,portage.output.blue("check_useflags_all_versions: package: " + package.cpv))
864         if ((package is None) or (package == "")):
865             return
866
867         useflag_removal_display=""
868
869         if (len(line) <= 0):
870             return
871
872         iuse = get_useflags(package)
873
874         #for iuse_item in iuse:
875         #    print_output(debug,portage.output.blue(("iuse_item is " + iuse_item)))
876     
877         useflags_fromfile = line.replace("\t", " ").split(" ")
878
879         #for useflags_fromfile_item in useflags_fromfile:
880         #    print_output(debug,portage.output.blue(("useflags_fromfile_item is " + useflags_fromfile_item)))
881
882         package_string = useflags_fromfile.pop(0)
883         print_output(debug,portage.output.blue(("package_string is " + package_string)))
884     
885         clean_useflags_list = []
886         # remove + or -
887         atom = "-+"
888     
889         #clean list from portage of + or -
890         clean_iuse = []
891         for item in iuse:
892             if item[0] in atom:
893                 clean_iuse.append(item[1:])
894             else:
895                 clean_iuse.append(item)
896     
897         for original_flag in useflags_fromfile:
898             if (original_flag is None or original_flag == ""):
899                 continue
900             flag = original_flag
901             if original_flag[0] in atom:
902                 flag = original_flag[1:]
903             if flag not in clean_iuse:
904                 print_output(debug,portage.output.blue(("found invalid flag: " + flag)))
905
906                 # only add to invalid list if it's not in valid list
907                 try:
908                     index = valid_flag_list.index(original_flag)
909                 except ValueError as error:
910
911                     try:
912                        index = potential_invalid_flag.index(original_flag)
913                     except ValueError:
914                        print_output(debug,portage.output.blue(original_flag + " not found for " + package.cpv))
915                        potential_invalid_flag.append(original_flag)
916
917             else:
918                 print_output(debug,portage.output.blue(("found valid flag: " + flag)))
919                 try:
920                     index = valid_flag_list.index(original_flag)
921                 except ValueError as error:
922                     valid_flag_list.append(original_flag)
923
924                 try:
925                     index = potential_invalid_flag.index(original_flag)
926                     potential_invalid_flag.remove(original_flag)
927                 except ValueError as error:
928                     continue
929
930
931     # if potential_invalid_flag list is empty, we are done
932     if (len(potential_invalid_flag) <= 0):
933         return
934
935     invalid_flag_found = True
936
937     # build sentence
938     invalid_flags = ""
939     verb = "is"
940     for inv_flag in potential_invalid_flag:
941         if (len(invalid_flags) > 0):
942             invalid_flags += ","
943             verb = "are"
944         invalid_flags += inv_flag
945
946     # if there are no valid flags at all, we remove the line
947     if ( len(valid_flag_list) == 0):
948         print_output (info,portage.output.red("No valid use flags found for package: " + str(package.category) + "/" + str(package.name) + ". Invalid flag(s) found: " + invalid_flags +  "\n"))
949         useremove_display += "Removing line: " + line + "\n"
950         use_flag_dict[line] = ""
951         return
952
953     # if there are values in potential_invalid_flag, we need to remove them
954
955     if (len(potential_invalid_flag) > 0):
956         removal_text = "use flags: "
957     else:
958         removal_text = "use flag: "
959
960     if ( (len(valid_flag_list) > 0)):
961         useremove_display += "Removing " + removal_text + invalid_flags + " for package " + check_pkgs + "\n"
962         print (portage.output.yellow(removal_text) +  portage.output.red(invalid_flags) + portage.output.yellow(" " + verb + " invalid for " + str(package.cpv)))
963
964     valid_flag_list.insert(0,package_string);
965
966     if (len(potential_invalid_flag) > 0):
967         use_flag_dict[line] = valid_flag_list
968         
969     return valid_flag_list
970
971 def check_useflags(package,line):
972
973     global useremove_display, invalid_flag_found 
974     invalid_flag_found = False
975
976     print_output(debug,portage.output.blue("check_useflags: package: " + package.cpv))
977     if ((package is None) or (package == "")):
978         return
979
980     useflag_removal_display=""
981
982     if (len(line) <= 0):
983         return
984
985     iuse = get_useflags(package)
986
987     #for iuse_item in iuse:
988     #    print_output(debug,portage.output.blue(("iuse_item is " + iuse_item)))
989
990     useflags_fromfile = line.replace("\t", " ").split(" ")
991     #for useflags_fromfile_item in useflags_fromfile:
992     #    print_output(debug,portage.output.blue(("useflags_fromfile_item is " + useflags_fromfile_item)))
993
994     package_string = useflags_fromfile.pop(0)
995     print_output(debug,portage.output.blue(("package_string is " + package_string)))
996
997     clean_useflags_list = []
998     # remove + or -
999     atom = "-+"
1000
1001     #clean list from portage of + or -
1002     clean_iuse = []
1003     for item in iuse:
1004         if item[0] in atom:
1005             clean_iuse.append(item[1:])
1006         else:
1007             clean_iuse.append(item)
1008
1009     valid_flag_list = []
1010     for original_flag in useflags_fromfile:
1011         if (original_flag is None or original_flag == ""):
1012             continue
1013         flag = original_flag
1014         if original_flag[0] in atom:
1015             flag = original_flag[1:]
1016         if flag not in clean_iuse:
1017             print_output (info,portage.output.red("use flag: " + flag + " is invalid for : " + str(package.cpv)))
1018             useflag_removal_display += "Removing use flag: " + flag + " for package " + str(package.cpv)
1019             invalid_flag_found = True
1020         else:
1021             valid_flag_list.append(original_flag)
1022
1023     # if valid_flag_list is empty, there are no valid flags
1024     if ( (len(valid_flag_list) > 0) and (len(useflag_removal_display) >0)):
1025         useremove_display += useflag_removal_display + "\n"
1026     elif ( len(valid_flag_list) == 0):
1027         useremove_display += "No valid use flags found for package " + str(package.cpv) + ". Removing line: " + line + "\n"
1028         if ( invalid_flag_found != True):
1029             print_output (info,portage.output.red("No valid use flags found for package " + str(package.cpv)))
1030         invalid_flag_found = True
1031
1032     valid_flag_list.insert(0,package_string);
1033     if (invalid_flag_found == True):
1034         use_flag_dict[line] = valid_flag_list
1035
1036     return valid_flag_list
1037
1038
1039 def clean_useflagsFile(filename):
1040
1041     if "--fix-confirm" in cmdline:
1042         if (confirmFix() == False):
1043             return
1044     
1045     display_line = ""
1046     removed_list = []
1047
1048     try:
1049         # determine if filename is a directory
1050         if os.path.isdir(filename):
1051             # get listing of directory
1052             filenames = os.listdir(filename)
1053             for file_name in filenames:
1054                 clean_useflagsFile(filename+os.path.sep+file_name)
1055             return
1056         else:
1057             #go through stable array and remove line if found
1058             for line in fileinput.input(filename,inplace =1):
1059                 itemFound = False
1060                 line = line.strip()
1061
1062                 # make sure line is not empty and do not remove commented out lines
1063                 if len(line) <= 0:
1064                     continue
1065                 elif line.find("#") == 0:
1066                     print (line)
1067                     continue
1068
1069                 check_for_change = ""
1070                 use_flag_dict.get(line,"")
1071                 try:
1072                     check_for_change = use_flag_dict[line]
1073                     removed_list.append(line)
1074                     if ( len(check_for_change) > 1):
1075                         print (" ".join(check_for_change))
1076                 except KeyError as error:
1077                     print (line)
1078
1079             fileinput.close()
1080     except OSError as error:
1081         print (portage.output.red("Modify/Read access to file: " + filename + " failed: " + format(error)))
1082
1083     if (len(removed_list) > 0):
1084         print ("\n")
1085         for package in removed_list:
1086             print (portage.output.red("Removing from: ") + portage.output.yellow(filename + ": Invalid use flag(s) from ")  + portage.output.green(package) + "\n")
1087
1088     return
1089
1090 def handle_if_overlay(package):
1091     overlay_text = ""
1092     global print_overlay_flag,using_gentoo_as_overlay
1093
1094     if (using_gentoo_as_overlay):
1095         return overlay_text
1096
1097     print_overlay_flag = True
1098
1099     ebuild_path,overlay_path = porttree.dbapi.findname2(str(package.cpv))
1100     index = -1
1101     try:
1102         index = overlay_list.index(overlay_path)
1103     except ValueError as error:
1104         overlay_list.append(overlay_path)
1105         index = overlay_list.index(overlay_path)
1106
1107     overlay_text = " [%s]" % (str(index+1))
1108
1109     return overlay_text
1110
1111 # if the overlay_text was displayed to the user
1112 # we need to display the string at the end 
1113 # this array will store the overlays to be displayed
1114 def print_overlay_text():
1115    
1116     global print_overlay_flag
1117     
1118     if (not print_overlay_flag):
1119         return
1120     
1121     if (len(overlay_list) <= 0):
1122         return
1123
1124     index = 1
1125     for x in overlay_list:
1126         print (portage.output.turquoise("[" + str(index) + "] ") + x)
1127         index = index + 1
1128     
1129     print ("\n")
1130
1131 #helper function to print output
1132 def print_output(log_level,output_string, package=None, filename=None):
1133     
1134     global logLevel
1135
1136     if package != None:
1137         if (package.is_overlay()):
1138             output_string = "%s%s" % (output_string,portage.output.turquoise(handle_if_overlay(package)))
1139             #output_string = output_string + portage.output.turquoise(handle_if_overlay(package))
1140         else:
1141             if filename != None:
1142                 output_string = "%s%s" % (output_string,portage.output.brown(" : " + filename))
1143                 #output_string = output_string + portage.output.brown(" : " + filename)
1144
1145     if (log_level <= logLevel):
1146         print (output_string)
1147
1148 # remove stabled files that are no longer needed from package.keywords
1149 # or package.mask
1150 # includes support for etc/portage/package.keywords/<whatever>/package.keywords
1151 def cleanFile (filename):
1152
1153     removeDups = []
1154     removed_list = []
1155
1156     if "--fix-confirm" in cmdline:
1157         if (confirmFix() == False):
1158             return
1159
1160     # if the file or directory does not exist
1161     # exit out
1162     if (os.path.exists(filename) == False):
1163         return
1164     
1165     if "package.keywords" in filename:
1166         if ( len(stable_list) == 0):
1167             return
1168         removeDups = stable_list
1169     elif "package.accept_keywords" in filename:
1170         if ( len(stable_listNg) == 0):
1171             return
1172         removeDups = stable_listNg
1173     else:
1174         if ( len(unmask_list) == 0):
1175             return
1176         removeDups = unmask_list
1177
1178     removedDict = {}
1179
1180     try:
1181         # determine if filename is a directory
1182         if os.path.isdir(filename):
1183             # get listing of directory
1184             filenames = os.listdir(filename)
1185             for file_name in filenames:
1186                 cleanFile(filename+os.path.sep+file_name)
1187             return
1188         else:   
1189             #go through stable array and remove line if found
1190             for line in fileinput.input(filename,inplace =1):
1191                 itemFound = False
1192                 line = line.strip()
1193
1194                 # make sure line is not empty and do not remove commented out lines
1195                 if len(line) <= 0:
1196                     continue
1197                 elif line.find("#") == 0:
1198                     print (line)
1199                     continue
1200
1201                 for item in removeDups:
1202                     if item in line:
1203                         removed_list.append(item)
1204                         removedDict[filename] = item
1205                         itemFound = True
1206                         removeDups.pop(removeDups.index(item))
1207                         break
1208                 if (itemFound == False):
1209                     print (line)
1210             fileinput.close()
1211     except OSError as error:
1212         print (portage.output.red("Modify/Read access to file: " + filename + " failed: " + format(error)))
1213     
1214     if (len(removed_list) > 0):
1215         print ("\n")
1216         for package in removed_list:
1217             print (portage.output.red("Removing from: ") + portage.output.yellow(filename) + ": " + portage.output.green(package) + "\n")
1218
1219 # ask the user if they want to fix their files
1220 # and remove unneeded entries
1221 # Return true if they say yes and False if they say no
1222 def confirmFix():
1223     
1224     global fix_asked,fix_confirm
1225
1226     if (fix_asked == True):
1227         return fix_confirm
1228
1229     # only ask if we actually have anything to check
1230     if ( (len(stable_list) == 0) and 
1231           (len(stable_listNg) == 0) and
1232           (len(unmask_list) == 0) and
1233           (invalid_flag_found == False) and 
1234           (len(use_flag_dict) == 0)):
1235         fix_confirm = True
1236         return fix_confirm
1237
1238     fix_asked = True 
1239
1240     valid = {"yes":"yes",   "y":"yes", 
1241              "no":"no",     "n":"no"}
1242    
1243     prompt = portage.output.bold("Remove entries from files [") + portage.output.green("y") + "/" + portage.output.red("n") + portage.output.bold("]") + " "
1244
1245     while 1:
1246         sys.stdout.write('\n' + prompt)
1247         choice = input().lower()
1248         if choice == '':
1249             fix_confirm = False
1250             break
1251         elif choice in valid.keys():
1252             if (choice == 'y' or choice == 'yes'):
1253                 fix_confirm = True
1254                 break
1255             else:
1256                 fix_confirm = False
1257                 break 
1258         else:
1259             sys.stdout.write("Please respond with 'yes' or 'no' "\
1260                              "(or 'y' or 'n').\n")
1261
1262     return fix_confirm
1263
1264
1265 def check_for_any_installed_version(pkgs):
1266     
1267     for package in pkgs:
1268         if (package.is_installed()):
1269             return True
1270
1271     return False
1272
1273 # main
1274 if __name__ == "__main__":
1275
1276     if len(sys.argv) == 1:
1277         print_usage()
1278         sys.exit(1)
1279
1280     # soooooo stolen from emerge
1281     tmpcmdline = sys.argv[1:]
1282
1283     for cmd in tmpcmdline:
1284         if cmd[0:1] == "-" and cmd[1:2] != "-":
1285             for cmd_item in cmd[1:]:
1286                 if cmd_item in mappings:
1287                     if mappings[cmd_item] in cmdline:
1288                         print ()
1289                         print ("*** Warning: Redundant use of ", mappings[cmd_item])
1290                     else:
1291                         cmdline.append(mappings[cmd_item])
1292                 else:
1293                     print ("!!! Error: -"+cmd_item+" is an invalid option.")
1294                     sys.exit(-1)
1295         else:
1296             cmdline.append(cmd)
1297
1298     #parse long options
1299     for cmd in cmdline:
1300         if len(cmd)>=2 and cmd[0:2]=="--":
1301             try:
1302                 i = options.index(cmd)
1303                 continue
1304             except ValueError:
1305                 print ("!!! Error: -"+cmd+" is an invalid option.")
1306                 sys.exit(-1)
1307
1308     if "--changes-only" in cmdline:
1309         cmdline.remove("--changes-only")
1310         show_changes_only_flag = True
1311
1312     if "--removable-only" in cmdline:
1313         cmdline.remove("--removable-only")
1314         show_removable_only_flag = True
1315
1316     if "--debug" in cmdline:
1317         logLevel = debug
1318
1319     if "--no-color" in cmdline:
1320         portage.output.nocolor()
1321
1322     if "--tilde-check" in cmdline:
1323         tilde=1
1324
1325     if "--version" in cmdline:
1326         print_version()
1327         sys.exit(0)
1328
1329     if "--fix-confirm" in cmdline:
1330         if '--fix' not in cmdline:
1331             cmdline.append("--fix")
1332     
1333     if "--all" in cmdline:
1334         tmpcmdline = ["--all"]
1335         if "--fix" in cmdline:
1336             tmpcmdline.append("--fix")
1337             if "--fix-confirm" in cmdline:
1338                 tmpcmdline.append("--fix-confirm")
1339                 fix_confirm = False
1340         cmdline=tmpcmdline      
1341
1342     if "--help" in cmdline:
1343         print_usage()
1344         sys.exit(0)
1345     
1346     if (show_changes_only_flag and show_removable_only_flag):
1347         print ("Please select only one of --show-removable (-r) or --changes-only")
1348         print ("Use --help for more info.")
1349         sys.exit(0)
1350         
1351     for cmd in cmdline:
1352         if cmd == "--keyword":
1353             print (portage.output.bold("\npackage.keywords:"))
1354             get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1355             if "--fix" in cmdline:
1356                 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1357             print (portage.output.bold("Done\n"))
1358             print (portage.output.bold("\npackage.accept_keywords:"))
1359             get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1360             if "--fix" in cmdline:
1361                 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1362             print (portage.output.bold("Done\n"))
1363         elif cmd == "--unmask": 
1364             print (portage.output.bold("\npackage.unmask:"))
1365             checking_package_unmask = True
1366             get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1367             checking_package_unmask = False
1368             if "--fix" in cmdline:
1369                 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1370         elif cmd == "--mask":
1371             checking_package_mask = True
1372             print (portage.output.bold("\npackage.mask:"))
1373             get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1374             print (portage.output.bold("Done\n"))
1375             checking_package_mask = False
1376             if "--fix" in cmdline:
1377                 cleanFile(USER_CONFIG_PATH + "/package.mask")
1378         elif cmd == "--package-use":
1379             print (portage.output.bold("\npackage.use:"))
1380             processing_package_use = True
1381             get_recursive_info(USER_CONFIG_PATH + "/package.use")
1382             if "--fix" in cmdline:
1383                 cleanFile(USER_CONFIG_PATH + "/package.use")
1384                 clean_useflagsFile(USER_CONFIG_PATH + "/package.use")
1385             print (portage.output.bold("Done\n"))
1386         elif cmd == "--all":
1387             print (portage.output.bold("\npackage.keywords:"))
1388             get_recursive_info(USER_CONFIG_PATH + "/package.keywords")
1389             print (portage.output.bold("\npackage.accept_keywords:"))
1390             get_recursive_info(USER_CONFIG_PATH + "/package.accept_keywords")
1391             print (portage.output.bold("\npackage.unmask:"))
1392             checking_package_unmask = True
1393             get_recursive_info(USER_CONFIG_PATH + "/package.unmask")
1394             checking_package_unmask = False
1395             checking_package_mask = True
1396             print (portage.output.bold("\npackage.mask:"))
1397             get_recursive_info(USER_CONFIG_PATH + "/package.mask")
1398             print (portage.output.bold("\npackage.use:"))
1399             processing_package_use = True
1400             get_recursive_info(USER_CONFIG_PATH + "/package.use")
1401             if "--fix" in cmdline:
1402                 cleanFile(USER_CONFIG_PATH + "/package.keywords")
1403                 cleanFile(USER_CONFIG_PATH + "/package.accept_keywords")
1404                 cleanFile(USER_CONFIG_PATH + "/package.unmask")
1405                 cleanFile(USER_CONFIG_PATH + "/package.use")
1406                 cleanFile(USER_CONFIG_PATH + "/package.mask")
1407                 clean_useflagsFile(USER_CONFIG_PATH + "/package.use")
1408             print (portage.output.bold("\nDone\n"))
1409
1410     print_overlay_text()
1411
1412     if len(cmdline) == 0:
1413         if show_changes_only_flag or show_removable_only_flag:
1414             if (show_changes_only_flag):
1415                 print (portage.output.green("-c") + " or " + portage.output.green("--changes-only") + " must be accompanied by one of the following:")
1416             else:
1417                 print (portage.output.green("-r") + " or " + portage.output.green("--removable-only") + " must be accompanied by one of the following:")
1418
1419             print ("     " + portage.output.yellow("-k") + " or " + portage.output.yellow("--keyword"))
1420             print ("     " + portage.output.yellow("-u") + " or " + portage.output.yellow("--unmask"))
1421             print ("     " + portage.output.yellow("-m") + " or " + portage.output.yellow("--mask"))
1422             print ("     " + portage.output.yellow("-a") + " or " + portage.output.yellow("--all"))
1423
1424             print_usage()
1425