diff --git a/README.md b/README.md index 7c943900..af4459da 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `cd_mkdir` – creates directories before cd'ing into them; * `cd_parent` – changes `cd..` to `cd ..`; * `composer_not_command` – fixes composer command name; +* `cp_dir` – adds `-r` when you try to copy a directory; * `cp_omitting_directory` – adds `-a` when you `cp` directory; * `cpp11` – add missing `-std=c++11` to `g++` or `clang++`; * `django_south_ghost` – adds `--delete-ghost-migrations` to failed because ghosts django south migration; diff --git a/tests/rules/test_cp_dir.py b/tests/rules/test_cp_dir.py new file mode 100644 index 00000000..8e3e1101 --- /dev/null +++ b/tests/rules/test_cp_dir.py @@ -0,0 +1,22 @@ +import pytest +from thefuck.rules.cp_dir import match, get_new_command +from tests.utils import Command + + +@pytest.mark.parametrize('command', [ + Command('cp foo foo_copy', stderr='cp: foo: is a directory'), + Command('cp bar bar_copy', stderr='cp: bar: Is a directory'), + Command('sudo cp qux qux_copy', stderr='cp: qux: is a directory')]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command', [ + Command('cp foo foo_copy'), Command('cp foo foo_copy'), Command()]) +def test_not_match(command): + assert not match(command, None) + + +def test_get_new_command(): + assert get_new_command( + Command('cp foo foo_copy', '', ''), None) == 'cp -r foo foo_copy' diff --git a/thefuck/rules/cp_dir.py b/thefuck/rules/cp_dir.py new file mode 100644 index 00000000..c7a262c6 --- /dev/null +++ b/thefuck/rules/cp_dir.py @@ -0,0 +1,13 @@ +import re +from thefuck.utils import sudo_support + + +@sudo_support +def match(command, settings): + return (command.script.startswith('cp ') + and 'is a directory' in command.stderr.lower()) + + +@sudo_support +def get_new_command(command, settings): + return re.sub('^cp (.*)', 'cp -r \\1', command.script)