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
28
from bzrlib.errors import (BzrCommandError, NotBranchError, NoSuchFile,
29
UnsupportedFormatError, TransportError,
30
NoWorkingTree, PermissionDenied)
29
UnsupportedFormatError, TransportError,
31
31
from bzrlib.bzrdir import BzrDir, BzrDirFormat
40
40
def is_clean(cur_tree):
42
42
Return true if no files are modifed or unknown
44
>>> tree = temp_tree()
47
>>> fooname = os.path.join(tree.basedir, "foo")
48
>>> file(fooname, "wb").write("bar")
51
>>> bzrlib.add.smart_add_tree(tree, [tree.basedir])
55
>>> tree.commit("added file")
60
from bzrlib.diff import compare_trees
44
61
old_tree = cur_tree.basis_tree()
45
62
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)
64
for path, file_class, kind, file_id, entry in new_tree.list_files():
65
if file_class in ('?', 'I'):
66
non_source.append(path)
67
delta = compare_trees(old_tree, new_tree, want_unchanged=False)
55
68
return not delta.has_changed(), non_source
57
70
def set_push_data(tree, location):
58
tree.branch.control_files.put_utf8("x-push-data", "%s\n" % location)
71
push_file = file (tree.branch.control_files.controlfilename("x-push-data"), "wb")
72
push_file.write("%s\n" % location)
60
74
def get_push_data(tree):
65
79
>>> set_push_data(tree, 'http://somewhere')
66
80
>>> get_push_data(tree)
71
location = tree.branch.control_files.get_utf8('x-push-data').read()
84
filename = tree.branch.control_files.controlfilename("x-push-data")
85
if not os.path.exists(filename):
74
return location.rstrip('\n')
87
push_file = file (filename, "rb")
88
(location,) = [f.rstrip('\n') for f in push_file]
77
92
>>> shell_escape('hello')
99
114
def __init__(self, rsync_name):
100
115
Exception.__init__(self, "%s not found." % rsync_name)
102
def rsync(source, target, ssh=False, excludes=(), silent=False,
117
def rsync(source, target, ssh=False, excludes=(), silent=False,
103
118
rsync_name="rsync"):
105
120
>>> new_dir = tempfile.mkdtemp()
176
191
raise RsyncUnknownStatus(proc.returncode)
177
192
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',
194
exclusions = ('.bzr/x-push-data', '.bzr/branch/x-push/data', '.bzr/parent',
180
195
'.bzr/branch/parent', '.bzr/x-pull-data', '.bzr/x-pull',
181
196
'.bzr/pull', '.bzr/stat-cache', '.bzr/x-rsync-data',
182
197
'.bzr/basis-inventory', '.bzr/inventory.backup.weave')
226
241
except RsyncNoFile:
229
def rspush(tree, location=None, overwrite=False, working_tree=True):
244
def push(tree, location=None, overwrite=False, working_tree=True):
230
245
push_location = get_push_data(tree)
231
246
if location is not None:
232
247
if not location.endswith('/'):
234
249
push_location = location
236
251
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)
252
if tree.branch.get_push_location() is None:
253
raise BzrCommandError("No push location known or specified.")
255
raise bzrlib.errors.MustUseDecorated
257
if push_location.find('://') != -1:
258
raise bzrlib.errors.MustUseDecorated
260
if push_location.find(':') == -1:
261
raise bzrlib.errors.MustUseDecorated
249
264
clean, non_source = is_clean(tree)
275
290
" specified location. Please ensure that"
276
291
' "%s" is of the form "machine:/path".' % push_location)
277
292
print "Pushing to %s" % push_location
278
rsync(tree.basedir+'/', push_location, ssh=usessh,
293
rsync(tree.basedir+'/', push_location, ssh=True,
279
294
excludes=final_exclusions)
281
296
set_push_data(tree, push_location)
291
306
def apache_ls(t):
292
307
"""Screen-scrape Apache listings"""
293
apache_dir = '<img border="0" src="/icons/folder.gif" alt="[dir]">'\
308
apache_dir = '<IMG border="0" src="/icons/folder.gif" ALT="[DIR]">'\
295
310
lines = t.get('.')
296
expr = re.compile('<a[^>]*href="([^>]*)"[^>]*>', flags=re.I)
297
311
for line in lines:
298
match = expr.search(line)
302
if url.startswith('http://') or url.startswith('/') or '../' in url:
306
yield url.rstrip('/')
312
if line.startswith(apache_dir):
313
url = line[len(apache_dir):].split('"')[0]
314
yield url.rstrip('/')
309
317
def iter_branches(t, lister=None):
339
346
bzrdir = bzrdir_from_transport(t)
341
except (NotBranchError, UnsupportedFormatError, TransportError,
348
except (NotBranchError, UnsupportedFormatError, TransportError):
345
351
for directory in lister(t):
346
352
if directory == ".bzr":
349
subt = t.clone(directory)
350
except UnicodeDecodeError:
352
for bzrdir in iter_bzrdirs(subt, lister):
354
subt = t.clone(directory)
355
for bzrdir in iter_bzrdirs(subt):
354
except (NoSuchFile, PermissionDenied, TransportError):
359
except TransportError, e:
358
363
def bzrdir_from_transport(t):
359
364
"""Open a bzrdir from a transport (not a location)"""
360
365
format = BzrDirFormat.find_format(t)