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