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