~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:
12707.8.2 by Tim Penhey
Update the stacking fixit scripts.
11
    '<id> <branch_type> <unique_name> <stacked_on_id> <stacked_on_unique_name>\n'.
7109.3.3 by Jonathan Lange
Docstrings.
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
12707.8.4 by Tim Penhey
Use the branch_id_alias function, which requires an object with an id.
24
from collections import namedtuple
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
25
import sys
26
27
from bzrlib.bzrdir import BzrDir
28
from bzrlib.config import TransportConfig
29
from bzrlib import errors
30
9590.1.117 by Michael Hudson
kill off get_multi_server
31
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,'
32
from lp.codehosting.bzrutils import get_branch_stacked_on_url
12707.8.4 by Tim Penhey
Use the branch_id_alias function, which requires an object with an id.
33
from lp.code.interfaces.codehosting import branch_id_alias
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/.
34
from lp.services.scripts.base import LaunchpadScript
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
35
36
12707.8.4 by Tim Penhey
Use the branch_id_alias function, which requires an object with an id.
37
FakeBranch = namedtuple('FakeBranch', 'id')
38
39
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
40
def set_branch_stacked_on_url(bzrdir, stacked_on_url):
7109.3.3 by Jonathan Lange
Docstrings.
41
    """Set the stacked_on_location for the branch at 'bzrdir'.
42
43
    We cannot use Branch.set_stacked_on, since that requires us to first open
44
    the branch. Opening the branch requires a working stacked_on_url:
45
    something we don't yet have.
46
    """
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
47
    branch_transport = bzrdir.get_branch_transport(None)
48
    branch_config = TransportConfig(branch_transport, 'branch.conf')
49
    stacked_on_url = branch_config.set_option(
50
        stacked_on_url, 'stacked_on_location')
51
52
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
53
class UpdateStackedBranches(LaunchpadScript):
54
    """Update stacked branches so their stacked_on_location matches the db."""
55
56
    def __init__(self):
57
        super(UpdateStackedBranches, self).__init__('update-stacked-on')
58
59
    def add_my_options(self):
60
        self.parser.add_option(
61
            '-n', '--dry-run', default=False, action="store_true",
62
            dest="dry_run",
63
            help=("Don't change anything on disk, just go through the "
64
                  "motions."))
12707.8.2 by Tim Penhey
Update the stacking fixit scripts.
65
        self.parser.add_option(
66
            '-i', '--id', default=False, action="store_true",
67
            dest="stack_on_id",
68
            help=("Stack on the +branch-id alias."))
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
69
70
    def main(self):
9590.1.117 by Michael Hudson
kill off get_multi_server
71
        if self.options.dry_run:
72
            server = get_ro_server()
73
        else:
74
            server = get_rw_server()
10197.5.9 by Michael Hudson
even more
75
        server.start_server()
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
76
        if self.options.dry_run:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
77
            self.logger.debug('Running read-only')
78
        self.logger.debug('Beginning processing')
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
79
        try:
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
80
            self.updateBranches(self.parseFromStream(sys.stdin))
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
81
        finally:
10197.5.9 by Michael Hudson
even more
82
            server.stop_server()
7109.3.8 by Jonathan Lange
Use the real logger, not print.
83
        self.logger.info('Done')
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
84
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
85
    def updateStackedOn(self, branch_id, bzr_branch_url, stacked_on_location):
86
        """Stack the Bazaar branch at 'bzr_branch_url' on the given URL.
87
88
        :param branch_id: The database ID of the branch. This is only used for
89
            logging.
9590.1.118 by Michael Hudson
maybe this entirely untested script works now
90
        :param bzr_branch_url: The lp-internal:/// URL of the Bazaar branch.
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
91
        :param stacked_on_location: The location to store in the branch's
92
            stacked_on_location configuration variable.
93
        """
94
        try:
95
            bzrdir = BzrDir.open(bzr_branch_url)
96
        except errors.NotBranchError:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
97
            self.logger.warn(
98
                "No bzrdir for %r at %r" % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
99
            return
100
101
        try:
102
            current_stacked_on_location = get_branch_stacked_on_url(bzrdir)
103
        except errors.NotBranchError:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
104
            self.logger.warn(
105
                "No branch for %r at %r" % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
106
        except errors.NotStacked:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
107
            self.logger.warn(
108
                "Branch for %r at %r is not stacked at all. Giving up."
109
                % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
110
        except errors.UnstackableBranchFormat:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
111
            self.logger.error(
112
                "Branch for %r at %r is unstackable. Giving up."
113
                % (branch_id, bzr_branch_url))
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
114
        else:
115
            if current_stacked_on_location != stacked_on_location:
7109.3.8 by Jonathan Lange
Use the real logger, not print.
116
                self.logger.info(
117
                    'Branch for %r at %r stacked on %r, should be on %r.'
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
118
                    % (branch_id, bzr_branch_url, current_stacked_on_location,
119
                       stacked_on_location))
120
                if not self.options.dry_run:
121
                    set_branch_stacked_on_url(bzrdir, stacked_on_location)
122
123
    def parseFromStream(self, stream):
124
        """Parse branch input from the given stream.
125
7109.3.9 by Jonathan Lange
78 cols and vws
126
        Expects the stream to be populated only by blank lines or by lines
127
        with whitespace-separated fields. Such lines are yielded as tuples.
128
        Blank lines are ignored.
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
129
        """
130
        for line in stream.readlines():
131
            if not line.strip():
132
                continue
7109.3.9 by Jonathan Lange
78 cols and vws
133
            yield line.split()
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
134
135
    def updateBranches(self, branches):
136
        """Update the stacked_on_location for all branches in 'branches'.
137
138
        :param branches: An iterator yielding (branch_id, branch_type,
139
            unique_name, stacked_on_unique_name).
140
        """
141
        for branch_info in branches:
7109.3.9 by Jonathan Lange
78 cols and vws
142
            (branch_id, branch_type, unique_name,
12707.8.2 by Tim Penhey
Update the stacking fixit scripts.
143
             stacked_on_id, stacked_on_name) = branch_info
144
            if self.options.stack_on_id:
12707.8.4 by Tim Penhey
Use the branch_id_alias function, which requires an object with an id.
145
                branch = FakeBranch(stacked_on_id)
146
                stacked_on_location = branch_id_alias(branch)
12707.8.2 by Tim Penhey
Update the stacking fixit scripts.
147
            else:
148
                stacked_on_location = '/' + stacked_on_name
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
149
            self.updateStackedOn(
9590.1.118 by Michael Hudson
maybe this entirely untested script works now
150
                branch_id, 'lp-internal:///' + unique_name,
151
                stacked_on_location)
7109.3.7 by Jonathan Lange
Bring some methods into the fold.
152
153
7109.3.1 by Jonathan Lange
Initial version of stacking update scripts.
154
if __name__ == '__main__':
7109.3.6 by Jonathan Lange
Use the LaunchpadScript structure to give us power.
155
    UpdateStackedBranches().lock_and_run()