/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(), """
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
19
import codecs
20
import cStringIO
21
from fnmatch import fnmatch
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
22
import os
23
import re
24
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
25
from bzrlib import log as logcmd
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
26
from bzrlib import bzrdir
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
27
from bzrlib.workingtree import WorkingTree
28
from bzrlib.revisionspec import RevisionSpec, RevisionSpec_revid
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
29
from bzrlib import (
30
    errors,
31
    lazy_regex,
0.40.47 by Parth Malwankar
fixes bug #531336. binary files are now skipped.
32
    osutils,
33
    textfile,
34
    trace,
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
35
    )
36
""")
37
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
38
_terminal_encoding = osutils.get_terminal_encoding()
39
_user_encoding = osutils.get_user_encoding()
40
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
41
def compile_pattern(pattern, flags=0):
42
    patternc = None
43
    try:
44
        # use python's re.compile as we need to catch re.error in case of bad pattern
45
        lazy_regex.reset_compile()
46
        patternc = re.compile(pattern, flags)
47
    except re.error, e:
48
        raise errors.BzrError("Invalid pattern: '%s'" % pattern)
49
    return patternc
50
0.40.86 by Parth Malwankar
the check for implicit fixed_string now allows for spaces.
51
def is_fixed_string(s):
52
    if re.match("^([A-Za-z0-9]|\s)*$", s):
53
        return True
54
    return False
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
55
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
56
def versioned_grep(revision, pattern, compiled_pattern, path_list, recursive,
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
57
        line_number, from_root, eol_marker, print_revno, levels,
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
58
        include, exclude, verbose, fixed_string, ignore_case, outf):
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
59
60
    wt, relpath = WorkingTree.open_containing('.')
61
0.40.78 by Parth Malwankar
added comment.
62
    # We do an optimization below. For grepping a specific revison
63
    # We don't need to call _graph_view_revisions which is slow.
64
    # We create the start_rev_tuple for only that specific revision.
65
    # _graph_view_revisions is used only for revision range.
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
66
    start_rev = revision[0]
0.40.76 by Parth Malwankar
optimization for single revision.
67
    start_revid = start_rev.as_revision_id(wt.branch)
68
    srevno_tuple = wt.branch.revision_id_to_dotted_revno(start_revid)
69
    start_revno = '.'.join(map(str, srevno_tuple))
70
    start_rev_tuple = (start_revid, start_revno, 0)
71
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
72
    if len(revision) == 2:
73
        end_rev = revision[1]
0.40.76 by Parth Malwankar
optimization for single revision.
74
        end_revid   = end_rev.as_revision_id(wt.branch)
75
        given_revs = logcmd._graph_view_revisions(wt.branch, start_revid, end_revid)
76
    else:
77
        given_revs = [start_rev_tuple]
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
78
79
    for revid, revno, merge_depth in given_revs:
80
        if levels == 1 and merge_depth != 0:
81
            # with level=1 show only top level
82
            continue
83
84
        wt.lock_read()
85
        rev = RevisionSpec_revid.from_string("revid:"+revid)
86
        try:
87
            for path in path_list:
88
                tree = rev.as_tree(wt.branch)
89
                path_for_id = osutils.pathjoin(relpath, path)
90
                id = tree.path2id(path_for_id)
91
                if not id:
0.41.22 by Parth Malwankar
added basic --exclude/include tests
92
                    trace.warning("Skipped unknown file '%s'." % path)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
93
                    continue
94
95
                if osutils.isdir(path):
96
                    path_prefix = path
97
                    dir_grep(tree, path, relpath, recursive, line_number,
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
98
                        pattern, compiled_pattern, from_root, eol_marker,
99
                        revno, print_revno, include, exclude, verbose,
100
                        fixed_string, ignore_case, outf, path_prefix)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
101
                else:
0.40.69 by Parth Malwankar
reduced lock/unlock
102
                    versioned_file_grep(tree, id, '.', path,
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
103
                        pattern, compiled_pattern, eol_marker, line_number,
104
                        revno, print_revno, include, exclude, verbose,
105
                        fixed_string, ignore_case, outf)
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
106
        finally:
107
            wt.unlock()
108
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
109
def workingtree_grep(pattern, compiled_pattern, path_list, recursive,
110
        line_number, from_root, eol_marker, include, exclude, verbose,
111
        fixed_string, ignore_case, outf):
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
112
    revno = print_revno = None # for working tree set revno to None
0.40.69 by Parth Malwankar
reduced lock/unlock
113
114
    tree, branch, relpath = \
115
        bzrdir.BzrDir.open_containing_tree_or_branch('.')
116
    tree.lock_read()
117
    try:
118
        for path in path_list:
119
            if osutils.isdir(path):
120
                path_prefix = path
121
                dir_grep(tree, path, relpath, recursive, line_number,
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
122
                    pattern, compiled_pattern, from_root, eol_marker, revno,
123
                    print_revno, include, exclude, verbose, fixed_string,
124
                    ignore_case, outf, path_prefix)
0.40.69 by Parth Malwankar
reduced lock/unlock
125
            else:
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
126
                _file_grep(open(path).read(), '.', path, pattern,
127
                    compiled_pattern, eol_marker, line_number, revno,
128
                    print_revno, include, exclude, verbose,
129
                    fixed_string, ignore_case, outf)
0.40.69 by Parth Malwankar
reduced lock/unlock
130
    finally:
131
        tree.unlock()
0.41.11 by Parth Malwankar
moved top level grep code to versioned_grep.
132
0.40.74 by Parth Malwankar
optimization. --include/exclude are checked before reading the file.
133
def _skip_file(include, exclude, path):
134
    if include and not _path_in_glob_list(path, include):
135
        return True
136
    if exclude and _path_in_glob_list(path, exclude):
137
        return True
138
    return False
139
140
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
141
def dir_grep(tree, path, relpath, recursive, line_number, pattern,
142
        compiled_pattern, from_root, eol_marker, revno, print_revno,
143
        include, exclude, verbose, fixed_string, ignore_case, outf, path_prefix):
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
144
    # setup relpath to open files relative to cwd
145
    rpath = relpath
146
    if relpath:
147
        rpath = osutils.pathjoin('..',relpath)
148
149
    from_dir = osutils.pathjoin(relpath, path)
150
    if from_root:
151
        # start searching recursively from root
152
        from_dir=None
153
        recursive=True
154
0.40.85 by Parth Malwankar
optimized versioned grep to use iter_files_bytes.
155
    to_grep = []
0.40.69 by Parth Malwankar
reduced lock/unlock
156
    for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
157
        from_dir=from_dir, recursive=recursive):
158
0.40.74 by Parth Malwankar
optimization. --include/exclude are checked before reading the file.
159
        if _skip_file(include, exclude, fp):
160
            continue
161
0.40.69 by Parth Malwankar
reduced lock/unlock
162
        if fc == 'V' and fkind == 'file':
163
            if revno != None:
0.40.85 by Parth Malwankar
optimized versioned grep to use iter_files_bytes.
164
                to_grep.append((fid, fp))
0.40.69 by Parth Malwankar
reduced lock/unlock
165
            else:
166
                # we are grepping working tree.
167
                if from_dir == None:
168
                    from_dir = '.'
169
170
                path_for_file = osutils.pathjoin(tree.basedir, from_dir, fp)
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
171
                file_text = codecs.open(path_for_file, 'r').read()
172
                _file_grep(file_text, rpath, fp,
173
                    pattern, compiled_pattern, eol_marker, line_number, revno,
174
                    print_revno, include, exclude, verbose, fixed_string,
175
                    ignore_case, outf, path_prefix)
0.40.43 by Parth Malwankar
moved cmd_grep._grep_dir to grep.dir_grep
176
0.40.85 by Parth Malwankar
optimized versioned grep to use iter_files_bytes.
177
    if revno != None: # grep versioned files
178
        for path, chunks in tree.iter_files_bytes(to_grep):
179
            path = _make_display_path(relpath, path)
180
            _file_grep(chunks[0], rpath, path, pattern, compiled_pattern,
181
                eol_marker, line_number, revno, print_revno, include,
182
                exclude, verbose, fixed_string, ignore_case, outf,
183
                path_prefix)
0.40.43 by Parth Malwankar
moved cmd_grep._grep_dir to grep.dir_grep
184
0.41.8 by Parth Malwankar
code cleanup.
185
def _make_display_path(relpath, path):
186
    """Return path string relative to user cwd.
0.40.42 by Parth Malwankar
fix to make grep paths relative to cwd
187
0.41.8 by Parth Malwankar
code cleanup.
188
    Take tree's 'relpath' and user supplied 'path', and return path
189
    that can be displayed to the user.
190
    """
0.40.15 by Parth Malwankar
some fixes and test updates
191
    if relpath:
0.40.52 by Parth Malwankar
code cleanup and documentation
192
        # update path so to display it w.r.t cwd
193
        # handle windows slash separator
0.40.20 by Parth Malwankar
used path functions from bzrlib.osutils
194
        path = osutils.normpath(osutils.pathjoin(relpath, path))
0.40.22 by Parth Malwankar
fixed display path formatting on windows
195
        path = path.replace('\\', '/')
196
        path = path.replace(relpath + '/', '', 1)
0.41.8 by Parth Malwankar
code cleanup.
197
    return path
198
199
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
200
def versioned_file_grep(tree, id, relpath, path, pattern, patternc,
201
        eol_marker, line_number, revno, print_revno, include, exclude,
202
        verbose, fixed_string, ignore_case, outf, path_prefix = None):
0.41.10 by Parth Malwankar
code cleanup. added comments. path adjustment is now done
203
    """Create a file object for the specified id and pass it on to _file_grep.
204
    """
205
206
    path = _make_display_path(relpath, path)
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
207
    file_text = tree.get_file_text(id)
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
208
    _file_grep(file_text, relpath, path, pattern, patternc, eol_marker,
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
209
        line_number, revno, print_revno, include, exclude, verbose,
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
210
        fixed_string, ignore_case, outf, path_prefix)
0.41.21 by Parth Malwankar
include/exclude working now. tests not added.
211
212
def _path_in_glob_list(path, glob_list):
213
    present = False
214
    for glob in glob_list:
215
        if fnmatch(path, glob):
216
            present = True
217
            break
218
    return present
0.41.12 by Parth Malwankar
initial support for working tree grep (no test cases yet!)
219
0.40.70 by Parth Malwankar
lines are decoded correctly before printing.
220
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
221
def _file_grep(file_text, relpath, path, pattern, patternc, eol_marker,
222
        line_number, revno, print_revno, include, exclude, verbose,
223
        fixed_string, ignore_case, outf, path_prefix=None):
224
225
    pattern = pattern.encode(_user_encoding, 'replace')
226
    if fixed_string and ignore_case:
227
        pattern = pattern.lower()
228
0.41.9 by Parth Malwankar
refactored code towards support for working tree grep.
229
    # test and skip binary files
0.40.62 by Parth Malwankar
performance optimization
230
    if '\x00' in file_text[:1024]:
0.40.60 by Parth Malwankar
'binary file skipped' warning is only shown with --verbose flag
231
        if verbose:
232
            trace.warning("Binary file '%s' skipped." % path)
0.41.9 by Parth Malwankar
refactored code towards support for working tree grep.
233
        return
234
0.40.52 by Parth Malwankar
code cleanup and documentation
235
    if path_prefix and path_prefix != '.':
236
        # user has passed a dir arg, show that as result prefix
237
        path = osutils.pathjoin(path_prefix, path)
238
0.40.79 by Parth Malwankar
fixed unicode handling.
239
    path = path.encode(_terminal_encoding, 'replace')
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
240
0.40.64 by Parth Malwankar
cosmetic: improved comment
241
    # for better performance we moved formatting conditionals out
242
    # of the core loop. hence, the core loop is somewhat duplicated
243
    # for various combinations of formatting options.
244
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
245
    if print_revno and line_number:
246
0.40.79 by Parth Malwankar
fixed unicode handling.
247
        pfmt = "~%s:%d:%s".encode(_terminal_encoding)
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
248
        if fixed_string:
249
            for index, line in enumerate(file_text.splitlines()):
250
                if ignore_case:
251
                    line = line.lower()
252
                if pattern in line:
253
                    line = line.decode(_terminal_encoding, 'replace')
254
                    outf.write(path + (pfmt % (revno, index+1, line)) + eol_marker)
255
        else:
256
            for index, line in enumerate(file_text.splitlines()):
257
                if patternc.search(line):
258
                    line = line.decode(_terminal_encoding, 'replace')
259
                    outf.write(path + (pfmt % (revno, index+1, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
260
261
    elif print_revno and not line_number:
262
0.40.82 by Parth Malwankar
chenged encoding_type to 'replace' to handle unicode better
263
        pfmt = "~%s:%s".encode(_terminal_encoding, 'replace')
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
264
        if fixed_string:
265
            for line in file_text.splitlines():
266
                if ignore_case:
267
                    line = line.lower()
268
                if pattern in line:
269
                    line = line.decode(_terminal_encoding, 'replace')
270
                    outf.write(path + (pfmt % (revno, line)) + eol_marker)
271
        else:
272
            for line in file_text.splitlines():
273
                if patternc.search(line):
274
                    line = line.decode(_terminal_encoding, 'replace')
275
                    outf.write(path + (pfmt % (revno, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
276
277
    elif not print_revno and line_number:
278
0.40.79 by Parth Malwankar
fixed unicode handling.
279
        pfmt = ":%d:%s".encode(_terminal_encoding)
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
280
        if fixed_string:
281
            for index, line in enumerate(file_text.splitlines()):
282
                if ignore_case:
283
                    line = line.lower()
284
                if pattern in line:
285
                    line = line.decode(_terminal_encoding, 'replace')
286
                    outf.write(path + (pfmt % (index+1, line)) + eol_marker)
287
        else:
288
            for index, line in enumerate(file_text.splitlines()):
289
                if patternc.search(line):
290
                    line = line.decode(_terminal_encoding, 'replace')
291
                    outf.write(path + (pfmt % (index+1, line)) + eol_marker)
0.40.63 by Parth Malwankar
performance: moved conditionals out of core loop.
292
293
    else:
0.40.64 by Parth Malwankar
cosmetic: improved comment
294
0.40.79 by Parth Malwankar
fixed unicode handling.
295
        pfmt = ":%s".encode(_terminal_encoding)
0.40.83 by Parth Malwankar
added support for -F/--fixed-string.
296
        if fixed_string:
297
            for line in file_text.splitlines():
298
                if ignore_case:
299
                    line = line.lower()
300
                if pattern in line:
301
                    line = line.decode(_terminal_encoding, 'replace')
302
                    outf.write(path + (pfmt % (line,)) + eol_marker)
303
        else:
304
            for line in file_text.splitlines():
305
                if patternc.search(line):
306
                    line = line.decode(_terminal_encoding, 'replace')
307
                    outf.write(path + (pfmt % (line,)) + eol_marker)
0.40.9 by Parth Malwankar
factored out grep related code to grep.py
308