~launchpad-pqm/launchpad/devel

10637.3.1 by Guilherme Salgado
Use the default python version instead of a hard-coded version
1
#!/usr/bin/python -S
8687.15.22 by Karl Fogel
Add the copyright header block to the remaining .py 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).
5
7109.3.10 by Jonathan Lange
Disable lint.
6
# pylint: disable-msg=W0403
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
7
8
"""Update stacked_on_location for all Bazaar branches.
9
7109.3.3 by Jonathan Lange
Docstrings.
10
Expects standard input of:
11
    '<id> <branch_type> <unique_name> <stacked_on_unique_name>\n'.
12
13
Such input can be provided using "get-stacked-on-branches.py".
14
15
This script makes the stacked_on_location variables in all Bazaar branches
16
match the stacked_on column in the Launchpad database. This is useful for
17
updating stacked branches when their stacked-on branch has been moved or
18
renamed.
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
19
"""
20
21
__metaclass__ = type
22
23
import _pythonpath
24
import sys
25
26
from bzrlib.bzrdir import BzrDir
27
from bzrlib.config import TransportConfig
28
from bzrlib import errors
29
9590.1.117 by Michael Hudson
kill off get_multi_server
30
from lp.codehosting.vfs import get_rw_server, get_ro_server
8426.6.1 by Michael Hudson
bzr ls --versioned --recursive --kind=file | xargs sed -i -e 's,from canonical.codehosting,from lp.codehosting,'
31
from lp.codehosting.bzrutils import get_branch_stacked_on_url
8356.1.9 by Leonard Richardson
Renamed the base script module in scripts/, which module_rename.py didn't touch because it wasn't under lib/.
32
from lp.services.scripts.base import LaunchpadScript
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
33
34
35
def set_branch_stacked_on_url(bzrdir, stacked_on_url):
7109.3.3 by Jonathan Lange
Docstrings.
36
    """Set the stacked_on_location for the branch at 'bzrdir'.
37
38
    We cannot use Branch.set_stacked_on, since that requires us to first open
39
    the branch. Opening the branch requires a working stacked_on_url:
40
    something we don't yet have.
41
    """
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
42
    branch_transport = bzrdir.get_branch_transport(None)
43
    branch_config = TransportConfig(branch_transport, 'branch.conf')
44
    stacked_on_url = branch_config.set_option(
45
        stacked_on_url, 'stacked_on_location')
46
47
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
48
class UpdateStackedBranches(LaunchpadScript):
49
    """Update stacked branches so their stacked_on_location matches the db."""
50
51
    def __init__(self):
52
        super(UpdateStackedBranches, self).__init__('update-stacked-on')
53
54
    def add_my_options(self):
55
        self.parser.add_option(
56
            '-n', '--dry-run', default=False, action="store_true",
57
            dest="dry_run",
58
            help=("Don't change anything on disk, just go through the "
59
                  "motions."))
60
61
    def main(self):
9590.1.117 by Michael Hudson
kill off get_multi_server
62
        if self.options.dry_run:
63
            server = get_ro_server()
64
        else:
65
            server = get_rw_server()
10197.5.9 by Michael Hudson
even more
66
        server.start_server()
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
67
        if self.options.dry_run:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
68
            self.logger.debug('Running read-only')
69
        self.logger.debug('Beginning processing')
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
70
        try:
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
71
            self.updateBranches(self.parseFromStream(sys.stdin))
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
72
        finally:
10197.5.9 by Michael Hudson
even more
73
            server.stop_server()
7109.3.8 by Jonathan Lange
Use the real logger, not print.
74
        self.logger.info('Done')
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
75
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
76
    def updateStackedOn(self, branch_id, bzr_branch_url, stacked_on_location):
77
        """Stack the Bazaar branch at 'bzr_branch_url' on the given URL.
78
79
        :param branch_id: The database ID of the branch. This is only used for
80
            logging.
9590.1.118 by Michael Hudson
maybe this entirely untested script works now
81
        :param bzr_branch_url: The lp-internal:/// URL of the Bazaar branch.
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
82
        :param stacked_on_location: The location to store in the branch's
83
            stacked_on_location configuration variable.
84
        """
85
        try:
86
            bzrdir = BzrDir.open(bzr_branch_url)
87
        except errors.NotBranchError:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
88
            self.logger.warn(
89
                "No bzrdir for %r at %r" % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
90
            return
91
92
        try:
93
            current_stacked_on_location = get_branch_stacked_on_url(bzrdir)
94
        except errors.NotBranchError:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
95
            self.logger.warn(
96
                "No branch for %r at %r" % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
97
        except errors.NotStacked:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
98
            self.logger.warn(
99
                "Branch for %r at %r is not stacked at all. Giving up."
100
                % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
101
        except errors.UnstackableBranchFormat:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
102
            self.logger.error(
103
                "Branch for %r at %r is unstackable. Giving up."
104
                % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
105
        else:
106
            if current_stacked_on_location != stacked_on_location:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
107
                self.logger.info(
108
                    'Branch for %r at %r stacked on %r, should be on %r.'
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
109
                    % (branch_id, bzr_branch_url, current_stacked_on_location,
110
                       stacked_on_location))
111
                if not self.options.dry_run:
112
                    set_branch_stacked_on_url(bzrdir, stacked_on_location)
113
114
    def parseFromStream(self, stream):
115
        """Parse branch input from the given stream.
116
7109.3.9 by Jonathan Lange
78 cols and vws
117
        Expects the stream to be populated only by blank lines or by lines
118
        with whitespace-separated fields. Such lines are yielded as tuples.
119
        Blank lines are ignored.
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
120
        """
121
        for line in stream.readlines():
122
            if not line.strip():
123
                continue
7109.3.9 by Jonathan Lange
78 cols and vws
124
            yield line.split()
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
125
126
    def updateBranches(self, branches):
127
        """Update the stacked_on_location for all branches in 'branches'.
128
129
        :param branches: An iterator yielding (branch_id, branch_type,
130
            unique_name, stacked_on_unique_name).
131
        """
132
        for branch_info in branches:
7109.3.9 by Jonathan Lange
78 cols and vws
133
            (branch_id, branch_type, unique_name,
134
             stacked_on_name) = branch_info
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
135
            stacked_on_location = '/' + stacked_on_name
136
            self.updateStackedOn(
9590.1.118 by Michael Hudson
maybe this entirely untested script works now
137
                branch_id, 'lp-internal:///' + unique_name,
138
                stacked_on_location)
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
139
140
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
141
if __name__ == '__main__':
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
142
    UpdateStackedBranches().lock_and_run()