|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 #!/usr/bin/env python |
|
17 ## |
|
18 # @author Teemu Rytkonen |
|
19 |
|
20 import os |
|
21 import sys |
|
22 import logging |
|
23 import logging.config |
|
24 import re, fnmatch |
|
25 from optparse import Option |
|
26 import cone_tool |
|
27 |
|
28 |
|
29 """ |
|
30 try to import cone and modify the sys.paths if it does not succeed. |
|
31 This is done mainly for local installation and testing purposes. |
|
32 """ |
|
33 ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) |
|
34 |
|
35 try: |
|
36 from cone.public import api, settings |
|
37 except ImportError: |
|
38 sys.path.append(os.path.join(ROOT_PATH)) |
|
39 sys.path.append(os.path.join(ROOT_PATH,'..')) |
|
40 from cone.public import api, settings |
|
41 |
|
42 # Common command line options used by all sub-actions |
|
43 COMMON_OPTIONS = [ |
|
44 Option("--print-settings", |
|
45 dest="print_settings", |
|
46 action="store_true", |
|
47 help="Print all the default settings from the current setting container.", |
|
48 default=False), |
|
49 |
|
50 Option("--print-supported-impls", |
|
51 action="store_true", |
|
52 help="Print all supported ImplML XML namespaces and file extensions.", |
|
53 default=False), |
|
54 |
|
55 Option("--print-runtime-info", |
|
56 action="store_true", |
|
57 help="Print runtime information about ConE.", |
|
58 default=False), |
|
59 |
|
60 Option("-v", "--verbose",\ |
|
61 dest="verbose",\ |
|
62 help="""Print error, warning and information on system out. |
|
63 Possible choices: Default is 3. |
|
64 NONE (all) 0 |
|
65 CRITICAL 1 |
|
66 ERROR 2 |
|
67 WARNING 3 |
|
68 INFO 4 |
|
69 DEBUG 5""", |
|
70 metavar="LEVEL", |
|
71 default="3"), |
|
72 |
|
73 Option("--log-file", |
|
74 dest="log_file", |
|
75 action="store", |
|
76 type="string", |
|
77 help="Location of the used log file. Default is 'cone.log'", |
|
78 metavar="FILE", |
|
79 default="cone.log"), |
|
80 |
|
81 Option("--log-config", |
|
82 dest="log_conf", |
|
83 action="store", |
|
84 type="string", |
|
85 help="Location of the used logging configuration file. Default is 'logging.ini'", |
|
86 metavar="FILE"), |
|
87 |
|
88 Option("--username", |
|
89 dest="username", |
|
90 action="store", |
|
91 type="string", |
|
92 help="Username for webstorage operations. Not needed for filestorage or cpf storage. If the username \ |
|
93 is not given, the tool will use the loggged in username.", |
|
94 metavar="USERNAME"), |
|
95 |
|
96 Option("--password", |
|
97 dest="password", |
|
98 action="store", |
|
99 type="string", |
|
100 help="Password for webstorage operations. Not needed for filestorage or cpf storage. If the password \ |
|
101 is not given, the tool will prompt for password if needed.", |
|
102 metavar="PASSWORD"), |
|
103 ] |
|
104 |
|
105 def handle_common_options(options, settings=None): |
|
106 """ |
|
107 Handle common command line options. |
|
108 @param options: The parsed command line options. |
|
109 @param settings: The settings to print if --print-settings is used. |
|
110 Can be None, in which case the default settings are printed. |
|
111 """ |
|
112 if options.log_conf: |
|
113 open_log(options.verbose, options.log_file, options.log_conf) |
|
114 else: |
|
115 open_log(options.verbose, options.log_file) |
|
116 |
|
117 exit = False |
|
118 |
|
119 if options.print_settings: |
|
120 if settings == None: |
|
121 settings = get_settings([]) |
|
122 print_settings(settings) |
|
123 exit = True |
|
124 |
|
125 if options.print_supported_impls: |
|
126 from cone.public import plugin |
|
127 print "Supported ImplML namespaces:" |
|
128 for ns in sorted(plugin.get_supported_namespaces()): |
|
129 print ns |
|
130 |
|
131 print "" |
|
132 print "Supported ImplML file extensions:" |
|
133 for ns in plugin.get_supported_file_extensions(): |
|
134 print ns |
|
135 exit = True |
|
136 |
|
137 if options.print_runtime_info: |
|
138 print _get_runtime_info() |
|
139 print "\nsys.path contents:" |
|
140 print '\n'.join(sys.path) |
|
141 exit = True |
|
142 |
|
143 if exit: sys.exit() |
|
144 |
|
145 def _get_runtime_info(): |
|
146 if hasattr(sys, 'executable'): executable = sys.executable |
|
147 else: executable = 'N/A' |
|
148 info = ["ConE version: %s" % cone_tool.VERSION, |
|
149 "Python version: %s" % sys.version, |
|
150 "Platform: %s" % sys.platform, |
|
151 "Executable: %s" % executable, |
|
152 "Command line: %s" % ' '.join(sys.argv), |
|
153 "Working dir: %s" % os.getcwd(), |
|
154 "Script location: %s" % ROOT_PATH] |
|
155 return '\n'.join(info) |
|
156 |
|
157 def open_log(verbose, log_file, log_conf_file=os.path.join(ROOT_PATH, 'logging.ini')): |
|
158 try: |
|
159 log_dir = os.path.dirname(log_file) |
|
160 if log_dir != '' and not os.path.exists(log_dir): |
|
161 os.makedirs(log_dir) |
|
162 |
|
163 if (os.path.exists(log_conf_file)): |
|
164 defaults = {'logfile': log_file, 'level': get_log_level_for_config(verbose)} |
|
165 logging.config.fileConfig(log_conf_file, defaults) |
|
166 else: |
|
167 print "Failed to load logging configuration file: %s" % log_conf_file |
|
168 |
|
169 logger = logging.getLogger('cone') |
|
170 logger.info("Runtime info:\n%s" % _get_runtime_info()) |
|
171 logger.debug("sys.path contents:\n%s" % '\n'.join(sys.path)) |
|
172 |
|
173 def get_var(varname): |
|
174 try: return os.environ[varname] |
|
175 except KeyError: return 'N/A' |
|
176 logger.debug("PATH: %s" % get_var('PATH')) |
|
177 logger.debug("PYTHONPATH: %s" % get_var('PYTHONPATH')) |
|
178 except IOError, e: |
|
179 print "Cannot create log file. ", e |
|
180 |
|
181 def get_settings(files): |
|
182 parser = settings.SettingsFactory.cone_parser() |
|
183 parser.read(files) |
|
184 return parser |
|
185 |
|
186 def print_settings(parser): |
|
187 print_section(parser,"DEFAULT") |
|
188 for section in parser.sections(): |
|
189 print_section(parser,section) |
|
190 |
|
191 def print_section(parser, section): |
|
192 print "[%s]" % section |
|
193 for (name,value) in parser.items(section): |
|
194 print " %s = %s" % (name,value) |
|
195 |
|
196 |
|
197 def get_log_level(level): |
|
198 """ |
|
199 Change the given user input log level to logging categorisation |
|
200 """ |
|
201 # If the level is empty, revert to the default |
|
202 if level in ('', None): |
|
203 level = '3' |
|
204 |
|
205 if level == '0' : return logging.NOTSET |
|
206 elif level == '1' : return logging.CRITICAL |
|
207 elif level == '2' : return logging.ERROR |
|
208 elif level == '3' : return logging.WARNING |
|
209 elif level == '4' : return logging.INFO |
|
210 elif level == '5' : return logging.DEBUG |
|
211 else : return logging.NOTSET |
|
212 |
|
213 def get_log_level_for_config(level): |
|
214 """ |
|
215 Change the given user input to log level to logging configuration file |
|
216 """ |
|
217 |
|
218 # If the level is empty, revert to the default |
|
219 if level in ('', None): |
|
220 level = 'WARNING' |
|
221 |
|
222 if level == '0' : return 'NOTSET' |
|
223 elif level == '1' : return 'CRITICAL' |
|
224 elif level == '2' : return 'ERROR' |
|
225 elif level == '3' : return 'WARNING' |
|
226 elif level == '4' : return 'INFO' |
|
227 elif level == '5' : return 'DEBUG' |
|
228 else : return 'NOTSET' |
|
229 |
|
230 |
|
231 class ConfigurationNotFoundError(Exception): |
|
232 """ |
|
233 Exception raised by get_config_list_from_project() if an invalid |
|
234 configuration is given. |
|
235 """ |
|
236 pass |
|
237 |
|
238 def get_config_list_from_project(project, configs, config_wildcards, config_regexes): |
|
239 """ |
|
240 Return a list of configuration root names based on the given parameters. |
|
241 @param project: The project from which to get the configuration list. |
|
242 @param configs: List of configuration names to add. All of these should exist |
|
243 in the project, or a ConfigurationNotFoundError is raised. |
|
244 @param config_wildcards: List of wildcard patterns for including configurations. |
|
245 @param config_regexs: List of regular expression patters for including configurations. |
|
246 @return: A distinct list of configuration names matched by the given parameters. The |
|
247 list contains matched configurations in the following order: |
|
248 1. Configurations specified in configs |
|
249 2. Configurations matched by wildcard patterns |
|
250 3. Configurations matched by regular expressions |
|
251 If a configuration is matched by more than one of these, the first match determines |
|
252 its placement in the list. |
|
253 @raise ConfigurationNotFoundError: A configuration specified in configs is not |
|
254 actually found in the project. |
|
255 """ |
|
256 config_list = [] |
|
257 |
|
258 configs_in_project = sorted(project.list_configurations()) |
|
259 |
|
260 # Handle configurations specified with --configuration first |
|
261 for config in configs: |
|
262 if config not in configs_in_project: |
|
263 raise ConfigurationNotFoundError("No such configuration: %s" % config) |
|
264 if config not in config_list: |
|
265 config_list.append(config) |
|
266 |
|
267 # Then handle wildcards |
|
268 if config_wildcards: |
|
269 for config in configs_in_project: |
|
270 for wildcard in config_wildcards: |
|
271 if fnmatch.fnmatch(config, wildcard): |
|
272 if config not in config_list: |
|
273 config_list.append(config) |
|
274 |
|
275 # Lastly handle regexes |
|
276 if config_regexes: |
|
277 for config in configs_in_project: |
|
278 for pattern in config_regexes: |
|
279 if re.match(pattern, config) is not None: |
|
280 if config not in config_list: |
|
281 config_list.append(config) |
|
282 |
|
283 return config_list |