f8a6774767ef02680a25b572854c80c9427eb035
[gentoolkit.git] / pym / gentoolkit / enalyze / base.py
1 # Copyright(c) 2009, Gentoo Foundation
2 #
3 # Copyright 2010 Brian Dolbec <brian.dolbec@gmail.com>
4 # Copyright(c) 2010, Gentoo Foundation
5 # Distributed under the terms of the GNU General Public License v2
6 #
7 # $Header: $
8
9 """General Base Module class to hold common module operation functions
10 """
11
12 from __future__ import print_function
13
14 __docformat__ = 'epytext'
15
16
17 import errno
18 import sys
19 import time
20 from getopt import gnu_getopt, GetoptError
21
22 import gentoolkit.pprinter as pp
23 from gentoolkit.formatters import format_options
24 from gentoolkit.base import mod_usage
25 from gentoolkit import CONFIG
26
27 class ModuleBase(object):
28         """E-app base module class to parse module options print module help, etc.."""
29
30         def __init__(self):
31                 self.module_name = None
32                 self.options = {}
33                 self.formatted_options = None
34                 self.short_opts = None
35                 self.long_opts = None
36                 self.module_opts = {}
37                 self.warning = None
38                 self.need_queries = True
39                 self.saved_verbose = None
40
41
42         def print_help(self, with_description=True):
43                 """Print description, usage and a detailed help message.
44
45                 @type with_description: bool
46                 @param with_description: if true, print module's __doc__ string
47                 """
48
49                 if with_description:
50                         print()
51                         print(__doc__.strip())
52                         print()
53                 if self.warning:
54                         print()
55                         for line in self.warning:
56                                 sys.stderr.write(pp.warn(line))
57                         print()
58                 print(mod_usage(mod_name=self.module_name, arg=self.arg_spec, optional=self.arg_option))
59                 print()
60                 print(pp.command("options"))
61                 print(format_options( self.formatted_options ))
62                 if self.formatted_args:
63                         print()
64                         print(pp.command(self.arg_spec))
65                         print(format_options(self.formatted_args))
66                 print()
67
68         def parse_module_options(self, module_opts):
69                 """Parse module options and update self.options"""
70
71                 opts = (x[0] for x in module_opts)
72                 posargs = (x[1] for x in module_opts)
73                 for opt, posarg in zip(opts, posargs):
74                         if opt in ('-h', '--help'):
75                                         self.print_help()
76                                         sys.exit(0)
77                         opt_name, opt_type, opt_setting = self.module_opts[opt]
78                         if opt_type == 'boolean':
79                                 self.options[opt_name] = opt_setting
80                         elif opt_type == 'int':
81                                 if posarg.isdigit():
82                                         val = int(posarg)
83                                 else:
84                                         print()
85                                         err = "Module option %s requires integer (got '%s')"
86                                         sys.stdout.write(pp.error(err % (opt,posarg)))
87                                         print()
88                                         self.print_help(with_description=False)
89                                         sys.exit(2)
90                                 self.options[opt_name] = val
91
92         def set_quiet(self, quiet):
93                 """sets the class option["quiet"] and option["verbose"] accordingly"""
94                 if quiet == self.options['quiet']:
95                         return
96                 if self.saved_verbose:
97                         # detected a switch
98                         verbose = self.options['verbose']
99                         self.options['verbose']  = self.saved_verbose
100                         self.saved_verbose = verbose
101                 elif quiet:
102                         self.saved_verbose = self.options['verbose']
103                         self.options['verbose'] = False
104                 self.options['quiet'] = quiet
105                 return
106
107         def validate_query(self, query, depth=0):
108                 """check that the query meets the modules TargetSpec
109                 If not it attempts to reduce it to a valid TargetSpec
110                 or prints the help message and exits
111                 """
112                 if depth > 1:
113                         return []
114                 if len(query) > 1:
115                         query = list(set(self.arg_options).intersection(query))
116                         #print "reduced query =", query
117                         query = self.validate_query(query, depth+1)
118                 if isinstance(query, list):
119                         query = query[0]
120                 if query not in self.arg_options:
121                         print()
122                         print(pp.error(
123                                 "Error starting module. Incorrect or No TargetSpec specified!"
124                                 ))
125                         print("query = ", query)
126                         self.print_help()
127                         sys.exit(2)
128                 return query
129
130
131         def main_setup(self, input_args):
132                 """Parse input and prepares the program"""
133
134                 try:
135                         module_opts, queries = gnu_getopt(input_args, self.short_opts, self.long_opts)
136                 except GetoptError as err:
137                         sys.stderr.write(pp.error("Module %s" % err))
138                         print()
139                         self.print_help(with_description=False)
140                         sys.exit(2)
141                 self.parse_module_options(module_opts)
142                 if self.need_queries and not queries:
143                         self.print_help()
144                         sys.exit(2)
145                 return queries
146
147
148 # vim: set ts=4 sw=4 tw=79: