diff --git a/README.md b/README.md index 2ff554fa..36bf881f 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ using the matched rule and runs it. Rules enabled by default are as follows: * `java` – removes `.java` extension when running Java programs; * `javac` – appends missing `.java` when compiling Java files; * `lein_not_task` – fixes wrong `lein` tasks like `lein rpl`; +* `ln_no_hard_link` – catches hard link creation on directories, suggest symbolic link; * `ls_lah` – adds `-lah` to `ls`; * `man` – changes manual section; * `man_no_space` – fixes man commands without spaces, for example `mandiff`; diff --git a/tests/rules/test_ln_no_hard_link.py b/tests/rules/test_ln_no_hard_link.py new file mode 100644 index 00000000..9ada4d51 --- /dev/null +++ b/tests/rules/test_ln_no_hard_link.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +import pytest +from thefuck.rules.ln_no_hard_link import match, get_new_command +from tests.utils import Command + +error = "hard link not allowed for directory" + + +@pytest.mark.parametrize('script, stderr', [ + ("ln barDir barLink", "ln: ‘barDir’: {}"), + ("sudo ln a b", "ln: ‘a’: {}"), + ("sudo ln -nbi a b", "ln: ‘a’: {}")]) +def test_match(script, stderr): + command = Command(script, stderr=stderr.format(error)) + assert match(command) + + +@pytest.mark.parametrize('script, stderr', [ + ('', ''), + ("ln a b", "... hard link"), + ("sudo ln a b", "... hard link"), + ("a b", error)]) +def test_assert_not_match(script, stderr): + command = Command(script, stderr=stderr) + assert not match(command) + + +@pytest.mark.parametrize('script, result', [ + ("ln barDir barLink", "ln -s barDir barLink"), + ("sudo ln barDir barLink", "sudo ln -s barDir barLink"), + ("sudo ln -nbi a b", "sudo ln -s -nbi a b"), + ("ln -nbi a b && ls", "ln -s -nbi a b && ls"), + ("ln a ln", "ln -s a ln"), + ("sudo ln a ln", "sudo ln -s a ln")]) +def test_get_new_command(script, result): + command = Command(script) + assert get_new_command(command) == result diff --git a/thefuck/rules/ln_no_hard_link.py b/thefuck/rules/ln_no_hard_link.py new file mode 100644 index 00000000..3aca042b --- /dev/null +++ b/thefuck/rules/ln_no_hard_link.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +"""Suggest creating symbolic link if hard link is not allowed. + +Example: +> ln barDir barLink +ln: ‘barDir’: hard link not allowed for directory + +--> ln -s barDir barLink +""" + +import re +from thefuck.specific.sudo import sudo_support + + +@sudo_support +def match(command): + return (command.stderr.endswith("hard link not allowed for directory") and + command.script.startswith("ln ")) + + +@sudo_support +def get_new_command(command): + return re.sub(r'^ln ', 'ln -s ', command.script)