Merge lp:~jelmer/brz/promote-grep into lp:brz
- promote-grep
- Merge into trunk
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~jelmer/brz/promote-grep |
Merge into: | lp:brz |
Diff against target: |
790 lines (+245/-394) 9 files modified
breezy/builtins.py (+178/-0) breezy/grep.py (+46/-11) breezy/plugins/grep/.bzrignore (+0/-1) breezy/plugins/grep/NEWS (+0/-73) breezy/plugins/grep/__init__.py (+0/-38) breezy/plugins/grep/cmds.py (+0/-254) breezy/tests/__init__.py (+1/-0) breezy/tests/test_grep.py (+17/-17) doc/en/release-notes/brz-3.0.txt (+3/-0) |
To merge this branch: | bzr merge lp:~jelmer/brz/promote-grep |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Packman | Approve | ||
Review via email: mp+359487@code.launchpad.net |
Commit message
Move grep into core.
Description of the change
Move grep into core.
To post a comment you must log in.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/builtins.py' |
2 | --- breezy/builtins.py 2019-01-27 18:48:32 +0000 |
3 | +++ breezy/builtins.py 2019-02-04 01:01:36 +0000 |
4 | @@ -6831,6 +6831,184 @@ |
5 | cmd_reconcile().run(".") |
6 | |
7 | |
8 | +class cmd_grep(Command): |
9 | + """Print lines matching PATTERN for specified files and revisions. |
10 | + |
11 | + This command searches the specified files and revisions for a given |
12 | + pattern. The pattern is specified as a Python regular expressions[1]. |
13 | + |
14 | + If the file name is not specified, the revisions starting with the |
15 | + current directory are searched recursively. If the revision number is |
16 | + not specified, the working copy is searched. To search the last committed |
17 | + revision, use the '-r -1' or '-r last:1' option. |
18 | + |
19 | + Unversioned files are not searched unless explicitly specified on the |
20 | + command line. Unversioned directores are not searched. |
21 | + |
22 | + When searching a pattern, the output is shown in the 'filepath:string' |
23 | + format. If a revision is explicitly searched, the output is shown as |
24 | + 'filepath~N:string', where N is the revision number. |
25 | + |
26 | + --include and --exclude options can be used to search only (or exclude |
27 | + from search) files with base name matches the specified Unix style GLOB |
28 | + pattern. The GLOB pattern an use *, ?, and [...] as wildcards, and \\ |
29 | + to quote wildcard or backslash character literally. Note that the glob |
30 | + pattern is not a regular expression. |
31 | + |
32 | + [1] http://docs.python.org/library/re.html#regular-expression-syntax |
33 | + """ |
34 | + |
35 | + encoding_type = 'replace' |
36 | + takes_args = ['pattern', 'path*'] |
37 | + takes_options = [ |
38 | + 'verbose', |
39 | + 'revision', |
40 | + Option('color', type=text_type, argname='when', |
41 | + help='Show match in color. WHEN is never, always or auto.'), |
42 | + Option('diff', short_name='p', |
43 | + help='Grep for pattern in changeset for each revision.'), |
44 | + ListOption('exclude', type=text_type, argname='glob', short_name='X', |
45 | + help="Skip files whose base name matches GLOB."), |
46 | + ListOption('include', type=text_type, argname='glob', short_name='I', |
47 | + help="Search only files whose base name matches GLOB."), |
48 | + Option('files-with-matches', short_name='l', |
49 | + help='Print only the name of each input file in ' |
50 | + 'which PATTERN is found.'), |
51 | + Option('files-without-match', short_name='L', |
52 | + help='Print only the name of each input file in ' |
53 | + 'which PATTERN is not found.'), |
54 | + Option('fixed-string', short_name='F', |
55 | + help='Interpret PATTERN is a single fixed string (not regex).'), |
56 | + Option('from-root', |
57 | + help='Search for pattern starting from the root of the branch. ' |
58 | + '(implies --recursive)'), |
59 | + Option('ignore-case', short_name='i', |
60 | + help='Ignore case distinctions while matching.'), |
61 | + Option('levels', |
62 | + help='Number of levels to display - 0 for all, 1 for collapsed ' |
63 | + '(1 is default).', |
64 | + argname='N', |
65 | + type=_parse_levels), |
66 | + Option('line-number', short_name='n', |
67 | + help='Show 1-based line number.'), |
68 | + Option('no-recursive', |
69 | + help="Don't recurse into subdirectories. (default is --recursive)"), |
70 | + Option('null', short_name='Z', |
71 | + help='Write an ASCII NUL (\\0) separator ' |
72 | + 'between output lines rather than a newline.'), |
73 | + ] |
74 | + |
75 | + @display_command |
76 | + def run(self, verbose=False, ignore_case=False, no_recursive=False, |
77 | + from_root=False, null=False, levels=None, line_number=False, |
78 | + path_list=None, revision=None, pattern=None, include=None, |
79 | + exclude=None, fixed_string=False, files_with_matches=False, |
80 | + files_without_match=False, color=None, diff=False): |
81 | + from breezy import _termcolor |
82 | + from . import grep |
83 | + import re |
84 | + if path_list is None: |
85 | + path_list = ['.'] |
86 | + else: |
87 | + if from_root: |
88 | + raise errors.BzrCommandError( |
89 | + 'cannot specify both --from-root and PATH.') |
90 | + |
91 | + if files_with_matches and files_without_match: |
92 | + raise errors.BzrCommandError( |
93 | + 'cannot specify both ' |
94 | + '-l/--files-with-matches and -L/--files-without-matches.') |
95 | + |
96 | + global_config = _mod_config.GlobalConfig() |
97 | + |
98 | + if color is None: |
99 | + color = global_config.get_user_option('grep_color') |
100 | + |
101 | + if color is None: |
102 | + color = 'never' |
103 | + |
104 | + if color not in ['always', 'never', 'auto']: |
105 | + raise errors.BzrCommandError('Valid values for --color are ' |
106 | + '"always", "never" or "auto".') |
107 | + |
108 | + if levels is None: |
109 | + levels = 1 |
110 | + |
111 | + print_revno = False |
112 | + if revision is not None or levels == 0: |
113 | + # print revision numbers as we may be showing multiple revisions |
114 | + print_revno = True |
115 | + |
116 | + eol_marker = '\n' |
117 | + if null: |
118 | + eol_marker = '\0' |
119 | + |
120 | + if not ignore_case and grep.is_fixed_string(pattern): |
121 | + # if the pattern isalnum, implicitly use to -F for faster grep |
122 | + fixed_string = True |
123 | + elif ignore_case and fixed_string: |
124 | + # GZ 2010-06-02: Fall back to regexp rather than lowercasing |
125 | + # pattern and text which will cause pain later |
126 | + fixed_string = False |
127 | + pattern = re.escape(pattern) |
128 | + |
129 | + patternc = None |
130 | + re_flags = re.MULTILINE |
131 | + if ignore_case: |
132 | + re_flags |= re.IGNORECASE |
133 | + |
134 | + if not fixed_string: |
135 | + patternc = grep.compile_pattern( |
136 | + pattern.encode(grep._user_encoding), re_flags) |
137 | + |
138 | + if color == 'always': |
139 | + show_color = True |
140 | + elif color == 'never': |
141 | + show_color = False |
142 | + elif color == 'auto': |
143 | + show_color = _termcolor.allow_color() |
144 | + |
145 | + opts = grep.GrepOptions() |
146 | + |
147 | + opts.verbose = verbose |
148 | + opts.ignore_case = ignore_case |
149 | + opts.no_recursive = no_recursive |
150 | + opts.from_root = from_root |
151 | + opts.null = null |
152 | + opts.levels = levels |
153 | + opts.line_number = line_number |
154 | + opts.path_list = path_list |
155 | + opts.revision = revision |
156 | + opts.pattern = pattern |
157 | + opts.include = include |
158 | + opts.exclude = exclude |
159 | + opts.fixed_string = fixed_string |
160 | + opts.files_with_matches = files_with_matches |
161 | + opts.files_without_match = files_without_match |
162 | + opts.color = color |
163 | + opts.diff = False |
164 | + |
165 | + opts.eol_marker = eol_marker |
166 | + opts.print_revno = print_revno |
167 | + opts.patternc = patternc |
168 | + opts.recursive = not no_recursive |
169 | + opts.fixed_string = fixed_string |
170 | + opts.outf = self.outf |
171 | + opts.show_color = show_color |
172 | + |
173 | + if diff: |
174 | + # options not used: |
175 | + # files_with_matches, files_without_match |
176 | + # levels(?), line_number, from_root |
177 | + # include, exclude |
178 | + # These are silently ignored. |
179 | + grep.grep_diff(opts) |
180 | + elif revision is None: |
181 | + grep.workingtree_grep(opts) |
182 | + else: |
183 | + grep.versioned_grep(opts) |
184 | + |
185 | + |
186 | def _register_lazy_builtins(): |
187 | # register lazy builtins from other modules; called at startup and should |
188 | # be only called once. |
189 | |
190 | === renamed file 'breezy/plugins/grep/grep.py' => 'breezy/grep.py' |
191 | --- breezy/plugins/grep/grep.py 2018-11-21 03:20:30 +0000 |
192 | +++ breezy/grep.py 2019-02-04 01:01:36 +0000 |
193 | @@ -1,5 +1,5 @@ |
194 | # Copyright (C) 2010 Canonical Ltd |
195 | -# |
196 | + |
197 | # This program is free software; you can redistribute it and/or modify |
198 | # it under the terms of the GNU General Public License as published by |
199 | # the Free Software Foundation; either version 2 of the License, or |
200 | @@ -12,36 +12,35 @@ |
201 | # |
202 | # You should have received a copy of the GNU General Public License |
203 | # along with this program; if not, write to the Free Software |
204 | -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
205 | +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
206 | |
207 | from __future__ import absolute_import |
208 | |
209 | import re |
210 | |
211 | -from ...lazy_import import lazy_import |
212 | +from .lazy_import import lazy_import |
213 | lazy_import(globals(), """ |
214 | from fnmatch import fnmatch |
215 | |
216 | from breezy._termcolor import color_string, FG |
217 | |
218 | from breezy import ( |
219 | + diff, |
220 | + ) |
221 | +""") |
222 | +from . import ( |
223 | controldir, |
224 | - diff, |
225 | errors, |
226 | - lazy_regex, |
227 | + osutils, |
228 | revision as _mod_revision, |
229 | - ) |
230 | -""") |
231 | -from breezy import ( |
232 | - osutils, |
233 | trace, |
234 | ) |
235 | -from breezy.revisionspec import ( |
236 | +from .revisionspec import ( |
237 | RevisionSpec, |
238 | RevisionSpec_revid, |
239 | RevisionSpec_revno, |
240 | ) |
241 | -from breezy.sixish import ( |
242 | +from .sixish import ( |
243 | BytesIO, |
244 | ) |
245 | |
246 | @@ -52,6 +51,42 @@ |
247 | """Raised when a revision is not on left-hand history.""" |
248 | |
249 | |
250 | +class GrepOptions(object): |
251 | + """Container to pass around grep options. |
252 | + |
253 | + This class is used as a container to pass around user option and |
254 | + some other params (like outf) to processing functions. This makes |
255 | + it easier to add more options as grep evolves. |
256 | + """ |
257 | + verbose = False |
258 | + ignore_case = False |
259 | + no_recursive = False |
260 | + from_root = False |
261 | + null = False |
262 | + levels = None |
263 | + line_number = False |
264 | + path_list = None |
265 | + revision = None |
266 | + pattern = None |
267 | + include = None |
268 | + exclude = None |
269 | + fixed_string = False |
270 | + files_with_matches = False |
271 | + files_without_match = False |
272 | + color = None |
273 | + diff = False |
274 | + |
275 | + # derived options |
276 | + recursive = None |
277 | + eol_marker = None |
278 | + patternc = None |
279 | + sub_patternc = None |
280 | + print_revno = None |
281 | + fixed_string = None |
282 | + outf = None |
283 | + show_color = False |
284 | + |
285 | + |
286 | def _rev_on_mainline(rev_tuple): |
287 | """returns True is rev tuple is on mainline""" |
288 | if len(rev_tuple) == 1: |
289 | |
290 | === removed directory 'breezy/plugins/grep' |
291 | === removed file 'breezy/plugins/grep/.bzrignore' |
292 | --- breezy/plugins/grep/.bzrignore 2010-06-08 03:05:42 +0000 |
293 | +++ breezy/plugins/grep/.bzrignore 1970-01-01 00:00:00 +0000 |
294 | @@ -1,1 +0,0 @@ |
295 | -./build |
296 | |
297 | === removed file 'breezy/plugins/grep/NEWS' |
298 | --- breezy/plugins/grep/NEWS 2017-07-30 16:59:50 +0000 |
299 | +++ breezy/plugins/grep/NEWS 1970-01-01 00:00:00 +0000 |
300 | @@ -1,73 +0,0 @@ |
301 | -This is the NEWS file from bzr-grep from before it was merged into bzr core. |
302 | -For changes before then, please refer to the main bzr log file. |
303 | - |
304 | -bzr-grep 0.5.0-final - Unreleased |
305 | -================================== |
306 | -* ``bzr grep`` now supports ``--diff|-p`` option to search through |
307 | - changesets. (Parth Malwankar, #540705) |
308 | - |
309 | -* Option ``grep_color`` can be set in ``breezy.conf`` instead of using |
310 | - the option ``--color`` from the command line. (Johan Dahlin) |
311 | - |
312 | -bzr-grep 0.4.0-final - 08-Jun-2010 |
313 | -================================== |
314 | -* Add seperate output formatter to reduce duplication of search loops, |
315 | - additionally make -Fi use regexp rather than lowercasing pattern and |
316 | - entirety of text for the same reason. This also fixes bug #590589 |
317 | - - UnicodeDecodeError with options -Fi. (Martin [gz]) |
318 | - |
319 | -* Added fast path for no match that avoids splitting the file text into |
320 | - seperate lines and testing each one, by checking the entire text for a |
321 | - possible match initially. (Martin [gz]) |
322 | - |
323 | -* Added Makefile. (Parth Malwankar) |
324 | - |
325 | -* Fixed setup.py to work correctly. (Martin [gz]) |
326 | - |
327 | -bzr-grep 0.3.0-final - 23-May-2010 |
328 | -================================== |
329 | -* Support for --color option (POSIX only). (Parth Malwankar, #571694) |
330 | - |
331 | -* Revisions in branches without trees can now be searched with |
332 | - -r option. (Parth Malwankar, #584240) |
333 | - |
334 | -* Trying to search working tree for a treeless branch no longer |
335 | - produces a stack trace but gives an error message suggesting use of |
336 | - -r option. (Parth Malwankar, #572658) |
337 | - |
338 | -bzr-grep 0.2.0-final - 30-Mar-2010 |
339 | -================================== |
340 | -* 'binary file skipped' warning is not shows without --verbose flag |
341 | - (Parth Malwankar, #539031) |
342 | - |
343 | -* Added support for -F/--fixed-string for faster search. |
344 | - Simple patterns [a-zA-Z0-9 _] are now implicitly -F and searched faster. |
345 | - (Parth Malwankar, #539263) |
346 | - |
347 | -* Better unicode handling. bzr-grep no longer crashes with UnicodeDecode |
348 | - error for some outputs. (Parth Malwankar, #539258) |
349 | - |
350 | -* Faster grep for revision range. bzr-grep now caches results for |
351 | - files that have not changed between revisions. |
352 | - (Parth Malwankar, #542375) |
353 | - |
354 | -* Faster grep for specific revision. (Parth Malwankar, #539429) |
355 | - |
356 | -* Significant performance improvement. Working tree grep for bzr.dev |
357 | - has gone from ~7.5s to ~1s. (Parth Malwankar, #539028) |
358 | - |
359 | -* Support for -L/--files-without-match and -l/files-with-matches |
360 | - (Parth Malwankar, #540097) |
361 | - |
362 | -bzr-grep 0.1.0-final - 14-Mar-2010 |
363 | -================================== |
364 | -* --recursive is now default. (Parth Malwankar, #536688) |
365 | - |
366 | -* ``bzr grep`` searches working copy by default. (Parth Malwankar, #537072) |
367 | - |
368 | -* --include/exclude=GLOB is now supported. (Parth Malwankar, #529889) |
369 | - |
370 | -bzr-grep 0.0.1-final - 10-Mar-2010 |
371 | -================================== |
372 | -* Initial release (Parth Malwankar) |
373 | - |
374 | |
375 | === removed file 'breezy/plugins/grep/__init__.py' |
376 | --- breezy/plugins/grep/__init__.py 2018-11-11 04:08:32 +0000 |
377 | +++ breezy/plugins/grep/__init__.py 1970-01-01 00:00:00 +0000 |
378 | @@ -1,38 +0,0 @@ |
379 | -# Copyright (C) 2010 Canonical Ltd |
380 | -# |
381 | -# This program is free software; you can redistribute it and/or modify |
382 | -# it under the terms of the GNU General Public License as published by |
383 | -# the Free Software Foundation; either version 2 of the License, or |
384 | -# (at your option) any later version. |
385 | -# |
386 | -# This program is distributed in the hope that it will be useful, |
387 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
388 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
389 | -# GNU General Public License for more details. |
390 | -# |
391 | -# You should have received a copy of the GNU General Public License |
392 | -# along with this program; if not, write to the Free Software |
393 | -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
394 | - |
395 | -"""Print lines matching PATTERN for specified files and revisions.""" |
396 | - |
397 | -from __future__ import absolute_import |
398 | - |
399 | -from ... import version_info # noqa: F401 |
400 | -from ...commands import plugin_cmds |
401 | - |
402 | -plugin_cmds.register_lazy("cmd_grep", [], "breezy.plugins.grep.cmds") |
403 | - |
404 | - |
405 | -def test_suite(): |
406 | - from ...tests import TestUtil |
407 | - |
408 | - suite = TestUtil.TestSuite() |
409 | - loader = TestUtil.TestLoader() |
410 | - testmod_names = [ |
411 | - 'test_grep', |
412 | - ] |
413 | - |
414 | - suite.addTest(loader.loadTestsFromModuleNames( |
415 | - ["%s.%s" % (__name__, tmn) for tmn in testmod_names])) |
416 | - return suite |
417 | |
418 | === removed file 'breezy/plugins/grep/cmds.py' |
419 | --- breezy/plugins/grep/cmds.py 2018-11-17 16:53:10 +0000 |
420 | +++ breezy/plugins/grep/cmds.py 1970-01-01 00:00:00 +0000 |
421 | @@ -1,254 +0,0 @@ |
422 | -# Copyright (C) 2010 Canonical Ltd |
423 | -# |
424 | -# This program is free software; you can redistribute it and/or modify |
425 | -# it under the terms of the GNU General Public License as published by |
426 | -# the Free Software Foundation; either version 2 of the License, or |
427 | -# (at your option) any later version. |
428 | -# |
429 | -# This program is distributed in the hope that it will be useful, |
430 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
431 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
432 | -# GNU General Public License for more details. |
433 | -# |
434 | -# You should have received a copy of the GNU General Public License |
435 | -# along with this program; if not, write to the Free Software |
436 | -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
437 | - |
438 | -"""Print lines matching PATTERN for specified files and revisions.""" |
439 | - |
440 | -from __future__ import absolute_import |
441 | - |
442 | -from ... import errors |
443 | -from ...commands import Command, display_command |
444 | -from ...option import Option, ListOption |
445 | -from ...config import GlobalConfig |
446 | - |
447 | -from ...sixish import ( |
448 | - text_type, |
449 | - ) |
450 | - |
451 | -# FIXME: _parse_levels should be shared with breezy.builtins. this is a copy |
452 | -# to avoid the error |
453 | -# "IllegalUseOfScopeReplacer: ScopeReplacer object '_parse_levels' was used |
454 | -# incorrectly: Object already cleaned up, did you assign it to another |
455 | -# variable?: _factory |
456 | -# with lazy import |
457 | - |
458 | - |
459 | -def _parse_levels(s): |
460 | - try: |
461 | - return int(s) |
462 | - except ValueError: |
463 | - msg = "The levels argument must be an integer." |
464 | - raise errors.BzrCommandError(msg) |
465 | - |
466 | - |
467 | -class GrepOptions(object): |
468 | - """Container to pass around grep options. |
469 | - |
470 | - This class is used as a container to pass around user option and |
471 | - some other params (like outf) to processing functions. This makes |
472 | - it easier to add more options as grep evolves. |
473 | - """ |
474 | - verbose = False |
475 | - ignore_case = False |
476 | - no_recursive = False |
477 | - from_root = False |
478 | - null = False |
479 | - levels = None |
480 | - line_number = False |
481 | - path_list = None |
482 | - revision = None |
483 | - pattern = None |
484 | - include = None |
485 | - exclude = None |
486 | - fixed_string = False |
487 | - files_with_matches = False |
488 | - files_without_match = False |
489 | - color = None |
490 | - diff = False |
491 | - |
492 | - # derived options |
493 | - recursive = None |
494 | - eol_marker = None |
495 | - patternc = None |
496 | - sub_patternc = None |
497 | - print_revno = None |
498 | - fixed_string = None |
499 | - outf = None |
500 | - show_color = False |
501 | - |
502 | - |
503 | -class cmd_grep(Command): |
504 | - """Print lines matching PATTERN for specified files and revisions. |
505 | - |
506 | - This command searches the specified files and revisions for a given |
507 | - pattern. The pattern is specified as a Python regular expressions[1]. |
508 | - |
509 | - If the file name is not specified, the revisions starting with the |
510 | - current directory are searched recursively. If the revision number is |
511 | - not specified, the working copy is searched. To search the last committed |
512 | - revision, use the '-r -1' or '-r last:1' option. |
513 | - |
514 | - Unversioned files are not searched unless explicitly specified on the |
515 | - command line. Unversioned directores are not searched. |
516 | - |
517 | - When searching a pattern, the output is shown in the 'filepath:string' |
518 | - format. If a revision is explicitly searched, the output is shown as |
519 | - 'filepath~N:string', where N is the revision number. |
520 | - |
521 | - --include and --exclude options can be used to search only (or exclude |
522 | - from search) files with base name matches the specified Unix style GLOB |
523 | - pattern. The GLOB pattern an use *, ?, and [...] as wildcards, and \\ |
524 | - to quote wildcard or backslash character literally. Note that the glob |
525 | - pattern is not a regular expression. |
526 | - |
527 | - [1] http://docs.python.org/library/re.html#regular-expression-syntax |
528 | - """ |
529 | - |
530 | - encoding_type = 'replace' |
531 | - takes_args = ['pattern', 'path*'] |
532 | - takes_options = [ |
533 | - 'verbose', |
534 | - 'revision', |
535 | - Option('color', type=text_type, argname='when', |
536 | - help='Show match in color. WHEN is never, always or auto.'), |
537 | - Option('diff', short_name='p', |
538 | - help='Grep for pattern in changeset for each revision.'), |
539 | - ListOption('exclude', type=text_type, argname='glob', short_name='X', |
540 | - help="Skip files whose base name matches GLOB."), |
541 | - ListOption('include', type=text_type, argname='glob', short_name='I', |
542 | - help="Search only files whose base name matches GLOB."), |
543 | - Option('files-with-matches', short_name='l', |
544 | - help='Print only the name of each input file in ' |
545 | - 'which PATTERN is found.'), |
546 | - Option('files-without-match', short_name='L', |
547 | - help='Print only the name of each input file in ' |
548 | - 'which PATTERN is not found.'), |
549 | - Option('fixed-string', short_name='F', |
550 | - help='Interpret PATTERN is a single fixed string (not regex).'), |
551 | - Option('from-root', |
552 | - help='Search for pattern starting from the root of the branch. ' |
553 | - '(implies --recursive)'), |
554 | - Option('ignore-case', short_name='i', |
555 | - help='ignore case distinctions while matching.'), |
556 | - Option('levels', |
557 | - help='Number of levels to display - 0 for all, 1 for collapsed ' |
558 | - '(1 is default).', |
559 | - argname='N', |
560 | - type=_parse_levels), |
561 | - Option('line-number', short_name='n', |
562 | - help='show 1-based line number.'), |
563 | - Option('no-recursive', |
564 | - help="Don't recurse into subdirectories. (default is --recursive)"), |
565 | - Option('null', short_name='Z', |
566 | - help='Write an ASCII NUL (\\0) separator ' |
567 | - 'between output lines rather than a newline.'), |
568 | - ] |
569 | - |
570 | - @display_command |
571 | - def run(self, verbose=False, ignore_case=False, no_recursive=False, |
572 | - from_root=False, null=False, levels=None, line_number=False, |
573 | - path_list=None, revision=None, pattern=None, include=None, |
574 | - exclude=None, fixed_string=False, files_with_matches=False, |
575 | - files_without_match=False, color=None, diff=False): |
576 | - from breezy import _termcolor |
577 | - from . import grep |
578 | - import re |
579 | - if path_list is None: |
580 | - path_list = ['.'] |
581 | - else: |
582 | - if from_root: |
583 | - raise errors.BzrCommandError( |
584 | - 'cannot specify both --from-root and PATH.') |
585 | - |
586 | - if files_with_matches and files_without_match: |
587 | - raise errors.BzrCommandError('cannot specify both ' |
588 | - '-l/--files-with-matches and -L/--files-without-matches.') |
589 | - |
590 | - global_config = GlobalConfig() |
591 | - |
592 | - if color is None: |
593 | - color = global_config.get_user_option('grep_color') |
594 | - |
595 | - if color is None: |
596 | - color = 'never' |
597 | - |
598 | - if color not in ['always', 'never', 'auto']: |
599 | - raise errors.BzrCommandError('Valid values for --color are ' |
600 | - '"always", "never" or "auto".') |
601 | - |
602 | - if levels is None: |
603 | - levels = 1 |
604 | - |
605 | - print_revno = False |
606 | - if revision is not None or levels == 0: |
607 | - # print revision numbers as we may be showing multiple revisions |
608 | - print_revno = True |
609 | - |
610 | - eol_marker = '\n' |
611 | - if null: |
612 | - eol_marker = '\0' |
613 | - |
614 | - if not ignore_case and grep.is_fixed_string(pattern): |
615 | - # if the pattern isalnum, implicitly use to -F for faster grep |
616 | - fixed_string = True |
617 | - elif ignore_case and fixed_string: |
618 | - # GZ 2010-06-02: Fall back to regexp rather than lowercasing |
619 | - # pattern and text which will cause pain later |
620 | - fixed_string = False |
621 | - pattern = re.escape(pattern) |
622 | - |
623 | - patternc = None |
624 | - re_flags = re.MULTILINE |
625 | - if ignore_case: |
626 | - re_flags |= re.IGNORECASE |
627 | - |
628 | - if not fixed_string: |
629 | - patternc = grep.compile_pattern( |
630 | - pattern.encode(grep._user_encoding), re_flags) |
631 | - |
632 | - if color == 'always': |
633 | - show_color = True |
634 | - elif color == 'never': |
635 | - show_color = False |
636 | - elif color == 'auto': |
637 | - show_color = _termcolor.allow_color() |
638 | - |
639 | - GrepOptions.verbose = verbose |
640 | - GrepOptions.ignore_case = ignore_case |
641 | - GrepOptions.no_recursive = no_recursive |
642 | - GrepOptions.from_root = from_root |
643 | - GrepOptions.null = null |
644 | - GrepOptions.levels = levels |
645 | - GrepOptions.line_number = line_number |
646 | - GrepOptions.path_list = path_list |
647 | - GrepOptions.revision = revision |
648 | - GrepOptions.pattern = pattern |
649 | - GrepOptions.include = include |
650 | - GrepOptions.exclude = exclude |
651 | - GrepOptions.fixed_string = fixed_string |
652 | - GrepOptions.files_with_matches = files_with_matches |
653 | - GrepOptions.files_without_match = files_without_match |
654 | - GrepOptions.color = color |
655 | - GrepOptions.diff = False |
656 | - |
657 | - GrepOptions.eol_marker = eol_marker |
658 | - GrepOptions.print_revno = print_revno |
659 | - GrepOptions.patternc = patternc |
660 | - GrepOptions.recursive = not no_recursive |
661 | - GrepOptions.fixed_string = fixed_string |
662 | - GrepOptions.outf = self.outf |
663 | - GrepOptions.show_color = show_color |
664 | - |
665 | - if diff: |
666 | - # options not used: |
667 | - # files_with_matches, files_without_match |
668 | - # levels(?), line_number, from_root |
669 | - # include, exclude |
670 | - # These are silently ignored. |
671 | - grep.grep_diff(GrepOptions) |
672 | - elif revision is None: |
673 | - grep.workingtree_grep(GrepOptions) |
674 | - else: |
675 | - grep.versioned_grep(GrepOptions) |
676 | |
677 | === modified file 'breezy/tests/__init__.py' |
678 | --- breezy/tests/__init__.py 2018-11-23 23:51:34 +0000 |
679 | +++ breezy/tests/__init__.py 2019-02-04 01:01:36 +0000 |
680 | @@ -4107,6 +4107,7 @@ |
681 | 'breezy.tests.test_globbing', |
682 | 'breezy.tests.test_gpg', |
683 | 'breezy.tests.test_graph', |
684 | + 'breezy.tests.test_grep', |
685 | 'breezy.tests.test_groupcompress', |
686 | 'breezy.tests.test_hashcache', |
687 | 'breezy.tests.test_help', |
688 | |
689 | === renamed file 'breezy/plugins/grep/test_grep.py' => 'breezy/tests/test_grep.py' |
690 | --- breezy/plugins/grep/test_grep.py 2018-11-12 01:41:38 +0000 |
691 | +++ breezy/tests/test_grep.py 2019-02-04 01:01:36 +0000 |
692 | @@ -12,7 +12,7 @@ |
693 | # |
694 | # You should have received a copy of the GNU General Public License |
695 | # along with this program; if not, write to the Free Software |
696 | -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
697 | +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
698 | |
699 | from __future__ import absolute_import |
700 | |
701 | @@ -20,11 +20,11 @@ |
702 | import re |
703 | import unicodedata as ud |
704 | |
705 | -from ... import tests, osutils |
706 | -from ...sixish import PY3 |
707 | -from ..._termcolor import color_string, FG |
708 | +from .. import tests, osutils |
709 | +from ..sixish import PY3 |
710 | +from .._termcolor import color_string, FG |
711 | |
712 | -from ...tests.features import ( |
713 | +from ..tests.features import ( |
714 | UnicodeFilenameFeature, |
715 | ) |
716 | |
717 | @@ -2429,13 +2429,13 @@ |
718 | self.assertEqualDiff(subst_dates(out), '''\ |
719 | === revno:3 === |
720 | === modified file 'hello' |
721 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
722 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
723 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
724 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
725 | +hello world! |
726 | === revno:1 === |
727 | === added file 'hello' |
728 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
729 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
730 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
731 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
732 | ''') |
733 | |
734 | def test_grep_diff_revision(self): |
735 | @@ -2448,8 +2448,8 @@ |
736 | self.assertEqualDiff(subst_dates(out), '''\ |
737 | === revno:3 === |
738 | === modified file 'hello' |
739 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
740 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
741 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
742 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
743 | +hello world! |
744 | ''') |
745 | |
746 | @@ -2470,16 +2470,16 @@ |
747 | self.assertEqualDiff(subst_dates(out), '''\ |
748 | === revno:5 === |
749 | === modified file 'hello' |
750 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
751 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
752 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
753 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
754 | +hello world!3 |
755 | === revno:4 === |
756 | === added file 'blah' |
757 | +hello world!2 |
758 | === revno:3 === |
759 | === modified file 'hello' |
760 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
761 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
762 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
763 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
764 | +hello world!1 |
765 | ''') |
766 | |
767 | @@ -2496,8 +2496,8 @@ |
768 | " === modified file 'hello'", fg=FG.BOLD_MAGENTA) + '\n' |
769 | redhello = color_string('hello', fg=FG.BOLD_RED) |
770 | diffstr = '''\ |
771 | - --- hello YYYY-MM-DD HH:MM:SS +ZZZZ |
772 | - +++ hello YYYY-MM-DD HH:MM:SS +ZZZZ |
773 | + --- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
774 | + +++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ |
775 | +hello world! |
776 | ''' |
777 | diffstr = diffstr.replace('hello', redhello) |
778 | |
779 | === modified file 'doc/en/release-notes/brz-3.0.txt' |
780 | --- doc/en/release-notes/brz-3.0.txt 2019-02-02 22:23:40 +0000 |
781 | +++ doc/en/release-notes/brz-3.0.txt 2019-02-04 01:01:36 +0000 |
782 | @@ -93,6 +93,9 @@ |
783 | * The 'fastimport' plugin is now bundled with Breezy. |
784 | (Jelmer Vernooij) |
785 | |
786 | + * The ``grep`` plugin has been merged into Breezy. |
787 | + (Parth Malwankar, Martin Packman, Jelmer Vernooij) |
788 | + |
789 | * The 'stats' plugin is now bundled with Breezy. |
790 | (Jelmer Vernooij) |
791 |
Thanks, I think is a good thing to do.