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