Merge genscripts rev 406
[gentoolkit.git] / pym / gentoolkit / analyse / 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 """Analyse 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
26
27 class ModuleBase(object):
28         """Analyse 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
40
41         def print_help(self, with_description=True):
42                 """Print description, usage and a detailed help message.
43
44                 @type with_description: bool
45                 @param with_description: if true, print module's __doc__ string
46                 """
47
48                 if with_description:
49                         print()
50                         print(__doc__.strip())
51                         print()
52                 if self.warning:
53                         print()
54                         for line in self.warning:
55                                 sys.stderr.write(pp.warn(line))
56                         print()
57                 print(mod_usage(mod_name=self.module_name, arg=self.arg_spec, optional=self.arg_option))
58                 print()
59                 print(pp.command("options"))
60                 print(format_options( self.formatted_options ))
61                 if self.formatted_args:
62                         print()
63                         print(pp.command(self.arg_spec))
64                         print(format_options(self.formatted_args))
65                 print()
66
67         def parse_module_options(self, module_opts):
68                 """Parse module options and update self.options"""
69
70                 opts = (x[0] for x in module_opts)
71                 posargs = (x[1] for x in module_opts)
72                 for opt, posarg in zip(opts, posargs):
73                         if opt in ('-h', '--help'):
74                                         self.print_help()
75                                         sys.exit(0)
76                         opt_name, opt_type, opt_setting = self.module_opts[opt]
77                         if opt_type == 'boolean':
78                                 self.options[opt_name] = opt_setting
79                         elif opt_type == 'int':
80                                 if posarg.isdigit():
81                                         val = int(posarg)
82                                 else:
83                                         print()
84                                         err = "Module option %s requires integer (got '%s')"
85                                         sys.stdout.write(pp.error(err % (opt,posarg)))
86                                         print()
87                                         self.print_help(with_description=False)
88                                         sys.exit(2)
89                                 self.options[opt_name] = val
90                 if self.options['quiet']:
91                         self.options['verbose'] = False
92
93         def validate_query(self, query, depth=0):
94                 """check that the query meets the modules TargetSpec
95                 If not it attempts to reduce it to a valid TargetSpec
96                 or prints the help message and exits
97                 """
98                 if depth > 1:
99                         return []
100                 if len(query) > 1:
101                         query = list(set(self.arg_options).intersection(query))
102                         #print "reduced query =", query
103                         query = self.validate_query(query, depth+1)
104                 if isinstance(query, list):
105                         query = query[0]
106                 if query not in self.arg_options:
107                         print()
108                         print(pp.error(
109                                 "Error starting module. Incorrect or No TargetSpec specified!"
110                                 ))
111                         print("query = ", query)
112                         self.print_help()
113                         sys.exit(2)
114                 return query
115
116
117         def main_setup(self, input_args):
118                 """Parse input and prepares the program"""
119
120                 try:
121                         module_opts, queries = gnu_getopt(input_args, self.short_opts, self.long_opts)
122                 except GetoptError as err:
123                         sys.stderr.write(pp.error("Module %s" % err))
124                         print()
125                         self.print_help(with_description=False)
126                         sys.exit(2)
127                 self.parse_module_options(module_opts)
128                 if self.need_queries and not queries:
129                         self.print_help()
130                         sys.exit(2)
131                 return queries
132
133
134 # vim: set ts=4 sw=4 tw=79: