~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to bzrtools.py

  • Committer: Aaron Bentley
  • Date: 2007-03-09 18:25:10 UTC
  • mto: This revision was merged to the branch mainline in revision 520.
  • Revision ID: abentley@panoramicfeedback.com-20070309182510-fkj1j6t119d1cj5q
Handle broken python tar implementations

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Aaron Bentley
2
 
# <aaron.bentley@utoronto.ca>
 
1
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron.bentley@utoronto.ca>
 
2
# Copyright (C) 2007 John Arbash Meinel
3
3
#
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
25
25
 
26
26
import bzrlib
27
27
import bzrlib.errors
28
 
from bzrlib.errors import BzrCommandError
29
 
from bzrlib.bzrdir import BzrDir
 
28
from bzrlib.errors import (BzrCommandError, NotBranchError, NoSuchFile,
 
29
                           UnsupportedFormatError, TransportError, 
 
30
                           NoWorkingTree, PermissionDenied)
 
31
from bzrlib.bzrdir import BzrDir, BzrDirFormat
30
32
 
31
33
def temp_tree():
32
34
    dirname = tempfile.mkdtemp("temp-branch")
38
40
def is_clean(cur_tree):
39
41
    """
40
42
    Return true if no files are modifed or unknown
41
 
    >>> import bzrlib.add
42
 
    >>> tree = temp_tree()
43
 
    >>> is_clean(tree)
44
 
    (True, [])
45
 
    >>> fooname = os.path.join(tree.basedir, "foo")
46
 
    >>> file(fooname, "wb").write("bar")
47
 
    >>> is_clean(tree)
48
 
    (True, [u'foo'])
49
 
    >>> bzrlib.add.smart_add_tree(tree, [tree.basedir])
50
 
    ([u'foo'], {})
51
 
    >>> is_clean(tree)
52
 
    (False, [])
53
 
    >>> tree.commit("added file")
54
 
    >>> is_clean(tree)
55
 
    (True, [])
56
 
    >>> rm_tree(tree)
57
43
    """
58
 
    from bzrlib.diff import compare_trees
59
44
    old_tree = cur_tree.basis_tree()
60
45
    new_tree = cur_tree
61
46
    non_source = []
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)
 
47
    new_tree.lock_read()
 
48
    try:
 
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)
 
53
    finally:
 
54
        new_tree.unlock()
66
55
    return not delta.has_changed(), non_source
67
56
 
68
57
def set_push_data(tree, location):
69
 
    push_file = file (tree.branch.control_files.controlfilename("x-push-data"), "wb")
70
 
    push_file.write("%s\n" % location)
 
58
    tree.branch.control_files.put_utf8("x-push-data", "%s\n" % location)
71
59
 
72
60
def get_push_data(tree):
73
61
    """
76
64
    True
77
65
    >>> set_push_data(tree, 'http://somewhere')
78
66
    >>> get_push_data(tree)
79
 
    'http://somewhere'
 
67
    u'http://somewhere'
80
68
    >>> rm_tree(tree)
81
69
    """
82
 
    filename = tree.branch.control_files.controlfilename("x-push-data")
83
 
    if not os.path.exists(filename):
 
70
    try:
 
71
        location = tree.branch.control_files.get_utf8('x-push-data').read()
 
72
    except NoSuchFile:
84
73
        return None
85
 
    push_file = file (filename, "rb")
86
 
    (location,) = [f.rstrip('\n') for f in push_file]
87
 
    return location
 
74
    return location.rstrip('\n')
88
75
 
89
76
"""
90
77
>>> shell_escape('hello')
239
226
    except RsyncNoFile:
240
227
        return True
241
228
 
242
 
def push(tree, location=None, overwrite=False, working_tree=True):
 
229
def rspush(tree, location=None, overwrite=False, working_tree=True):
243
230
    push_location = get_push_data(tree)
244
231
    if location is not None:
245
232
        if not location.endswith('/'):
247
234
        push_location = location
248
235
    
249
236
    if push_location is None:
250
 
        if tree.branch.get_push_location() is None:
251
 
            raise BzrCommandError("No push location known or specified.")
252
 
        else:
253
 
            raise bzrlib.errors.MustUseDecorated
254
 
 
255
 
    if push_location.find('://') != -1:
256
 
        raise bzrlib.errors.MustUseDecorated
257
 
 
258
 
    if push_location.find(':') == -1:
259
 
        raise bzrlib.errors.MustUseDecorated
 
237
        raise BzrCommandError("No rspush location known or specified.")
 
238
 
 
239
    if (push_location.find('::') != -1):
 
240
        usessh=False
 
241
    else:
 
242
        usessh=True
 
243
 
 
244
    if (push_location.find('://') != -1 or
 
245
        push_location.find(':') == -1):
 
246
        raise BzrCommandError("Invalid rsync path %r." % push_location)
260
247
 
261
248
    if working_tree:
262
249
        clean, non_source = is_clean(tree)
288
275
                " specified location.  Please ensure that"
289
276
                ' "%s" is of the form "machine:/path".' % push_location)
290
277
    print "Pushing to %s" % push_location
291
 
    rsync(tree.basedir+'/', push_location, ssh=True, 
 
278
    rsync(tree.basedir+'/', push_location, ssh=usessh, 
292
279
          excludes=final_exclusions)
293
280
 
294
281
    set_push_data(tree, push_location)
301
288
    return new_committer
302
289
 
303
290
 
 
291
def apache_ls(t):
 
292
    """Screen-scrape Apache listings"""
 
293
    apache_dir = '<img border="0" src="/icons/folder.gif" alt="[dir]">'\
 
294
        ' <a href="'
 
295
    lines = t.get('.')
 
296
    expr = re.compile('<a[^>]*href="([^>]*)"[^>]*>', flags=re.I)
 
297
    for line in lines:
 
298
        match = expr.search(line)
 
299
        if match is None:
 
300
            continue
 
301
        url = match.group(1)
 
302
        if url.startswith('http://') or url.startswith('/') or '../' in url:
 
303
            continue
 
304
        if '?' in url:
 
305
            continue
 
306
        yield url.rstrip('/')
 
307
 
 
308
 
 
309
def iter_branches(t, lister=None):
 
310
    """Iterate through all the branches under a transport"""
 
311
    for bzrdir in iter_bzrdirs(t, lister):
 
312
        try:
 
313
            branch = bzrdir.open_branch()
 
314
            if branch.bzrdir is bzrdir:
 
315
                yield branch
 
316
        except (NotBranchError, UnsupportedFormatError):
 
317
            pass
 
318
 
 
319
 
 
320
def iter_branch_tree(t, lister=None):
 
321
    for bzrdir in iter_bzrdirs(t, lister):
 
322
        try:
 
323
            wt = bzrdir.open_workingtree()
 
324
            yield wt.branch, wt
 
325
        except NoWorkingTree, UnsupportedFormatError:
 
326
            try:
 
327
                branch = bzrdir.open_branch()
 
328
                if branch.bzrdir is bzrdir:
 
329
                    yield branch, None
 
330
            except (NotBranchError, UnsupportedFormatError):
 
331
                continue
 
332
 
 
333
 
 
334
def iter_bzrdirs(t, lister=None):
 
335
    if lister is None:
 
336
        def lister(t):
 
337
            return t.list_dir('.')
 
338
    try:
 
339
        bzrdir = bzrdir_from_transport(t)
 
340
        yield bzrdir
 
341
    except (NotBranchError, UnsupportedFormatError, TransportError,
 
342
            PermissionDenied):
 
343
        pass
 
344
    try:
 
345
        for directory in lister(t):
 
346
            if directory == ".bzr":
 
347
                continue
 
348
            try:
 
349
                subt = t.clone(directory)
 
350
            except UnicodeDecodeError:
 
351
                continue
 
352
            for bzrdir in iter_bzrdirs(subt, lister):
 
353
                yield bzrdir
 
354
    except (NoSuchFile, PermissionDenied, TransportError):
 
355
        pass
 
356
 
 
357
    
 
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)
 
363
 
 
364
 
304
365
def run_tests():
305
366
    import doctest
306
367
    result = doctest.testmod()