Merge lp:~openerp-dev/openerp-command/auto-discovery-chs into lp:openerp-command

Proposed by Christophe Simonis (OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openerp-command/auto-discovery-chs
Merge into: lp:openerp-command
Diff against target: 130 lines (+96/-1)
5 files modified
oe (+2/-1)
openerpcommand/__init__.py (+21/-0)
openerpcommand/command.py (+48/-0)
openerpcommand/commands/__init__.py (+13/-0)
openerpcommand/commands/test.py (+12/-0)
To merge this branch: bzr merge lp:~openerp-dev/openerp-command/auto-discovery-chs
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+136360@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

185. By Christophe Simonis (OpenERP)

[WIP] auto discovery of commands

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'oe'
2--- oe 2012-01-31 17:55:23 +0000
3+++ oe 2012-11-27 10:39:21 +0000
4@@ -1,5 +1,6 @@
5 #! /usr/bin/env python2
6
7 if __name__ == '__main__':
8+ import sys
9 import openerpcommand.main
10- openerpcommand.main.run()
11+ sys.exit(openerpcommand.main.run())
12
13=== modified file 'openerpcommand/__init__.py'
14--- openerpcommand/__init__.py 2012-11-05 11:27:01 +0000
15+++ openerpcommand/__init__.py 2012-11-27 10:39:21 +0000
16@@ -58,4 +58,25 @@
17 # Client-side commands. TODO one per .py file.
18 for x in command_list_client:
19 x(subparsers)
20+
21+ from . import commands # auto import commands
22+
23+ def register_classes(classes):
24+ abstracts = set()
25+ for class_ in classes:
26+ # check if class is abstract
27+ attrs = [getattr(class_, attr) for attr in dir(class_) if not attr.startswith('__')]
28+ if any(getattr(attr, '__isabstractmethod__', False) for attr in attrs):
29+ abstracts.add(class_)
30+ else:
31+ subparser = subparsers.add_parser(class_.__name__.lower(), description=class_.__doc__)
32+ class_.configure_parser(subparser)
33+ subparser.set_defaults(run=class_._run)
34+
35+ for abstract in abstracts:
36+ register_classes(abstract.__subclasses__())
37+
38+ from . import command
39+ register_classes(command.Command.__subclasses__())
40+
41 return parser
42
43=== added file 'openerpcommand/command.py'
44--- openerpcommand/command.py 1970-01-01 00:00:00 +0000
45+++ openerpcommand/command.py 2012-11-27 10:39:21 +0000
46@@ -0,0 +1,48 @@
47+import abc
48+import os
49+
50+def required_or_default(name, h):
51+ """
52+ Helper to define `argparse` arguments. If the name is the environment,
53+ the argument is optional and draw its value from the environment if not
54+ supplied on the command-line. If it is not in the environment, make it
55+ a mandatory argument.
56+ """
57+ if os.environ.get('OPENERP_' + name.upper()):
58+ d = {'default': os.environ['OPENERP_' + name.upper()]}
59+ else:
60+ d = {'required': True}
61+ d['help'] = h + '. The environment variable OPENERP_' + name.upper() + ' can be used instead.'
62+ return d
63+
64+class Command(object):
65+ __metaclass__ = abc.ABCMeta
66+
67+ @classmethod
68+ def _run(cls, args):
69+ c = cls()
70+ c.run(args)
71+
72+ @abc.abstractmethod
73+ def run(self, args):
74+ raise NotImplementedError()
75+
76+ @classmethod
77+ def configure_parser(cls, parser):
78+ parser.add_argument('-d', '--database', metavar='DATABASE',
79+ **required_or_default('DATABASE', 'the database to connect to'))
80+ parser.add_argument('-u', '--user', metavar='USER',
81+ **required_or_default('USER', 'the user login or ID. When using '
82+ 'RPC, providing an ID avoid the login() step'))
83+ parser.add_argument('-p', '--password', metavar='PASSWORD',
84+ **required_or_default('PASSWORD', 'the user password')) # TODO read it from the command line or from file.
85+
86+
87+class RemoteCommand(Command):
88+ @classmethod
89+ def configure_parser(cls, parser):
90+ parser.add_argument('-H', '--host', metavar='HOST',
91+ **required_or_default('HOST', 'the server host'))
92+ parser.add_argument('-P', '--port', metavar='PORT',
93+ **required_or_default('PORT', 'the server port'))
94+ super(RemoteCommand, cls).configure_parser(parser)
95
96=== added directory 'openerpcommand/commands'
97=== added file 'openerpcommand/commands/__init__.py'
98--- openerpcommand/commands/__init__.py 1970-01-01 00:00:00 +0000
99+++ openerpcommand/commands/__init__.py 2012-11-27 10:39:21 +0000
100@@ -0,0 +1,13 @@
101+import os
102+import imp
103+
104+HERE = os.path.dirname(__file__)
105+
106+# XXX also search commands in other directory? (/usr/share, ~/.oe/) ?
107+
108+for x in os.listdir(HERE):
109+ if not x.endswith('.py') or x.startswith(('_', '.')):
110+ continue
111+ m, _ = os.path.splitext(x)
112+ i = imp.find_module(m, [HERE])
113+ imp.load_module('openerpcommand.commands.' + m, *i)
114
115=== added file 'openerpcommand/commands/test.py'
116--- openerpcommand/commands/test.py 1970-01-01 00:00:00 +0000
117+++ openerpcommand/commands/test.py 2012-11-27 10:39:21 +0000
118@@ -0,0 +1,12 @@
119+
120+from .. import command
121+
122+class Test(command.Command):
123+ def run(self, args):
124+ print "test is run"
125+
126+ @property
127+ def name(self):
128+ return "test"
129+
130+print "test imported"

Subscribers

People subscribed via source and target branches