mirror of
https://github.com/nvbn/thefuck.git
synced 2025-04-19 01:00:42 +01:00
Add support for stdout in the fix_file rule
At least `pep8` and `py.test` consider errors as normal and print them on stdout.
This commit is contained in:
parent
7f0f9a966f
commit
4a2f869c6d
@ -4,9 +4,9 @@ from thefuck.rules.fix_file import match, get_new_command
|
|||||||
from tests.utils import Command
|
from tests.utils import Command
|
||||||
|
|
||||||
|
|
||||||
# (script, file, line, col (or None), stderr)
|
# (script, file, line, col (or None), stdout, stderr)
|
||||||
tests = (
|
tests = (
|
||||||
('gcc a.c', 'a.c', 3, 1,
|
('gcc a.c', 'a.c', 3, 1, '',
|
||||||
"""
|
"""
|
||||||
a.c: In function 'main':
|
a.c: In function 'main':
|
||||||
a.c:3:1: error: expected expression before '}' token
|
a.c:3:1: error: expected expression before '}' token
|
||||||
@ -14,47 +14,47 @@ a.c:3:1: error: expected expression before '}' token
|
|||||||
^
|
^
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('clang a.c', 'a.c', 3, 1,
|
('clang a.c', 'a.c', 3, 1, '',
|
||||||
"""
|
"""
|
||||||
a.c:3:1: error: expected expression
|
a.c:3:1: error: expected expression
|
||||||
}
|
}
|
||||||
^
|
^
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('perl a.pl', 'a.pl', 3, None,
|
('perl a.pl', 'a.pl', 3, None, '',
|
||||||
"""
|
"""
|
||||||
syntax error at a.pl line 3, at EOF
|
syntax error at a.pl line 3, at EOF
|
||||||
Execution of a.pl aborted due to compilation errors.
|
Execution of a.pl aborted due to compilation errors.
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('perl a.pl', 'a.pl', 2, None,
|
('perl a.pl', 'a.pl', 2, None, '',
|
||||||
"""
|
"""
|
||||||
Search pattern not terminated at a.pl line 2.
|
Search pattern not terminated at a.pl line 2.
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('sh a.sh', 'a.sh', 2, None,
|
('sh a.sh', 'a.sh', 2, None, '',
|
||||||
"""
|
"""
|
||||||
a.sh: line 2: foo: command not found
|
a.sh: line 2: foo: command not found
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('zsh a.sh', 'a.sh', 2, None,
|
('zsh a.sh', 'a.sh', 2, None, '',
|
||||||
"""
|
"""
|
||||||
a.sh:2: command not found: foo
|
a.sh:2: command not found: foo
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('bash a.sh', 'a.sh', 2, None,
|
('bash a.sh', 'a.sh', 2, None, '',
|
||||||
"""
|
"""
|
||||||
a.sh: line 2: foo: command not found
|
a.sh: line 2: foo: command not found
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('rustc a.rs', 'a.rs', 2, 5,
|
('rustc a.rs', 'a.rs', 2, 5, '',
|
||||||
"""
|
"""
|
||||||
a.rs:2:5: 2:6 error: unexpected token: `+`
|
a.rs:2:5: 2:6 error: unexpected token: `+`
|
||||||
a.rs:2 +
|
a.rs:2 +
|
||||||
^
|
^
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('cargo build', 'src/lib.rs', 3, 5,
|
('cargo build', 'src/lib.rs', 3, 5, '',
|
||||||
"""
|
"""
|
||||||
Compiling test v0.1.0 (file:///tmp/fix-error/test)
|
Compiling test v0.1.0 (file:///tmp/fix-error/test)
|
||||||
src/lib.rs:3:5: 3:6 error: unexpected token: `+`
|
src/lib.rs:3:5: 3:6 error: unexpected token: `+`
|
||||||
@ -65,7 +65,7 @@ Could not compile `test`.
|
|||||||
To learn more, run the command again with --verbose.
|
To learn more, run the command again with --verbose.
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('python a.py', 'a.py', 2, None,
|
('python a.py', 'a.py', 2, None, '',
|
||||||
"""
|
"""
|
||||||
File "a.py", line 2
|
File "a.py", line 2
|
||||||
+
|
+
|
||||||
@ -73,7 +73,7 @@ To learn more, run the command again with --verbose.
|
|||||||
SyntaxError: invalid syntax
|
SyntaxError: invalid syntax
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('python a.py', 'a.py', 8, None,
|
('python a.py', 'a.py', 8, None, '',
|
||||||
"""
|
"""
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "a.py", line 8, in <module>
|
File "a.py", line 8, in <module>
|
||||||
@ -87,43 +87,43 @@ Traceback (most recent call last):
|
|||||||
TypeError: first argument must be string or compiled pattern
|
TypeError: first argument must be string or compiled pattern
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('ruby a.rb', 'a.rb', 3, None,
|
('ruby a.rb', 'a.rb', 3, None, '',
|
||||||
"""
|
"""
|
||||||
a.rb:3: syntax error, unexpected keyword_end
|
a.rb:3: syntax error, unexpected keyword_end
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('lua a.lua', 'a.lua', 2, None,
|
('lua a.lua', 'a.lua', 2, None, '',
|
||||||
"""
|
"""
|
||||||
lua: a.lua:2: unexpected symbol near '+'
|
lua: a.lua:2: unexpected symbol near '+'
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('fish a.sh', '/tmp/fix-error/a.sh', 2, None,
|
('fish a.sh', '/tmp/fix-error/a.sh', 2, None, '',
|
||||||
"""
|
"""
|
||||||
fish: Unknown command 'foo'
|
fish: Unknown command 'foo'
|
||||||
/tmp/fix-error/a.sh (line 2): foo
|
/tmp/fix-error/a.sh (line 2): foo
|
||||||
^
|
^
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('./a', './a', 2, None,
|
('./a', './a', 2, None, '',
|
||||||
"""
|
"""
|
||||||
awk: ./a:2: BEGIN { print "Hello, world!" + }
|
awk: ./a:2: BEGIN { print "Hello, world!" + }
|
||||||
awk: ./a:2: ^ syntax error
|
awk: ./a:2: ^ syntax error
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('llc a.ll', 'a.ll', 1, None,
|
('llc a.ll', 'a.ll', 1, None, '',
|
||||||
"""
|
"""
|
||||||
llc: a.ll:1:1: error: expected top-level entity
|
llc: a.ll:1:1: error: expected top-level entity
|
||||||
+
|
+
|
||||||
^
|
^
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('go build a.go', 'a.go', 1, None,
|
('go build a.go', 'a.go', 1, None, '',
|
||||||
"""
|
"""
|
||||||
can't load package:
|
can't load package:
|
||||||
a.go:1:1: expected 'package', found '+'
|
a.go:1:1: expected 'package', found '+'
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('make', 'Makefile', 2, None,
|
('make', 'Makefile', 2, None, '',
|
||||||
"""
|
"""
|
||||||
bidule
|
bidule
|
||||||
make: bidule: Command not found
|
make: bidule: Command not found
|
||||||
@ -131,12 +131,12 @@ Makefile:2: recipe for target 'target' failed
|
|||||||
make: *** [target] Error 127
|
make: *** [target] Error 127
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('git st', '/home/martin/.config/git/config', 1, None,
|
('git st', '/home/martin/.config/git/config', 1, None, '',
|
||||||
"""
|
"""
|
||||||
fatal: bad config file line 1 in /home/martin/.config/git/config
|
fatal: bad config file line 1 in /home/martin/.config/git/config
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
('node fuck.js asdf qwer', '/Users/pablo/Workspace/barebones/fuck.js', '2', 5,
|
('node fuck.js asdf qwer', '/Users/pablo/Workspace/barebones/fuck.js', '2', 5, '',
|
||||||
"""
|
"""
|
||||||
/Users/pablo/Workspace/barebones/fuck.js:2
|
/Users/pablo/Workspace/barebones/fuck.js:2
|
||||||
conole.log(arg); // this should read console.log(arg);
|
conole.log(arg); // this should read console.log(arg);
|
||||||
@ -153,35 +153,63 @@ ReferenceError: conole is not defined
|
|||||||
at startup (node.js:129:16)
|
at startup (node.js:129:16)
|
||||||
at node.js:814:3
|
at node.js:814:3
|
||||||
"""),
|
"""),
|
||||||
|
|
||||||
|
('pep8', './tests/rules/test_systemctl.py', 17, 80,
|
||||||
|
"""
|
||||||
|
./tests/rules/test_systemctl.py:17:80: E501 line too long (93 > 79 characters)
|
||||||
|
./tests/rules/test_systemctl.py:18:80: E501 line too long (103 > 79 characters)
|
||||||
|
./tests/rules/test_whois.py:20:80: E501 line too long (89 > 79 characters)
|
||||||
|
./tests/rules/test_whois.py:22:80: E501 line too long (83 > 79 characters)
|
||||||
|
""", ''),
|
||||||
|
|
||||||
|
('py.test', '/home/thefuck/tests/rules/test_fix_file.py', 218, None,
|
||||||
|
"""
|
||||||
|
monkeypatch = <_pytest.monkeypatch.monkeypatch object at 0x7fdb76a25b38>
|
||||||
|
test = ('fish a.sh', '/tmp/fix-error/a.sh', 2, None, '', "\\nfish: Unknown command 'foo'\\n/tmp/fix-error/a.sh (line 2): foo\\n ^\\n")
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('test', tests)
|
||||||
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
|
def test_get_new_command(monkeypatch, test):
|
||||||
|
> mocker.patch('os.path.isfile', return_value=True)
|
||||||
|
E NameError: name 'mocker' is not defined
|
||||||
|
|
||||||
|
/home/thefuck/tests/rules/test_fix_file.py:218: NameError
|
||||||
|
""", ''),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('test', tests)
|
@pytest.mark.parametrize('test', tests)
|
||||||
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
def test_match(mocker, monkeypatch, test):
|
def test_match(mocker, monkeypatch, test):
|
||||||
mocker.patch('os.path.isfile', return_value=True)
|
mocker.patch('os.path.isfile', return_value=True)
|
||||||
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
||||||
assert match(Command(stderr=test[4]), None)
|
assert match(Command(stdout=test[4], stderr=test[5]), None)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('test', tests)
|
@pytest.mark.parametrize('test', tests)
|
||||||
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
def test_no_editor(mocker, monkeypatch, test):
|
def test_no_editor(mocker, monkeypatch, test):
|
||||||
mocker.patch('os.path.isfile', return_value=True)
|
mocker.patch('os.path.isfile', return_value=True)
|
||||||
if 'EDITOR' in os.environ:
|
if 'EDITOR' in os.environ:
|
||||||
monkeypatch.delenv('EDITOR')
|
monkeypatch.delenv('EDITOR')
|
||||||
|
|
||||||
assert not match(Command(stderr=test[4]), None)
|
assert not match(Command(stdout=test[4], stderr=test[5]), None)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('test', tests)
|
@pytest.mark.parametrize('test', tests)
|
||||||
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
def test_not_file(mocker, monkeypatch, test):
|
def test_not_file(mocker, monkeypatch, test):
|
||||||
mocker.patch('os.path.isfile', return_value=False)
|
mocker.patch('os.path.isfile', return_value=False)
|
||||||
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
||||||
|
|
||||||
assert not match(Command(stderr=test[4]), None)
|
assert not match(Command(stdout=test[4], stderr=test[5]), None)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('test', tests)
|
@pytest.mark.parametrize('test', tests)
|
||||||
def test_get_new_command(monkeypatch, test):
|
@pytest.mark.usefixtures('no_memoize')
|
||||||
|
def test_get_new_command(mocker, monkeypatch, test):
|
||||||
|
mocker.patch('os.path.isfile', return_value=True)
|
||||||
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
monkeypatch.setenv('EDITOR', 'dummy_editor')
|
||||||
assert (get_new_command(Command(script=test[0], stderr=test[4]), None) ==
|
cmd = Command(script=test[0], stdout=test[4], stderr=test[5])
|
||||||
|
assert (get_new_command(cmd, None) ==
|
||||||
'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))
|
'dummy_editor {} +{} && {}'.format(test[1], test[2], test[0]))
|
||||||
|
@ -25,7 +25,7 @@ patterns = (
|
|||||||
'^{file}: line {line}: ',
|
'^{file}: line {line}: ',
|
||||||
# ghc, make, ruby, zsh:
|
# ghc, make, ruby, zsh:
|
||||||
'^{file}:{line}:',
|
'^{file}:{line}:',
|
||||||
# cargo, clang, gcc, go, rustc:
|
# cargo, clang, gcc, go, pep8, rustc:
|
||||||
'^{file}:{line}:{col}',
|
'^{file}:{line}:{col}',
|
||||||
# perl:
|
# perl:
|
||||||
'at {file} line {line}',
|
'at {file} line {line}',
|
||||||
@ -45,7 +45,7 @@ patterns = [_make_pattern(p) for p in patterns]
|
|||||||
def _search(stderr):
|
def _search(stderr):
|
||||||
for pattern in patterns:
|
for pattern in patterns:
|
||||||
m = re.search(pattern, stderr)
|
m = re.search(pattern, stderr)
|
||||||
if m:
|
if m and os.path.isfile(m.group('file')):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
@ -53,15 +53,15 @@ def match(command, settings):
|
|||||||
if 'EDITOR' not in os.environ:
|
if 'EDITOR' not in os.environ:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
m = _search(command.stderr)
|
return _search(command.stderr) or _search(command.stdout)
|
||||||
|
|
||||||
return m and os.path.isfile(m.group('file'))
|
|
||||||
|
|
||||||
|
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
m = _search(command.stderr)
|
m = _search(command.stderr) or _search(command.stdout)
|
||||||
|
|
||||||
# Note: there does not seem to be a standard for columns, so they are just
|
# Note: there does not seem to be a standard for columns, so they are just
|
||||||
# ignored for now
|
# ignored for now
|
||||||
return shells.and_('{} {} +{}'.format(os.environ['EDITOR'], m.group('file'), m.group('line')),
|
editor_call = '{} {} +{}'.format(os.environ['EDITOR'],
|
||||||
command.script)
|
m.group('file'),
|
||||||
|
m.group('line'))
|
||||||
|
return shells.and_(editor_call, command.script)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user