Merge pull request #716 from tdeo/multiline_pygrep

Add multiline mode to pygrep
This commit is contained in:
Anthony Sottile 2018-03-09 09:39:09 -08:00 committed by GitHub
commit c6b6d2340e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 1 deletions

View file

@ -27,6 +27,23 @@ def _process_filename_by_line(pattern, filename):
return retv return retv
def _process_filename_at_once(pattern, filename):
retv = 0
with open(filename, 'rb') as f:
contents = f.read()
match = pattern.search(contents)
if match:
retv = 1
line_no = contents[:match.start()].count(b'\n')
output.write('{}:{}:'.format(filename, line_no + 1))
matched_lines = match.group().split(b'\n')
matched_lines[0] = contents.split(b'\n')[line_no]
output.write_line(b'\n'.join(matched_lines))
return retv
def run_hook(prefix, hook, file_args): def run_hook(prefix, hook, file_args):
exe = (sys.executable, '-m', __name__) exe = (sys.executable, '-m', __name__)
exe += tuple(hook['args']) + (hook['entry'],) exe += tuple(hook['args']) + (hook['entry'],)
@ -42,15 +59,22 @@ def main(argv=None):
), ),
) )
parser.add_argument('-i', '--ignore-case', action='store_true') parser.add_argument('-i', '--ignore-case', action='store_true')
parser.add_argument('--multiline', action='store_true')
parser.add_argument('pattern', help='python regex pattern.') parser.add_argument('pattern', help='python regex pattern.')
parser.add_argument('filenames', nargs='*') parser.add_argument('filenames', nargs='*')
args = parser.parse_args(argv) args = parser.parse_args(argv)
flags = re.IGNORECASE if args.ignore_case else 0 flags = re.IGNORECASE if args.ignore_case else 0
if args.multiline:
flags |= re.MULTILINE | re.DOTALL
pattern = re.compile(args.pattern.encode(), flags) pattern = re.compile(args.pattern.encode(), flags)
retv = 0 retv = 0
for filename in args.filenames: for filename in args.filenames:
if args.multiline:
retv |= _process_filename_at_once(pattern, filename)
else:
retv |= _process_filename_by_line(pattern, filename) retv |= _process_filename_by_line(pattern, filename)
return retv return retv

View file

@ -38,3 +38,31 @@ def test_ignore_case(some_files, cap_out):
out = cap_out.get() out = cap_out.get()
assert ret == 1 assert ret == 1
assert out == 'f2:1:[INFO] hi\n' assert out == 'f2:1:[INFO] hi\n'
def test_multiline(some_files, cap_out):
ret = pygrep.main(('--multiline', r'foo\nbar', 'f1', 'f2', 'f3'))
out = cap_out.get()
assert ret == 1
assert out == 'f1:1:foo\nbar\n'
def test_multiline_line_number(some_files, cap_out):
ret = pygrep.main(('--multiline', r'ar', 'f1', 'f2', 'f3'))
out = cap_out.get()
assert ret == 1
assert out == 'f1:2:bar\n'
def test_multiline_dotall_flag_is_enabled(some_files, cap_out):
ret = pygrep.main(('--multiline', r'o.*bar', 'f1', 'f2', 'f3'))
out = cap_out.get()
assert ret == 1
assert out == 'f1:1:foo\nbar\n'
def test_multiline_multiline_flag_is_enabled(some_files, cap_out):
ret = pygrep.main(('--multiline', r'foo$.*bar', 'f1', 'f2', 'f3'))
out = cap_out.get()
assert ret == 1
assert out == 'f1:1:foo\nbar\n'