diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 8d630b267b1..fcc60ca1809 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -275,12 +275,14 @@ def get_modules(): def create_graph(module_list, force=None): graph = Graph() - return upgrade_graph(graph, module_list, force) + upgrade_graph(graph, module_list, force) + return graph def upgrade_graph(graph, module_list, force=None): if force is None: force = [] packages = [] + len_graph = len(graph) for module in module_list: try: mod_path = get_module_path(module) @@ -326,8 +328,11 @@ def upgrade_graph(graph, module_list, force=None): for package in later: unmet_deps = filter(lambda p: p not in graph, dependencies[package]) logger.notifyChannel('init', netsvc.LOG_ERROR, 'module %s: Unmet dependencies: %s' % (package, ', '.join(unmet_deps))) - - return graph + + result = len(graph) - len_graph + if result != len(module_list): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'Not all modules have loaded.') + return result def init_module_objects(cr, module_name, obj_list): @@ -682,14 +687,23 @@ def load_modules(db, force_demo=False, status=None, update_module=False): STATES_TO_LOAD += ['to install'] + loop_guardrail = 0 while True: + loop_guardrail += 1 + if loop_guardrail > 100: + raise ProgrammingError() cr.execute("SELECT name from ir_module_module WHERE state in (%s)" % ','.join(['%s']*len(STATES_TO_LOAD)), STATES_TO_LOAD) module_list = [name for (name,) in cr.fetchall() if name not in graph] if not module_list: break - - upgrade_graph(graph, module_list, force) + + new_modules_in_graph = upgrade_graph(graph, module_list, force) + if new_modules_in_graph == 0: + # nothing to load + break + + logger.notifyChannel('init', netsvc.LOG_DEBUG, 'Updating graph with %d more modules' % (len(module_list))) r = load_module_graph(cr, graph, status, report=report) has_updates = has_updates or r @@ -703,7 +717,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): obj = pool.get(model) if obj: obj._check_removed_columns(cr, log=True) - + if report.get_report(): logger.notifyChannel('init', netsvc.LOG_INFO, report)