/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: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

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 import bzrdir, errors
 
22
from bzrlib.osutils import isdir
 
23
from bzrlib.trace import note
 
24
from bzrlib.workingtree import WorkingTree
32
25
 
33
26
 
34
27
def is_detritus(subp):
55
48
               dry_run=False, no_prompt=False):
56
49
    """Remove files in the specified classes from the tree"""
57
50
    tree = WorkingTree.open_containing(directory)[0]
58
 
    with tree.lock_read():
 
51
    tree.lock_read()
 
52
    try:
59
53
        deletables = list(iter_deletables(tree, unknown=unknown,
60
 
                                          ignored=ignored, detritus=detritus))
61
 
        deletables = _filter_out_nested_controldirs(deletables)
 
54
            ignored=ignored, detritus=detritus))
 
55
        deletables = _filter_out_nested_bzrdirs(deletables)
62
56
        if len(deletables) == 0:
63
 
            note(gettext('Nothing to delete.'))
 
57
            note('Nothing to delete.')
64
58
            return 0
65
59
        if not no_prompt:
66
60
            for path, subp in deletables:
67
 
                ui.ui_factory.note(subp)
68
 
            prompt = gettext('Are you sure you wish to delete these')
69
 
            if not ui.ui_factory.get_boolean(prompt):
70
 
                ui.ui_factory.note(gettext('Canceled'))
 
61
                # FIXME using print is very bad idea
 
62
                # clean_tree should accept to_file argument to write the output
 
63
                print subp
 
64
            val = raw_input('Are you sure you wish to delete these [y/N]?')
 
65
            if val.lower() not in ('y', 'yes'):
 
66
                print 'Canceled'
71
67
                return 0
72
68
        delete_items(deletables, dry_run=dry_run)
73
 
 
74
 
 
75
 
def _filter_out_nested_controldirs(deletables):
 
69
    finally:
 
70
        tree.unlock()
 
71
 
 
72
 
 
73
def _filter_out_nested_bzrdirs(deletables):
76
74
    result = []
77
75
    for path, subp in deletables:
78
76
        # bzr won't recurse into unknowns/ignored directories by default
79
77
        # so we don't pay a penalty for checking subdirs of path for nested
80
 
        # control dir.
 
78
        # bzrdir.
81
79
        # That said we won't detect the branch in the subdir of non-branch
82
80
        # directory and therefore delete it. (worth to FIXME?)
83
81
        if isdir(path):
84
82
            try:
85
 
                controldir.ControlDir.open(path)
 
83
                bzrdir.BzrDir.open(path)
86
84
            except errors.NotBranchError:
87
 
                result.append((path, subp))
 
85
                result.append((path,subp))
88
86
            else:
89
87
                # TODO may be we need to notify user about skipped directories?
90
88
                pass
91
89
        else:
92
 
            result.append((path, subp))
 
90
            result.append((path,subp))
93
91
    return result
94
92
 
95
93
 
96
94
def delete_items(deletables, dry_run=False):
97
95
    """Delete files in the deletables iterable"""
98
 
    def onerror(function, path, excinfo):
99
 
        """Show warning for errors seen by rmtree.
100
 
        """
101
 
        # Handle only permission error while removing files.
102
 
        # Other errors are re-raised.
103
 
        if function is not os.remove or excinfo[1].errno != errno.EACCES:
104
 
            raise
105
 
        ui.ui_factory.show_warning(gettext('unable to remove %s') % path)
106
96
    has_deleted = False
107
97
    for path, subp in deletables:
108
98
        if not has_deleted:
109
 
            note(gettext("deleting paths:"))
 
99
            note("deleting paths:")
110
100
            has_deleted = True
 
101
        note('  ' + subp)
111
102
        if not dry_run:
112
103
            if isdir(path):
113
 
                shutil.rmtree(path, onerror=onerror)
 
104
                shutil.rmtree(path)
114
105
            else:
115
 
                try:
116
 
                    os.unlink(path)
117
 
                    note('  ' + subp)
118
 
                except OSError as e:
119
 
                    # We handle only permission error here
120
 
                    if e.errno != errno.EACCES:
121
 
                        raise e
122
 
                    ui.ui_factory.show_warning(gettext(
123
 
                        'unable to remove "{0}": {1}.').format(
124
 
                        path, e.strerror))
125
 
        else:
126
 
            note('  ' + subp)
 
106
                os.unlink(path)
127
107
    if not has_deleted:
128
 
        note(gettext("No files deleted."))
 
108
        note("No files deleted.")