14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from __future__ import absolute_import
21
from bzrlib.osutils import isdir
22
from bzrlib.trace import note
23
from bzrlib.workingtree import WorkingTree
28
from .osutils import isdir
29
from .trace import note
30
from .workingtree import WorkingTree
31
from .i18n import gettext
26
33
def is_detritus(subp):
27
34
"""Return True if the supplied path is detritus, False otherwise"""
47
54
dry_run=False, no_prompt=False):
48
55
"""Remove files in the specified classes from the tree"""
49
56
tree = WorkingTree.open_containing(directory)[0]
57
with tree.lock_read():
52
58
deletables = list(iter_deletables(tree, unknown=unknown,
53
59
ignored=ignored, detritus=detritus))
60
deletables = _filter_out_nested_controldirs(deletables)
54
61
if len(deletables) == 0:
55
note('Nothing to delete.')
62
note(gettext('Nothing to delete.'))
58
65
for path, subp in deletables:
60
val = raw_input('Are you sure you wish to delete these [y/N]?')
61
if val.lower() not in ('y', 'yes'):
66
ui.ui_factory.note(subp)
67
prompt = gettext('Are you sure you wish to delete these')
68
if not ui.ui_factory.get_boolean(prompt):
69
ui.ui_factory.note(gettext('Canceled'))
64
71
delete_items(deletables, dry_run=dry_run)
74
def _filter_out_nested_controldirs(deletables):
76
for path, subp in deletables:
77
# bzr won't recurse into unknowns/ignored directories by default
78
# so we don't pay a penalty for checking subdirs of path for nested
80
# That said we won't detect the branch in the subdir of non-branch
81
# directory and therefore delete it. (worth to FIXME?)
84
controldir.ControlDir.open(path)
85
except errors.NotBranchError:
86
result.append((path, subp))
88
# TODO may be we need to notify user about skipped directories?
91
result.append((path, subp))
69
95
def delete_items(deletables, dry_run=False):
70
96
"""Delete files in the deletables iterable"""
97
def onerror(function, path, excinfo):
98
"""Show warning for errors seen by rmtree.
100
# Handle only permission error while removing files.
101
# Other errors are re-raised.
102
if function is not os.remove or excinfo[1].errno != errno.EACCES:
104
ui.ui_factory.show_warning(gettext('unable to remove %s') % path)
71
105
has_deleted = False
72
106
for path, subp in deletables:
73
107
if not has_deleted:
74
note("deleting paths:")
108
note(gettext("deleting paths:"))
75
109
has_deleted = True
112
shutil.rmtree(path, onerror=onerror)
118
# We handle only permission error here
119
if e.errno != errno.EACCES:
121
ui.ui_factory.show_warning(gettext(
122
'unable to remove "{0}": {1}.').format(
82
126
if not has_deleted:
83
note("No files deleted.")
127
note(gettext("No files deleted."))