24 # *ctl module should limit the number of import to be imported as quickly as |
24 # *ctl module should limit the number of import to be imported as quickly as |
25 # possible (for cubicweb-ctl reactivity, necessary for instance for usable bash |
25 # possible (for cubicweb-ctl reactivity, necessary for instance for usable bash |
26 # completion). So import locally in command helpers. |
26 # completion). So import locally in command helpers. |
27 import sys |
27 import sys |
28 from datetime import datetime |
28 from datetime import datetime |
29 from os import mkdir, chdir |
29 from os import mkdir, chdir, listdir, path as osp |
30 from os.path import join, exists, abspath, basename, normpath, split, isdir |
|
31 from warnings import warn |
30 from warnings import warn |
32 |
31 |
33 from logilab.common import STD_BLACKLIST |
32 from logilab.common import STD_BLACKLIST |
34 |
33 |
35 from cubicweb.__pkginfo__ import version as cubicwebversion |
34 from cubicweb.__pkginfo__ import version as cubicwebversion |
36 from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage |
35 from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage |
37 from cubicweb.cwctl import CWCTL |
36 from cubicweb.cwctl import CWCTL |
38 from cubicweb.toolsutils import (SKEL_EXCLUDE, Command, |
37 from cubicweb.toolsutils import (SKEL_EXCLUDE, Command, copy_skeleton, |
39 copy_skeleton, underline_title) |
38 underline_title) |
40 from cubicweb.web.webconfig import WebConfiguration |
39 from cubicweb.web.webconfig import WebConfiguration |
41 from cubicweb.server.serverconfig import ServerConfiguration |
40 from cubicweb.server.serverconfig import ServerConfiguration |
42 |
41 |
43 |
42 |
44 class DevConfiguration(ServerConfiguration, WebConfiguration): |
43 class DevConfiguration(ServerConfiguration, WebConfiguration): |
175 add_msg(w, 'add a %s' % tschema, |
175 add_msg(w, 'add a %s' % tschema, |
176 'inlined:%s.%s.%s' % (etype, rschema, role)) |
176 'inlined:%s.%s.%s' % (etype, rschema, role)) |
177 add_msg(w, str(tschema), |
177 add_msg(w, str(tschema), |
178 'inlined:%s.%s.%s' % (etype, rschema, role)) |
178 'inlined:%s.%s.%s' % (etype, rschema, role)) |
179 if appearsin_addmenu.etype_get(eschema, rschema, role, tschema): |
179 if appearsin_addmenu.etype_get(eschema, rschema, role, tschema): |
180 if libconfig is not None and libappearsin_addmenu.etype_get(eschema, rschema, role, tschema): |
180 if libconfig is not None and libappearsin_addmenu.etype_get( |
|
181 eschema, rschema, role, tschema): |
181 if eschema in libschema and tschema in libschema: |
182 if eschema in libschema and tschema in libschema: |
182 continue |
183 continue |
183 if role == 'subject': |
184 if role == 'subject': |
184 label = 'add %s %s %s %s' % (eschema, rschema, |
185 label = 'add %s %s %s %s' % (eschema, rschema, |
185 tschema, role) |
186 tschema, role) |
260 "Generated-By: cubicweb-devtools\n" |
261 "Generated-By: cubicweb-devtools\n" |
261 "Plural-Forms: nplurals=2; plural=(n > 1);\n" |
262 "Plural-Forms: nplurals=2; plural=(n > 1);\n" |
262 |
263 |
263 ''' % cubicwebversion |
264 ''' % cubicwebversion |
264 |
265 |
|
266 def cw_languages(): |
|
267 for fname in listdir(osp.join(WebConfiguration.i18n_lib_dir())): |
|
268 if fname.endswith('.po'): |
|
269 yield osp.splitext(fname)[0] |
|
270 |
265 |
271 |
266 class UpdateCubicWebCatalogCommand(Command): |
272 class UpdateCubicWebCatalogCommand(Command): |
267 """Update i18n catalogs for cubicweb library. |
273 """Update i18n catalogs for cubicweb library. |
268 |
274 |
269 It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those |
275 It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those |
270 files to add translations of newly added messages. |
276 files to add translations of newly added messages. |
271 """ |
277 """ |
272 name = 'i18ncubicweb' |
278 name = 'i18ncubicweb' |
|
279 min_args = max_args = 0 |
273 |
280 |
274 def run(self, args): |
281 def run(self, args): |
275 """run the command with its specific arguments""" |
282 """run the command with its specific arguments""" |
276 if args: |
|
277 raise BadCommandUsage('Too many arguments') |
|
278 import shutil |
283 import shutil |
279 import tempfile |
284 import tempfile |
280 import yams |
285 import yams |
281 from logilab.common.fileutils import ensure_fs_mode |
286 from logilab.common.fileutils import ensure_fs_mode |
282 from logilab.common.shellutils import globfind, find, rm |
287 from logilab.common.shellutils import globfind, find, rm |
283 from logilab.common.modutils import get_module_files |
288 from logilab.common.modutils import get_module_files |
284 from cubicweb.i18n import extract_from_tal, execute |
289 from cubicweb.i18n import extract_from_tal, execute |
285 tempdir = tempfile.mkdtemp() |
290 tempdir = tempfile.mkdtemp() |
286 potfiles = [join(I18NDIR, 'static-messages.pot')] |
291 cwi18ndir = WebConfiguration.i18n_lib_dir() |
287 print '-> extract schema messages.' |
292 print '-> extract schema messages.' |
288 schemapot = join(tempdir, 'schema.pot') |
293 schemapot = osp.join(tempdir, 'schema.pot') |
|
294 potfiles = [schemapot] |
289 potfiles.append(schemapot) |
295 potfiles.append(schemapot) |
290 # explicit close necessary else the file may not be yet flushed when |
296 # explicit close necessary else the file may not be yet flushed when |
291 # we'll using it below |
297 # we'll using it below |
292 schemapotstream = file(schemapot, 'w') |
298 schemapotstream = file(schemapot, 'w') |
293 generate_schema_pot(schemapotstream.write, cubedir=None) |
299 generate_schema_pot(schemapotstream.write, cubedir=None) |
294 schemapotstream.close() |
300 schemapotstream.close() |
295 print '-> extract TAL messages.' |
301 print '-> extract TAL messages.' |
296 tali18nfile = join(tempdir, 'tali18n.py') |
302 tali18nfile = osp.join(tempdir, 'tali18n.py') |
297 extract_from_tal(find(join(BASEDIR, 'web'), ('.py', '.pt')), tali18nfile) |
303 extract_from_tal(find(osp.join(BASEDIR, 'web'), ('.py', '.pt')), |
|
304 tali18nfile) |
298 print '-> generate .pot files.' |
305 print '-> generate .pot files.' |
299 for id, files, lang in [('pycubicweb', get_module_files(BASEDIR) + list(globfind(join(BASEDIR, 'misc', 'migration'), '*.py')), None), |
306 pyfiles = get_module_files(BASEDIR) |
300 ('schemadescr', globfind(join(BASEDIR, 'schemas'), '*.py'), None), |
307 pyfiles += globfind(osp.join(BASEDIR, 'misc', 'migration'), '*.py') |
|
308 schemafiles = globfind(osp.join(BASEDIR, 'schemas'), '*.py') |
|
309 jsfiles = globfind(osp.join(BASEDIR, 'web'), 'cub*.js') |
|
310 for id, files, lang in [('pycubicweb', pyfiles, None), |
|
311 ('schemadescr', schemafiles, None), |
301 ('yams', get_module_files(yams.__path__[0]), None), |
312 ('yams', get_module_files(yams.__path__[0]), None), |
302 ('tal', [tali18nfile], None), |
313 ('tal', [tali18nfile], None), |
303 ('js', globfind(join(BASEDIR, 'web'), 'cub*.js'), 'java'), |
314 ('js', jsfiles, 'java'), |
304 ]: |
315 ]: |
305 cmd = 'xgettext --no-location --omit-header -k_ -o %s %s' |
316 cmd = 'xgettext --no-location --omit-header -k_ -o %s %s' |
306 if lang is not None: |
317 if lang is not None: |
307 cmd += ' -L %s' % lang |
318 cmd += ' -L %s' % lang |
308 potfile = join(tempdir, '%s.pot' % id) |
319 potfile = osp.join(tempdir, '%s.pot' % id) |
309 execute(cmd % (potfile, ' '.join('"%s"' % f for f in files))) |
320 execute(cmd % (potfile, ' '.join('"%s"' % f for f in files))) |
310 if exists(potfile): |
321 if osp.exists(potfile): |
311 potfiles.append(potfile) |
322 potfiles.append(potfile) |
312 else: |
323 else: |
313 print '-> WARNING: %s file was not generated' % potfile |
324 print '-> WARNING: %s file was not generated' % potfile |
314 print '-> merging %i .pot files' % len(potfiles) |
325 print '-> merging %i .pot files' % len(potfiles) |
315 cubicwebpot = join(tempdir, 'cubicweb.pot') |
326 cubicwebpot = osp.join(tempdir, 'cubicweb.pot') |
316 execute('msgcat -o %s %s' % (cubicwebpot, ' '.join('"%s"' % f for f in potfiles))) |
327 execute('msgcat -o %s %s' |
|
328 % (cubicwebpot, ' '.join('"%s"' % f for f in potfiles))) |
317 print '-> merging main pot file with existing translations.' |
329 print '-> merging main pot file with existing translations.' |
318 chdir(I18NDIR) |
330 chdir(cwi18ndir) |
319 toedit = [] |
331 toedit = [] |
320 for lang in LANGS: |
332 for lang in cw_languages(): |
321 target = '%s.po' % lang |
333 target = '%s.po' % lang |
322 execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"' % (target, target, cubicwebpot)) |
334 execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"' |
|
335 % (target, target, cubicwebpot)) |
323 ensure_fs_mode(target) |
336 ensure_fs_mode(target) |
324 shutil.move('%snew' % target, target) |
337 shutil.move('%snew' % target, target) |
325 toedit.append(abspath(target)) |
338 toedit.append(osp.abspath(target)) |
326 # cleanup |
339 # cleanup |
327 rm(tempdir) |
340 rm(tempdir) |
328 # instructions pour la suite |
341 # instructions pour la suite |
329 print '-> regenerated CubicWeb\'s .po catalogs.' |
342 print '-> regenerated CubicWeb\'s .po catalogs.' |
330 print '\nYou can now edit the following files:' |
343 print '\nYou can now edit the following files:' |
374 import shutil |
388 import shutil |
375 import tempfile |
389 import tempfile |
376 from logilab.common.fileutils import ensure_fs_mode |
390 from logilab.common.fileutils import ensure_fs_mode |
377 from logilab.common.shellutils import find, rm |
391 from logilab.common.shellutils import find, rm |
378 from cubicweb.i18n import extract_from_tal, execute |
392 from cubicweb.i18n import extract_from_tal, execute |
379 cube = basename(normpath(cubedir)) |
393 cube = osp.basename(osp.normpath(cubedir)) |
380 tempdir = tempfile.mkdtemp() |
394 tempdir = tempfile.mkdtemp() |
381 print underline_title('Updating i18n catalogs for cube %s' % cube) |
395 print underline_title('Updating i18n catalogs for cube %s' % cube) |
382 chdir(cubedir) |
396 chdir(cubedir) |
383 if exists(join('i18n', 'entities.pot')): |
397 if osp.exists(osp.join('i18n', 'entities.pot')): |
384 warn('entities.pot is deprecated, rename file to static-messages.pot (%s)' |
398 warn('entities.pot is deprecated, rename file to static-messages.pot (%s)' |
385 % join('i18n', 'entities.pot'), DeprecationWarning) |
399 % osp.join('i18n', 'entities.pot'), DeprecationWarning) |
386 potfiles = [join('i18n', 'entities.pot')] |
400 potfiles = [osp.join('i18n', 'entities.pot')] |
387 elif exists(join('i18n', 'static-messages.pot')): |
401 elif osp.exists(osp.join('i18n', 'static-messages.pot')): |
388 potfiles = [join('i18n', 'static-messages.pot')] |
402 potfiles = [osp.join('i18n', 'static-messages.pot')] |
389 else: |
403 else: |
390 potfiles = [] |
404 potfiles = [] |
391 print '-> extract schema messages' |
405 print '-> extract schema messages' |
392 schemapot = join(tempdir, 'schema.pot') |
406 schemapot = osp.join(tempdir, 'schema.pot') |
393 potfiles.append(schemapot) |
407 potfiles.append(schemapot) |
394 # explicit close necessary else the file may not be yet flushed when |
408 # explicit close necessary else the file may not be yet flushed when |
395 # we'll using it below |
409 # we'll using it below |
396 schemapotstream = file(schemapot, 'w') |
410 schemapotstream = file(schemapot, 'w') |
397 generate_schema_pot(schemapotstream.write, cubedir) |
411 generate_schema_pot(schemapotstream.write, cubedir) |
398 schemapotstream.close() |
412 schemapotstream.close() |
399 print '-> extract TAL messages' |
413 print '-> extract TAL messages' |
400 tali18nfile = join(tempdir, 'tali18n.py') |
414 tali18nfile = osp.join(tempdir, 'tali18n.py') |
401 extract_from_tal(find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)), tali18nfile) |
415 ptfiles = find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)) |
|
416 extract_from_tal(ptfiles, tali18nfile) |
402 print '-> extract Javascript messages' |
417 print '-> extract Javascript messages' |
403 jsfiles = [jsfile for jsfile in find('.', '.js') if basename(jsfile).startswith('cub')] |
418 jsfiles = [jsfile for jsfile in find('.', '.js') |
|
419 if osp.basename(jsfile).startswith('cub')] |
404 if jsfiles: |
420 if jsfiles: |
405 tmppotfile = join(tempdir, 'js.pot') |
421 tmppotfile = osp.join(tempdir, 'js.pot') |
406 execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s' |
422 execute('xgettext --no-location --omit-header -k_ -L java ' |
407 % (tmppotfile, ' '.join(jsfiles))) |
423 '--from-code=utf-8 -o %s %s' % (tmppotfile, ' '.join(jsfiles))) |
408 # no pot file created if there are no string to translate |
424 # no pot file created if there are no string to translate |
409 if exists(tmppotfile): |
425 if osp.exists(tmppotfile): |
410 potfiles.append(tmppotfile) |
426 potfiles.append(tmppotfile) |
411 print '-> create cube-specific catalog' |
427 print '-> create cube-specific catalog' |
412 tmppotfile = join(tempdir, 'generated.pot') |
428 tmppotfile = osp.join(tempdir, 'generated.pot') |
413 cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',)) |
429 cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',)) |
414 cubefiles.append(tali18nfile) |
430 cubefiles.append(tali18nfile) |
415 execute('xgettext --no-location --omit-header -k_ -o %s %s' |
431 execute('xgettext --no-location --omit-header -k_ -o %s %s' |
416 % (tmppotfile, ' '.join('"%s"' % f for f in cubefiles))) |
432 % (tmppotfile, ' '.join('"%s"' % f for f in cubefiles))) |
417 if exists(tmppotfile): # doesn't exists of no translation string found |
433 if osp.exists(tmppotfile): # doesn't exists of no translation string found |
418 potfiles.append(tmppotfile) |
434 potfiles.append(tmppotfile) |
419 potfile = join(tempdir, 'cube.pot') |
435 potfile = osp.join(tempdir, 'cube.pot') |
420 print '-> merging %i .pot files:' % len(potfiles) |
436 print '-> merging %i .pot files:' % len(potfiles) |
421 execute('msgcat -o %s %s' % (potfile, |
437 execute('msgcat -o %s %s' % (potfile, |
422 ' '.join('"%s"' % f for f in potfiles))) |
438 ' '.join('"%s"' % f for f in potfiles))) |
423 if not exists(potfile): |
439 if not osp.exists(potfile): |
424 print 'no message catalog for cube', cube, 'nothing to translate' |
440 print 'no message catalog for cube', cube, 'nothing to translate' |
425 # cleanup |
441 # cleanup |
426 rm(tempdir) |
442 rm(tempdir) |
427 return () |
443 return () |
428 print '-> merging main pot file with existing translations:' |
444 print '-> merging main pot file with existing translations:' |
429 chdir('i18n') |
445 chdir('i18n') |
430 toedit = [] |
446 toedit = [] |
431 for lang in LANGS: |
447 for lang in cw_languages(): |
432 print '-> language', lang |
448 print '-> language', lang |
433 cubepo = '%s.po' % lang |
449 cubepo = '%s.po' % lang |
434 if not exists(cubepo): |
450 if not osp.exists(cubepo): |
435 shutil.copy(potfile, cubepo) |
451 shutil.copy(potfile, cubepo) |
436 else: |
452 else: |
437 execute('msgmerge -N -s -o %snew %s %s' % (cubepo, cubepo, potfile)) |
453 execute('msgmerge -N -s -o %snew %s %s' % (cubepo, cubepo, potfile)) |
438 ensure_fs_mode(cubepo) |
454 ensure_fs_mode(cubepo) |
439 shutil.move('%snew' % cubepo, cubepo) |
455 shutil.move('%snew' % cubepo, cubepo) |
440 toedit.append(abspath(cubepo)) |
456 toedit.append(osp.abspath(cubepo)) |
441 # cleanup |
457 # cleanup |
442 rm(tempdir) |
458 rm(tempdir) |
443 return toedit |
459 return toedit |
444 |
460 |
445 |
461 |
544 } |
560 } |
545 |
561 |
546 def run(self, args): |
562 def run(self, args): |
547 import re |
563 import re |
548 from logilab.common.shellutils import ASK |
564 from logilab.common.shellutils import ASK |
549 if len(args) != 1: |
|
550 raise BadCommandUsage("exactly one argument (cube name) is expected") |
|
551 cubename = args[0] |
565 cubename = args[0] |
552 if not re.match('[_A-Za-z][_A-Za-z0-9]*$', cubename): |
566 if not re.match('[_A-Za-z][_A-Za-z0-9]*$', cubename): |
553 raise BadCommandUsage("cube name should be a valid python module name") |
567 raise BadCommandUsage( |
|
568 'cube name must be a valid python module name') |
554 verbose = self.get('verbose') |
569 verbose = self.get('verbose') |
555 cubesdir = self.get('directory') |
570 cubesdir = self.get('directory') |
556 if not cubesdir: |
571 if not cubesdir: |
557 cubespath = ServerConfiguration.cubes_search_path() |
572 cubespath = ServerConfiguration.cubes_search_path() |
558 if len(cubespath) > 1: |
573 if len(cubespath) > 1: |
559 raise BadCommandUsage("can't guess directory where to put the new cube." |
574 raise BadCommandUsage( |
560 " Please specify it using the --directory option") |
575 "can't guess directory where to put the new cube." |
|
576 " Please specify it using the --directory option") |
561 cubesdir = cubespath[0] |
577 cubesdir = cubespath[0] |
562 if not isdir(cubesdir): |
578 if not osp.isdir(cubesdir): |
563 print "-> creating cubes directory", cubesdir |
579 print "-> creating cubes directory", cubesdir |
564 try: |
580 try: |
565 mkdir(cubesdir) |
581 mkdir(cubesdir) |
566 except OSError, err: |
582 except OSError, err: |
567 self.fail("failed to create directory %r\n(%s)" % (cubesdir, err)) |
583 self.fail("failed to create directory %r\n(%s)" |
568 cubedir = join(cubesdir, cubename) |
584 % (cubesdir, err)) |
569 if exists(cubedir): |
585 cubedir = osp.join(cubesdir, cubename) |
570 self.fail("%s already exists !" % (cubedir)) |
586 if osp.exists(cubedir): |
571 skeldir = join(BASEDIR, 'skeleton') |
587 self.fail("%s already exists !" % cubedir) |
|
588 skeldir = osp.join(BASEDIR, 'skeleton') |
572 default_name = 'cubicweb-%s' % cubename.lower().replace('_', '-') |
589 default_name = 'cubicweb-%s' % cubename.lower().replace('_', '-') |
573 if verbose: |
590 if verbose: |
574 distname = raw_input('Debian name for your cube ? [%s]): ' % default_name).strip() |
591 distname = raw_input('Debian name for your cube ? [%s]): ' |
|
592 % default_name).strip() |
575 if not distname: |
593 if not distname: |
576 distname = default_name |
594 distname = default_name |
577 elif not distname.startswith('cubicweb-'): |
595 elif not distname.startswith('cubicweb-'): |
578 if ASK.confirm('Do you mean cubicweb-%s ?' % distname): |
596 if ASK.confirm('Do you mean cubicweb-%s ?' % distname): |
579 distname = 'cubicweb-' + distname |
597 distname = 'cubicweb-' + distname |
580 else: |
598 else: |
581 distname = default_name |
599 distname = default_name |
582 if not re.match('[a-z][-a-z0-9]*$', distname): |
600 if not re.match('[a-z][-a-z0-9]*$', distname): |
583 raise BadCommandUsage("cube distname should be a valid debian package name") |
601 raise BadCommandUsage( |
584 longdesc = shortdesc = raw_input('Enter a short description for your cube: ') |
602 'cube distname should be a valid debian package name') |
|
603 longdesc = shortdesc = raw_input( |
|
604 'Enter a short description for your cube: ') |
585 if verbose: |
605 if verbose: |
586 longdesc = raw_input('Enter a long description (leave empty to reuse the short one): ') |
606 longdesc = raw_input( |
|
607 'Enter a long description (leave empty to reuse the short one): ') |
587 dependencies = {'cubicweb': '>= %s' % cubicwebversion} |
608 dependencies = {'cubicweb': '>= %s' % cubicwebversion} |
588 if verbose: |
609 if verbose: |
589 dependencies.update(self._ask_for_dependencies()) |
610 dependencies.update(self._ask_for_dependencies()) |
590 context = {'cubename' : cubename, |
611 context = {'cubename' : cubename, |
591 'distname' : distname, |
612 'distname' : distname, |
683 class GenerateSchema(Command): |
703 class GenerateSchema(Command): |
684 """Generate schema image for the given cube""" |
704 """Generate schema image for the given cube""" |
685 name = "schema" |
705 name = "schema" |
686 arguments = '<cube>' |
706 arguments = '<cube>' |
687 min_args = max_args = 1 |
707 min_args = max_args = 1 |
688 options = [('output-file', {'type':'file', 'default': None, |
708 options = [ |
689 'metavar': '<file>', 'short':'o', 'help':'output image file', |
709 ('output-file', |
690 'input':False}), |
710 {'type':'file', 'default': None, |
691 ('viewer', {'type': 'string', 'default':None, |
711 'metavar': '<file>', 'short':'o', 'help':'output image file', |
692 'short': "d", 'metavar':'<cmd>', |
712 'input':False, |
693 'help':'command use to view the generated file (empty for none)'} |
713 }), |
694 ), |
714 ('viewer', |
695 ('show-meta', {'action': 'store_true', 'default':False, |
715 {'type': 'string', 'default':None, |
696 'short': "m", 'metavar': "<yN>", |
716 'short': "d", 'metavar':'<cmd>', |
697 'help':'include meta and internal entities in schema'} |
717 'help':'command use to view the generated file (empty for none)', |
698 ), |
718 }), |
699 ('show-workflow', {'action': 'store_true', 'default':False, |
719 ('show-meta', |
700 'short': "w", 'metavar': "<yN>", |
720 {'action': 'store_true', 'default':False, |
701 'help':'include workflow entities in schema'} |
721 'short': "m", 'metavar': "<yN>", |
702 ), |
722 'help':'include meta and internal entities in schema', |
703 ('show-cw-user', {'action': 'store_true', 'default':False, |
723 }), |
704 'metavar': "<yN>", |
724 ('show-workflow', |
705 'help':'include cubicweb user entities in schema'} |
725 {'action': 'store_true', 'default':False, |
706 ), |
726 'short': "w", 'metavar': "<yN>", |
707 ('exclude-type', {'type':'string', 'default':'', |
727 'help':'include workflow entities in schema', |
708 'short': "x", 'metavar': "<types>", |
728 }), |
709 'help':'coma separated list of entity types to remove from view'} |
729 ('show-cw-user', |
710 ), |
730 {'action': 'store_true', 'default':False, |
711 ('include-type', {'type':'string', 'default':'', |
731 'metavar': "<yN>", |
712 'short': "i", 'metavar': "<types>", |
732 'help':'include cubicweb user entities in schema', |
713 'help':'coma separated list of entity types to include in view'} |
733 }), |
714 ), |
734 ('exclude-type', |
715 ] |
735 {'type':'string', 'default':'', |
|
736 'short': "x", 'metavar': "<types>", |
|
737 'help':'coma separated list of entity types to remove from view', |
|
738 }), |
|
739 ('include-type', |
|
740 {'type':'string', 'default':'', |
|
741 'short': "i", 'metavar': "<types>", |
|
742 'help':'coma separated list of entity types to include in view', |
|
743 }), |
|
744 ] |
716 |
745 |
717 def run(self, args): |
746 def run(self, args): |
718 from subprocess import Popen |
747 from subprocess import Popen |
719 from tempfile import NamedTemporaryFile |
748 from tempfile import NamedTemporaryFile |
720 from logilab.common.textutils import splitstrip |
749 from logilab.common.textutils import splitstrip |