203 # base commands ############################################################### |
203 # base commands ############################################################### |
204 |
204 |
205 class ListCommand(Command): |
205 class ListCommand(Command): |
206 """List configurations, cubes and instances. |
206 """List configurations, cubes and instances. |
207 |
207 |
208 list available configurations, installed cubes, and registered instances |
208 List available configurations, installed cubes, and registered instances. |
|
209 |
|
210 If given, the optional argument allows to restrict listing only a category of items. |
209 """ |
211 """ |
210 name = 'list' |
212 name = 'list' |
|
213 arguments = '[all|cubes|configurations|instances]' |
211 options = ( |
214 options = ( |
212 ('verbose', |
215 ('verbose', |
213 {'short': 'v', 'action' : 'store_true', |
216 {'short': 'v', 'action' : 'store_true', |
214 'help': "display more information."}), |
217 'help': "display more information."}), |
215 ) |
218 ) |
216 |
219 |
217 def run(self, args): |
220 def run(self, args): |
218 """run the command with its specific arguments""" |
221 """run the command with its specific arguments""" |
219 if args: |
222 if not args: |
|
223 mode = 'all' |
|
224 elif len(args) == 1: |
|
225 mode = args[0] |
|
226 else: |
220 raise BadCommandUsage('Too many arguments') |
227 raise BadCommandUsage('Too many arguments') |
|
228 |
221 from cubicweb.migration import ConfigurationProblem |
229 from cubicweb.migration import ConfigurationProblem |
222 print 'CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode) |
230 |
223 print |
231 if mode == 'all': |
224 print 'Available configurations:' |
232 print 'CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode) |
225 for config in CONFIGURATIONS: |
233 print |
226 print '*', config.name |
234 |
227 for line in config.__doc__.splitlines(): |
235 if mode in ('all', 'config', 'configurations'): |
228 line = line.strip() |
236 print 'Available configurations:' |
229 if not line: |
237 for config in CONFIGURATIONS: |
230 continue |
238 print '*', config.name |
231 print ' ', line |
239 for line in config.__doc__.splitlines(): |
232 print |
240 line = line.strip() |
233 cfgpb = ConfigurationProblem(cwcfg) |
241 if not line: |
234 try: |
242 continue |
235 cubesdir = pathsep.join(cwcfg.cubes_search_path()) |
243 print ' ', line |
236 namesize = max(len(x) for x in cwcfg.available_cubes()) |
244 print |
237 except ConfigurationError as ex: |
245 |
238 print 'No cubes available:', ex |
246 if mode in ('all', 'cubes'): |
239 except ValueError: |
247 cfgpb = ConfigurationProblem(cwcfg) |
240 print 'No cubes available in %s' % cubesdir |
248 try: |
241 else: |
249 cubesdir = pathsep.join(cwcfg.cubes_search_path()) |
242 print 'Available cubes (%s):' % cubesdir |
250 namesize = max(len(x) for x in cwcfg.available_cubes()) |
243 for cube in cwcfg.available_cubes(): |
251 except ConfigurationError as ex: |
244 try: |
252 print 'No cubes available:', ex |
245 tinfo = cwcfg.cube_pkginfo(cube) |
253 except ValueError: |
246 tversion = tinfo.version |
254 print 'No cubes available in %s' % cubesdir |
247 cfgpb.add_cube(cube, tversion) |
255 else: |
248 except (ConfigurationError, AttributeError) as ex: |
256 print 'Available cubes (%s):' % cubesdir |
249 tinfo = None |
257 for cube in cwcfg.available_cubes(): |
250 tversion = '[missing cube information: %s]' % ex |
258 try: |
251 print '* %s %s' % (cube.ljust(namesize), tversion) |
259 tinfo = cwcfg.cube_pkginfo(cube) |
252 if self.config.verbose: |
260 tversion = tinfo.version |
253 if tinfo: |
261 cfgpb.add_cube(cube, tversion) |
254 descr = getattr(tinfo, 'description', '') |
262 except (ConfigurationError, AttributeError) as ex: |
255 if not descr: |
263 tinfo = None |
256 descr = getattr(tinfo, 'short_desc', '') |
264 tversion = '[missing cube information: %s]' % ex |
|
265 print '* %s %s' % (cube.ljust(namesize), tversion) |
|
266 if self.config.verbose: |
|
267 if tinfo: |
|
268 descr = getattr(tinfo, 'description', '') |
|
269 if not descr: |
|
270 descr = getattr(tinfo, 'short_desc', '') |
|
271 if descr: |
|
272 warn('[3.8] short_desc is deprecated, update %s' |
|
273 ' pkginfo' % cube, DeprecationWarning) |
|
274 else: |
|
275 descr = tinfo.__doc__ |
257 if descr: |
276 if descr: |
258 warn('[3.8] short_desc is deprecated, update %s' |
277 print ' '+ ' \n'.join(descr.splitlines()) |
259 ' pkginfo' % cube, DeprecationWarning) |
278 modes = detect_available_modes(cwcfg.cube_dir(cube)) |
260 else: |
279 print ' available modes: %s' % ', '.join(modes) |
261 descr = tinfo.__doc__ |
|
262 if descr: |
|
263 print ' '+ ' \n'.join(descr.splitlines()) |
|
264 modes = detect_available_modes(cwcfg.cube_dir(cube)) |
|
265 print ' available modes: %s' % ', '.join(modes) |
|
266 print |
|
267 try: |
|
268 regdir = cwcfg.instances_dir() |
|
269 except ConfigurationError as ex: |
|
270 print 'No instance available:', ex |
|
271 print |
280 print |
272 return |
281 |
273 instances = list_instances(regdir) |
282 if mode in ('all', 'instances'): |
274 if instances: |
283 try: |
275 print 'Available instances (%s):' % regdir |
284 regdir = cwcfg.instances_dir() |
276 for appid in instances: |
285 except ConfigurationError as ex: |
277 modes = cwcfg.possible_configurations(appid) |
286 print 'No instance available:', ex |
278 if not modes: |
287 print |
279 print '* %s (BROKEN instance, no configuration found)' % appid |
288 return |
280 continue |
289 instances = list_instances(regdir) |
281 print '* %s (%s)' % (appid, ', '.join(modes)) |
290 if instances: |
282 try: |
291 print 'Available instances (%s):' % regdir |
283 config = cwcfg.config_for(appid, modes[0]) |
292 for appid in instances: |
284 except Exception as exc: |
293 modes = cwcfg.possible_configurations(appid) |
285 print ' (BROKEN instance, %s)' % exc |
294 if not modes: |
286 continue |
295 print '* %s (BROKEN instance, no configuration found)' % appid |
287 else: |
296 continue |
288 print 'No instance available in %s' % regdir |
297 print '* %s (%s)' % (appid, ', '.join(modes)) |
289 print |
298 try: |
290 # configuration management problem solving |
299 config = cwcfg.config_for(appid, modes[0]) |
291 cfgpb.solve() |
300 except Exception as exc: |
292 if cfgpb.warnings: |
301 print ' (BROKEN instance, %s)' % exc |
293 print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings) |
302 continue |
294 if cfgpb.errors: |
303 else: |
295 print 'Errors:' |
304 print 'No instance available in %s' % regdir |
296 for op, cube, version, src in cfgpb.errors: |
305 print |
297 if op == 'add': |
306 |
298 print '* cube', cube, |
307 if mode == 'all': |
299 if version: |
308 # configuration management problem solving |
300 print ' version', version, |
309 cfgpb.solve() |
301 print 'is not installed, but required by %s' % src |
310 if cfgpb.warnings: |
302 else: |
311 print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings) |
303 print '* cube %s version %s is installed, but version %s is required by %s' % ( |
312 if cfgpb.errors: |
304 cube, cfgpb.cubes[cube], version, src) |
313 print 'Errors:' |
|
314 for op, cube, version, src in cfgpb.errors: |
|
315 if op == 'add': |
|
316 print '* cube', cube, |
|
317 if version: |
|
318 print ' version', version, |
|
319 print 'is not installed, but required by %s' % src |
|
320 else: |
|
321 print '* cube %s version %s is installed, but version %s is required by %s' % ( |
|
322 cube, cfgpb.cubes[cube], version, src) |
305 |
323 |
306 def check_options_consistency(config): |
324 def check_options_consistency(config): |
307 if config.automatic and config.config_level > 0: |
325 if config.automatic and config.config_level > 0: |
308 raise BadCommandUsage('--automatic and --config-level should not be ' |
326 raise BadCommandUsage('--automatic and --config-level should not be ' |
309 'used together') |
327 'used together') |