From 469c5a60b0196a24a63936408333a3090d3a99cd Mon Sep 17 00:00:00 2001 From: nvbn Date: Fri, 24 Jul 2015 00:39:56 +0300 Subject: [PATCH] #N/A Add `replace_argument` helper --- tests/test_utils.py | 9 ++++++++- thefuck/rules/brew_install.py | 4 ++-- thefuck/rules/brew_unknown_command.py | 4 ++-- thefuck/rules/cargo_no_command.py | 3 ++- thefuck/rules/composer_not_command.py | 3 ++- thefuck/rules/docker_not_command.py | 5 ++--- thefuck/rules/git_branch_delete.py | 3 ++- thefuck/rules/git_checkout.py | 3 ++- thefuck/rules/git_diff_staged.py | 3 ++- thefuck/rules/git_fix_stash.py | 21 ++++++++++----------- thefuck/rules/git_not_command.py | 4 ++-- thefuck/rules/git_pull_clone.py | 3 ++- thefuck/rules/git_push_force.py | 3 ++- thefuck/rules/git_push_pull.py | 3 ++- thefuck/rules/heroku_not_command.py | 4 ++-- thefuck/rules/lein_not_task.py | 4 ++-- thefuck/rules/pip_unknown_command.py | 3 ++- thefuck/rules/tmux.py | 4 ++-- thefuck/utils.py | 11 +++++++++++ 19 files changed, 61 insertions(+), 36 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 208911d5..ec8605de 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,7 +1,7 @@ import pytest from mock import Mock from thefuck.utils import git_support, sudo_support, wrap_settings,\ - memoize, get_closest, get_all_executables + memoize, get_closest, get_all_executables, replace_argument from thefuck.types import Settings from tests.utils import Command @@ -92,3 +92,10 @@ def test_get_all_callables(): assert 'vim' in all_callables assert 'fsck' in all_callables assert 'fuck' not in all_callables + + +@pytest.mark.parametrize('args, result', [ + (('apt-get instol vim', 'instol', 'install'), 'apt-get install vim'), + (('git brnch', 'brnch', 'branch'), 'git branch')]) +def test_replace_argument(args, result): + assert replace_argument(*args) == result diff --git a/thefuck/rules/brew_install.py b/thefuck/rules/brew_install.py index 7fa56893..751c1f7c 100644 --- a/thefuck/rules/brew_install.py +++ b/thefuck/rules/brew_install.py @@ -1,7 +1,7 @@ import os import re from subprocess import check_output -from thefuck.utils import get_closest +from thefuck.utils import get_closest, replace_argument # Formulars are base on each local system's status @@ -40,4 +40,4 @@ def get_new_command(command, settings): command.stderr)[0] exist_formula = _get_similar_formula(not_exist_formula) - return command.script.replace(not_exist_formula, exist_formula, 1) + return replace_argument(command.script, not_exist_formula, exist_formula) diff --git a/thefuck/rules/brew_unknown_command.py b/thefuck/rules/brew_unknown_command.py index 81e4a678..0a2402f3 100644 --- a/thefuck/rules/brew_unknown_command.py +++ b/thefuck/rules/brew_unknown_command.py @@ -1,7 +1,7 @@ import os import re import subprocess -from thefuck.utils import get_closest +from thefuck.utils import get_closest, replace_argument BREW_CMD_PATH = '/Library/Homebrew/cmd' TAP_PATH = '/Library/Taps' @@ -99,4 +99,4 @@ def get_new_command(command, settings): command.stderr)[0] new_cmd = _get_similar_command(broken_cmd) - return command.script.replace(broken_cmd, new_cmd, 1) + return replace_argument(command.script, broken_cmd, new_cmd) diff --git a/thefuck/rules/cargo_no_command.py b/thefuck/rules/cargo_no_command.py index 350e9273..c4f6c072 100644 --- a/thefuck/rules/cargo_no_command.py +++ b/thefuck/rules/cargo_no_command.py @@ -1,4 +1,5 @@ import re +from thefuck.utils import replace_argument def match(command, settings): @@ -11,4 +12,4 @@ def get_new_command(command, settings): broken = command.script.split()[1] fix = re.findall(r'Did you mean `([^`]*)`', command.stderr)[0] - return command.script.replace(broken, fix, 1) + return replace_argument(command.script, broken, fix) diff --git a/thefuck/rules/composer_not_command.py b/thefuck/rules/composer_not_command.py index 930608d6..115ca180 100644 --- a/thefuck/rules/composer_not_command.py +++ b/thefuck/rules/composer_not_command.py @@ -1,4 +1,5 @@ import re +from thefuck.utils import replace_argument def match(command, settings): @@ -12,4 +13,4 @@ def get_new_command(command, settings): new_cmd = re.findall(r'Did you mean this\?[^\n]*\n\s*([^\n]*)', command.stderr) if not new_cmd: new_cmd = re.findall(r'Did you mean one of these\?[^\n]*\n\s*([^\n]*)', command.stderr) - return command.script.replace(broken_cmd, new_cmd[0].strip(), 1) \ No newline at end of file + return replace_argument(command.script, broken_cmd, new_cmd[0].strip()) diff --git a/thefuck/rules/docker_not_command.py b/thefuck/rules/docker_not_command.py index 24c828f0..4b473bbf 100644 --- a/thefuck/rules/docker_not_command.py +++ b/thefuck/rules/docker_not_command.py @@ -1,7 +1,7 @@ from itertools import dropwhile, takewhile, islice import re import subprocess -from thefuck.utils import get_closest, sudo_support +from thefuck.utils import get_closest, sudo_support, replace_argument @sudo_support @@ -24,5 +24,4 @@ def get_new_command(command, settings): wrong_command = re.findall( r"docker: '(\w+)' is not a docker command.", command.stderr)[0] fixed_command = get_closest(wrong_command, get_docker_commands()) - return command.script.replace( - ' {}'.format(wrong_command), ' {}'.format(fixed_command), 1) + return replace_argument(command.script, wrong_command, fixed_command) diff --git a/thefuck/rules/git_branch_delete.py b/thefuck/rules/git_branch_delete.py index 8f20bc4b..781aad37 100644 --- a/thefuck/rules/git_branch_delete.py +++ b/thefuck/rules/git_branch_delete.py @@ -1,4 +1,5 @@ from thefuck import utils +from thefuck.utils import replace_argument @utils.git_support @@ -9,4 +10,4 @@ def match(command, settings): @utils.git_support def get_new_command(command, settings): - return command.script.replace('-d', '-D') + return replace_argument(command.script, '-d', '-D') diff --git a/thefuck/rules/git_checkout.py b/thefuck/rules/git_checkout.py index 992f615b..afff835a 100644 --- a/thefuck/rules/git_checkout.py +++ b/thefuck/rules/git_checkout.py @@ -1,6 +1,7 @@ import re import subprocess from thefuck import shells, utils +from thefuck.utils import replace_argument @utils.git_support @@ -30,7 +31,7 @@ def get_new_command(command, settings): closest_branch = utils.get_closest(missing_file, get_branches(), fallback_to_first=False) if closest_branch: - return command.script.replace(missing_file, closest_branch, 1) + return replace_argument(command.script, missing_file, closest_branch) else: return shells.and_('git branch {}', '{}').format( missing_file, command.script) diff --git a/thefuck/rules/git_diff_staged.py b/thefuck/rules/git_diff_staged.py index 41113d54..91b46e0e 100644 --- a/thefuck/rules/git_diff_staged.py +++ b/thefuck/rules/git_diff_staged.py @@ -1,4 +1,5 @@ from thefuck import utils +from thefuck.utils import replace_argument @utils.git_support @@ -9,4 +10,4 @@ def match(command, settings): @utils.git_support def get_new_command(command, settings): - return command.script.replace(' diff', ' diff --staged') + return replace_argument(command.script, 'diff', 'diff --staged') diff --git a/thefuck/rules/git_fix_stash.py b/thefuck/rules/git_fix_stash.py index 2ac29a94..cedfcaf5 100644 --- a/thefuck/rules/git_fix_stash.py +++ b/thefuck/rules/git_fix_stash.py @@ -1,4 +1,5 @@ from thefuck import utils +from thefuck.utils import replace_argument @utils.git_support @@ -6,18 +7,16 @@ def match(command, settings): return (command.script.split()[1] == 'stash' and 'usage:' in command.stderr) - # git's output here is too complicated to be parsed (see the test file) stash_commands = ( - 'apply', - 'branch', - 'clear', - 'drop', - 'list', - 'pop', - 'save', - 'show', - ) + 'apply', + 'branch', + 'clear', + 'drop', + 'list', + 'pop', + 'save', + 'show') @utils.git_support @@ -26,7 +25,7 @@ def get_new_command(command, settings): fixed = utils.get_closest(stash_cmd, stash_commands, fallback_to_first=False) if fixed is not None: - return command.script.replace(stash_cmd, fixed) + return replace_argument(command.script, stash_cmd, fixed) else: cmd = command.script.split() cmd.insert(2, 'save') diff --git a/thefuck/rules/git_not_command.py b/thefuck/rules/git_not_command.py index 81214b85..0eb5fbf9 100644 --- a/thefuck/rules/git_not_command.py +++ b/thefuck/rules/git_not_command.py @@ -1,5 +1,5 @@ import re -from thefuck.utils import get_closest, git_support +from thefuck.utils import get_closest, git_support, replace_argument @git_support @@ -23,5 +23,5 @@ def get_new_command(command, settings): command.stderr)[0] new_cmd = get_closest(broken_cmd, _get_all_git_matched_commands(command.stderr)) - return command.script.replace(broken_cmd, new_cmd, 1) + return replace_argument(command.script, broken_cmd, new_cmd) diff --git a/thefuck/rules/git_pull_clone.py b/thefuck/rules/git_pull_clone.py index 79472ea0..a62f941c 100644 --- a/thefuck/rules/git_pull_clone.py +++ b/thefuck/rules/git_pull_clone.py @@ -1,4 +1,5 @@ from thefuck import utils +from thefuck.utils import replace_argument @utils.git_support @@ -9,4 +10,4 @@ def match(command, settings): @utils.git_support def get_new_command(command, settings): - return command.script.replace(' pull ', ' clone ') + return replace_argument(command.script, 'pull', 'clone') diff --git a/thefuck/rules/git_push_force.py b/thefuck/rules/git_push_force.py index 5b3f25d5..5016545c 100644 --- a/thefuck/rules/git_push_force.py +++ b/thefuck/rules/git_push_force.py @@ -1,4 +1,5 @@ from thefuck import utils +from thefuck.utils import replace_argument @utils.git_support @@ -11,7 +12,7 @@ def match(command, settings): @utils.git_support def get_new_command(command, settings): - return command.script.replace('push', 'push --force') + return replace_argument(command.script, 'push', 'push --force') enabled_by_default = False diff --git a/thefuck/rules/git_push_pull.py b/thefuck/rules/git_push_pull.py index 7ae7b9a8..3529a182 100644 --- a/thefuck/rules/git_push_pull.py +++ b/thefuck/rules/git_push_pull.py @@ -1,5 +1,6 @@ from thefuck import utils from thefuck.shells import and_ +from thefuck.utils import replace_argument @utils.git_support @@ -12,5 +13,5 @@ def match(command, settings): @utils.git_support def get_new_command(command, settings): - return and_(command.script.replace('push', 'pull'), + return and_(replace_argument(command.script, 'push', 'pull'), command.script) diff --git a/thefuck/rules/heroku_not_command.py b/thefuck/rules/heroku_not_command.py index ca14f74d..04600b31 100644 --- a/thefuck/rules/heroku_not_command.py +++ b/thefuck/rules/heroku_not_command.py @@ -1,5 +1,5 @@ import re -from thefuck.utils import get_closest +from thefuck.utils import get_closest, replace_argument def match(command, settings): @@ -17,4 +17,4 @@ def _get_suggests(stderr): def get_new_command(command, settings): wrong = re.findall(r'`(\w+)` is not a heroku command', command.stderr)[0] correct = get_closest(wrong, _get_suggests(command.stderr)) - return command.script.replace(' {}'.format(wrong), ' {}'.format(correct), 1) + return replace_argument(command.script, wrong, correct) diff --git a/thefuck/rules/lein_not_task.py b/thefuck/rules/lein_not_task.py index a0432633..6ecdd38b 100644 --- a/thefuck/rules/lein_not_task.py +++ b/thefuck/rules/lein_not_task.py @@ -1,5 +1,5 @@ import re -from thefuck.utils import sudo_support +from thefuck.utils import sudo_support, replace_argument @sudo_support @@ -15,4 +15,4 @@ def get_new_command(command, settings): command.stderr)[0] new_cmd = re.findall(r'Did you mean this\?\n\s*([^\n]*)', command.stderr)[0] - return command.script.replace(broken_cmd, new_cmd, 1) + return replace_argument(command.script, broken_cmd, new_cmd) diff --git a/thefuck/rules/pip_unknown_command.py b/thefuck/rules/pip_unknown_command.py index 162258e2..9ae185d3 100644 --- a/thefuck/rules/pip_unknown_command.py +++ b/thefuck/rules/pip_unknown_command.py @@ -1,4 +1,5 @@ import re +from thefuck.utils import replace_argument def match(command, settings): @@ -12,4 +13,4 @@ def get_new_command(command, settings): command.stderr)[0] new_cmd = re.findall(r'maybe you meant \"([a-z]+)\"', command.stderr)[0] - return command.script.replace(broken_cmd, new_cmd, 1) + return replace_argument(command.script, broken_cmd, new_cmd) diff --git a/thefuck/rules/tmux.py b/thefuck/rules/tmux.py index 683ee46e..719e8208 100644 --- a/thefuck/rules/tmux.py +++ b/thefuck/rules/tmux.py @@ -1,4 +1,4 @@ -from thefuck.utils import get_closest +from thefuck.utils import get_closest, replace_argument import re @@ -17,4 +17,4 @@ def get_new_command(command, settings): new_cmd = get_closest(old_cmd, suggestions) - return command.script.replace(old_cmd, new_cmd) + return replace_argument(command.script, old_cmd, new_cmd) diff --git a/thefuck/utils.py b/thefuck/utils.py index 5be2c2bb..8bd6dc75 100644 --- a/thefuck/utils.py +++ b/thefuck/utils.py @@ -148,3 +148,14 @@ def get_all_executables(): for exe in _safe(lambda: list(Path(path).iterdir()), []) if not _safe(exe.is_dir, True)] + [ alias for alias in get_aliases() if alias != tf_alias] + + +def replace_argument(script, from_, to): + """Replaces command line argument.""" + replaced_in_the_end = re.sub(u' {}$'.format(from_), u' {}'.format(to), + script, count=1) + if replaced_in_the_end != script: + return replaced_in_the_end + else: + return script.replace( + u' {} '.format(from_), u' {} '.format(to), 1)