~launchpad-pqm/launchpad/devel

7944.3.4 by Francis J. Lacoste
Added a script to rename module.
1
#!/usr/bin/python
8687.15.4 by Karl Fogel
Add the copyright header block to more files; tweak format in a few files.
2
#
3
# Copyright 2009 Canonical Ltd.  This software is licensed under the
4
# GNU Affero General Public License version 3 (see the file LICENSE).
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
5
6
"""Move a python module in the tree.
7
8
It uses bzr mv to rename the module and will try to find all imports.
9
10
rename-module.py src_file+ target
11
12
Both files must be under lib/.
13
14
If more than one src files is given, target must be a directory.
15
"""
16
17
__metaclass__ = type
18
__all__ = []
19
20
import os
21
import subprocess
22
import sys
23
24
25
def fail(message):
26
    os.sys.stderr.write(message + "\n")
27
    sys.exit(1)
28
29
30
def log(message):
31
    os.sys.stdout.write(message + "\n")
32
33
34
def file2module(module_file):
35
    """From a filename, return the python module name."""
36
    start_path = 'lib' + os.path.sep
37
    assert module_file.startswith(start_path), "File should start with lib"
7944.3.17 by Francis J. Lacoste
Handle directory package rename.
38
    if module_file.endswith('.py'):
39
        module_file = module_file[:-3]
40
    return module_file[len(start_path):].replace(os.path.sep, '.')
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
41
42
43
def rename_module(src_file, target_file):
44
    # Move the file using bzr.
45
    p = subprocess.Popen(['bzr', 'mv', src_file, target_file])
46
    if (p.wait() != 0):
47
        fail("bzr mv failed: %d" % p.returncode)
48
    if os.path.exists(src_file + 'c'):
49
        os.remove(src_file + 'c')
50
    log("Renamed %s -> %s" % (src_file, target_file))
51
52
    # Find the files to update.
53
    src_module = file2module(src_file)
54
    p = subprocess.Popen([
7944.3.17 by Francis J. Lacoste
Handle directory package rename.
55
        'egrep', '-rl', '--exclude', '*.pyc', '%s' % src_module, 'lib'],
56
        stdout=subprocess.PIPE)
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
57
    files = [f.strip() for f in p.stdout.readlines()]
58
    p.wait()
59
    # grep fails if it didn't find anything to update. So ignore return code.
60
61
    target_module = file2module(target_file)
62
    log("Found %d files with imports to update." % len(files))
7944.3.8 by Francis J. Lacoste
Use more precise regex.
63
    src_module_re = src_module.replace('.', '\\.')
64
    target_module_re = target_module.replace('.', '\\.')
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
65
    for f in files:
66
        # YES! Perl
67
        cmdline = [
7944.3.17 by Francis J. Lacoste
Handle directory package rename.
68
            'perl', '-i', '-pe',
69
            's/%s\\b/%s/g;' % (src_module_re, target_module_re),
7944.3.8 by Francis J. Lacoste
Use more precise regex.
70
            f]
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
71
        p = subprocess.Popen(cmdline)
72
        rv = p.wait()
73
        if rv != 0:
74
            log('Failed to update %s' % f)
75
        else:
76
            log('Updated %s' % f)
77
78
79
def main():
80
    if len(sys.argv) < 3:
81
        fail('Usage: %s src_file+ target' % os.path.basename(sys.argv[0]))
82
    src_files = sys.argv[1:-1]
83
    target = sys.argv[-1]
84
85
    if os.path.exists(target) and not os.path.isdir(target):
86
        fail('Destination file "%s" already exists.' % target)
87
    if not target.startswith('lib'):
88
        fail('Destination file "%s" must be under lib.' % target)
89
    if len(src_files) > 1 and not os.path.isdir(target):
90
        fail('Destination must be a directory.')
91
92
    for src_file in src_files:
93
        if not os.path.exists(src_file):
94
            log('Source file "%s" doesn\'t exists. Skipping' % src_file)
95
            continue
96
        if not src_file.startswith('lib'):
97
            log('Source file "%s" must be under lib. Skipping' % src_file)
98
            continue
7944.3.17 by Francis J. Lacoste
Handle directory package rename.
99
        if not (src_file.endswith('.py') or os.path.isdir(src_file)):
100
            log('Source file "%s" should end with .py or be a directory. '
101
                'Skipping' % src_file)
7944.3.4 by Francis J. Lacoste
Added a script to rename module.
102
            continue
103
104
        if os.path.isdir(target):
105
            target_file = os.path.join(target, os.path.basename(src_file))
106
        else:
107
            target_file = target
108
109
        rename_module(src_file, target_file)
110
111
if __name__ == '__main__':
112
    main()