1
0
mirror of https://github.com/nvbn/thefuck.git synced 2025-11-01 23:51:59 +00:00

Compare commits

..

8 Commits
3.8 ... 3.9

Author SHA1 Message Date
nvbn
f74bbb7a9a Bump to 3.9 2016-04-24 17:56:06 +03:00
nvbn
d6c2c7266d Merge branch 'scorphus-fish-put-to-history' 2016-04-22 03:17:40 +03:00
nvbn
51839e65cd #495: Add comment in put_to_history 2016-04-22 03:16:16 +03:00
nvbn
d5ae3a6b41 Merge branch 'fish-put-to-history' of https://github.com/scorphus/thefuck into scorphus-fish-put-to-history
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2016-04-22 03:14:31 +03:00
Vladimir Iakovlev
9f421a17e5 Merge pull request #494 from scorphus/brew-update-formula
#N/A Add a new rule `brew_update_formula`
2016-04-21 13:06:11 +03:00
Pablo Santiago Blum de Aguiar
9d9820676a #N/A Add a new rule brew_update_formula 2016-04-20 22:27:39 -03:00
nvbn
5ec4909d2f #N/A: Minor style changes 2016-04-12 00:37:18 +03:00
nvbn
c6d2766553 #N/A: Add chmod +x rule 2016-04-11 16:13:41 +03:00
11 changed files with 139 additions and 3 deletions

View File

@@ -144,6 +144,7 @@ using the matched rule and runs it. Rules enabled by default are as follows:
* `cd_correction` – spellchecks and correct failed cd commands;
* `cd_mkdir` – creates directories before cd'ing into them;
* `cd_parent` – changes `cd..` to `cd ..`;
* `chmod_x` – add execution bit;
* `composer_not_command` – fixes composer command name;
* `cp_omitting_directory` – adds `-a` when you `cp` directory;
* `cpp11` – adds missing `-std=c++11` to `g++` or `clang++`;
@@ -221,6 +222,7 @@ Enabled by default only on specific platforms:
* `apt_invalid_operation` – fixes invalid `apt` and `apt-get` calls, like `apt-get isntall vim`;
* `brew_install` – fixes formula name for `brew install`;
* `brew_unknown_command` – fixes wrong brew commands, for example `brew docto/brew doctor`;
* `brew_update_formula` &ndash; turns `brew update <formula>` into `brew upgrade <formula>`;
* `brew_upgrade` &ndash; appends `--all` to `brew upgrade` as per Homebrew's new behaviour;
* `pacman` &ndash; installs app with `pacman` if it is not installed (uses `yaourt` if available);
* `pacman_not_found` &ndash; fixes package name with `pacman` or `yaourt`.

View File

@@ -26,7 +26,7 @@ elif (3, 0) < version < (3, 3):
' ({}.{} detected).'.format(*version))
sys.exit(-1)
VERSION = '3.8'
VERSION = '3.9'
install_requires = ['psutil', 'colorama', 'six', 'decorator']
extras_require = {':python_version<"3.4"': ['pathlib'],

View File

@@ -0,0 +1,30 @@
import pytest
from tests.utils import Command
from thefuck.rules.brew_update_formula import get_new_command, match
@pytest.fixture
def stderr():
return ("Error: This command updates brew itself, and does not take formula"
" names.\nUse 'brew upgrade <formula>'.")
@pytest.fixture
def new_command(formula):
return 'brew upgrade {}'.format(formula)
@pytest.mark.parametrize('script', ['brew update foo', 'brew update bar zap'])
def test_match(stderr, script):
assert match(Command(script=script, stderr=stderr))
@pytest.mark.parametrize('script', ['brew upgrade foo', 'brew update'])
def test_not_match(script):
assert not match(Command(script=script, stderr=''))
@pytest.mark.parametrize('script, formula, ', [
('brew update foo', 'foo'), ('brew update bar zap', 'bar zap')])
def test_get_new_command(stderr, new_command, script, formula):
assert get_new_command(Command(script=script, stderr=stderr)) == new_command

View File

@@ -0,0 +1,39 @@
import pytest
from tests.utils import Command
from thefuck.rules.chmod_x import match, get_new_command
@pytest.fixture
def file_exists(mocker):
return mocker.patch('os.path.exists', return_value=True)
@pytest.fixture
def file_access(mocker):
return mocker.patch('os.access', return_value=False)
@pytest.mark.usefixtures('file_exists', 'file_access')
@pytest.mark.parametrize('script, stderr', [
('./gradlew build', 'gradlew: Permission denied'),
('./install.sh --help', 'install.sh: permission denied')])
def test_match(script, stderr):
assert match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, stderr, exists, callable', [
('./gradlew build', 'gradlew: Permission denied', True, True),
('./gradlew build', 'gradlew: Permission denied', False, False),
('./gradlew build', 'gradlew: error', True, False),
('gradlew build', 'gradlew: Permission denied', True, False)])
def test_not_match(file_exists, file_access, script, stderr, exists, callable):
file_exists.return_value = exists
file_access.return_value = callable
assert not match(Command(script, stderr=stderr))
@pytest.mark.parametrize('script, result', [
('./gradlew build', 'chmod +x gradlew && ./gradlew build'),
('./install.sh --help', 'chmod +x install.sh && ./install.sh --help')])
def test_get_new_command(script, result):
assert get_new_command(Command(script)) == result

View File

@@ -78,3 +78,12 @@ class TestFish(object):
history_lines(['- cmd: ls', ' when: 1432613911',
'- cmd: rm', ' when: 1432613916'])
assert list(shell.get_history()) == ['ls', 'rm']
@pytest.mark.parametrize('entry, entry_utf8', [
('ls', '- cmd: ls\n when: 1430707243\n'),
(u'echo café', '- cmd: echo café\n when: 1430707243\n')])
def test_put_to_history(self, entry, entry_utf8, builtins_open, mocker, shell):
mocker.patch('thefuck.shells.fish.time', return_value=1430707243.3517463)
shell.put_to_history(entry)
builtins_open.return_value.__enter__.return_value. \
write.assert_called_once_with(entry_utf8)

View File

@@ -0,0 +1,12 @@
from thefuck.utils import for_app
@for_app('brew', at_least=2)
def match(command):
return ('update' in command.script
and "Error: This command updates brew itself" in command.stderr
and "Use 'brew upgrade <formula>'" in command.stderr)
def get_new_command(command):
return command.script.replace('update', 'upgrade')

15
thefuck/rules/chmod_x.py Normal file
View File

@@ -0,0 +1,15 @@
import os
from thefuck.shells import shell
def match(command):
return (command.script.startswith('./')
and 'permission denied' in command.stderr.lower()
and os.path.exists(command.script_parts[0])
and not os.access(command.script_parts[0], os.X_OK))
def get_new_command(command):
return shell.and_(
'chmod +x {}'.format(command.script_parts[0][2:]),
command.script)

View File

@@ -22,8 +22,7 @@ shells = {'bash': Bash,
def _get_shell():
proc = Process(os.getpid())
while (proc is not None):
name = None
while proc is not None:
try:
name = proc.name()
except TypeError:

View File

@@ -1,6 +1,9 @@
from subprocess import Popen, PIPE
from time import time
import os
import sys
import six
from .. import logs
from ..utils import DEVNULL, memoize, cache
from .generic import Generic
@@ -65,3 +68,20 @@ class Fish(Generic):
def how_to_configure(self):
return (r"eval (thefuck --alias | tr '\n' ';')",
'~/.config/fish/config.fish')
def put_to_history(self, command):
try:
return self._put_to_history(command)
except IOError:
logs.exception("Can't update history", sys.exc_info())
def _put_to_history(self, command_script):
"""Puts command script to shell history."""
history_file_name = self._get_history_file_name()
if os.path.isfile(history_file_name):
with open(history_file_name, 'a') as history:
entry = self._get_history_line(command_script)
if six.PY2:
history.write(entry.encode('utf-8'))
else:
history.write(entry)

View File

@@ -81,3 +81,11 @@ class Generic(object):
def _script_from_history(self, line):
return line
def put_to_history(self, command):
"""Adds fixed command to shell history.
In most of shells we change history on shell-level, but not
all shells support it (Fish).
"""

View File

@@ -280,6 +280,8 @@ class CorrectedCommand(object):
"""
if self.side_effect:
compatibility_call(self.side_effect, old_cmd, self.script)
if settings.alter_history:
shell.put_to_history(self.script)
# This depends on correct setting of PYTHONIOENCODING by the alias:
logs.debug(u'PYTHONIOENCODING: {}'.format(
os.environ.get('PYTHONIOENCODING', '!!not-set!!')))