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