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