[IMP] oe initialize must take the port as parameter (for http tests)
[odoo/odoo.git] / openerpcommand / initialize.py
1 """
2 Install OpenERP on a new (by default) database.
3 """
4 import contextlib
5 import errno
6 import os
7 import sys
8 import time
9
10 import common
11
12 def install_openerp(database_name, create_database_flag, module_names, install_demo_data):
13     import openerp
14     config = openerp.tools.config
15
16     if create_database_flag:
17         with lock_file('/tmp/global_openerp_create_database.lock'):
18             create_database(database_name)
19
20     config['init'] = dict.fromkeys(module_names, 1)
21
22     # Install the import hook, to import openerp.addons.<module>.
23     openerp.modules.module.initialize_sys_path()
24
25     print 
26
27     registry = openerp.modules.registry.RegistryManager.get(
28         database_name, update_module=True, force_demo=install_demo_data)
29
30     return registry
31
32 # From http://code.activestate.com/recipes/576572/
33 @contextlib.contextmanager
34 def lock_file(path, wait_delay=.1, max_try=600):
35     attempt = 0
36     while True:
37         attempt += 1
38         if attempt > max_try:
39             raise IOError("Could not lock file %s." % path)
40         try:
41             fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
42         except OSError, e:
43             if e.errno != errno.EEXIST:
44                 raise
45             time.sleep(wait_delay)
46             continue
47         else:
48             break
49     try:
50         yield fd
51     finally:
52         os.close(fd)
53         os.unlink(path)
54
55 # TODO turn template1 in a parameter
56 # This should be exposed from openerp (currently in
57 # openerp/service/web_services.py).
58 def create_database(database_name):
59     import openerp
60     db = openerp.sql_db.db_connect('template1')
61     cr = db.cursor() # TODO `with db as cr:`
62     try:
63         cr.autocommit(True)
64         cr.execute("""CREATE DATABASE "%s"
65             ENCODING 'unicode' TEMPLATE "template1" """ \
66             % (database_name,))
67     finally:
68         cr.close()
69
70 def run(args):
71     assert args.database
72     assert not (args.module and args.all_modules)
73
74     import openerp
75
76     config = openerp.tools.config
77
78     if args.tests:
79         config['log_handler'] = [':INFO']
80         config['test_enable'] = True
81         config['without_demo'] = False
82         if args.port:
83             config['xmlrpc_port'] = int(args.port)
84     else:
85         config['log_handler'] = [':CRITICAL']
86         config['test_enable'] = False
87         config['without_demo'] = True
88
89     if args.addons:
90         args.addons = args.addons.split(':')
91     else:
92         args.addons = []
93     config['addons_path'] = ','.join(args.addons)
94
95     print "MY addons path is", config['addons_path']
96
97     if args.all_modules:
98         module_names = common.get_addons_from_paths(args.addons, args.exclude)
99     elif args.module:
100         module_names = args.module
101     else:
102         module_names = ['base']
103
104     if args.coverage:
105         import coverage
106         # Without the `include` kwarg, coverage generates 'memory:0xXXXXX'
107         # filenames (which do not exist) and cause it to crash. No idea why.
108         cov = coverage.coverage(branch=True, include='*.py')
109         cov.start()
110     openerp.netsvc.init_logger()
111     registry = install_openerp(args.database, not args.no_create, module_names, not config['without_demo'])
112     if args.coverage:
113         cov.stop()
114         cov.html_report(directory='coverage')
115         # If we wanted the report on stdout:
116         # cov.report()
117
118     # The `_assertion_report` attribute was added on the registry during the
119     # OpenERP 7.0 development.
120     if hasattr(registry, '_assertion_report'):
121         sys.exit(1 if registry._assertion_report.failures else 0)
122
123 def add_parser(subparsers):
124     parser = subparsers.add_parser('initialize',
125         description='Create and initialize a new OpenERP database.')
126     parser.add_argument('-d', '--database', metavar='DATABASE',
127         **common.required_or_default('DATABASE', 'the database to create'))
128     common.add_addons_argument(parser)
129     parser.add_argument('-P', '--port', metavar='PORT',
130         **common.required_or_default('PORT', 'the server port'))
131     parser.add_argument('--module', metavar='MODULE', action='append',
132         help='specify a module to install'
133         ' (this option can be repeated)')
134     parser.add_argument('--all-modules', action='store_true',
135         help='install all visible modules (not compatible with --module)')
136     parser.add_argument('--no-create', action='store_true',
137         help='do not create the database, only initialize it')
138     parser.add_argument('--exclude', metavar='MODULE', action='append',
139         help='exclude a module from installation'
140         ' (this option can be repeated)')
141     parser.add_argument('--tests', action='store_true',
142         help='run the tests as modules are installed'
143         ' (use the `run-tests` command to choose specific'
144         ' tests to run against an existing database).'
145         ' Demo data are installed.')
146     parser.add_argument('--coverage', action='store_true',
147         help='report code coverage (particularly useful with --tests).'
148         ' The report is generated in a coverage directory and you can'
149         ' then point your browser to coverage/index.html.')
150
151     parser.set_defaults(run=run)