mirror of
https://github.com/nvbn/thefuck.git
synced 2025-11-01 23:51:59 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54d82f9528 | ||
|
|
888756d519 | ||
|
|
d5b4bddc4c | ||
|
|
d09238a6e8 | ||
|
|
c6c3756caf | ||
|
|
275574beae | ||
|
|
de4b774134 | ||
|
|
3af5c80d29 | ||
|
|
bd5f5045aa | ||
|
|
798928b5ad | ||
|
|
82e2c89472 | ||
|
|
f2392349f7 | ||
|
|
478fa4cd09 | ||
|
|
273fc097bd | ||
|
|
00d0987cf5 | ||
|
|
3798c341d5 |
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
|
||||
setup(name='thefuck',
|
||||
version=1.18,
|
||||
version="1.23",
|
||||
description="Magnificent app which corrects your previous console command",
|
||||
author='Vladimir Iakovlev',
|
||||
author_email='nvbn.rm@gmail.com',
|
||||
|
||||
@@ -24,7 +24,7 @@ def test_load_rule():
|
||||
return_value=Mock(
|
||||
match=match,
|
||||
get_new_command=get_new_command)) as load_source:
|
||||
assert main.load_rule(Path('/rules/bash.py')) == main.Rule(match, get_new_command)
|
||||
assert main.load_rule(Path('/rules/bash.py')) == main.Rule('bash', match, get_new_command)
|
||||
load_source.assert_called_once_with('bash', '/rules/bash.py')
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@ def test_get_rules():
|
||||
glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
|
||||
assert main.get_rules(
|
||||
Path('~'),
|
||||
Mock(rules=None)) == [main.Rule('bash', 'bash'),
|
||||
main.Rule('lisp', 'lisp'),
|
||||
main.Rule('bash', 'bash'),
|
||||
main.Rule('lisp', 'lisp')]
|
||||
Mock(rules=None)) == [main.Rule('bash', 'bash', 'bash'),
|
||||
main.Rule('lisp', 'lisp', 'lisp'),
|
||||
main.Rule('bash', 'bash', 'bash'),
|
||||
main.Rule('lisp', 'lisp', 'lisp')]
|
||||
assert main.get_rules(
|
||||
Path('~'),
|
||||
Mock(rules=['bash'])) == [main.Rule('bash', 'bash'),
|
||||
main.Rule('bash', 'bash')]
|
||||
Mock(rules=['bash'])) == [main.Rule('bash', 'bash', 'bash'),
|
||||
main.Rule('bash', 'bash', 'bash')]
|
||||
|
||||
|
||||
def test_get_command():
|
||||
@@ -61,24 +61,28 @@ def test_get_command():
|
||||
stdout=PIPE,
|
||||
stderr=PIPE,
|
||||
env={'LANG': 'C'})
|
||||
assert main.get_command(Mock(), ['']) is None
|
||||
|
||||
|
||||
def test_get_matched_rule():
|
||||
rules = [main.Rule(lambda x, _: x.script == 'cd ..', None),
|
||||
main.Rule(lambda *_: False, None)]
|
||||
def test_get_matched_rule(capsys):
|
||||
rules = [main.Rule('', lambda x, _: x.script == 'cd ..', None),
|
||||
main.Rule('', lambda *_: False, None),
|
||||
main.Rule('rule', Mock(side_effect=OSError('Denied')), None)]
|
||||
assert main.get_matched_rule(main.Command('ls', '', ''),
|
||||
rules, None) is None
|
||||
assert main.get_matched_rule(main.Command('cd ..', '', ''),
|
||||
rules, None) == rules[0]
|
||||
assert capsys.readouterr()[1].split('\n')[0]\
|
||||
== '[WARN] rule: Traceback (most recent call last):'
|
||||
|
||||
|
||||
def test_run_rule(capsys):
|
||||
with patch('thefuck.main.confirm', return_value=True):
|
||||
main.run_rule(main.Rule(None, lambda *_: 'new-command'),
|
||||
main.run_rule(main.Rule('', None, lambda *_: 'new-command'),
|
||||
None, None)
|
||||
assert capsys.readouterr() == ('new-command\n', '')
|
||||
with patch('thefuck.main.confirm', return_value=False):
|
||||
main.run_rule(main.Rule(None, lambda *_: 'new-command'),
|
||||
main.run_rule(main.Rule('', None, lambda *_: 'new-command'),
|
||||
None, None)
|
||||
assert capsys.readouterr() == ('', '')
|
||||
|
||||
|
||||
@@ -5,11 +5,12 @@ from os.path import expanduser
|
||||
from subprocess import Popen, PIPE
|
||||
import os
|
||||
import sys
|
||||
from traceback import format_exception
|
||||
from psutil import Process, TimeoutExpired
|
||||
|
||||
|
||||
Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
|
||||
Rule = namedtuple('Rule', ('match', 'get_new_command'))
|
||||
Rule = namedtuple('Rule', ('name', 'match', 'get_new_command'))
|
||||
|
||||
|
||||
def setup_user_dir():
|
||||
@@ -43,7 +44,8 @@ def is_rule_enabled(settings, rule):
|
||||
def load_rule(rule):
|
||||
"""Imports rule module and returns it."""
|
||||
rule_module = load_source(rule.name[:-3], str(rule))
|
||||
return Rule(rule_module.match, rule_module.get_new_command)
|
||||
return Rule(rule.name[:-3], rule_module.match,
|
||||
rule_module.get_new_command)
|
||||
|
||||
|
||||
def get_rules(user_dir, settings):
|
||||
@@ -80,6 +82,10 @@ def get_command(settings, args):
|
||||
script = ' '.join(arg.decode('utf-8') for arg in args[1:])
|
||||
else:
|
||||
script = ' '.join(args[1:])
|
||||
|
||||
if not script:
|
||||
return
|
||||
|
||||
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE,
|
||||
env=dict(os.environ, LANG='C'))
|
||||
if wait_output(settings, result):
|
||||
@@ -90,8 +96,12 @@ def get_command(settings, args):
|
||||
def get_matched_rule(command, rules, settings):
|
||||
"""Returns first matched rule for command."""
|
||||
for rule in rules:
|
||||
if rule.match(command, settings):
|
||||
return rule
|
||||
try:
|
||||
if rule.match(command, settings):
|
||||
return rule
|
||||
except Exception:
|
||||
sys.stderr.write(u'[WARN] {}: {}---------------------\n\n'.format(
|
||||
rule.name, ''.join(format_exception(*sys.exc_info()))))
|
||||
|
||||
|
||||
def confirm(new_command, settings):
|
||||
|
||||
@@ -3,11 +3,18 @@ import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _safe(fn, fallback):
|
||||
try:
|
||||
return fn()
|
||||
except OSError:
|
||||
return fallback
|
||||
|
||||
|
||||
def _get_all_bins():
|
||||
return [exe.name
|
||||
for path in os.environ['PATH'].split(':')
|
||||
for exe in Path(path).iterdir()
|
||||
if exe.is_file()]
|
||||
for path in os.environ.get('PATH', '').split(':')
|
||||
for exe in _safe(lambda: list(Path(path).iterdir()), [])
|
||||
if not _safe(exe.is_dir, True)]
|
||||
|
||||
|
||||
def match(command, settings):
|
||||
|
||||
@@ -3,7 +3,9 @@ patterns = ['permission denied',
|
||||
'pkg: Insufficient privileges',
|
||||
'you cannot perform this operation unless you are root',
|
||||
'non-root users cannot',
|
||||
'Operation not permitted']
|
||||
'Operation not permitted',
|
||||
'root privilege',
|
||||
'This command has to be run under the root user.']
|
||||
|
||||
|
||||
def match(command, settings):
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
target_layout = '''qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?'''
|
||||
|
||||
source_layouts = [u'''йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,''']
|
||||
source_layouts = [u'''йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,''',
|
||||
u'''ضصثقفغعهخحجچشسیبلاتنمکگظطزرذدپو./ًٌٍَُِّْ][}{ؤئيإأآة»«:؛كٓژٰٔء><؟''']
|
||||
|
||||
|
||||
def _get_matched_layout(command):
|
||||
|
||||
Reference in New Issue
Block a user