migration.py
author Julien Cristau <julien.cristau@logilab.fr>
Mon, 18 May 2015 20:00:06 +0200
changeset 10436 6493c8bf521d
parent 10107 1ef92a6193a8
child 10569 af47954c1015
permissions -rw-r--r--
[test] don't leave NULL columns around when making an attribute required It doesn't matter on sqlite (it doesn't do ALTER COLUMN), but when running this test on postgresql it fails to add the 'NOT NULL' constraint otherwise.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7576
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5967
8deedfeb7846 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5590
diff changeset
    18
"""utilities for instances migration"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
import sys
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
import os
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
import logging
2446
440cb4ea7e5c [refactor] #342855: replace uses of (deprecated) mktemp
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2275
diff changeset
    25
import tempfile
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
from os.path import exists, join, basename, splitext
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
    27
from itertools import chain
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
    29
from logilab.common import IGNORED_EXTENSIONS
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
from logilab.common.decorators import cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
from logilab.common.configuration import REQUIRED, read_old_config
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
    32
from logilab.common.shellutils import ASK
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    33
from logilab.common.changelog import Version
10107
1ef92a6193a8 [serverctl] rename remove_cube to drop_cube (closes #4545093)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 10074
diff changeset
    34
from logilab.common.deprecation import deprecated
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
    36
from cubicweb import ConfigurationError, ExecutionError
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
    37
from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
8056
8909800a8c51 [cleanup] drop some appengine support junk
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    38
from cubicweb.toolsutils import show_diffs
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
def filter_scripts(config, directory, fromversion, toversion, quiet=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    """return a list of paths of migration files to consider to upgrade
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    from a version to a greater one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    from logilab.common.changelog import Version # doesn't work with appengine
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    assert fromversion
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    assert toversion
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
    assert isinstance(fromversion, tuple), fromversion.__class__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    assert isinstance(toversion, tuple), toversion.__class__
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
    assert fromversion <= toversion, (fromversion, toversion)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    if not exists(directory):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        if not quiet:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
            print directory, "doesn't exists, no migration path"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    if fromversion == toversion:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
    result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
    for fname in os.listdir(directory):
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
    58
        if fname.endswith(IGNORED_EXTENSIONS):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        fpath = join(directory, fname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
            tver, mode = fname.split('_', 1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
        mode = mode.split('.', 1)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        if not config.accept_mode(mode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
            tver = Version(tver)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
        except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        if tver <= fromversion:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        if tver > toversion:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        result.append((tver, fpath))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    # be sure scripts are executed in order
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    return sorted(result)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
def execscript_confirm(scriptpath):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    """asks for confirmation before executing a script and provides the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
    ability to show the script's content
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
    while True:
4553
23201259ffeb [migration] abort becomes possible when asked for confirmation before migration script
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4252
diff changeset
    86
        answer = ASK.ask('Execute %r ?' % scriptpath,
23201259ffeb [migration] abort becomes possible when asked for confirmation before migration script
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4252
diff changeset
    87
                         ('Y','n','show','abort'), 'Y')
23201259ffeb [migration] abort becomes possible when asked for confirmation before migration script
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4252
diff changeset
    88
        if answer == 'abort':
23201259ffeb [migration] abort becomes possible when asked for confirmation before migration script
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4252
diff changeset
    89
            raise SystemExit(1)
23201259ffeb [migration] abort becomes possible when asked for confirmation before migration script
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 4252
diff changeset
    90
        elif answer == 'n':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
            return False
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
    92
        elif answer == 'show':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
            stream = open(scriptpath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
            scriptcontent = stream.read()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            stream.close()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
            print
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
            print scriptcontent
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
            print
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
            return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
def yes(*args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
class MigrationHelper(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    """class holding CubicWeb Migration Actions used by migration scripts"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    def __init__(self, config, interactive=True, verbosity=1):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        self.config = config
3700
fd550e4dc515 #481017: cubicweb-ctl shell on remote instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3230
diff changeset
   111
        if config:
fd550e4dc515 #481017: cubicweb-ctl shell on remote instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3230
diff changeset
   112
            # no config on shell to a remote instance
5442
3ed8afbbdf70 [webconfig] refactor/cleanup debug mode management on startup: simply use config.debugmode instead of debug argument everywhere...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5436
diff changeset
   113
            self.config.init_log(logthreshold=logging.ERROR)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        # 0: no confirmation, 1: only main commands confirmed, 2 ask for everything
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
        self.verbosity = verbosity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        self.need_wrap = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        if not interactive or not verbosity:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            self.confirm = yes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
            self.execscript_confirm = yes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
            self.execscript_confirm = execscript_confirm
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        self._option_changes = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        self.__context = {'confirm': self.confirm,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                          'config': self.config,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
                          'interactive_mode': interactive,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                          }
6217
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   127
        self._context_stack = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   129
    def __getattribute__(self, name):
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   130
        try:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   131
            return object.__getattribute__(self, name)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   132
        except AttributeError:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   133
            cmd = 'cmd_%s' % name
6362
1b5fc8581437 [c-c] fix RuntimeError: 'maximum recursion depth exceeded while calling a Python object' we get when creating/upgrading/shelling an instance: hasattr() call __getattribute__, creating an infinite recursion error catched by the interpretor. Avoid this by testing the method is available on the class instead of the instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6221
diff changeset
   134
            # search self.__class__ to avoid infinite recursion
1b5fc8581437 [c-c] fix RuntimeError: 'maximum recursion depth exceeded while calling a Python object' we get when creating/upgrading/shelling an instance: hasattr() call __getattribute__, creating an infinite recursion error catched by the interpretor. Avoid this by testing the method is available on the class instead of the instance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6221
diff changeset
   135
            if hasattr(self.__class__, cmd):
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   136
                meth = getattr(self, cmd)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   137
                return lambda *args, **kwargs: self.interact(args, kwargs,
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   138
                                                             meth=meth)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   139
            raise
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   140
        raise AttributeError(name)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   141
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    def repo_connect(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        return self.config.repository()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   144
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
    def migrate(self, vcconf, toupgrade, options):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        """upgrade the given set of cubes
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   147
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        `cubes` is an ordered list of 3-uple:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        (cube, fromversion, toversion)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        if options.fs_only:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
            # monkey path configuration.accept_mode so database mode (e.g. Any)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
            # won't be accepted
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
            orig_accept_mode = self.config.accept_mode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
            def accept_mode(mode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
                if mode == 'Any':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
                    return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
                return orig_accept_mode(mode)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
            self.config.accept_mode = accept_mode
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   160
        # may be an iterator
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   161
        toupgrade = tuple(toupgrade)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   162
        vmap = dict( (cube, (fromver, tover)) for cube, fromver, tover in toupgrade)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   163
        ctx = self.__context
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   164
        ctx['versions_map'] = vmap
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   165
        if self.config.accept_mode('Any') and 'cubicweb' in vmap:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   166
            migrdir = self.config.migration_scripts_dir()
3715
e3ccadb126d7 [shell] make process_script available throuhg c-c shell / migration script context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3700
diff changeset
   167
            self.cmd_process_script(join(migrdir, 'bootstrapmigration_repository.py'))
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   168
        for cube, fromversion, toversion in toupgrade:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   169
            if cube == 'cubicweb':
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   170
                migrdir = self.config.migration_scripts_dir()
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   171
            else:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   172
                migrdir = self.config.cube_migration_scripts_dir(cube)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   173
            scripts = filter_scripts(self.config, migrdir, fromversion, toversion)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   174
            if scripts:
2481
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   175
                prevversion = None
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   176
                for version, script in scripts:
2481
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   177
                    # take care to X.Y.Z_Any.py / X.Y.Z_common.py: we've to call
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   178
                    # cube_upgraded once all script of X.Y.Z have been executed
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   179
                    if prevversion is not None and version != prevversion:
2897
2658f432284c [migration] consider previous version as done, not current version
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2738
diff changeset
   180
                        self.cube_upgraded(cube, prevversion)
2481
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   181
                    prevversion = version
3715
e3ccadb126d7 [shell] make process_script available throuhg c-c shell / migration script context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3700
diff changeset
   182
                    self.cmd_process_script(script)
2481
24bad65dbebd take care to migration w/ X.Y.Z_Any.py / X.Y.Z_common.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
   183
                self.cube_upgraded(cube, toversion)
2275
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   184
            else:
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   185
                self.cube_upgraded(cube, toversion)
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   186
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   187
    def cube_upgraded(self, cube, version):
bc0bed0616a3 fix #344387, remember upgraded version step by step
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2124
diff changeset
   188
        pass
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
    def shutdown(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        pass
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   192
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    def interact(self, args, kwargs, meth):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
        """execute the given method according to user's confirmation"""
2512
106b2a05dc88 [cleanup] started to improve cubicweb-ctl dialog messages consistency
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2481
diff changeset
   195
        msg = 'Execute command: %s(%s) ?' % (
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
            meth.__name__[4:],
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
            ', '.join([repr(arg) for arg in args] +
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
                      ['%s=%r' % (n,v) for n,v in kwargs.items()]))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        if 'ask_confirm' in kwargs:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
            ask_confirm = kwargs.pop('ask_confirm')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
            ask_confirm = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        if not ask_confirm or self.confirm(msg):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
            return meth(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   206
    def confirm(self, question, # pylint: disable=E0202
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   207
                shell=True, abort=True, retry=False, pdb=False, default='y'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        """ask for confirmation and return true on positive answer
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        if `retry` is true the r[etry] answer may return 2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """
4721
8f63691ccb7f pylint style fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4553
diff changeset
   212
        possibleanswers = ['y', 'n']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        if abort:
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   214
            possibleanswers.append('abort')
6187
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   215
        if pdb:
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   216
            possibleanswers.append('pdb')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        if shell:
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   218
            possibleanswers.append('shell')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        if retry:
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   220
            possibleanswers.append('retry')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        try:
2738
e7e46121a4f9 [migration] mh.confirm support a new default argument, fix default handling for ASK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2615
diff changeset
   222
            answer = ASK.ask(question, possibleanswers, default)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        except (EOFError, KeyboardInterrupt):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
            answer = 'abort'
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   225
        if answer == 'n':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
            return False
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   227
        if answer == 'retry':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
            return 2
2615
1ea41b7c0836 F [dialog] offer to create backup. refactor to use l.c.shellutils.ASK
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2512
diff changeset
   229
        if answer == 'abort':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
            raise SystemExit(1)
6187
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   231
        if answer == 'shell':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
            self.interactive_shell()
6187
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   233
            return self.confirm(question, shell, abort, retry, pdb, default)
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   234
        if answer == 'pdb':
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   235
            import pdb
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   236
            pdb.set_trace()
348c7d93cda3 [migration] propose to open pdb on error during execution of rql/sql query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6042
diff changeset
   237
            return self.confirm(question, shell, abort, retry, pdb, default)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    def interactive_shell(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        self.confirm = yes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        self.need_wrap = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        # avoid '_' to be added to builtins by sys.display_hook
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
        def do_not_add___to_builtins(obj):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
            if obj is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
                print repr(obj)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        sys.displayhook = do_not_add___to_builtins
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
        local_ctx = self._create_context()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
            import readline
9740
c0239d8ae742 [shell] provide autocompletion for rql queries in cubicweb-ctl shell (closes #3560541)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 9294
diff changeset
   251
            from cubicweb.toolsutils import CWShellCompleter
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
        except ImportError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
            # readline not available
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
            pass
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   255
        else:
9740
c0239d8ae742 [shell] provide autocompletion for rql queries in cubicweb-ctl shell (closes #3560541)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 9294
diff changeset
   256
            rql_completer = CWShellCompleter(local_ctx)
c0239d8ae742 [shell] provide autocompletion for rql queries in cubicweb-ctl shell (closes #3560541)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 9294
diff changeset
   257
            readline.set_completer(rql_completer.complete)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            readline.parse_and_bind('tab: complete')
3201
8af05e82510c HOME is spelled USERPROFILE on windows
Aurelien Campeas
parents: 2897
diff changeset
   259
            home_key = 'HOME'
8af05e82510c HOME is spelled USERPROFILE on windows
Aurelien Campeas
parents: 2897
diff changeset
   260
            if sys.platform == 'win32':
8af05e82510c HOME is spelled USERPROFILE on windows
Aurelien Campeas
parents: 2897
diff changeset
   261
                home_key = 'USERPROFILE'
9294
769b8867f8ce [cwshell] rename history file to .cwshell_history (erudi is dead, long live cw)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8532
diff changeset
   262
            histfile = os.path.join(os.environ[home_key], ".cwshell_history")
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
                readline.read_history_file(histfile)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
            except IOError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
        from code import interact
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        banner = """entering the migration python shell
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
just type migration commands or arbitrary python code and type ENTER to execute it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
type "exit" or Ctrl-D to quit the shell and resume operation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        # give custom readfunc to avoid http://bugs.python.org/issue1288615
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        def unicode_raw_input(prompt):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
            return unicode(raw_input(prompt), sys.stdin.encoding)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
        interact(banner, readfunc=unicode_raw_input, local=local_ctx)
8108
91868ec92391 [migration] Ignore IOError from readline.write_history_file (closes #2106621)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8107
diff changeset
   275
        try:
91868ec92391 [migration] Ignore IOError from readline.write_history_file (closes #2106621)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8107
diff changeset
   276
            readline.write_history_file(histfile)
91868ec92391 [migration] Ignore IOError from readline.write_history_file (closes #2106621)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8107
diff changeset
   277
        except IOError:
91868ec92391 [migration] Ignore IOError from readline.write_history_file (closes #2106621)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8107
diff changeset
   278
            pass
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
        # delete instance's confirm attribute to avoid questions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        del self.confirm
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        self.need_wrap = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
    def _create_context(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        """return a dictionary to use as migration script execution context"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
        context = self.__context
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
        for attr in dir(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
            if attr.startswith('cmd_'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
                if self.need_wrap:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
                    context[attr[4:]] = getattr(self, attr[4:])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
                    context[attr[4:]] = getattr(self, attr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
        return context
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   294
6217
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   295
    def update_context(self, key, value):
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   296
        for context in self._context_stack:
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   297
            context[key] = value
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   298
        self.__context[key] = value
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   299
3715
e3ccadb126d7 [shell] make process_script available throuhg c-c shell / migration script context
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3700
diff changeset
   300
    def cmd_process_script(self, migrscript, funcname=None, *args, **kwargs):
5430
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   301
        """execute a migration script in interactive mode
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   302
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   303
        Display the migration script path, ask for confirmation and execute it
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   304
        if confirmed
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   305
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   306
        Allowed input file formats for migration scripts:
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   307
        - `python` (.py)
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   308
        - `sql` (.sql)
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   309
        - `doctest` (.txt or .rst)
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   310
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   311
        .. warning:: sql migration scripts are not available in web-only instance
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   312
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   313
        You can pass script parameters with using double dash (--) in the
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   314
        command line
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   315
5430
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   316
        Context environment can have these variables defined:
5436
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   317
        - __name__ : will be determine by funcname parameter
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   318
        - __file__ : is the name of the script if it exists
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   319
        - __args__ : script arguments coming from command-line
5430
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   320
ed8f71e244f8 [shell] #715938: support of script parameters (using standard '--' as arguments separator)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5426
diff changeset
   321
        :param migrscript: name of the script
5436
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   322
        :param funcname: defines __name__ inside the shell (or use __main__)
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   323
        :params args: optional arguments for funcname
2455ca3a2a3a [c-c shell] make script arguments available as __args__ in the script namespace. Use scriptargs instead of args as process_script argument name.
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5430
diff changeset
   324
        :keyword scriptargs: optional arguments of the script
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
        """
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   326
        ftypes = {'python':  ('.py',),
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   327
                  'doctest': ('.txt', '.rst'),
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   328
                  'sql':     ('.sql',)}
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   329
        # sql migration scripts are not available in web-only instance
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   330
        if not hasattr(self, "session"):
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   331
            ftypes.pop('sql')
3812
d37d7105e15f [B] migration: normalize migration script path
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 3715
diff changeset
   332
        migrscript = os.path.normpath(migrscript)
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   333
        for (script_mode, ftype) in ftypes.items():
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   334
            if migrscript.endswith(ftype):
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   335
                break
3935
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   336
        else:
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   337
            ftypes = ', '.join(chain(*ftypes.values()))
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   338
            msg = 'ignoring %s, not a valid script extension (%s)'
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   339
            raise ExecutionError(msg % (migrscript, ftypes))
3935
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   340
        if not self.execscript_confirm(migrscript):
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   341
            return
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   342
        scriptlocals = self._create_context().copy()
6696
160ca95eb4cc [migration] put some migration context info in doctest environment: __file__ and __args__
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6687
diff changeset
   343
        scriptlocals.update({'__file__': migrscript,
160ca95eb4cc [migration] put some migration context info in doctest environment: __file__ and __args__
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6687
diff changeset
   344
                             '__args__': kwargs.pop("scriptargs", [])})
6217
e2aeb40d5983 [migration] fix so that context modification are reflected on the currently executed migration script
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6187
diff changeset
   345
        self._context_stack.append(scriptlocals)
3935
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   346
        if script_mode == 'python':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
            if funcname is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
                pyname = '__main__'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
                pyname = splitext(basename(migrscript))[0]
6696
160ca95eb4cc [migration] put some migration context info in doctest environment: __file__ and __args__
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6687
diff changeset
   351
            scriptlocals['__name__'] = pyname
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
            execfile(migrscript, scriptlocals)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
            if funcname is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
                    func = scriptlocals[funcname]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
                    self.info('found %s in locals', funcname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
                    assert callable(func), '%s (%s) is not callable' % (func, funcname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
                except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
                    self.critical('no %s in script %s', funcname, migrscript)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
                    return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
                return func(*args, **kwargs)
6035
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   362
        elif script_mode == 'sql':
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   363
            from cubicweb.server.sqlutils import sqlexec
f8c7aa251782 [migration] unify process_script command
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5967
diff changeset
   364
            sqlexec(open(migrscript).read(), self.session.system_sql)
6042
df9cafb8062c [migration] commit only sql script migration
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6035
diff changeset
   365
            self.commit()
3935
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   366
        else: # script_mode == 'doctest'
2fbb79054a1a imported patch cwctl-shell-textfile
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3812
diff changeset
   367
            import doctest
6687
0b1f5c14646e [shell, testlib] return doc test results in process_script and new assertDocTestFile method on CubicWebTC
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6659
diff changeset
   368
            return doctest.testfile(migrscript, module_relative=False,
0b1f5c14646e [shell, testlib] return doc test results in process_script and new assertDocTestFile method on CubicWebTC
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6659
diff changeset
   369
                                    optionflags=doctest.ELLIPSIS,
6732
f63cef610b97 [migration] improve doctest report format
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6696
diff changeset
   370
                                    # verbose mode when user input is expected
f63cef610b97 [migration] improve doctest report format
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6696
diff changeset
   371
                                    verbose=self.verbosity==2,
f63cef610b97 [migration] improve doctest report format
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6696
diff changeset
   372
                                    report=True,
6687
0b1f5c14646e [shell, testlib] return doc test results in process_script and new assertDocTestFile method on CubicWebTC
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6659
diff changeset
   373
                                    encoding='utf-8',
0b1f5c14646e [shell, testlib] return doc test results in process_script and new assertDocTestFile method on CubicWebTC
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6659
diff changeset
   374
                                    globs=scriptlocals)
6219
803c1019138e [migration] .pop() is more readable
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6217
diff changeset
   375
        self._context_stack.pop()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   376
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
    def cmd_option_renamed(self, oldname, newname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
        """a configuration option has been renamed"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
        self._option_changes.append(('renamed', oldname, newname))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
5580
3e9e6dd54ebb [migration] add migration file commands to follow option group changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5488
diff changeset
   381
    def cmd_option_group_changed(self, option, oldgroup, newgroup):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
        """a configuration option has been moved in another group"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
        self._option_changes.append(('moved', option, oldgroup, newgroup))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
    def cmd_option_added(self, optname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
        """a configuration option has been added"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        self._option_changes.append(('added', optname))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
    def cmd_option_removed(self, optname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
        """a configuration option has been removed"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
        # can safely be ignored
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
        #self._option_changes.append(('removed', optname))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
    def cmd_option_type_changed(self, optname, oldtype, newvalue):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
        """a configuration option's type has changed"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
        self._option_changes.append(('typechanged', optname, oldtype, newvalue))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   397
676
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   398
    def cmd_add_cubes(self, cubes):
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   399
        """modify the list of used cubes in the in-memory config
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   400
        returns newly inserted cubes, including dependencies
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   401
        """
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   402
        if isinstance(cubes, basestring):
270eb87a768a provide a new add_cubes() migration function for cases where the new cubes are linked together by new relations
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 447
diff changeset
   403
            cubes = (cubes,)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
        origcubes = self.config.cubes()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   405
        newcubes = [p for p in self.config.expand_cubes(cubes)
6221
a5cc5dc15f9d [migration] remove buggy assertion
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6219
diff changeset
   406
                    if not p in origcubes]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
        if newcubes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
            self.config.add_cubes(newcubes)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        return newcubes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
10107
1ef92a6193a8 [serverctl] rename remove_cube to drop_cube (closes #4545093)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 10074
diff changeset
   411
    @deprecated('[3.20] use drop_cube() instead of remove_cube()')
2124
5a0b02f37b23 set removedeps to False by default, raise an exception instead of a simple assertion for error, more remove_cube tests
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2122
diff changeset
   412
    def cmd_remove_cube(self, cube, removedeps=False):
10107
1ef92a6193a8 [serverctl] rename remove_cube to drop_cube (closes #4545093)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 10074
diff changeset
   413
        return self.cmd_drop_cube(cube, removedeps)
1ef92a6193a8 [serverctl] rename remove_cube to drop_cube (closes #4545093)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 10074
diff changeset
   414
1ef92a6193a8 [serverctl] rename remove_cube to drop_cube (closes #4545093)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 10074
diff changeset
   415
    def cmd_drop_cube(self, cube, removedeps=False):
2122
4ea13a828513 add removedeps option to remove_cube to control wether a cube's dependencies should be removed as well or not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   416
        if removedeps:
4ea13a828513 add removedeps option to remove_cube to control wether a cube's dependencies should be removed as well or not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   417
            toremove = self.config.expand_cubes([cube])
4ea13a828513 add removedeps option to remove_cube to control wether a cube's dependencies should be removed as well or not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   418
        else:
4ea13a828513 add removedeps option to remove_cube to control wether a cube's dependencies should be removed as well or not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   419
            toremove = (cube,)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        origcubes = self.config._cubes
2122
4ea13a828513 add removedeps option to remove_cube to control wether a cube's dependencies should be removed as well or not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   421
        basecubes = [c for c in origcubes if not c in toremove]
9829
e0e71b45bf8d [migration] don't add new elements to config._cubes in remove_cube
Julien Cristau <julien.cristau@logilab.fr>
parents: 9294
diff changeset
   422
        # don't fake-add any new ones, or we won't be able to really-add them later
e0e71b45bf8d [migration] don't add new elements to config._cubes in remove_cube
Julien Cristau <julien.cristau@logilab.fr>
parents: 9294
diff changeset
   423
        self.config._cubes = tuple(cube for cube in self.config.expand_cubes(basecubes)
e0e71b45bf8d [migration] don't add new elements to config._cubes in remove_cube
Julien Cristau <julien.cristau@logilab.fr>
parents: 9294
diff changeset
   424
                                   if cube in origcubes)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        removed = [p for p in origcubes if not p in self.config._cubes]
8107
e5858a4a1244 [migration] make remove_cube('foo') not fail if foo is already removed. Closes #2106532
Julien Cristau <julien.cristau@logilab.fr>
parents: 7879
diff changeset
   426
        if not cube in removed and cube in origcubes:
2124
5a0b02f37b23 set removedeps to False by default, raise an exception instead of a simple assertion for error, more remove_cube tests
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2122
diff changeset
   427
            raise ConfigurationError("can't remove cube %s, "
5a0b02f37b23 set removedeps to False by default, raise an exception instead of a simple assertion for error, more remove_cube tests
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2122
diff changeset
   428
                                     "used as a dependency" % cube)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
        return removed
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 676
diff changeset
   430
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
    def rewrite_configuration(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
        configfile = self.config.main_config_file()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
        if self._option_changes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
            read_old_config(self.config, self._option_changes, configfile)
3152
7ef7c82daf59 close file handler leak
Aurelien Campeas
parents: 2897
diff changeset
   435
        fd, newconfig = tempfile.mkstemp()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        for optdescr in self._option_changes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
            if optdescr[0] == 'added':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
                optdict = self.config.get_option_def(optdescr[1])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
                if optdict.get('default') is REQUIRED:
447
0e52d72104a6 pylint fixes
sylvain.thenault@logilab.fr
parents: 0
diff changeset
   440
                    self.config.input_option(optdescr[1], optdict)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        self.config.generate_config(open(newconfig, 'w'))
5487
3ab2682a4b37 [migration] ask_confirm argument of show_diff doesn't contain an _
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5484
diff changeset
   442
        show_diffs(configfile, newconfig, askconfirm=self.confirm is not yes)
3152
7ef7c82daf59 close file handler leak
Aurelien Campeas
parents: 2897
diff changeset
   443
        os.close(fd)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
        if exists(newconfig):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
            os.unlink(newconfig)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6732
diff changeset
   447
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6732
diff changeset
   448
    # only defining here to prevent pylint from complaining
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6732
diff changeset
   449
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
from cubicweb import set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
set_log_methods(MigrationHelper, getLogger('cubicweb.migration'))
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   454
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   455
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   456
def version_strictly_lower(a, b):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   457
    if a:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   458
        a = Version(a)
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   459
    if b:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   460
        b = Version(b)
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   461
    return a < b
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   462
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   463
def max_version(a, b):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   464
    return str(max(Version(a), Version(b)))
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   465
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   466
class ConfigurationProblem(object):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   467
    """Each cube has its own list of dependencies on other cubes/versions.
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   468
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   469
    The ConfigurationProblem is used to record the loaded cubes, then to detect
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   470
    inconsistencies in their dependencies.
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   471
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   472
    See configuration management on wikipedia for litterature.
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   473
    """
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   474
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   475
    def __init__(self, config):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   476
        self.config = config
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   477
        self.cubes = {'cubicweb': cwcfg.cubicweb_version()}
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   478
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   479
    def add_cube(self, name, version):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   480
        self.cubes[name] = version
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   481
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   482
    def solve(self):
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   483
        self.warnings = []
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   484
        self.errors = []
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   485
        self.dependencies = {}
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   486
        self.reverse_dependencies = {}
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   487
        self.constraints = {}
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   488
        # read dependencies
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   489
        for cube in self.cubes:
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   490
            if cube == 'cubicweb': continue
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   491
            self.dependencies[cube] = dict(self.config.cube_dependencies(cube))
6659
6205927e927a fix problem introduced with previous commit
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6657
diff changeset
   492
            self.dependencies[cube]['cubicweb'] = self.config.cube_depends_cubicweb_version(cube)
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   493
        # compute reverse dependencies
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   494
        for cube, dependencies in self.dependencies.iteritems():
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   495
            for name, constraint in dependencies.iteritems():
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   496
                self.reverse_dependencies.setdefault(name,set())
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   497
                if constraint:
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   498
                    try:
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   499
                        oper, version = constraint.split()
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   500
                        self.reverse_dependencies[name].add( (oper, version, cube) )
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7576
diff changeset
   501
                    except Exception:
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   502
                        self.warnings.append(
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   503
                            'cube %s depends on %s but constraint badly '
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   504
                            'formatted: %s' % (cube, name, constraint))
7537
1af162bd78b8 [migration] bugfix: c-c list was not displaying the name of a cube requiring another cube without constraining the version.
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   505
                else:
1af162bd78b8 [migration] bugfix: c-c list was not displaying the name of a cube requiring another cube without constraining the version.
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   506
                    self.reverse_dependencies[name].add( (None, None, cube) )
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   507
        # check consistency
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   508
        for cube, versions in sorted(self.reverse_dependencies.items()):
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   509
            oper, version, source = None, None, None
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   510
            # simplify constraints
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   511
            if versions:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   512
                for constraint in versions:
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   513
                    op, ver, src = constraint
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   514
                    if oper is None:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   515
                        oper = op
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   516
                        version = ver
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   517
                        source = src
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   518
                    elif op == '>=' and oper == '>=':
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   519
                        if version_strictly_lower(version, ver):
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   520
                            version = ver
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   521
                            source = src
7576
1b7fa4df1f83 [cw-ctl] command list should not break when cube depends on version None (closes #1787209)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7537
diff changeset
   522
                    elif op == None:
1b7fa4df1f83 [cw-ctl] command list should not break when cube depends on version None (closes #1787209)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7537
diff changeset
   523
                        continue
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   524
                    else:
8532
28a346df670e [cwctl] show a better diagnostic message on version violation (closes #2464800)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8119
diff changeset
   525
                        print ('unable to handle %s in %s, set to `%s %s` '
28a346df670e [cwctl] show a better diagnostic message on version violation (closes #2464800)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8119
diff changeset
   526
                               'but currently up to `%s %s`' %
28a346df670e [cwctl] show a better diagnostic message on version violation (closes #2464800)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8119
diff changeset
   527
                               (cube, source, oper, version, op, ver))
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   528
            # "solve" constraint satisfaction problem
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   529
            if cube not in self.cubes:
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   530
                self.errors.append( ('add', cube, version, source) )
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   531
            elif versions:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   532
                lower_strict = version_strictly_lower(self.cubes[cube], version)
10060
08dc10ef9ab1 Accept '==' operator in cubes dependencies
Christophe de Vienne <christophe@unlish.com>
parents: 9829
diff changeset
   533
                if oper in ('>=','=','=='):
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   534
                    if lower_strict:
6657
402bff898024 [cwctl] command list now checks version of cw, not only versions of cubes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6362
diff changeset
   535
                        self.errors.append( ('update', cube, version, source) )
7537
1af162bd78b8 [migration] bugfix: c-c list was not displaying the name of a cube requiring another cube without constraining the version.
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   536
                elif oper is None:
1af162bd78b8 [migration] bugfix: c-c list was not displaying the name of a cube requiring another cube without constraining the version.
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   537
                    pass # no constraint on version
5027
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   538
                else:
d688daf0a62c [config] move ConfigurationProblem to migration + refactor it to benefit from config methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
   539
                    print 'unknown operator', oper