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.branch.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.branch.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')
99
112
def __init__(self, rsync_name):
100
113
Exception.__init__(self, "%s not found." % rsync_name)
102
def rsync(source, target, ssh=False, excludes=(), silent=False,
115
def rsync(source, target, ssh=False, excludes=(), silent=False,
103
116
rsync_name="rsync"):
105
118
>>> new_dir = tempfile.mkdtemp()
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',
192
exclusions = ('.bzr/x-push-data', '.bzr/branch/x-push/data', '.bzr/parent',
180
193
'.bzr/branch/parent', '.bzr/x-pull-data', '.bzr/x-pull',
181
194
'.bzr/pull', '.bzr/stat-cache', '.bzr/x-rsync-data',
182
195
'.bzr/basis-inventory', '.bzr/inventory.backup.weave')
226
239
except RsyncNoFile:
229
def rspush(tree, location=None, overwrite=False, working_tree=True):
242
def push(tree, location=None, overwrite=False, working_tree=True):
230
243
push_location = get_push_data(tree)
231
244
if location is not None:
232
245
if not location.endswith('/'):
234
247
push_location = location
236
249
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)
250
if tree.branch.get_push_location() is None:
251
raise BzrCommandError("No push location known or specified.")
253
raise bzrlib.errors.MustUseDecorated
255
if push_location.find('://') != -1:
256
raise bzrlib.errors.MustUseDecorated
258
if push_location.find(':') == -1:
259
raise bzrlib.errors.MustUseDecorated
249
262
clean, non_source = is_clean(tree)
275
288
" specified location. Please ensure that"
276
289
' "%s" is of the form "machine:/path".' % push_location)
277
290
print "Pushing to %s" % push_location
278
rsync(tree.basedir+'/', push_location, ssh=usessh,
291
rsync(tree.basedir+'/', push_location, ssh=True,
279
292
excludes=final_exclusions)
281
294
set_push_data(tree, push_location)
288
301
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
306
result = doctest.testmod()