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