1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-02-20 20:09:07 +00:00

Merge branch 'mcarton-git-aliases'

This commit is contained in:
nvbn 2015-07-19 21:29:39 +03:00
commit 463b4fef2f
15 changed files with 93 additions and 38 deletions

View File

@ -3,15 +3,13 @@ from thefuck.rules.git_diff_staged import match, get_new_command
from tests.utils import Command
@pytest.mark.parametrize('command', [
Command(script='git diff'),
Command(script='git df'),
Command(script='git ds')])
@pytest.mark.parametrize('command', [Command(script='git diff')])
def test_match(command):
assert match(command, None)
@pytest.mark.parametrize('command', [
Command(script='git diff --staged'),
Command(script='git tag'),
Command(script='git branch'),
Command(script='git log')])
@ -20,8 +18,6 @@ def test_not_match(command):
@pytest.mark.parametrize('command, new_command', [
(Command('git diff'), 'git diff --staged'),
(Command('git df'), 'git df --staged'),
(Command('git ds'), 'git ds --staged')])
(Command('git diff'), 'git diff --staged')])
def test_get_new_command(command, new_command):
assert get_new_command(command, None) == new_command

View File

@ -3,22 +3,20 @@ from thefuck.rules.git_stash import match, get_new_command
from tests.utils import Command
@pytest.fixture
def cherry_pick_error():
return ('error: Your local changes would be overwritten by cherry-pick.\n'
'hint: Commit your changes or stash them to proceed.\n'
'fatal: cherry-pick failed')
cherry_pick_error = (
'error: Your local changes would be overwritten by cherry-pick.\n'
'hint: Commit your changes or stash them to proceed.\n'
'fatal: cherry-pick failed')
@pytest.fixture
def rebase_error():
return ('Cannot rebase: Your index contains uncommitted changes.\n'
'Please commit or stash them.')
rebase_error = (
'Cannot rebase: Your index contains uncommitted changes.\n'
'Please commit or stash them.')
@pytest.mark.parametrize('command', [
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error()),
Command(script='git rebase -i HEAD~7', stderr=rebase_error())])
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error),
Command(script='git rebase -i HEAD~7', stderr=rebase_error)])
def test_match(command):
assert match(command, None)

View File

@ -77,23 +77,23 @@ class TestGetCommand(object):
monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x)
def test_get_command_calls(self, Popen):
assert main.get_command(Mock(),
assert main.get_command(Mock(env={}),
['thefuck', 'apt-get', 'search', 'vim']) \
== Command('apt-get search vim', 'stdout', 'stderr')
Popen.assert_called_once_with('apt-get search vim',
shell=True,
stdout=PIPE,
stderr=PIPE,
env={'LANG': 'C'})
env={})
@pytest.mark.parametrize('args, result', [
(['thefuck', 'ls', '-la'], 'ls -la'),
(['thefuck', 'ls'], 'ls')])
def test_get_command_script(self, args, result):
if result:
assert main.get_command(Mock(), args).script == result
assert main.get_command(Mock(env={}), args).script == result
else:
assert main.get_command(Mock(), args) is None
assert main.get_command(Mock(env={}), args) is None
class TestGetMatchedRule(object):

View File

@ -1,6 +1,6 @@
import pytest
from mock import Mock
from thefuck.utils import sudo_support, wrap_settings, memoize, get_closest
from thefuck.utils import git_support, sudo_support, wrap_settings, memoize, get_closest
from thefuck.types import Settings
from tests.utils import Command
@ -26,6 +26,15 @@ def test_sudo_support(return_value, command, called, result):
fn.assert_called_once_with(Command(called), None)
@pytest.mark.parametrize('called, command, stderr', [
('git co', 'git checkout', "19:22:36.299340 git.c:282 trace: alias expansion: co => 'checkout'"),
('git com file', 'git commit --verbose file', "19:23:25.470911 git.c:282 trace: alias expansion: com => 'commit' '--verbose'")])
def test_git_support(called, command, stderr):
@git_support
def fn(command, settings): return command.script
assert fn(Command(script=called, stderr=stderr), None) == command
def test_memoize():
fn = Mock(__name__='fn')
memoized = memoize(fn)

View File

@ -30,7 +30,8 @@ DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
'require_confirmation': False,
'no_colors': False,
'debug': False,
'priority': {}}
'priority': {},
'env': {'LANG': 'C', 'GIT_TRACE': '1'}}
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
'THEFUCK_WAIT_COMMAND': 'wait_command',

View File

@ -81,8 +81,12 @@ def get_command(settings, args):
script = shells.from_shell(script)
logs.debug('Call: {}'.format(script), settings)
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE,
env=dict(os.environ, LANG='C'))
env = dict(os.environ)
env.update(settings.env)
logs.debug('Executing with env: {}'.format(env), settings)
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
if wait_output(settings, result):
return types.Command(script, result.stdout.read().decode('utf-8'),
result.stderr.read().decode('utf-8'))

View File

@ -1,13 +1,15 @@
import re
from thefuck import shells
from thefuck import utils, shells
@utils.git_support
def match(command, settings):
return ('git' in command.script
and 'did not match any file(s) known to git.' in command.stderr
and "Did you forget to 'git add'?" in command.stderr)
@utils.git_support
def get_new_command(command, settings):
missing_file = re.findall(
r"error: pathspec '([^']*)' "

View File

@ -1,10 +1,12 @@
from thefuck import shells
from thefuck import utils, shells
@utils.git_support
def match(command, settings):
# catches "git branch list" in place of "git branch"
return command.script.split() == 'git branch list'.split()
@utils.git_support
def get_new_command(command, settings):
return shells.and_('git branch --delete list', 'git branch')

View File

@ -1,13 +1,15 @@
import re
from thefuck import shells
from thefuck import shells, utils
@utils.git_support
def match(command, settings):
return ('git' in command.script
and 'did not match any file(s) known to git.' in command.stderr
and "Did you forget to 'git add'?" not in command.stderr)
@utils.git_support
def get_new_command(command, settings):
missing_file = re.findall(
r"error: pathspec '([^']*)' "

View File

@ -1,6 +1,13 @@
from thefuck import utils
@utils.git_support
def match(command, settings):
return command.script.startswith('git d')
return ('git' in command.script and
'diff' in command.script and
'--staged' not in command.script)
@utils.git_support
def get_new_command(command, settings):
return '{} --staged'.format(command.script)

View File

@ -1,8 +1,8 @@
from difflib import get_close_matches
import re
from thefuck.utils import get_closest
from thefuck.utils import get_closest, git_support
@git_support
def match(command, settings):
return ('git' in command.script
and " is not a git command. See 'git --help'." in command.stderr
@ -18,6 +18,7 @@ def _get_all_git_matched_commands(stderr):
yield line.strip()
@git_support
def get_new_command(command, settings):
broken_cmd = re.findall(r"git: '([^']*)' is not a git command",
command.stderr)[0]

View File

@ -1,12 +1,14 @@
from thefuck import shells
from thefuck import shells, utils
@utils.git_support
def match(command, settings):
return ('git' in command.script
and 'pull' in command.script
and 'set-upstream' in command.stderr)
@utils.git_support
def get_new_command(command, settings):
line = command.stderr.split('\n')[-3].strip()
branch = line.split(' ')[-1]

View File

@ -1,8 +1,13 @@
from thefuck import utils
@utils.git_support
def match(command, settings):
return ('git' in command.script
and 'push' in command.script
and 'set-upstream' in command.stderr)
@utils.git_support
def get_new_command(command, settings):
return command.stderr.split('\n')[-3].strip()

View File

@ -1,12 +1,14 @@
from thefuck import shells
from thefuck import shells, utils
@utils.git_support
def match(command, settings):
# catches "Please commit or stash them" and "Please, commit your changes or
# stash them before you can switch branches."
return 'git' in command.script and 'or stash them' in command.stderr
@utils.git_support
def get_new_command(command, settings):
formatme = shells.and_('git stash', '{}')
return formatme.format(command.script)

View File

@ -1,7 +1,9 @@
from difflib import get_close_matches
from functools import wraps
from shlex import split
import os
import pickle
import re
import six
from .types import Command
@ -9,11 +11,9 @@ from .types import Command
DEVNULL = open(os.devnull, 'w')
if six.PY2:
import pipes
quote = pipes.quote
from pipes import quote
else:
import shlex
quote = shlex.quote
from shlex import quote
def which(program):
@ -73,6 +73,30 @@ def sudo_support(fn):
return wrapper
def git_support(fn):
"""Resolve git aliases."""
@wraps(fn)
def wrapper(command, settings):
if (command.script.startswith('git') and
'trace: alias expansion:' in command.stderr):
search = re.search("trace: alias expansion: ([^ ]*) => ([^\n]*)",
command.stderr)
alias = search.group(1)
# by default git quotes everything, for example:
# 'commit' '--amend'
# which is surprising and does not allow to easily test for
# eg. 'git commit'
expansion = ' '.join(map(quote, split(search.group(2))))
new_script = command.script.replace(alias, expansion)
command = Command._replace(command, script=new_script)
return fn(command, settings)
return wrapper
def memoize(fn):
"""Caches previous calls to the function."""
memo = {}