diff --git a/CHANGELOG b/CHANGELOG index 789716e2ba..8ccb2a7bff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add extras_depend to module definition * Store session in database * New Wizard design * Add pyson.Id diff --git a/trytond/ir/module/module.py b/trytond/ir/module/module.py index 9f04e9e05d..0c110ce445 100644 --- a/trytond/ir/module/module.py +++ b/trytond/ir/module/module.py @@ -23,6 +23,10 @@ class Module(ModelSQL, ModelView): version = fields.Function(fields.Char('Version'), 'get_version') dependencies = fields.One2Many('ir.module.module.dependency', 'module', 'Dependencies', readonly=True) + parents = fields.Function(fields.One2Many('ir.module.module', None, + 'Parents'), 'get_parents') + childs = fields.Function(fields.One2Many('ir.module.module', None, + 'Childs'), 'get_childs') state = fields.Selection([ ('uninstalled', 'Not Installed'), ('installed', 'Installed'), @@ -80,6 +84,32 @@ class Module(ModelSQL, ModelView): module.name).get('version', '') return res + def get_parents(self, ids, name): + parents = {} + modules = self.browse(ids) + parent_names = list(set(d.name for m in modules + for d in m.dependencies)) + parent_ids = self.search([ + ('name', 'in', parent_names), + ]) + name2id = dict((m.name, m.id) for m in self.browse(parent_ids)) + for module in self.browse(ids): + parents[module.id] = [name2id[d.name] for d in module.dependencies] + return parents + + def get_childs(self, ids, name): + childs = dict((i, []) for i in ids) + modules = self.browse(ids) + names = [m.name for m in modules] + child_ids = self.search([ + ('dependencies.name', 'in', names), + ]) + for child in self.browse(child_ids): + for dep in child.dependencies: + if dep.module.id in childs: + childs[dep.module.id].append(child.id) + return childs + def delete(self, ids): if not ids: return True @@ -103,23 +133,18 @@ class Module(ModelSQL, ModelView): for module in self.browse(ids): if module.name not in graph: continue - def get_parents(name, graph): - parents = set() - for node in graph: - if graph[name] in node.childs: - parents.add(node.name) - for parent in parents.copy(): - parents.update(get_parents(parent, graph)) + def get_parents(module): + parents = set(p.name for p in module.parents) + for p in module.parents: + parents.update(get_parents(p)) return parents - dependencies = get_parents(module.name, graph) - def get_childs(name, graph): - childs = set(x.name for x in graph[name].childs) - childs2 = set() - for child in childs: - childs2.update(get_childs(child, graph)) - childs.update(childs2) + dependencies = get_parents(module) + def get_childs(module): + childs = set(c.name for c in module.childs) + for c in module.childs: + childs.update(get_childs(c)) return childs - dependencies.update(get_childs(module.name, graph)) + dependencies.update(get_childs(module)) res += self.search([ ('name', 'in', list(dependencies)), ]) @@ -130,19 +155,16 @@ class Module(ModelSQL, ModelView): for module in self.browse(ids): if module.name not in graph: missings = [] - for package, deps, datas in packages: + for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] self.raise_user_error('missing_dep', (missings, module.name)) - def get_parents(name, graph): - parents = set() - for node in graph: - if graph[name] in node.childs: - parents.add(node.name) - for parent in parents.copy(): - parents.update(get_parents(parent, graph)) + def get_parents(module): + parents = set(p.name for p in module.parents) + for p in module.parents: + parents.update(get_parents(p)) return parents - dependencies = list(get_parents(module.name, graph)) + dependencies = list(get_parents(module)) module_install_ids = self.search([ ('name', 'in', dependencies), ('state', '=', 'uninstalled'), @@ -156,7 +178,7 @@ class Module(ModelSQL, ModelView): for module in self.browse(ids): if module.name not in graph: missings = [] - for package, deps, datas in packages: + for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] self.raise_user_error('missing_dep', (missings, module.name)) diff --git a/trytond/modules/__init__.py b/trytond/modules/__init__.py index 4c46dfed4d..cc84644d64 100644 --- a/trytond/modules/__init__.py +++ b/trytond/modules/__init__.py @@ -76,8 +76,10 @@ class Node(Singleton): super(Node, self).__init__() self.name = name self.graph = graph - if not hasattr(self, 'datas'): - self.datas = None + + # __init__ is called even if Node already exists + if not hasattr(self, 'info'): + self.info = None if not hasattr(self, 'childs'): self.childs = [] if not hasattr(self, 'depth'): @@ -153,25 +155,28 @@ def create_graph(module_list, force=None): if os.path.isfile(tryton_file): with tools.file_open(tryton_file, subdir='') as fp: info = tools.safe_eval(fp.read()) - packages.append((module, info.get('depends', []), info)) + packages.append((module, info.get('depends', []), + info.get('extras_depend', []), info)) elif module != 'all': raise Exception('Module %s not found' % module) current, later = set([x[0] for x in packages]), set() + all_packages = set(current) while packages and current > later: - package, deps, datas = packages[0] + package, deps, xdep, info = packages[0] # if all dependencies of 'package' are already in the graph, # add 'package' in the graph - if reduce(lambda x, y: x and y in graph, deps, True): + all_deps = deps + [x for x in xdep if x in all_packages] + if reduce(lambda x, y: x and y in graph, all_deps, True): if not package in current: packages.pop(0) continue later.clear() current.remove(package) - graph.add_node(package, deps) + graph.add_node(package, all_deps) node = Node(package, graph) - node.datas = datas + node.info = info for kind in ('init', 'update'): if (package in CONFIG[kind]) \ or (('all' in CONFIG[kind]) \ @@ -180,10 +185,10 @@ def create_graph(module_list, force=None): setattr(node, kind, True) else: later.add(package) - packages.append((package, deps, datas)) + packages.append((package, deps, xdep, info)) packages.pop(0) - for package, deps, datas in packages: + for package, deps, xdep, info in packages: if package not in later: continue missings = [x for x in deps if x not in graph] @@ -229,7 +234,7 @@ def load_module_graph(graph, pool, lang=None): #Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler(pool=pool, module=module) - for filename in package.datas.get('xml', []): + for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) mode = 'update' if hasattr(package, 'init') or package_state == 'to install': @@ -251,7 +256,7 @@ def load_module_graph(graph, pool, lang=None): modules_todo.append((module, list(tryton_parser.to_delete))) - for filename in package.datas.get('translation', []): + for filename in package.info.get('translation', []): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: