mirror of
https://github.com/nvbn/thefuck.git
synced 2025-11-02 08:02:04 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fb990742d | ||
|
|
cf3dca6f51 | ||
|
|
5187bada1b | ||
|
|
0238569b71 | ||
|
|
463b4fef2f | ||
|
|
f90bac10ed | ||
|
|
90014b2b05 | ||
|
|
4276cacaf6 | ||
|
|
b31aea3737 | ||
|
|
5d0912fee8 | ||
|
|
f6a4902074 | ||
|
|
707d91200e | ||
|
|
b3e09d68df |
@@ -6,4 +6,8 @@ python:
|
|||||||
install:
|
install:
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
- python setup.py develop
|
- python setup.py develop
|
||||||
script: py.test -v
|
- pip install coveralls
|
||||||
|
script:
|
||||||
|
- export COVERAGE_PYTHON_VERSION=python-${TRAVIS_PYTHON_VERSION:0:1}
|
||||||
|
- coverage run --source=thefuck,tests -m py.test -v
|
||||||
|
after_success: coveralls
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# The Fuck [](https://travis-ci.org/nvbn/thefuck)
|
# The Fuck [](https://travis-ci.org/nvbn/thefuck) [](https://coveralls.io/github/nvbn/thefuck?branch=master)
|
||||||
|
|
||||||
**Aliases changed in 1.34.**
|
**Aliases changed in 1.34.**
|
||||||
|
|
||||||
@@ -6,7 +6,9 @@ Magnificent app which corrects your previous console command,
|
|||||||
inspired by a [@liamosaur](https://twitter.com/liamosaur/)
|
inspired by a [@liamosaur](https://twitter.com/liamosaur/)
|
||||||
[tweet](https://twitter.com/liamosaur/status/506975850596536320).
|
[tweet](https://twitter.com/liamosaur/status/506975850596536320).
|
||||||
|
|
||||||
Few examples:
|

|
||||||
|
|
||||||
|
Few more examples:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
➜ apt-get install vim
|
➜ apt-get install vim
|
||||||
@@ -159,6 +161,7 @@ using the matched rule and runs it. Rules enabled by default are as follows:
|
|||||||
* `dry` – fix repetitions like "git git push";
|
* `dry` – fix repetitions like "git git push";
|
||||||
* `fix_alt_space` – replaces Alt+Space with Space character;
|
* `fix_alt_space` – replaces Alt+Space with Space character;
|
||||||
* `git_add` – fix *"Did you forget to 'git add'?"*;
|
* `git_add` – fix *"Did you forget to 'git add'?"*;
|
||||||
|
* `git_branch_delete` – changes `git branch -d` to `git branch -D`;
|
||||||
* `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch;
|
* `git_branch_list` – catches `git branch list` in place of `git branch` and removes created branch;
|
||||||
* `git_checkout` – creates the branch before checking-out;
|
* `git_checkout` – creates the branch before checking-out;
|
||||||
* `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output;
|
* `git_diff_staged` – adds `--staged` to previous `git diff` with unexpected output;
|
||||||
@@ -250,7 +253,7 @@ priority = 1000 # Lower first
|
|||||||
The Fuck has a few settings parameters which can be changed in `~/.thefuck/settings.py`:
|
The Fuck has a few settings parameters which can be changed in `~/.thefuck/settings.py`:
|
||||||
|
|
||||||
* `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
|
* `rules` – list of enabled rules, by default `thefuck.conf.DEFAULT_RULES`;
|
||||||
* `require_confirmation` – requires confirmation before running new command, by default `False`;
|
* `require_confirmation` – requires confirmation before running new command, by default `True`;
|
||||||
* `wait_command` – max amount of time in seconds for getting previous command output;
|
* `wait_command` – max amount of time in seconds for getting previous command output;
|
||||||
* `no_colors` – disable colored output;
|
* `no_colors` – disable colored output;
|
||||||
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
|
* `priority` – dict with rules priorities, rule with lower `priority` will be matched first;
|
||||||
|
|||||||
BIN
example.gif
Normal file
BIN
example.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 704 KiB |
2
setup.py
2
setup.py
@@ -11,7 +11,7 @@ elif (3, 0) < sys.version_info < (3, 3):
|
|||||||
' ({}.{} detected).'.format(*sys.version_info[:2]))
|
' ({}.{} detected).'.format(*sys.version_info[:2]))
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
VERSION = '1.49.1'
|
VERSION = '2.0'
|
||||||
|
|
||||||
install_requires = ['psutil', 'colorama', 'six']
|
install_requires = ['psutil', 'colorama', 'six']
|
||||||
extras_require = {':python_version<"3.4"': ['pathlib']}
|
extras_require = {':python_version<"3.4"': ['pathlib']}
|
||||||
|
|||||||
22
tests/rules/test_git_branch_delete.py
Normal file
22
tests/rules/test_git_branch_delete.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import pytest
|
||||||
|
from thefuck.rules.git_branch_delete import match, get_new_command
|
||||||
|
from tests.utils import Command
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def stderr():
|
||||||
|
return '''error: The branch 'branch' is not fully merged.
|
||||||
|
If you are sure you want to delete it, run 'git branch -D branch'.
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def test_match(stderr):
|
||||||
|
assert match(Command('git branch -d branch', stderr=stderr), None)
|
||||||
|
assert not match(Command('git branch -d branch'), None)
|
||||||
|
assert not match(Command('ls', stderr=stderr), None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_new_command(stderr):
|
||||||
|
assert get_new_command(Command('git branch -d branch', stderr=stderr), None)\
|
||||||
|
== "git branch -D branch"
|
||||||
@@ -3,15 +3,13 @@ from thefuck.rules.git_diff_staged import match, get_new_command
|
|||||||
from tests.utils import Command
|
from tests.utils import Command
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command', [
|
@pytest.mark.parametrize('command', [Command(script='git diff')])
|
||||||
Command(script='git diff'),
|
|
||||||
Command(script='git df'),
|
|
||||||
Command(script='git ds')])
|
|
||||||
def test_match(command):
|
def test_match(command):
|
||||||
assert match(command, None)
|
assert match(command, None)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command', [
|
@pytest.mark.parametrize('command', [
|
||||||
|
Command(script='git diff --staged'),
|
||||||
Command(script='git tag'),
|
Command(script='git tag'),
|
||||||
Command(script='git branch'),
|
Command(script='git branch'),
|
||||||
Command(script='git log')])
|
Command(script='git log')])
|
||||||
@@ -20,8 +18,6 @@ def test_not_match(command):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command, new_command', [
|
@pytest.mark.parametrize('command, new_command', [
|
||||||
(Command('git diff'), 'git diff --staged'),
|
(Command('git diff'), 'git diff --staged')])
|
||||||
(Command('git df'), 'git df --staged'),
|
|
||||||
(Command('git ds'), 'git ds --staged')])
|
|
||||||
def test_get_new_command(command, new_command):
|
def test_get_new_command(command, new_command):
|
||||||
assert get_new_command(command, None) == new_command
|
assert get_new_command(command, None) == new_command
|
||||||
|
|||||||
@@ -3,22 +3,20 @@ from thefuck.rules.git_stash import match, get_new_command
|
|||||||
from tests.utils import Command
|
from tests.utils import Command
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
cherry_pick_error = (
|
||||||
def cherry_pick_error():
|
'error: Your local changes would be overwritten by cherry-pick.\n'
|
||||||
return ('error: Your local changes would be overwritten by cherry-pick.\n'
|
'hint: Commit your changes or stash them to proceed.\n'
|
||||||
'hint: Commit your changes or stash them to proceed.\n'
|
'fatal: cherry-pick failed')
|
||||||
'fatal: cherry-pick failed')
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
rebase_error = (
|
||||||
def rebase_error():
|
'Cannot rebase: Your index contains uncommitted changes.\n'
|
||||||
return ('Cannot rebase: Your index contains uncommitted changes.\n'
|
'Please commit or stash them.')
|
||||||
'Please commit or stash them.')
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('command', [
|
@pytest.mark.parametrize('command', [
|
||||||
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error()),
|
Command(script='git cherry-pick a1b2c3d', stderr=cherry_pick_error),
|
||||||
Command(script='git rebase -i HEAD~7', stderr=rebase_error())])
|
Command(script='git rebase -i HEAD~7', stderr=rebase_error)])
|
||||||
def test_match(command):
|
def test_match(command):
|
||||||
assert match(command, None)
|
assert match(command, None)
|
||||||
|
|
||||||
|
|||||||
@@ -77,23 +77,23 @@ class TestGetCommand(object):
|
|||||||
monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x)
|
monkeypatch.setattr('thefuck.shells.to_shell', lambda x: x)
|
||||||
|
|
||||||
def test_get_command_calls(self, Popen):
|
def test_get_command_calls(self, Popen):
|
||||||
assert main.get_command(Mock(),
|
assert main.get_command(Mock(env={}),
|
||||||
['thefuck', 'apt-get', 'search', 'vim']) \
|
['thefuck', 'apt-get', 'search', 'vim']) \
|
||||||
== Command('apt-get search vim', 'stdout', 'stderr')
|
== Command('apt-get search vim', 'stdout', 'stderr')
|
||||||
Popen.assert_called_once_with('apt-get search vim',
|
Popen.assert_called_once_with('apt-get search vim',
|
||||||
shell=True,
|
shell=True,
|
||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
stderr=PIPE,
|
stderr=PIPE,
|
||||||
env={'LANG': 'C'})
|
env={})
|
||||||
|
|
||||||
@pytest.mark.parametrize('args, result', [
|
@pytest.mark.parametrize('args, result', [
|
||||||
(['thefuck', 'ls', '-la'], 'ls -la'),
|
(['thefuck', 'ls', '-la'], 'ls -la'),
|
||||||
(['thefuck', 'ls'], 'ls')])
|
(['thefuck', 'ls'], 'ls')])
|
||||||
def test_get_command_script(self, args, result):
|
def test_get_command_script(self, args, result):
|
||||||
if result:
|
if result:
|
||||||
assert main.get_command(Mock(), args).script == result
|
assert main.get_command(Mock(env={}), args).script == result
|
||||||
else:
|
else:
|
||||||
assert main.get_command(Mock(), args) is None
|
assert main.get_command(Mock(env={}), args) is None
|
||||||
|
|
||||||
|
|
||||||
class TestGetMatchedRule(object):
|
class TestGetMatchedRule(object):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from mock import Mock
|
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 thefuck.types import Settings
|
||||||
from tests.utils import Command
|
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)
|
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():
|
def test_memoize():
|
||||||
fn = Mock(__name__='fn')
|
fn = Mock(__name__='fn')
|
||||||
memoized = memoize(fn)
|
memoized = memoize(fn)
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ DEFAULT_PRIORITY = 1000
|
|||||||
|
|
||||||
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
|
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
|
||||||
'wait_command': 3,
|
'wait_command': 3,
|
||||||
'require_confirmation': False,
|
'require_confirmation': True,
|
||||||
'no_colors': False,
|
'no_colors': False,
|
||||||
'debug': False,
|
'debug': False,
|
||||||
'priority': {}}
|
'priority': {},
|
||||||
|
'env': {'LANG': 'C', 'GIT_TRACE': '1'}}
|
||||||
|
|
||||||
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
||||||
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
'THEFUCK_WAIT_COMMAND': 'wait_command',
|
||||||
|
|||||||
@@ -81,8 +81,12 @@ def get_command(settings, args):
|
|||||||
|
|
||||||
script = shells.from_shell(script)
|
script = shells.from_shell(script)
|
||||||
logs.debug('Call: {}'.format(script), settings)
|
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):
|
if wait_output(settings, result):
|
||||||
return types.Command(script, result.stdout.read().decode('utf-8'),
|
return types.Command(script, result.stdout.read().decode('utf-8'),
|
||||||
result.stderr.read().decode('utf-8'))
|
result.stderr.read().decode('utf-8'))
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import re
|
import re
|
||||||
from thefuck import shells
|
from thefuck import utils, shells
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('git' in command.script
|
||||||
and 'did not match any file(s) known to git.' in command.stderr
|
and 'did not match any file(s) known to git.' in command.stderr
|
||||||
and "Did you forget to 'git add'?" in command.stderr)
|
and "Did you forget to 'git add'?" in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
missing_file = re.findall(
|
missing_file = re.findall(
|
||||||
r"error: pathspec '([^']*)' "
|
r"error: pathspec '([^']*)' "
|
||||||
|
|||||||
7
thefuck/rules/git_branch_delete.py
Normal file
7
thefuck/rules/git_branch_delete.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
def match(command, settings):
|
||||||
|
return ('git branch -d' in command.script
|
||||||
|
and 'If you are sure you want to delete it' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def get_new_command(command, settings):
|
||||||
|
return command.script.replace('-d', '-D')
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
from thefuck import shells
|
from thefuck import utils, shells
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
# catches "git branch list" in place of "git branch"
|
# catches "git branch list" in place of "git branch"
|
||||||
return command.script.split() == 'git branch list'.split()
|
return command.script.split() == 'git branch list'.split()
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
return shells.and_('git branch --delete list', 'git branch')
|
return shells.and_('git branch --delete list', 'git branch')
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import re
|
import re
|
||||||
from thefuck import shells
|
from thefuck import shells, utils
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('git' in command.script
|
||||||
and 'did not match any file(s) known to git.' in command.stderr
|
and 'did not match any file(s) known to git.' in command.stderr
|
||||||
and "Did you forget to 'git add'?" not in command.stderr)
|
and "Did you forget to 'git add'?" not in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
missing_file = re.findall(
|
missing_file = re.findall(
|
||||||
r"error: pathspec '([^']*)' "
|
r"error: pathspec '([^']*)' "
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
|
from thefuck import utils
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
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):
|
def get_new_command(command, settings):
|
||||||
return '{} --staged'.format(command.script)
|
return '{} --staged'.format(command.script)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from difflib import get_close_matches
|
|
||||||
import re
|
import re
|
||||||
from thefuck.utils import get_closest
|
from thefuck.utils import get_closest, git_support
|
||||||
|
|
||||||
|
|
||||||
|
@git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('git' in command.script
|
||||||
and " is not a git command. See 'git --help'." in command.stderr
|
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()
|
yield line.strip()
|
||||||
|
|
||||||
|
|
||||||
|
@git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
broken_cmd = re.findall(r"git: '([^']*)' is not a git command",
|
broken_cmd = re.findall(r"git: '([^']*)' is not a git command",
|
||||||
command.stderr)[0]
|
command.stderr)[0]
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
from thefuck import shells
|
from thefuck import shells, utils
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('git' in command.script
|
||||||
and 'pull' in command.script
|
and 'pull' in command.script
|
||||||
and 'set-upstream' in command.stderr)
|
and 'set-upstream' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
line = command.stderr.split('\n')[-3].strip()
|
line = command.stderr.split('\n')[-3].strip()
|
||||||
branch = line.split(' ')[-1]
|
branch = line.split(' ')[-1]
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
from thefuck import utils
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
return ('git' in command.script
|
return ('git' in command.script
|
||||||
and 'push' in command.script
|
and 'push' in command.script
|
||||||
and 'set-upstream' in command.stderr)
|
and 'set-upstream' in command.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
return command.stderr.split('\n')[-3].strip()
|
return command.stderr.split('\n')[-3].strip()
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
from thefuck import shells
|
from thefuck import shells, utils
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def match(command, settings):
|
def match(command, settings):
|
||||||
# catches "Please commit or stash them" and "Please, commit your changes or
|
# catches "Please commit or stash them" and "Please, commit your changes or
|
||||||
# stash them before you can switch branches."
|
# stash them before you can switch branches."
|
||||||
return 'git' in command.script and 'or stash them' in command.stderr
|
return 'git' in command.script and 'or stash them' in command.stderr
|
||||||
|
|
||||||
|
|
||||||
|
@utils.git_support
|
||||||
def get_new_command(command, settings):
|
def get_new_command(command, settings):
|
||||||
formatme = shells.and_('git stash', '{}')
|
formatme = shells.and_('git stash', '{}')
|
||||||
return formatme.format(command.script)
|
return formatme.format(command.script)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from time import time
|
|||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
from psutil import Process
|
from psutil import Process
|
||||||
import six
|
|
||||||
from .utils import DEVNULL, memoize
|
from .utils import DEVNULL, memoize
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
from difflib import get_close_matches
|
from difflib import get_close_matches
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from shlex import split
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
|
import re
|
||||||
import six
|
import six
|
||||||
from .types import Command
|
from .types import Command
|
||||||
|
|
||||||
@@ -9,11 +11,9 @@ from .types import Command
|
|||||||
DEVNULL = open(os.devnull, 'w')
|
DEVNULL = open(os.devnull, 'w')
|
||||||
|
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
import pipes
|
from pipes import quote
|
||||||
quote = pipes.quote
|
|
||||||
else:
|
else:
|
||||||
import shlex
|
from shlex import quote
|
||||||
quote = shlex.quote
|
|
||||||
|
|
||||||
|
|
||||||
def which(program):
|
def which(program):
|
||||||
@@ -73,6 +73,30 @@ def sudo_support(fn):
|
|||||||
return wrapper
|
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):
|
def memoize(fn):
|
||||||
"""Caches previous calls to the function."""
|
"""Caches previous calls to the function."""
|
||||||
memo = {}
|
memo = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user