~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to bzrtools.py

  • Committer: Robert Collins
  • Date: 2005-09-13 10:46:27 UTC
  • mto: (147.2.6) (364.1.3 bzrtools)
  • mto: This revision was merged to the branch mainline in revision 324.
  • Revision ID: robertc@robertcollins.net-20050913104627-51f938950a907475
handle inaccessible sibling archives somewhat - note version-0 is still not handled

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Aaron Bentley
 
2
# <aaron.bentley@utoronto.ca>
 
3
#
 
4
#    This program is free software; you can redistribute it and/or modify
 
5
#    it under the terms of the GNU General Public License as published by
 
6
#    the Free Software Foundation; either version 2 of the License, or
 
7
#    (at your option) any later version.
 
8
#
 
9
#    This program is distributed in the hope that it will be useful,
 
10
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
#    GNU General Public License for more details.
 
13
#
 
14
#    You should have received a copy of the GNU General Public License
 
15
#    along with this program; if not, write to the Free Software
 
16
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1
17
import bzrlib
2
18
import os
3
19
import os.path
4
20
import sys
5
21
import tempfile
6
22
import shutil
 
23
from subprocess import Popen, PIPE
7
24
 
8
25
def temp_branch():
9
26
    dirname = tempfile.mkdtemp("temp-branch")
10
 
    return bzrlib.Branch(dirname, init=True)
 
27
    return bzrlib.branch.Branch(dirname, init=True)
11
28
 
12
29
def rm_branch(br):
13
30
    shutil.rmtree(br.base)
15
32
def is_clean(cur_branch):
16
33
    """
17
34
    Return true if no files are modifed or unknown
 
35
    >>> import bzrlib.add
18
36
    >>> br = temp_branch()
19
37
    >>> is_clean(br)
20
 
    True
 
38
    (True, [])
21
39
    >>> fooname = os.path.join(br.base, "foo")
22
40
    >>> file(fooname, "wb").write("bar")
23
41
    >>> is_clean(br)
24
 
    False
25
 
    >>> bzrlib.add.smart_add([fooname])
 
42
    (True, ['foo'])
 
43
    >>> bzrlib.add.smart_add_branch(br, [br.base])
 
44
    1
26
45
    >>> is_clean(br)
27
 
    False
 
46
    (False, [])
28
47
    >>> br.commit("added file")
 
48
    added foo
29
49
    >>> is_clean(br)
30
 
    True
 
50
    (True, [])
31
51
    >>> rm_branch(br)
32
52
    """
 
53
    from bzrlib.diff import compare_trees
33
54
    old_tree = cur_branch.basis_tree()
34
55
    new_tree = cur_branch.working_tree()
 
56
    non_source = []
35
57
    for path, file_class, kind, file_id in new_tree.list_files():
36
 
        if file_class == '?':
37
 
            return False
38
 
    delta = bzrlib.compare_trees(old_tree, new_tree, want_unchanged=False)
 
58
        if file_class in ('?', 'I'):
 
59
            non_source.append(path)
 
60
    delta = compare_trees(old_tree, new_tree, want_unchanged=False)
39
61
    if len(delta.added) > 0 or len(delta.removed) > 0 or \
40
62
        len(delta.modified) > 0:
41
 
        return False
42
 
    return True
 
63
        return False, non_source
 
64
    return True, non_source 
43
65
 
44
66
def set_pull_data(br, location, rev_id):
45
67
    pull_file = file (br.controlfilename("x-pull-data"), "wb")
101
123
    arg_str = " ".join([shell_escape(a) for a in args])
102
124
    return os.system(arg_str)
103
125
 
104
 
def rsync(source, target, ssh=False, exclude_globs=()):
 
126
def rsync(source, target, ssh=False, excludes=()):
105
127
    """
106
128
    >>> real_system = os.system
107
129
    >>> os.system = sys.stdout.write
108
130
    >>> rsync("a", "b")
109
 
    \\r\\s\\y\\n\\c \\-\\a\\v \\-\\-\\d\\e\\l\\e\\t\\e \\a \\b
110
 
    >>> rsync("a", "b", exclude_globs=("*.py",))
111
 
    \\r\\s\\y\\n\\c \\-\\a\\v \\-\\-\\d\\e\\l\\e\\t\\e\
112
 
 \\-\\-\\e\\x\\c\\l\\u\\d\\e \\*\\.\\p\\y \\a \\b
 
131
    ['rsync', '-av', '--delete', 'a', 'b']
 
132
    >>> rsync("a", "b", excludes=("*.py",))
 
133
    ['rsync', '-av', '--delete', '--exclude-from', '-', 'a', 'b']
113
134
    >>> os.system = real_system
114
135
    """
115
136
    cmd = ["rsync", "-av", "--delete"]
116
137
    if ssh:
117
138
        cmd.extend(('-e', 'ssh'))
118
 
    for exclude in exclude_globs:
119
 
        cmd.extend(('--exclude', exclude))
 
139
    if len(excludes) > 0:
 
140
        cmd.extend(('--exclude-from', '-'))
120
141
    cmd.extend((source, target))
121
 
    safe_system(cmd)
122
 
 
123
 
exclusions = ('x-push-data', 'x-pull-data')
124
 
 
125
 
 
126
 
def pull(cur_branch, location=None, overwrite=False):
127
 
    pull_location, pull_revision = get_pull_data(cur_branch)
128
 
    if pull_location is not None:
129
 
        if not overwrite and cur_branch.last_patch() != pull_revision:
130
 
            print "Aborting: This branch has had commits, so pull would lose data."
131
 
            sys.exit(1)
132
 
    if location is not None:
133
 
        pull_location = location
134
 
        if not pull_location.endswith('/'):
135
 
            pull_location+='/'
136
 
 
137
 
    if pull_location is None:
138
 
        print "No pull location saved.  Please specify one on the command line."
139
 
        sys.exit(1)
140
 
 
141
 
    if not is_clean(cur_branch):
142
 
        print "Error: This tree has uncommitted changes or unknown (?) files."
143
 
        sys.exit(1)
144
 
 
145
 
    print "Synchronizing with %s" % pull_location
146
 
    rsync (pull_location, cur_branch.base+'/', exclude_globs=exclusions)
147
 
 
148
 
    set_pull_data(cur_branch, pull_location, cur_branch.last_patch())
 
142
    proc = Popen(cmd, stdin=PIPE)
 
143
    proc.stdin.write('\n'.join(excludes)+'\n')
 
144
    proc.stdin.close()
 
145
    proc.wait()
 
146
    return cmd
 
147
 
 
148
exclusions = ('.bzr/x-push-data', '.bzr/x-pull-data', '.bzr/stat-cache')
149
149
 
150
150
 
151
151
def push(cur_branch, location=None):
159
159
        print "No push location saved.  Please specify one on the command line."
160
160
        sys.exit(1)
161
161
 
162
 
    if not is_clean(cur_branch):
163
 
        print "Error: This tree has uncommitted changes or unknown (?) files."
 
162
    clean, non_source = is_clean(cur_branch)
 
163
    if not clean:
 
164
        print """Error: This tree has uncommitted changes or unknown (?) files.
 
165
Use "bzr status" to list them."""
164
166
        sys.exit(1)
 
167
    non_source.extend(exclusions)
165
168
 
166
169
    print "Pushing to %s" % push_location
167
 
    rsync(cur_branch.base+'/', push_location, ssh=True,
168
 
          exclude_globs=exclusions)
 
170
    rsync(cur_branch.base+'/', push_location, ssh=True, excludes=non_source)
169
171
 
170
172
    set_push_data(cur_branch, push_location)
171
173