42
39
if has_symlinks() is False:
45
ControlDir.create_standalone_workingtree('branch')
42
BzrDir.create_standalone_workingtree('branch')
46
43
os.symlink(os.path.realpath('no-die-please'), 'branch/die-please')
47
44
os.mkdir('no-die-please')
48
self.assertPathExists('branch/die-please')
45
self.failUnlessExists('branch/die-please')
49
46
os.mkdir('no-die-please/child')
51
48
clean_tree('branch', unknown=True, no_prompt=True)
52
self.assertPathExists('no-die-please')
53
self.assertPathExists('no-die-please/child')
49
self.failUnlessExists('no-die-please')
50
self.failUnlessExists('no-die-please/child')
55
52
def test_iter_deletable(self):
56
53
"""Files are selected for deletion appropriately"""
58
tree = ControlDir.create_standalone_workingtree('branch')
59
transport = tree.controldir.root_transport
60
transport.put_bytes('.bzrignore', b'*~\n*.pyc\n.bzrignore\n')
61
transport.put_bytes('file.BASE', b'contents')
62
with tree.lock_write():
55
tree = BzrDir.create_standalone_workingtree('branch')
56
transport = tree.bzrdir.root_transport
57
transport.put_bytes('.bzrignore', '*~\n*.pyc\n.bzrignore\n')
58
transport.put_bytes('file.BASE', 'contents')
63
61
self.assertEqual(len(list(iter_deletables(tree, unknown=True))), 1)
64
transport.put_bytes('file', b'contents')
65
transport.put_bytes('file~', b'contents')
66
transport.put_bytes('file.pyc', b'contents')
67
dels = sorted([r for a, r in iter_deletables(tree, unknown=True)])
62
transport.put_bytes('file', 'contents')
63
transport.put_bytes('file~', 'contents')
64
transport.put_bytes('file.pyc', 'contents')
65
dels = sorted([r for a,r in iter_deletables(tree, unknown=True)])
68
66
self.assertEqual(['file', 'file.BASE'], dels)
70
dels = [r for a, r in iter_deletables(tree, detritus=True)]
68
dels = [r for a,r in iter_deletables(tree, detritus=True)]
71
69
self.assertEqual(sorted(['file~', 'file.BASE']), dels)
73
dels = [r for a, r in iter_deletables(tree, ignored=True)]
71
dels = [r for a,r in iter_deletables(tree, ignored=True)]
74
72
self.assertEqual(sorted(['file~', 'file.pyc', '.bzrignore']),
77
dels = [r for a, r in iter_deletables(tree, unknown=False)]
75
dels = [r for a,r in iter_deletables(tree, unknown=False)]
78
76
self.assertEqual([], dels)
80
def test_delete_items_warnings(self):
81
"""Ensure delete_items issues warnings on EACCES. (bug #430785)
83
def _dummy_unlink(path):
84
"""unlink() files other than files named '0foo'.
86
if path.endswith('0foo'):
87
# Simulate 'permission denied' error.
88
# This should show up as a warning for the
91
e.errno = errno.EACCES
94
def _dummy_rmtree(path, ignore_errors=False, onerror=None):
95
"""Call user supplied error handler onerror.
97
# Indicate failure in removing 'path' if path is subdir0
98
# We later check to ensure that this is indicated
99
# to the user as a warning. We raise OSError to construct
100
# proper excinfo that needs to be passed to onerror
104
e.errno = errno.EACCES
105
excinfo = sys.exc_info()
107
if 'subdir0' not in path:
108
# onerror should show warning only for os.remove
109
# error. For any other failures the error should
110
# be shown to the user.
111
function = os.listdir
112
onerror(function=function,
113
path=path, excinfo=excinfo)
115
self.overrideAttr(os, 'unlink', _dummy_unlink)
116
self.overrideAttr(shutil, 'rmtree', _dummy_rmtree)
117
ui.ui_factory = tests.TestUIFactory()
118
stderr = ui.ui_factory.stderr
120
ControlDir.create_standalone_workingtree('.')
121
self.build_tree(['0foo', '1bar', '2baz', 'subdir0/'])
122
clean_tree('.', unknown=True, no_prompt=True)
123
self.assertContainsRe(stderr.getvalue(),
124
'bzr: warning: unable to remove.*0foo')
125
self.assertContainsRe(stderr.getvalue(),
126
'bzr: warning: unable to remove.*subdir0')
128
# Ensure that error other than EACCES during os.remove are
129
# not turned into warnings.
130
self.build_tree(['subdir1/'])
131
self.assertRaises(OSError, clean_tree, '.',
132
unknown=True, no_prompt=True)