From 8d77a2d528ae7fcc29ce557ff1e2e7f80da998f3 Mon Sep 17 00:00:00 2001 From: Pablo Santiago Blum de Aguiar Date: Sun, 5 Jul 2015 20:59:48 -0300 Subject: [PATCH] improve(rules): add mercurial (hg) support Fix #269 --- tests/rules/test_mercurial.py | 134 ++++++++++++++++++++++++++++++++++ thefuck/rules/mercurial.py | 34 +++++++++ 2 files changed, 168 insertions(+) create mode 100644 tests/rules/test_mercurial.py create mode 100644 thefuck/rules/mercurial.py diff --git a/tests/rules/test_mercurial.py b/tests/rules/test_mercurial.py new file mode 100644 index 00000000..08962f91 --- /dev/null +++ b/tests/rules/test_mercurial.py @@ -0,0 +1,134 @@ +import pytest + +from tests.utils import Command +from thefuck.rules.mercurial import ( + extract_possisiblities, match, get_new_command +) + + +@pytest.mark.parametrize('command', [ + Command('hg base', stderr=( + "hg: unknown command 'base'" + '\n(did you mean one of blame, phase, rebase?)' + )), + Command('hg branchch', stderr=( + "hg: unknown command 'branchch'" + '\n(did you mean one of branch, branches?)' + )), + Command('hg vert', stderr=( + "hg: unknown command 'vert'" + '\n(did you mean one of revert?)' + )), + Command('hg lgo -r tip', stderr=( + "hg: command 're' is ambiguous:" + '\n(did you mean one of log?)' + )), + Command('hg rerere', stderr=( + "hg: unknown command 'rerere'" + '\n(did you mean one of revert?)' + )), + Command('hg re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), + Command('hg re re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), +]) +def test_match(command): + assert match(command, None) + + +@pytest.mark.parametrize('command', [ + Command('hg', stderr=( + '\nMercurial Distributed SCM\n\nbasic commands:' + )), + Command('hg asdf', stderr=( + "hg: unknown command 'asdf'" + '\nMercurial Distributed SCM\n\nbasic commands:' + )), + Command('hg qwer', stderr=( + "hg: unknown command 'qwer'" + '\nMercurial Distributed SCM\n\nbasic commands:' + )), + Command('hg me', stderr=( + "\nabort: no repository found in './thefuck' (.hg not found)!" + )), + Command('hg reb', stderr=( + "\nabort: no repository found in './thefuck' (.hg not found)!" + )), + Command('hg co', stderr=( + "\nabort: no repository found in './thefuck' (.hg not found)!" + )), +]) +def test_not_match(command): + assert not match(command, None) + + +@pytest.mark.parametrize('command, possibilities', [ + (Command('hg base', stderr=( + "hg: unknown command 'base'" + '\n(did you mean one of blame, phase, rebase?)' + )), ['blame', 'phase', 'rebase']), + (Command('hg branchch', stderr=( + "hg: unknown command 'branchch'" + '\n(did you mean one of branch, branches?)' + )), ['branch', 'branches']), + (Command('hg vert', stderr=( + "hg: unknown command 'vert'" + '\n(did you mean one of revert?)' + )), ['revert']), + (Command('hg lgo -r tip', stderr=( + "hg: command 're' is ambiguous:" + '\n(did you mean one of log?)' + )), ['log']), + (Command('hg rerere', stderr=( + "hg: unknown command 'rerere'" + '\n(did you mean one of revert?)' + )), ['revert']), + (Command('hg re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), ['rebase', 'recover', 'remove', 'rename', 'resolve', 'revert']), + (Command('hg re re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), ['rebase', 'recover', 'remove', 'rename', 'resolve', 'revert']), +]) +def test_extract_possisiblities(command, possibilities): + assert extract_possisiblities(command) == possibilities + + +@pytest.mark.parametrize('command, new_command', [ + (Command('hg base', stderr=( + "hg: unknown command 'base'" + '\n(did you mean one of blame, phase, rebase?)' + )), 'hg rebase'), + (Command('hg branchch', stderr=( + "hg: unknown command 'branchch'" + '\n(did you mean one of branch, branches?)' + )), 'hg branch'), + (Command('hg vert', stderr=( + "hg: unknown command 'vert'" + '\n(did you mean one of revert?)' + )), 'hg revert'), + (Command('hg lgo -r tip', stderr=( + "hg: command 're' is ambiguous:" + '\n(did you mean one of log?)' + )), 'hg log -r tip'), + (Command('hg rerere', stderr=( + "hg: unknown command 'rerere'" + '\n(did you mean one of revert?)' + )), 'hg revert'), + (Command('hg re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), 'hg rebase'), + (Command('hg re re', stderr=( + "hg: command 're' is ambiguous:" + '\n rebase recover remove rename resolve revert' + )), 'hg rebase re'), +]) +def test_get_new_command(command, new_command): + assert get_new_command(command, None) == new_command diff --git a/thefuck/rules/mercurial.py b/thefuck/rules/mercurial.py new file mode 100644 index 00000000..934e3f1e --- /dev/null +++ b/thefuck/rules/mercurial.py @@ -0,0 +1,34 @@ +import re + +from difflib import get_close_matches + + +def extract_possisiblities(command): + possib = re.findall(r'\n\(did you mean one of ([^\?]+)\?\)', command.stderr) + if possib: + return possib[0].split(', ') + possib = re.findall(r'\n ([^$]+)$', command.stderr) + if possib: + return possib[0].split(' ') + return possib + + +def match(command, settings): + return (command.script.startswith('hg ') + and ('hg: unknown command' in command.stderr + and '(did you mean one of ' in command.stderr + or "hg: command '" in command.stderr + and "' is ambiguous:" in command.stderr + ) + ) + + +def get_new_command(command, settings): + script = command.script.split(' ') + possisiblities = extract_possisiblities(command) + matches = get_close_matches(script[1], possisiblities) + if matches: + script[1] = matches[0] + else: + script[1] = possisiblities[0] + return ' '.join(script)