1
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron.bentley@utoronto.ca>
2
# Copyright (C) 2007 John Arbash Meinel
1
# Copyright (C) 2005 Aaron Bentley
2
# <aaron.bentley@utoronto.ca>
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
27
27
import bzrlib.errors
28
from bzrlib.errors import (BzrCommandError, NotBranchError, NoSuchFile,
29
UnsupportedFormatError, TransportError,
30
NoWorkingTree, PermissionDenied)
31
from bzrlib.bzrdir import BzrDir, BzrDirFormat
28
from bzrlib.errors import BzrCommandError
29
from bzrlib.bzrdir import BzrDir
34
32
dirname = tempfile.mkdtemp("temp-branch")
40
38
def is_clean(cur_tree):
42
40
Return true if no files are modifed or unknown
42
>>> tree = temp_tree()
45
>>> fooname = os.path.join(tree.basedir, "foo")
46
>>> file(fooname, "wb").write("bar")
49
>>> bzrlib.add.smart_add_tree(tree, [tree.basedir])
53
>>> tree.commit("added file")
58
from bzrlib.diff import compare_trees
44
59
old_tree = cur_tree.basis_tree()
45
60
new_tree = cur_tree
49
for path, file_class, kind, file_id, entry in new_tree.list_files():
50
if file_class in ('?', 'I'):
51
non_source.append(path)
52
delta = new_tree.changes_from(old_tree, want_unchanged=False)
62
for path, file_class, kind, file_id, entry in new_tree.list_files():
63
if file_class in ('?', 'I'):
64
non_source.append(path)
65
delta = compare_trees(old_tree, new_tree, want_unchanged=False)
55
66
return not delta.has_changed(), non_source
57
68
def set_push_data(tree, location):
58
tree.branch.control_files.put_utf8("x-push-data", "%s\n" % location)
69
push_file = file (tree._control_files.controlfilename("x-push-data"), "wb")
70
push_file.write("%s\n" % location)
60
72
def get_push_data(tree):
65
77
>>> set_push_data(tree, 'http://somewhere')
66
78
>>> get_push_data(tree)
71
location = tree.branch.control_files.get_utf8('x-push-data').read()
82
filename = tree._control_files.controlfilename("x-push-data")
83
if not os.path.exists(filename):
74
return location.rstrip('\n')
85
push_file = file (filename, "rb")
86
(location,) = [f.rstrip('\n') for f in push_file]
77
90
>>> shell_escape('hello')
176
189
raise RsyncUnknownStatus(proc.returncode)
177
190
return [l.split(' ')[-1].rstrip('\n') for l in result.splitlines(True)]
179
exclusions = ('.bzr/x-push-data', '.bzr/branch/x-push/data', '.bzr/parent',
180
'.bzr/branch/parent', '.bzr/x-pull-data', '.bzr/x-pull',
181
'.bzr/pull', '.bzr/stat-cache', '.bzr/x-rsync-data',
182
'.bzr/basis-inventory', '.bzr/inventory.backup.weave')
192
exclusions = ('.bzr/x-push-data', '.bzr/parent', '.bzr/x-pull-data',
193
'.bzr/x-pull', '.bzr/pull', '.bzr/stat-cache',
194
'.bzr/x-rsync-data', '.bzr/basis-inventory',
195
'.bzr/inventory.backup.weave')
185
198
def read_revision_history(fname):
198
211
tempdir = tempfile.mkdtemp('push')
200
213
history_fname = os.path.join(tempdir, 'revision-history')
202
cmd = rsync(location+'.bzr/revision-history', history_fname,
205
cmd = rsync(location+'.bzr/branch/revision-history', history_fname,
214
cmd = rsync(location+'.bzr/revision-history', history_fname,
207
216
history = read_revision_history(history_fname)
209
218
shutil.rmtree(tempdir)
226
235
except RsyncNoFile:
229
def rspush(tree, location=None, overwrite=False, working_tree=True):
238
def push(tree, location=None, overwrite=False, working_tree=True):
230
239
push_location = get_push_data(tree)
231
240
if location is not None:
232
241
if not location.endswith('/'):
234
243
push_location = location
236
245
if push_location is None:
237
raise BzrCommandError("No rspush location known or specified.")
239
if (push_location.find('::') != -1):
244
if (push_location.find('://') != -1 or
245
push_location.find(':') == -1):
246
raise BzrCommandError("Invalid rsync path %r." % push_location)
246
if tree.branch.get_push_location() is None:
247
raise BzrCommandError("No push location known or specified.")
249
raise bzrlib.errors.MustUseDecorated
251
if push_location.find('://') != -1:
252
raise bzrlib.errors.MustUseDecorated
254
if push_location.find(':') == -1:
255
raise bzrlib.errors.MustUseDecorated
257
clean, non_source = is_clean(tree)
259
print """Error: This tree has uncommitted changes or unknown (?) files.
260
Use "bzr status" to list them."""
249
clean, non_source = is_clean(tree)
251
print """Error: This tree has uncommitted changes or unknown (?) files.
252
Use "bzr status" to list them."""
254
263
final_exclusions = non_source[:]
275
284
" specified location. Please ensure that"
276
285
' "%s" is of the form "machine:/path".' % push_location)
277
286
print "Pushing to %s" % push_location
278
rsync(tree.basedir+'/', push_location, ssh=usessh,
287
rsync(tree.basedir+'/', push_location, ssh=True,
279
288
excludes=final_exclusions)
281
290
set_push_data(tree, push_location)
288
297
return new_committer
292
"""Screen-scrape Apache listings"""
293
apache_dir = '<img border="0" src="/icons/folder.gif" alt="[dir]">'\
296
expr = re.compile('<a[^>]*href="([^>]*)"[^>]*>', flags=re.I)
298
match = expr.search(line)
302
if url.startswith('http://') or url.startswith('/') or '../' in url:
306
yield url.rstrip('/')
309
def iter_branches(t, lister=None):
310
"""Iterate through all the branches under a transport"""
311
for bzrdir in iter_bzrdirs(t, lister):
313
branch = bzrdir.open_branch()
314
if branch.bzrdir is bzrdir:
316
except (NotBranchError, UnsupportedFormatError):
320
def iter_branch_tree(t, lister=None):
321
for bzrdir in iter_bzrdirs(t, lister):
323
wt = bzrdir.open_workingtree()
325
except NoWorkingTree, UnsupportedFormatError:
327
branch = bzrdir.open_branch()
328
if branch.bzrdir is bzrdir:
330
except (NotBranchError, UnsupportedFormatError):
334
def iter_bzrdirs(t, lister=None):
337
return t.list_dir('.')
339
bzrdir = bzrdir_from_transport(t)
341
except (NotBranchError, UnsupportedFormatError, TransportError,
345
for directory in lister(t):
346
if directory == ".bzr":
349
subt = t.clone(directory)
350
except UnicodeDecodeError:
352
for bzrdir in iter_bzrdirs(subt, lister):
354
except (NoSuchFile, PermissionDenied, TransportError):
358
def bzrdir_from_transport(t):
359
"""Open a bzrdir from a transport (not a location)"""
360
format = BzrDirFormat.find_format(t)
361
BzrDir._check_supported(format, False)
362
return format.open(t)
367
302
result = doctest.testmod()