~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/send.py

Turn completion assertions into separate methods.

Many common assertions used to be expressed as arguments to the complete
method.  This makes the checks more explicit, and the code easier to read.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
 
18
 
import os
19
 
import time
20
 
 
21
 
from bzrlib import (
22
 
    bzrdir,
23
 
    errors,
24
 
    osutils,
25
 
    registry,
26
 
    trace,
27
 
    )
28
 
from bzrlib.branch import (
29
 
    Branch,
30
 
    )
31
 
from bzrlib.revision import (
32
 
    NULL_REVISION,
33
 
    )
34
 
 
35
 
 
36
 
format_registry = registry.Registry()
37
 
 
38
 
 
39
 
def send(submit_branch, revision, public_branch, remember, format,
40
 
         no_bundle, no_patch, output, from_, mail_to, message, body,
41
 
         to_file, strict=None):
42
 
    tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
43
 
    # we may need to write data into branch's repository to calculate
44
 
    # the data to send.
45
 
    branch.lock_write()
46
 
    try:
47
 
        if output is None:
48
 
            config = branch.get_config()
49
 
            if mail_to is None:
50
 
                mail_to = config.get_user_option('submit_to')
51
 
            mail_client = config.get_mail_client()
52
 
            if (not getattr(mail_client, 'supports_body', False)
53
 
                and body is not None):
54
 
                raise errors.BzrCommandError(
55
 
                    'Mail client "%s" does not support specifying body' %
56
 
                    mail_client.__class__.__name__)
57
 
        if remember and submit_branch is None:
58
 
            raise errors.BzrCommandError(
59
 
                '--remember requires a branch to be specified.')
60
 
        stored_submit_branch = branch.get_submit_branch()
61
 
        remembered_submit_branch = None
62
 
        if submit_branch is None:
63
 
            submit_branch = stored_submit_branch
64
 
            remembered_submit_branch = "submit"
65
 
        else:
66
 
            # Remembers if asked explicitly or no previous location is set
67
 
            if remember or (remember is None and stored_submit_branch is None):
68
 
                branch.set_submit_branch(submit_branch)
69
 
        if submit_branch is None:
70
 
            submit_branch = branch.get_parent()
71
 
            remembered_submit_branch = "parent"
72
 
        if submit_branch is None:
73
 
            raise errors.BzrCommandError('No submit branch known or'
74
 
                                         ' specified')
75
 
        if remembered_submit_branch is not None:
76
 
            trace.note('Using saved %s location "%s" to determine what '
77
 
                       'changes to submit.', remembered_submit_branch,
78
 
                       submit_branch)
79
 
 
80
 
        if mail_to is None or format is None:
81
 
            # TODO: jam 20090716 we open the submit_branch here, but we *don't*
82
 
            #       pass it down into the format creation, so it will have to
83
 
            #       open it again
84
 
            submit_br = Branch.open(submit_branch)
85
 
            submit_config = submit_br.get_config()
86
 
            if mail_to is None:
87
 
                mail_to = submit_config.get_user_option("child_submit_to")
88
 
            if format is None:
89
 
                formatname = submit_br.get_child_submit_format()
90
 
                try:
91
 
                    format = format_registry.get(formatname)
92
 
                except KeyError:
93
 
                    raise errors.BzrCommandError("No such send format '%s'." % 
94
 
                                                 formatname)
95
 
 
96
 
        stored_public_branch = branch.get_public_branch()
97
 
        if public_branch is None:
98
 
            public_branch = stored_public_branch
99
 
        # Remembers if asked explicitly or no previous location is set
100
 
        elif (remember
101
 
              or (remember is None and stored_public_branch is None)):
102
 
            branch.set_public_branch(public_branch)
103
 
        if no_bundle and public_branch is None:
104
 
            raise errors.BzrCommandError('No public branch specified or'
105
 
                                         ' known')
106
 
        base_revision_id = None
107
 
        revision_id = None
108
 
        if revision is not None:
109
 
            if len(revision) > 2:
110
 
                raise errors.BzrCommandError('bzr send takes '
111
 
                    'at most two one revision identifiers')
112
 
            revision_id = revision[-1].as_revision_id(branch)
113
 
            if len(revision) == 2:
114
 
                base_revision_id = revision[0].as_revision_id(branch)
115
 
        if revision_id is None:
116
 
            if tree is not None:
117
 
                tree.check_changed_or_out_of_date(
118
 
                    strict, 'send_strict',
119
 
                    more_error='Use --no-strict to force the send.',
120
 
                    more_warning='Uncommitted changes will not be sent.')
121
 
            revision_id = branch.last_revision()
122
 
        if revision_id == NULL_REVISION:
123
 
            raise errors.BzrCommandError('No revisions to submit.')
124
 
        if format is None:
125
 
            format = format_registry.get()
126
 
        directive = format(branch, revision_id, submit_branch,
127
 
            public_branch, no_patch, no_bundle, message, base_revision_id)
128
 
        if output is None:
129
 
            directive.compose_merge_request(mail_client, mail_to, body,
130
 
                                            branch, tree)
131
 
        else:
132
 
            if directive.multiple_output_files:
133
 
                if output == '-':
134
 
                    raise errors.BzrCommandError('- not supported for '
135
 
                        'merge directives that use more than one output file.')
136
 
                if not os.path.exists(output):
137
 
                    os.mkdir(output, 0755)
138
 
                for (filename, lines) in directive.to_files():
139
 
                    path = os.path.join(output, filename)
140
 
                    outfile = open(path, 'wb')
141
 
                    try:
142
 
                        outfile.writelines(lines)
143
 
                    finally:
144
 
                        outfile.close()
145
 
            else:
146
 
                if output == '-':
147
 
                    outfile = to_file
148
 
                else:
149
 
                    outfile = open(output, 'wb')
150
 
                try:
151
 
                    outfile.writelines(directive.to_lines())
152
 
                finally:
153
 
                    if outfile is not to_file:
154
 
                        outfile.close()
155
 
    finally:
156
 
        branch.unlock()
157
 
 
158
 
 
159
 
def _send_4(branch, revision_id, submit_branch, public_branch,
160
 
            no_patch, no_bundle, message, base_revision_id):
161
 
    from bzrlib import merge_directive
162
 
    return merge_directive.MergeDirective2.from_objects(
163
 
        branch.repository, revision_id, time.time(),
164
 
        osutils.local_time_offset(), submit_branch,
165
 
        public_branch=public_branch, include_patch=not no_patch,
166
 
        include_bundle=not no_bundle, message=message,
167
 
        base_revision_id=base_revision_id)
168
 
 
169
 
 
170
 
def _send_0_9(branch, revision_id, submit_branch, public_branch,
171
 
              no_patch, no_bundle, message, base_revision_id):
172
 
    if not no_bundle:
173
 
        if not no_patch:
174
 
            patch_type = 'bundle'
175
 
        else:
176
 
            raise errors.BzrCommandError('Format 0.9 does not'
177
 
                ' permit bundle with no patch')
178
 
    else:
179
 
        if not no_patch:
180
 
            patch_type = 'diff'
181
 
        else:
182
 
            patch_type = None
183
 
    from bzrlib import merge_directive
184
 
    return merge_directive.MergeDirective.from_objects(
185
 
        branch.repository, revision_id, time.time(),
186
 
        osutils.local_time_offset(), submit_branch,
187
 
        public_branch=public_branch, patch_type=patch_type,
188
 
        message=message)
189
 
 
190
 
 
191
 
format_registry.register('4', 
192
 
    _send_4, 'Bundle format 4, Merge Directive 2 (default)')
193
 
format_registry.register('0.9',
194
 
    _send_0_9, 'Bundle format 0.9, Merge Directive 1')
195
 
format_registry.default_key = '4'