/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 breezy/clean_tree.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2009, 2010 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
17
18
 
 
19
import errno
18
20
import os
19
21
import shutil
20
22
 
21
 
from bzrlib import bzrdir, errors
22
 
from bzrlib.osutils import isdir
23
 
from bzrlib.trace import note
24
 
from bzrlib.workingtree import WorkingTree
25
 
 
 
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
26
32
 
27
33
def is_detritus(subp):
28
34
    """Return True if the supplied path is detritus, False otherwise"""
52
58
    try:
53
59
        deletables = list(iter_deletables(tree, unknown=unknown,
54
60
            ignored=ignored, detritus=detritus))
55
 
        deletables = _filter_out_nested_bzrdirs(deletables)
 
61
        deletables = _filter_out_nested_controldirs(deletables)
56
62
        if len(deletables) == 0:
57
 
            note('Nothing to delete.')
 
63
            note(gettext('Nothing to delete.'))
58
64
            return 0
59
65
        if not no_prompt:
60
66
            for path, subp in deletables:
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'
 
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'))
67
71
                return 0
68
72
        delete_items(deletables, dry_run=dry_run)
69
73
    finally:
70
74
        tree.unlock()
71
75
 
72
76
 
73
 
def _filter_out_nested_bzrdirs(deletables):
 
77
def _filter_out_nested_controldirs(deletables):
74
78
    result = []
75
79
    for path, subp in deletables:
76
80
        # bzr won't recurse into unknowns/ignored directories by default
77
81
        # so we don't pay a penalty for checking subdirs of path for nested
78
 
        # bzrdir.
 
82
        # control dir.
79
83
        # That said we won't detect the branch in the subdir of non-branch
80
84
        # directory and therefore delete it. (worth to FIXME?)
81
85
        if isdir(path):
82
86
            try:
83
 
                bzrdir.BzrDir.open(path)
 
87
                controldir.ControlDir.open(path)
84
88
            except errors.NotBranchError:
85
89
                result.append((path,subp))
86
90
            else:
93
97
 
94
98
def delete_items(deletables, dry_run=False):
95
99
    """Delete files in the deletables iterable"""
 
100
    def onerror(function, path, excinfo):
 
101
        """Show warning for errors seen by rmtree.
 
102
        """
 
103
        # Handle only permission error while removing files.
 
104
        # Other errors are re-raised.
 
105
        if function is not os.remove or excinfo[1].errno != errno.EACCES:
 
106
            raise
 
107
        ui.ui_factory.show_warning(gettext('unable to remove %s') % path)
96
108
    has_deleted = False
97
109
    for path, subp in deletables:
98
110
        if not has_deleted:
99
 
            note("deleting paths:")
 
111
            note(gettext("deleting paths:"))
100
112
            has_deleted = True
101
 
        note('  ' + subp)
102
113
        if not dry_run:
103
114
            if isdir(path):
104
 
                shutil.rmtree(path)
 
115
                shutil.rmtree(path, onerror=onerror)
105
116
            else:
106
 
                os.unlink(path)
 
117
                try:
 
118
                    os.unlink(path)
 
119
                    note('  ' + subp)
 
120
                except OSError as e:
 
121
                    # We handle only permission error here
 
122
                    if e.errno != errno.EACCES:
 
123
                        raise e
 
124
                    ui.ui_factory.show_warning(gettext(
 
125
                        'unable to remove "{0}": {1}.').format(
 
126
                                                    path, e.strerror))
 
127
        else:
 
128
            note('  ' + subp)
107
129
    if not has_deleted:
108
 
        note("No files deleted.")
 
130
        note(gettext("No files deleted."))