/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.40.10 by Parth Malwankar
assigned copyright to canonical
1
# Copyright (C) 2010 Canonical Ltd
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
from bzrlib.lazy_import import lazy_import
18
lazy_import(globals(), """
19
import os
20
import re
0.40.47 by Parth Malwankar
fixes bug #531336. binary files are now skipped.
21
import cStringIO
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
22
from fnmatch import fnmatch
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
23
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
24
from bzrlib import log as logcmd
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
25
from bzrlib import bzrdir
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
26
from bzrlib.workingtree import WorkingTree
27
from bzrlib.revisionspec import RevisionSpec, RevisionSpec_revid
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
28
from bzrlib import (
29
    errors,
30
    lazy_regex,
0.40.47 by Parth Malwankar
fixes bug #531336. binary files are now skipped.
31
    osutils,
32
    textfile,
33
    trace,
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
34
    )
35
""")
36
37
def compile_pattern(pattern, flags=0):
38
    patternc = None
39
    try:
40
        # use python's re.compile as we need to catch re.error in case of bad pattern
41
        lazy_regex.reset_compile()
42
        patternc = re.compile(pattern, flags)
43
    except re.error, e:
44
        raise errors.BzrError("Invalid pattern: '%s'" % pattern)
45
    return patternc
46
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
47
48
def versioned_grep(revision, compiled_pattern, path_list, recursive,
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
49
        line_number, from_root, eol_marker, print_revno, levels,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
50
        include, exclude, verbose, outf):
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
51
52
    wt, relpath = WorkingTree.open_containing('.')
53
0.40.78 by Parth Malwankar
added comment.
54
    # We do an optimization below. For grepping a specific revison
55
    # We don't need to call _graph_view_revisions which is slow.
56
    # We create the start_rev_tuple for only that specific revision.
57
    # _graph_view_revisions is used only for revision range.
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
58
    start_rev = revision[0]
0.40.76 by Parth Malwankar
optimization for single revision.
59
    start_revid = start_rev.as_revision_id(wt.branch)
60
    srevno_tuple = wt.branch.revision_id_to_dotted_revno(start_revid)
61
    start_revno = '.'.join(map(str, srevno_tuple))
62
    start_rev_tuple = (start_revid, start_revno, 0)
63
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
64
    if len(revision) == 2:
65
        end_rev = revision[1]
0.40.76 by Parth Malwankar
optimization for single revision.
66
        end_revid   = end_rev.as_revision_id(wt.branch)
67
        given_revs = logcmd._graph_view_revisions(wt.branch, start_revid, end_revid)
68
    else:
69
        given_revs = [start_rev_tuple]
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
70
71
    for revid, revno, merge_depth in given_revs:
72
        if levels == 1 and merge_depth != 0:
73
            # with level=1 show only top level
74
            continue
75
76
        wt.lock_read()
77
        rev = RevisionSpec_revid.from_string("revid:"+revid)
78
        try:
79
            for path in path_list:
80
                tree = rev.as_tree(wt.branch)
81
                path_for_id = osutils.pathjoin(relpath, path)
82
                id = tree.path2id(path_for_id)
83
                if not id:
0.41.22 by Parth Malwankar
added basic --exclude/include tests
84
                    trace.warning("Skipped unknown file '%s'." % path)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
85
                    continue
86
87
                if osutils.isdir(path):
88
                    path_prefix = path
89
                    dir_grep(tree, path, relpath, recursive, line_number,
90
                        compiled_pattern, from_root, eol_marker, revno, print_revno,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
91
                        include, exclude, verbose, outf, path_prefix)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
92
                else:
0.40.69 by Parth Malwankar
reduced lock/unlock
93
                    versioned_file_grep(tree, id, '.', path,
94
                        compiled_pattern, eol_marker, line_number, revno,
95
                        print_revno, include, exclude, verbose, outf)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
96
        finally:
97
            wt.unlock()
98
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
99
def workingtree_grep(compiled_pattern, path_list, recursive,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
100
        line_number, from_root, eol_marker, include, exclude, verbose, outf):
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
101
    revno = print_revno = None # for working tree set revno to None
0.40.69 by Parth Malwankar
reduced lock/unlock
102
103
    tree, branch, relpath = \
104
        bzrdir.BzrDir.open_containing_tree_or_branch('.')
105
    tree.lock_read()
106
    try:
107
        for path in path_list:
108
            if osutils.isdir(path):
109
                path_prefix = path
110
                dir_grep(tree, path, relpath, recursive, line_number,
111
                    compiled_pattern, from_root, eol_marker, revno, print_revno,
112
                    include, exclude, verbose, outf, path_prefix)
113
            else:
114
                _file_grep(open(path).read(), '.', path, compiled_pattern,
115
                    eol_marker, line_number, revno, print_revno, include,
116
                    exclude, verbose, outf)
117
    finally:
118
        tree.unlock()
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
119
0.40.74 by Parth Malwankar
optimization. --include/exclude are checked before reading the file.
120
def _skip_file(include, exclude, path):
121
    if include and not _path_in_glob_list(path, include):
122
        return True
123
    if exclude and _path_in_glob_list(path, exclude):
124
        return True
125
    return False
126
127
0.40.43 by Parth Malwankar
moved cmd_grep._grep_dir to grep.dir_grep
128
def dir_grep(tree, path, relpath, recursive, line_number, compiled_pattern,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
129
        from_root, eol_marker, revno, print_revno, include, exclude, verbose,
130
        outf, path_prefix):
131
    # setup relpath to open files relative to cwd
132
    rpath = relpath
133
    if relpath:
134
        rpath = osutils.pathjoin('..',relpath)
135
136
    from_dir = osutils.pathjoin(relpath, path)
137
    if from_root:
138
        # start searching recursively from root
139
        from_dir=None
140
        recursive=True
141
0.40.69 by Parth Malwankar
reduced lock/unlock
142
    for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
143
        from_dir=from_dir, recursive=recursive):
144
0.40.74 by Parth Malwankar
optimization. --include/exclude are checked before reading the file.
145
        if _skip_file(include, exclude, fp):
146
            continue
147
0.40.69 by Parth Malwankar
reduced lock/unlock
148
        if fc == 'V' and fkind == 'file':
149
            if revno != None:
150
                versioned_file_grep(tree, fid, rpath, fp,
151
                    compiled_pattern, eol_marker, line_number,
152
                    revno, print_revno, include, exclude, verbose,
153
                    outf, path_prefix)
154
            else:
155
                # we are grepping working tree.
156
                if from_dir == None:
157
                    from_dir = '.'
158
159
                path_for_file = osutils.pathjoin(tree.basedir, from_dir, fp)
160
                _file_grep(open(path_for_file).read(), rpath, fp,
161
                    compiled_pattern, eol_marker, line_number, revno,
162
                    print_revno, include, exclude, verbose, outf, path_prefix)
0.40.43 by Parth Malwankar
moved cmd_grep._grep_dir to grep.dir_grep
163
164
0.41.8 by Parth Malwankar
code cleanup.
165
def _make_display_path(relpath, path):
166
    """Return path string relative to user cwd.
0.40.42 by Parth Malwankar
fix to make grep paths relative to cwd
167
0.41.8 by Parth Malwankar
code cleanup.
168
    Take tree's 'relpath' and user supplied 'path', and return path
169
    that can be displayed to the user.
170
    """
0.40.15 by Parth Malwankar
some fixes and test updates
171
    if relpath:
0.40.52 by Parth Malwankar
code cleanup and documentation
172
        # update path so to display it w.r.t cwd
173
        # handle windows slash separator
0.40.20 by Parth Malwankar
used path functions from bzrlib.osutils
174
        path = osutils.normpath(osutils.pathjoin(relpath, path))
0.40.22 by Parth Malwankar
fixed display path formatting on windows
175
        path = path.replace('\\', '/')
176
        path = path.replace(relpath + '/', '', 1)
0.41.8 by Parth Malwankar
code cleanup.
177
    return path
178
179
0.41.9 by Parth Malwankar
refactored code towards support for working tree grep.
180
def versioned_file_grep(tree, id, relpath, path, patternc, eol_marker,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
181
        line_number, revno, print_revno, include, exclude, verbose, outf,
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
182
        path_prefix = None):
0.41.10 by Parth Malwankar
code cleanup. added comments. path adjustment is now done
183
    """Create a file object for the specified id and pass it on to _file_grep.
184
    """
185
186
    path = _make_display_path(relpath, path)
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
187
    file_text = tree.get_file_text(id)
188
    _file_grep(file_text, relpath, path, patternc, eol_marker,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
189
        line_number, revno, print_revno, include, exclude, verbose,
190
        outf, path_prefix)
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
191
192
def _path_in_glob_list(path, glob_list):
193
    present = False
194
    for glob in glob_list:
195
        if fnmatch(path, glob):
196
            present = True
197
            break
198
    return present
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
199
0.40.70 by Parth Malwankar
lines are decoded correctly before printing.
200
0.40.79 by Parth Malwankar
fixed unicode handling.
201
_terminal_encoding = osutils.get_terminal_encoding()
0.40.70 by Parth Malwankar
lines are decoded correctly before printing.
202
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
203
def _file_grep(file_text, relpath, path, patternc, eol_marker, line_number,
204
        revno, print_revno, include, exclude, verbose, outf, path_prefix=None):
0.41.9 by Parth Malwankar
refactored code towards support for working tree grep.
205
    # test and skip binary files
0.40.62 by Parth Malwankar
performance optimization
206
    if '\x00' in file_text[:1024]:
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
207
        if verbose:
208
            trace.warning("Binary file '%s' skipped." % path)
0.41.9 by Parth Malwankar
refactored code towards support for working tree grep.
209
        return
210
0.40.52 by Parth Malwankar
code cleanup and documentation
211
    if path_prefix and path_prefix != '.':
212
        # user has passed a dir arg, show that as result prefix
213
        path = osutils.pathjoin(path_prefix, path)
214
0.40.79 by Parth Malwankar
fixed unicode handling.
215
    path = path.encode(_terminal_encoding, 'replace')
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
216
0.40.64 by Parth Malwankar
cosmetic: improved comment
217
    # for better performance we moved formatting conditionals out
218
    # of the core loop. hence, the core loop is somewhat duplicated
219
    # for various combinations of formatting options.
220
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
221
    if print_revno and line_number:
222
0.40.79 by Parth Malwankar
fixed unicode handling.
223
        pfmt = "~%s:%d:%s".encode(_terminal_encoding)
0.40.80 by Parth Malwankar
replaced split with splitlines
224
        for index, line in enumerate(file_text.splitlines()):
0.40.65 by Parth Malwankar
core loop uses one less variable.
225
            if patternc.search(line):
0.40.79 by Parth Malwankar
fixed unicode handling.
226
                line = line.decode(_terminal_encoding, 'replace')
227
                outf.write(path + (pfmt % (revno, index+1, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
228
229
    elif print_revno and not line_number:
230
0.40.79 by Parth Malwankar
fixed unicode handling.
231
        pfmt = "~%s:%s".encode(_terminal_encoding)
0.40.80 by Parth Malwankar
replaced split with splitlines
232
        for line in file_text.splitlines():
0.40.65 by Parth Malwankar
core loop uses one less variable.
233
            if patternc.search(line):
0.40.79 by Parth Malwankar
fixed unicode handling.
234
                line = line.decode(_terminal_encoding, 'replace')
235
                outf.write(path + (pfmt % (revno, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
236
237
    elif not print_revno and line_number:
238
0.40.79 by Parth Malwankar
fixed unicode handling.
239
        pfmt = ":%d:%s".encode(_terminal_encoding)
0.40.80 by Parth Malwankar
replaced split with splitlines
240
        for index, line in enumerate(file_text.splitlines()):
0.40.65 by Parth Malwankar
core loop uses one less variable.
241
            if patternc.search(line):
0.40.79 by Parth Malwankar
fixed unicode handling.
242
                line = line.decode(_terminal_encoding, 'replace')
243
                outf.write(path + (pfmt % (index+1, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
244
245
    else:
0.40.64 by Parth Malwankar
cosmetic: improved comment
246
0.40.79 by Parth Malwankar
fixed unicode handling.
247
        pfmt = ":%s".encode(_terminal_encoding)
0.40.80 by Parth Malwankar
replaced split with splitlines
248
        for line in file_text.splitlines():
0.40.65 by Parth Malwankar
core loop uses one less variable.
249
            if patternc.search(line):
0.40.79 by Parth Malwankar
fixed unicode handling.
250
                line = line.decode(_terminal_encoding, 'replace')
251
                outf.write(path + (pfmt % (line,)) + eol_marker)
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
252
253