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