# HG changeset patch # User Nicolas Chauvat # Date 1288287559 -7200 # Node ID e8ede572b221a4aeda958e1dcc895cc505c7c001 # Parent bea4ab297e670ca663bc6f55a22684e79e50e761# Parent 402bff8980248337212bf0f6849a49a3d2c009eb merge changes from stable branch diff -r bea4ab297e67 -r e8ede572b221 cwconfig.py --- a/cwconfig.py Wed Oct 27 20:29:28 2010 +0200 +++ b/cwconfig.py Thu Oct 28 19:39:19 2010 +0200 @@ -495,6 +495,8 @@ deps = dict( (x[len('cubicweb-'):], v) for x, v in gendeps.iteritems() if x.startswith('cubicweb-')) + if 'cubicweb' in gendeps: + deps['cubicweb'] = gendeps['cubicweb'] if not isinstance(deps, dict): deps = dict((key, None) for key in deps) warn('[3.8] cube %s should define %s as a dict' % (cube, key), diff -r bea4ab297e67 -r e8ede572b221 cwctl.py --- a/cwctl.py Wed Oct 27 20:29:28 2010 +0200 +++ b/cwctl.py Thu Oct 28 19:39:19 2010 +0200 @@ -283,15 +283,15 @@ print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings) if cfgpb.errors: print 'Errors:' - for op, cube, version in cfgpb.errors: + for op, cube, version, src in cfgpb.errors: if op == 'add': print '* cube', cube, if version: print ' version', version, - print 'is not installed, but required by %s' % ' '.join(cfgpb.reverse_constraints[cube]) + print 'is not installed, but required by %s' % src else: - print '* cube %s version %s is installed, but version %s is required by (%s)' % ( - cube, cfgpb.cubes[cube], version, ', '.join(cfgpb.reverse_constraints[cube])) + print '* cube %s version %s is installed, but version %s is required by %s' % ( + cube, cfgpb.cubes[cube], version, src) class CreateInstanceCommand(Command): """Create an instance from a cube. This is an unified diff -r bea4ab297e67 -r e8ede572b221 migration.py --- a/migration.py Wed Oct 27 20:29:28 2010 +0200 +++ b/migration.py Thu Oct 28 19:39:19 2010 +0200 @@ -33,7 +33,7 @@ from logilab.common.changelog import Version from cubicweb import ConfigurationError, ExecutionError - +from cubicweb.cwconfig import CubicWebConfiguration as cwcfg def filter_scripts(config, directory, fromversion, toversion, quiet=True): """return a list of paths of migration files to consider to upgrade @@ -454,8 +454,8 @@ """ def __init__(self, config): - self.cubes = {} self.config = config + self.cubes = {'cubicweb': cwcfg.cubicweb_version()} def add_cube(self, name, version): self.cubes[name] = version @@ -463,44 +463,49 @@ def solve(self): self.warnings = [] self.errors = [] - self.read_constraints() - for cube, versions in sorted(self.constraints.items()): - oper, version = None, None + self.dependencies = {} + self.reverse_dependencies = {} + self.constraints = {} + # read dependencies + for cube in self.cubes: + if cube == 'cubicweb': continue + self.dependencies[cube] = dict(self.config.cube_dependencies(cube)) + # compute reverse dependencies + for cube, dependencies in self.dependencies.iteritems(): + for name, constraint in dependencies.iteritems(): + self.reverse_dependencies.setdefault(name,set()) + if constraint: + try: + oper, version = constraint.split() + self.reverse_dependencies[name].add( (oper, version, cube) ) + except: + self.warnings.append( + 'cube %s depends on %s but constraint badly ' + 'formatted: %s' % (cube, name, constraint)) + # check consistency + for cube, versions in sorted(self.reverse_dependencies.items()): + oper, version, source = None, None, None # simplify constraints if versions: for constraint in versions: - op, ver = constraint + op, ver, src = constraint if oper is None: oper = op version = ver + source = src elif op == '>=' and oper == '>=': - version = max_version(ver, version) + if version_strictly_lower(version, ver): + version = ver + source = src else: print 'unable to handle this case', oper, version, op, ver # "solve" constraint satisfaction problem if cube not in self.cubes: - self.errors.append( ('add', cube, version) ) + self.errors.append( ('add', cube, version, source) ) elif versions: lower_strict = version_strictly_lower(self.cubes[cube], version) if oper in ('>=','='): if lower_strict: - self.errors.append( ('update', cube, version) ) + self.errors.append( ('update', cube, version, source) ) else: print 'unknown operator', oper - - def read_constraints(self): - self.constraints = {} - self.reverse_constraints = {} - for cube in self.cubes: - use = self.config.cube_dependencies(cube) - for name, constraint in use.iteritems(): - self.constraints.setdefault(name,set()) - if constraint: - try: - oper, version = constraint.split() - self.constraints[name].add( (oper, version) ) - except: - self.warnings.append( - 'cube %s depends on %s but constraint badly ' - 'formatted: %s' % (cube, name, constraint)) - self.reverse_constraints.setdefault(name, set()).add(cube)