/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/clean_tree.py

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2005 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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
16
16
 
17
 
from __future__ import absolute_import
18
17
 
19
 
import errno
20
18
import os
21
19
import shutil
22
20
 
23
 
from . import (
24
 
    controldir,
25
 
    errors,
26
 
    ui,
27
 
    )
28
 
from .osutils import isdir
29
 
from .trace import note
30
 
from .workingtree import WorkingTree
31
 
from .i18n import gettext
 
21
from bzrlib.osutils import isdir
 
22
from bzrlib.trace import note
 
23
from bzrlib.workingtree import WorkingTree
 
24
 
32
25
 
33
26
def is_detritus(subp):
34
27
    """Return True if the supplied path is detritus, False otherwise"""
54
47
               dry_run=False, no_prompt=False):
55
48
    """Remove files in the specified classes from the tree"""
56
49
    tree = WorkingTree.open_containing(directory)[0]
57
 
    with tree.lock_read():
 
50
    tree.lock_read()
 
51
    try:
58
52
        deletables = list(iter_deletables(tree, unknown=unknown,
59
53
            ignored=ignored, detritus=detritus))
60
 
        deletables = _filter_out_nested_controldirs(deletables)
61
54
        if len(deletables) == 0:
62
 
            note(gettext('Nothing to delete.'))
 
55
            note('Nothing to delete.')
63
56
            return 0
64
57
        if not no_prompt:
65
58
            for path, subp in deletables:
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'))
 
59
                print subp
 
60
            val = raw_input('Are you sure you wish to delete these [y/N]?')
 
61
            if val.lower() not in ('y', 'yes'):
 
62
                print 'Canceled'
70
63
                return 0
71
64
        delete_items(deletables, dry_run=dry_run)
72
 
 
73
 
 
74
 
def _filter_out_nested_controldirs(deletables):
75
 
    result = []
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
79
 
        # control dir.
80
 
        # That said we won't detect the branch in the subdir of non-branch
81
 
        # directory and therefore delete it. (worth to FIXME?)
82
 
        if isdir(path):
83
 
            try:
84
 
                controldir.ControlDir.open(path)
85
 
            except errors.NotBranchError:
86
 
                result.append((path, subp))
87
 
            else:
88
 
                # TODO may be we need to notify user about skipped directories?
89
 
                pass
90
 
        else:
91
 
            result.append((path, subp))
92
 
    return result
 
65
    finally:
 
66
        tree.unlock()
93
67
 
94
68
 
95
69
def delete_items(deletables, dry_run=False):
96
70
    """Delete files in the deletables iterable"""
97
 
    def onerror(function, path, excinfo):
98
 
        """Show warning for errors seen by rmtree.
99
 
        """
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:
103
 
            raise
104
 
        ui.ui_factory.show_warning(gettext('unable to remove %s') % path)
105
71
    has_deleted = False
106
72
    for path, subp in deletables:
107
73
        if not has_deleted:
108
 
            note(gettext("deleting paths:"))
 
74
            note("deleting paths:")
109
75
            has_deleted = True
 
76
        note('  ' + subp)
110
77
        if not dry_run:
111
78
            if isdir(path):
112
 
                shutil.rmtree(path, onerror=onerror)
 
79
                shutil.rmtree(path)
113
80
            else:
114
 
                try:
115
 
                    os.unlink(path)
116
 
                    note('  ' + subp)
117
 
                except OSError as e:
118
 
                    # We handle only permission error here
119
 
                    if e.errno != errno.EACCES:
120
 
                        raise e
121
 
                    ui.ui_factory.show_warning(gettext(
122
 
                        'unable to remove "{0}": {1}.').format(
123
 
                                                    path, e.strerror))
124
 
        else:
125
 
            note('  ' + subp)
 
81
                os.unlink(path)
126
82
    if not has_deleted:
127
 
        note(gettext("No files deleted."))
 
83
        note("No files deleted.")