mirror of
https://github.com/nvbn/thefuck.git
synced 2025-02-21 20:38:54 +00:00
Make settings a global singleton
This commit is contained in:
parent
191a2e588d
commit
105d3d8137
@ -29,7 +29,7 @@ def environ(monkeypatch):
|
|||||||
def test_settings_defaults(load_source):
|
def test_settings_defaults(load_source):
|
||||||
load_source.return_value = object()
|
load_source.return_value = object()
|
||||||
for key, val in conf.DEFAULT_SETTINGS.items():
|
for key, val in conf.DEFAULT_SETTINGS.items():
|
||||||
assert getattr(conf.get_settings(Mock()), key) == val
|
assert getattr(conf.init_settings(Mock()), key) == val
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixture('environ')
|
@pytest.mark.usefixture('environ')
|
||||||
@ -41,7 +41,7 @@ class TestSettingsFromFile(object):
|
|||||||
no_colors=True,
|
no_colors=True,
|
||||||
priority={'vim': 100},
|
priority={'vim': 100},
|
||||||
exclude_rules=['git'])
|
exclude_rules=['git'])
|
||||||
settings = conf.get_settings(Mock())
|
settings = conf.init_settings(Mock())
|
||||||
assert settings.rules == ['test']
|
assert settings.rules == ['test']
|
||||||
assert settings.wait_command == 10
|
assert settings.wait_command == 10
|
||||||
assert settings.require_confirmation is True
|
assert settings.require_confirmation is True
|
||||||
@ -55,7 +55,7 @@ class TestSettingsFromFile(object):
|
|||||||
exclude_rules=[],
|
exclude_rules=[],
|
||||||
require_confirmation=True,
|
require_confirmation=True,
|
||||||
no_colors=True)
|
no_colors=True)
|
||||||
settings = conf.get_settings(Mock())
|
settings = conf.init_settings(Mock())
|
||||||
assert settings.rules == conf.DEFAULT_RULES + ['test']
|
assert settings.rules == conf.DEFAULT_RULES + ['test']
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class TestSettingsFromEnv(object):
|
|||||||
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
|
'THEFUCK_REQUIRE_CONFIRMATION': 'true',
|
||||||
'THEFUCK_NO_COLORS': 'false',
|
'THEFUCK_NO_COLORS': 'false',
|
||||||
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
|
'THEFUCK_PRIORITY': 'bash=10:lisp=wrong:vim=15'})
|
||||||
settings = conf.get_settings(Mock())
|
settings = conf.init_settings(Mock())
|
||||||
assert settings.rules == ['bash', 'lisp']
|
assert settings.rules == ['bash', 'lisp']
|
||||||
assert settings.exclude_rules == ['git', 'vim']
|
assert settings.exclude_rules == ['git', 'vim']
|
||||||
assert settings.wait_command == 55
|
assert settings.wait_command == 55
|
||||||
@ -78,7 +78,7 @@ class TestSettingsFromEnv(object):
|
|||||||
|
|
||||||
def test_from_env_with_DEFAULT(self, environ):
|
def test_from_env_with_DEFAULT(self, environ):
|
||||||
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
|
environ.update({'THEFUCK_RULES': 'DEFAULT_RULES:bash:lisp'})
|
||||||
settings = conf.get_settings(Mock())
|
settings = conf.init_settings(Mock())
|
||||||
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']
|
assert settings.rules == conf.DEFAULT_RULES + ['bash', 'lisp']
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
from copy import copy
|
|
||||||
from imp import load_source
|
from imp import load_source
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from six import text_type
|
from six import text_type
|
||||||
from . import logs, types
|
from .types import RulesNamesList, Settings
|
||||||
|
|
||||||
|
|
||||||
class _DefaultRulesNames(types.RulesNamesList):
|
class _DefaultRulesNames(RulesNamesList):
|
||||||
def __add__(self, items):
|
def __add__(self, items):
|
||||||
return _DefaultRulesNames(list(self) + items)
|
return _DefaultRulesNames(list(self) + items)
|
||||||
|
|
||||||
@ -24,7 +23,6 @@ class _DefaultRulesNames(types.RulesNamesList):
|
|||||||
DEFAULT_RULES = _DefaultRulesNames([])
|
DEFAULT_RULES = _DefaultRulesNames([])
|
||||||
DEFAULT_PRIORITY = 1000
|
DEFAULT_PRIORITY = 1000
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
|
DEFAULT_SETTINGS = {'rules': DEFAULT_RULES,
|
||||||
'exclude_rules': [],
|
'exclude_rules': [],
|
||||||
'wait_command': 3,
|
'wait_command': 3,
|
||||||
@ -42,7 +40,6 @@ ENV_TO_ATTR = {'THEFUCK_RULES': 'rules',
|
|||||||
'THEFUCK_PRIORITY': 'priority',
|
'THEFUCK_PRIORITY': 'priority',
|
||||||
'THEFUCK_DEBUG': 'debug'}
|
'THEFUCK_DEBUG': 'debug'}
|
||||||
|
|
||||||
|
|
||||||
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
|
SETTINGS_HEADER = u"""# ~/.thefuck/settings.py: The Fuck settings file
|
||||||
#
|
#
|
||||||
# The rules are defined as in the example bellow:
|
# The rules are defined as in the example bellow:
|
||||||
@ -105,30 +102,28 @@ def _settings_from_env():
|
|||||||
if env in os.environ}
|
if env in os.environ}
|
||||||
|
|
||||||
|
|
||||||
def get_settings(user_dir):
|
settings = Settings(DEFAULT_SETTINGS)
|
||||||
"""Returns settings filled with values from `settings.py` and env."""
|
|
||||||
conf = copy(DEFAULT_SETTINGS)
|
|
||||||
try:
|
def init_settings(user_dir):
|
||||||
conf.update(_settings_from_file(user_dir))
|
"""Fills `settings` with values from `settings.py` and env."""
|
||||||
except Exception:
|
from .logs import exception
|
||||||
logs.exception("Can't load settings from file",
|
|
||||||
sys.exc_info(),
|
|
||||||
types.Settings(conf))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conf.update(_settings_from_env())
|
settings.update(_settings_from_file(user_dir))
|
||||||
except Exception:
|
except Exception:
|
||||||
logs.exception("Can't load settings from env",
|
exception("Can't load settings from file", sys.exc_info())
|
||||||
sys.exc_info(),
|
|
||||||
types.Settings(conf))
|
|
||||||
|
|
||||||
if not isinstance(conf['rules'], types.RulesNamesList):
|
try:
|
||||||
conf['rules'] = types.RulesNamesList(conf['rules'])
|
settings.update(_settings_from_env())
|
||||||
|
except Exception:
|
||||||
|
exception("Can't load settings from env", sys.exc_info())
|
||||||
|
|
||||||
if not isinstance(conf['exclude_rules'], types.RulesNamesList):
|
if not isinstance(settings['rules'], RulesNamesList):
|
||||||
conf['exclude_rules'] = types.RulesNamesList(conf['exclude_rules'])
|
settings.rules = RulesNamesList(settings['rules'])
|
||||||
|
|
||||||
return types.Settings(conf)
|
if not isinstance(settings.exclude_rules, RulesNamesList):
|
||||||
|
settings.exclude_rules = RulesNamesList(settings.exclude_rules)
|
||||||
|
|
||||||
|
|
||||||
def initialize_settings_file(user_dir):
|
def initialize_settings_file(user_dir):
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import sys
|
import sys
|
||||||
from imp import load_source
|
from imp import load_source
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from . import conf, types, logs
|
from .conf import settings, DEFAULT_PRIORITY
|
||||||
|
from .types import Rule, CorrectedCommand, SortedCorrectedCommandsSequence
|
||||||
|
from . import logs
|
||||||
|
|
||||||
|
|
||||||
def load_rule(rule, settings):
|
def load_rule(rule):
|
||||||
"""Imports rule module and returns it."""
|
"""Imports rule module and returns it."""
|
||||||
name = rule.name[:-3]
|
name = rule.name[:-3]
|
||||||
with logs.debug_time(u'Importing rule: {};'.format(name), settings):
|
with logs.debug_time(u'Importing rule: {};'.format(name)):
|
||||||
rule_module = load_source(name, str(rule))
|
rule_module = load_source(name, str(rule))
|
||||||
priority = getattr(rule_module, 'priority', conf.DEFAULT_PRIORITY)
|
priority = getattr(rule_module, 'priority', DEFAULT_PRIORITY)
|
||||||
return types.Rule(name, rule_module.match,
|
return Rule(name, rule_module.match,
|
||||||
rule_module.get_new_command,
|
rule_module.get_new_command,
|
||||||
getattr(rule_module, 'enabled_by_default', True),
|
getattr(rule_module, 'enabled_by_default', True),
|
||||||
getattr(rule_module, 'side_effect', None),
|
getattr(rule_module, 'side_effect', None),
|
||||||
@ -18,27 +20,27 @@ def load_rule(rule, settings):
|
|||||||
getattr(rule_module, 'requires_output', True))
|
getattr(rule_module, 'requires_output', True))
|
||||||
|
|
||||||
|
|
||||||
def get_loaded_rules(rules, settings):
|
def get_loaded_rules(rules):
|
||||||
"""Yields all available rules."""
|
"""Yields all available rules."""
|
||||||
for rule in rules:
|
for rule in rules:
|
||||||
if rule.name != '__init__.py':
|
if rule.name != '__init__.py':
|
||||||
loaded_rule = load_rule(rule, settings)
|
loaded_rule = load_rule(rule)
|
||||||
if loaded_rule in settings.rules and \
|
if loaded_rule in settings.rules and \
|
||||||
loaded_rule not in settings.exclude_rules:
|
loaded_rule not in settings.exclude_rules:
|
||||||
yield loaded_rule
|
yield loaded_rule
|
||||||
|
|
||||||
|
|
||||||
def get_rules(user_dir, settings):
|
def get_rules(user_dir):
|
||||||
"""Returns all enabled rules."""
|
"""Returns all enabled rules."""
|
||||||
bundled = Path(__file__).parent \
|
bundled = Path(__file__).parent \
|
||||||
.joinpath('rules') \
|
.joinpath('rules') \
|
||||||
.glob('*.py')
|
.glob('*.py')
|
||||||
user = user_dir.joinpath('rules').glob('*.py')
|
user = user_dir.joinpath('rules').glob('*.py')
|
||||||
return sorted(get_loaded_rules(sorted(bundled) + sorted(user), settings),
|
return sorted(get_loaded_rules(sorted(bundled) + sorted(user)),
|
||||||
key=lambda rule: rule.priority)
|
key=lambda rule: rule.priority)
|
||||||
|
|
||||||
|
|
||||||
def is_rule_match(command, rule, settings):
|
def is_rule_match(command, rule):
|
||||||
"""Returns first matched rule for command."""
|
"""Returns first matched rule for command."""
|
||||||
script_only = command.stdout is None and command.stderr is None
|
script_only = command.stdout is None and command.stderr is None
|
||||||
|
|
||||||
@ -46,27 +48,26 @@ def is_rule_match(command, rule, settings):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with logs.debug_time(u'Trying rule: {};'.format(rule.name),
|
with logs.debug_time(u'Trying rule: {};'.format(rule.name)):
|
||||||
settings):
|
|
||||||
if rule.match(command, settings):
|
if rule.match(command, settings):
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
logs.rule_failed(rule, sys.exc_info(), settings)
|
logs.rule_failed(rule, sys.exc_info())
|
||||||
|
|
||||||
|
|
||||||
def make_corrected_commands(command, rule, settings):
|
def make_corrected_commands(command, rule):
|
||||||
new_commands = rule.get_new_command(command, settings)
|
new_commands = rule.get_new_command(command, settings)
|
||||||
if not isinstance(new_commands, list):
|
if not isinstance(new_commands, list):
|
||||||
new_commands = (new_commands,)
|
new_commands = (new_commands,)
|
||||||
for n, new_command in enumerate(new_commands):
|
for n, new_command in enumerate(new_commands):
|
||||||
yield types.CorrectedCommand(script=new_command,
|
yield CorrectedCommand(script=new_command,
|
||||||
side_effect=rule.side_effect,
|
side_effect=rule.side_effect,
|
||||||
priority=(n + 1) * rule.priority)
|
priority=(n + 1) * rule.priority)
|
||||||
|
|
||||||
|
|
||||||
def get_corrected_commands(command, user_dir, settings):
|
def get_corrected_commands(command, user_dir):
|
||||||
corrected_commands = (
|
corrected_commands = (
|
||||||
corrected for rule in get_rules(user_dir, settings)
|
corrected for rule in get_rules(user_dir)
|
||||||
if is_rule_match(command, rule, settings)
|
if is_rule_match(command, rule)
|
||||||
for corrected in make_corrected_commands(command, rule, settings))
|
for corrected in make_corrected_commands(command, rule))
|
||||||
return types.SortedCorrectedCommandsSequence(corrected_commands, settings)
|
return SortedCorrectedCommandsSequence(corrected_commands)
|
||||||
|
@ -5,9 +5,10 @@ from datetime import datetime
|
|||||||
import sys
|
import sys
|
||||||
from traceback import format_exception
|
from traceback import format_exception
|
||||||
import colorama
|
import colorama
|
||||||
|
from .conf import settings
|
||||||
|
|
||||||
|
|
||||||
def color(color_, settings):
|
def color(color_):
|
||||||
"""Utility for ability to disabling colored output."""
|
"""Utility for ability to disabling colored output."""
|
||||||
if settings.no_colors:
|
if settings.no_colors:
|
||||||
return ''
|
return ''
|
||||||
@ -15,37 +16,37 @@ def color(color_, settings):
|
|||||||
return color_
|
return color_
|
||||||
|
|
||||||
|
|
||||||
def exception(title, exc_info, settings):
|
def exception(title, exc_info):
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
u'{warn}[WARN] {title}:{reset}\n{trace}'
|
u'{warn}[WARN] {title}:{reset}\n{trace}'
|
||||||
u'{warn}----------------------------{reset}\n\n'.format(
|
u'{warn}----------------------------{reset}\n\n'.format(
|
||||||
warn=color(colorama.Back.RED + colorama.Fore.WHITE
|
warn=color(colorama.Back.RED + colorama.Fore.WHITE
|
||||||
+ colorama.Style.BRIGHT, settings),
|
+ colorama.Style.BRIGHT),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings),
|
reset=color(colorama.Style.RESET_ALL),
|
||||||
title=title,
|
title=title,
|
||||||
trace=''.join(format_exception(*exc_info))))
|
trace=''.join(format_exception(*exc_info))))
|
||||||
|
|
||||||
|
|
||||||
def rule_failed(rule, exc_info, settings):
|
def rule_failed(rule, exc_info):
|
||||||
exception('Rule {}'.format(rule.name), exc_info, settings)
|
exception('Rule {}'.format(rule.name), exc_info)
|
||||||
|
|
||||||
|
|
||||||
def failed(msg, settings):
|
def failed(msg):
|
||||||
sys.stderr.write('{red}{msg}{reset}\n'.format(
|
sys.stderr.write('{red}{msg}{reset}\n'.format(
|
||||||
msg=msg,
|
msg=msg,
|
||||||
red=color(colorama.Fore.RED, settings),
|
red=color(colorama.Fore.RED),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings)))
|
reset=color(colorama.Style.RESET_ALL)))
|
||||||
|
|
||||||
|
|
||||||
def show_corrected_command(corrected_command, settings):
|
def show_corrected_command(corrected_command):
|
||||||
sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format(
|
sys.stderr.write('{bold}{script}{reset}{side_effect}\n'.format(
|
||||||
script=corrected_command.script,
|
script=corrected_command.script,
|
||||||
side_effect=' (+side effect)' if corrected_command.side_effect else '',
|
side_effect=' (+side effect)' if corrected_command.side_effect else '',
|
||||||
bold=color(colorama.Style.BRIGHT, settings),
|
bold=color(colorama.Style.BRIGHT),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings)))
|
reset=color(colorama.Style.RESET_ALL)))
|
||||||
|
|
||||||
|
|
||||||
def confirm_text(corrected_command, settings):
|
def confirm_text(corrected_command):
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
('{clear}{bold}{script}{reset}{side_effect} '
|
('{clear}{bold}{script}{reset}{side_effect} '
|
||||||
'[{green}enter{reset}/{blue}↑{reset}/{blue}↓{reset}'
|
'[{green}enter{reset}/{blue}↑{reset}/{blue}↓{reset}'
|
||||||
@ -53,42 +54,42 @@ def confirm_text(corrected_command, settings):
|
|||||||
script=corrected_command.script,
|
script=corrected_command.script,
|
||||||
side_effect=' (+side effect)' if corrected_command.side_effect else '',
|
side_effect=' (+side effect)' if corrected_command.side_effect else '',
|
||||||
clear='\033[1K\r',
|
clear='\033[1K\r',
|
||||||
bold=color(colorama.Style.BRIGHT, settings),
|
bold=color(colorama.Style.BRIGHT),
|
||||||
green=color(colorama.Fore.GREEN, settings),
|
green=color(colorama.Fore.GREEN),
|
||||||
red=color(colorama.Fore.RED, settings),
|
red=color(colorama.Fore.RED),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings),
|
reset=color(colorama.Style.RESET_ALL),
|
||||||
blue=color(colorama.Fore.BLUE, settings)))
|
blue=color(colorama.Fore.BLUE)))
|
||||||
|
|
||||||
|
|
||||||
def debug(msg, settings):
|
def debug(msg):
|
||||||
if settings.debug:
|
if settings.debug:
|
||||||
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
|
sys.stderr.write(u'{blue}{bold}DEBUG:{reset} {msg}\n'.format(
|
||||||
msg=msg,
|
msg=msg,
|
||||||
reset=color(colorama.Style.RESET_ALL, settings),
|
reset=color(colorama.Style.RESET_ALL),
|
||||||
blue=color(colorama.Fore.BLUE, settings),
|
blue=color(colorama.Fore.BLUE),
|
||||||
bold=color(colorama.Style.BRIGHT, settings)))
|
bold=color(colorama.Style.BRIGHT)))
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def debug_time(msg, settings):
|
def debug_time(msg):
|
||||||
started = datetime.now()
|
started = datetime.now()
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
debug(u'{} took: {}'.format(msg, datetime.now() - started), settings)
|
debug(u'{} took: {}'.format(msg, datetime.now() - started))
|
||||||
|
|
||||||
|
|
||||||
def how_to_configure_alias(configuration_details, settings):
|
def how_to_configure_alias(configuration_details):
|
||||||
print("Seems like {bold}fuck{reset} alias isn't configured!".format(
|
print("Seems like {bold}fuck{reset} alias isn't configured!".format(
|
||||||
bold=color(colorama.Style.BRIGHT, settings),
|
bold=color(colorama.Style.BRIGHT),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings)))
|
reset=color(colorama.Style.RESET_ALL)))
|
||||||
if configuration_details:
|
if configuration_details:
|
||||||
content, path = configuration_details
|
content, path = configuration_details
|
||||||
print(
|
print(
|
||||||
"Please put {bold}{content}{reset} in your "
|
"Please put {bold}{content}{reset} in your "
|
||||||
"{bold}{path}{reset}.".format(
|
"{bold}{path}{reset}.".format(
|
||||||
bold=color(colorama.Style.BRIGHT, settings),
|
bold=color(colorama.Style.BRIGHT),
|
||||||
reset=color(colorama.Style.RESET_ALL, settings),
|
reset=color(colorama.Style.RESET_ALL),
|
||||||
path=path,
|
path=path,
|
||||||
content=content))
|
content=content))
|
||||||
print('More details - https://github.com/nvbn/thefuck#manual-installation')
|
print('More details - https://github.com/nvbn/thefuck#manual-installation')
|
||||||
|
@ -10,7 +10,8 @@ import sys
|
|||||||
from psutil import Process, TimeoutExpired
|
from psutil import Process, TimeoutExpired
|
||||||
import colorama
|
import colorama
|
||||||
import six
|
import six
|
||||||
from . import logs, conf, types, shells
|
from . import logs, types, shells
|
||||||
|
from .conf import initialize_settings_file, init_settings, settings
|
||||||
from .corrector import get_corrected_commands
|
from .corrector import get_corrected_commands
|
||||||
from .ui import select_command
|
from .ui import select_command
|
||||||
|
|
||||||
@ -21,11 +22,11 @@ def setup_user_dir():
|
|||||||
rules_dir = user_dir.joinpath('rules')
|
rules_dir = user_dir.joinpath('rules')
|
||||||
if not rules_dir.is_dir():
|
if not rules_dir.is_dir():
|
||||||
rules_dir.mkdir(parents=True)
|
rules_dir.mkdir(parents=True)
|
||||||
conf.initialize_settings_file(user_dir)
|
initialize_settings_file(user_dir)
|
||||||
return user_dir
|
return user_dir
|
||||||
|
|
||||||
|
|
||||||
def wait_output(settings, popen):
|
def wait_output(popen):
|
||||||
"""Returns `True` if we can get output of the command in the
|
"""Returns `True` if we can get output of the command in the
|
||||||
`settings.wait_command` time.
|
`settings.wait_command` time.
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ def wait_output(settings, popen):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_command(settings, args):
|
def get_command(args):
|
||||||
"""Creates command from `args` and executes it."""
|
"""Creates command from `args` and executes it."""
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
script = ' '.join(arg.decode('utf-8') for arg in args[1:])
|
script = ' '.join(arg.decode('utf-8') for arg in args[1:])
|
||||||
@ -58,23 +59,22 @@ def get_command(settings, args):
|
|||||||
env = dict(os.environ)
|
env = dict(os.environ)
|
||||||
env.update(settings.env)
|
env.update(settings.env)
|
||||||
|
|
||||||
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env),
|
with logs.debug_time(u'Call: {}; with env: {};'.format(script, env)):
|
||||||
settings):
|
|
||||||
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
|
result = Popen(script, shell=True, stdout=PIPE, stderr=PIPE, env=env)
|
||||||
if wait_output(settings, result):
|
if wait_output(result):
|
||||||
stdout = result.stdout.read().decode('utf-8')
|
stdout = result.stdout.read().decode('utf-8')
|
||||||
stderr = result.stderr.read().decode('utf-8')
|
stderr = result.stderr.read().decode('utf-8')
|
||||||
|
|
||||||
logs.debug(u'Received stdout: {}'.format(stdout), settings)
|
logs.debug(u'Received stdout: {}'.format(stdout))
|
||||||
logs.debug(u'Received stderr: {}'.format(stderr), settings)
|
logs.debug(u'Received stderr: {}'.format(stderr))
|
||||||
|
|
||||||
return types.Command(script, stdout, stderr)
|
return types.Command(script, stdout, stderr)
|
||||||
else:
|
else:
|
||||||
logs.debug(u'Execution timed out!', settings)
|
logs.debug(u'Execution timed out!')
|
||||||
return types.Command(script, None, None)
|
return types.Command(script, None, None)
|
||||||
|
|
||||||
|
|
||||||
def run_command(old_cmd, command, settings):
|
def run_command(old_cmd, command):
|
||||||
"""Runs command from rule for passed command."""
|
"""Runs command from rule for passed command."""
|
||||||
if command.side_effect:
|
if command.side_effect:
|
||||||
command.side_effect(old_cmd, command.script, settings)
|
command.side_effect(old_cmd, command.script, settings)
|
||||||
@ -87,20 +87,20 @@ def run_command(old_cmd, command, settings):
|
|||||||
def fix_command():
|
def fix_command():
|
||||||
colorama.init()
|
colorama.init()
|
||||||
user_dir = setup_user_dir()
|
user_dir = setup_user_dir()
|
||||||
settings = conf.get_settings(user_dir)
|
init_settings(user_dir)
|
||||||
with logs.debug_time('Total', settings):
|
with logs.debug_time('Total'):
|
||||||
logs.debug(u'Run with settings: {}'.format(pformat(settings)), settings)
|
logs.debug(u'Run with settings: {}'.format(pformat(settings)))
|
||||||
|
|
||||||
command = get_command(settings, sys.argv)
|
command = get_command(sys.argv)
|
||||||
|
|
||||||
if not command:
|
if not command:
|
||||||
logs.debug('Empty command, nothing to do', settings)
|
logs.debug('Empty command, nothing to do')
|
||||||
return
|
return
|
||||||
|
|
||||||
corrected_commands = get_corrected_commands(command, user_dir, settings)
|
corrected_commands = get_corrected_commands(command, user_dir)
|
||||||
selected_command = select_command(corrected_commands, settings)
|
selected_command = select_command(corrected_commands)
|
||||||
if selected_command:
|
if selected_command:
|
||||||
run_command(command, selected_command, settings)
|
run_command(command, selected_command)
|
||||||
|
|
||||||
|
|
||||||
def _get_current_version():
|
def _get_current_version():
|
||||||
@ -128,8 +128,8 @@ def how_to_configure_alias():
|
|||||||
"""
|
"""
|
||||||
colorama.init()
|
colorama.init()
|
||||||
user_dir = setup_user_dir()
|
user_dir = setup_user_dir()
|
||||||
settings = conf.get_settings(user_dir)
|
init_settings(user_dir)
|
||||||
logs.how_to_configure_alias(shells.how_to_configure(), settings)
|
logs.how_to_configure_alias(shells.how_to_configure())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from traceback import format_stack
|
from traceback import format_stack
|
||||||
from .logs import debug
|
|
||||||
|
|
||||||
Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
|
Command = namedtuple('Command', ('script', 'stdout', 'stderr'))
|
||||||
|
|
||||||
@ -8,6 +7,7 @@ Rule = namedtuple('Rule', ('name', 'match', 'get_new_command',
|
|||||||
'enabled_by_default', 'side_effect',
|
'enabled_by_default', 'side_effect',
|
||||||
'priority', 'requires_output'))
|
'priority', 'requires_output'))
|
||||||
|
|
||||||
|
|
||||||
class CorrectedCommand(object):
|
class CorrectedCommand(object):
|
||||||
def __init__(self, script, side_effect, priority):
|
def __init__(self, script, side_effect, priority):
|
||||||
self.script = script
|
self.script = script
|
||||||
@ -17,7 +17,7 @@ class CorrectedCommand(object):
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""Ignores `priority` field."""
|
"""Ignores `priority` field."""
|
||||||
if isinstance(other, CorrectedCommand):
|
if isinstance(other, CorrectedCommand):
|
||||||
return (other.script, other.side_effect) ==\
|
return (other.script, other.side_effect) == \
|
||||||
(self.script, self.side_effect)
|
(self.script, self.side_effect)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -41,13 +41,8 @@ class Settings(dict):
|
|||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
return self.get(item)
|
return self.get(item)
|
||||||
|
|
||||||
def update(self, **kwargs):
|
def __setattr__(self, key, value):
|
||||||
"""
|
self[key] = value
|
||||||
Returns new settings with values from `kwargs` for unset settings.
|
|
||||||
"""
|
|
||||||
conf = dict(kwargs)
|
|
||||||
conf.update(self)
|
|
||||||
return Settings(conf)
|
|
||||||
|
|
||||||
|
|
||||||
class SortedCorrectedCommandsSequence(object):
|
class SortedCorrectedCommandsSequence(object):
|
||||||
@ -59,8 +54,7 @@ class SortedCorrectedCommandsSequence(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, commands, settings):
|
def __init__(self, commands):
|
||||||
self._settings = settings
|
|
||||||
self._commands = commands
|
self._commands = commands
|
||||||
self._cached = self._realise_first()
|
self._cached = self._realise_first()
|
||||||
self._realised = False
|
self._realised = False
|
||||||
@ -81,13 +75,15 @@ class SortedCorrectedCommandsSequence(object):
|
|||||||
|
|
||||||
def _realise(self):
|
def _realise(self):
|
||||||
"""Realises generator, removes duplicates and sorts commands."""
|
"""Realises generator, removes duplicates and sorts commands."""
|
||||||
|
from .logs import debug
|
||||||
|
|
||||||
if self._cached:
|
if self._cached:
|
||||||
commands = self._remove_duplicates(self._commands)
|
commands = self._remove_duplicates(self._commands)
|
||||||
self._cached = [self._cached[0]] + sorted(
|
self._cached = [self._cached[0]] + sorted(
|
||||||
commands, key=lambda corrected_command: corrected_command.priority)
|
commands, key=lambda corrected_command: corrected_command.priority)
|
||||||
self._realised = True
|
self._realised = True
|
||||||
debug('SortedCommandsSequence was realised with: {}, after: {}'.format(
|
debug('SortedCommandsSequence was realised with: {}, after: {}'.format(
|
||||||
self._cached, '\n'.join(format_stack())), self._settings)
|
self._cached, '\n'.join(format_stack())))
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
if item != 0 and not self._realised:
|
if item != 0 and not self._realised:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from .conf import settings
|
||||||
from . import logs
|
from . import logs
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -71,7 +72,7 @@ class CommandSelector(object):
|
|||||||
fn(self.value)
|
fn(self.value)
|
||||||
|
|
||||||
|
|
||||||
def select_command(corrected_commands, settings):
|
def select_command(corrected_commands):
|
||||||
"""Returns:
|
"""Returns:
|
||||||
|
|
||||||
- the first command when confirmation disabled;
|
- the first command when confirmation disabled;
|
||||||
@ -80,21 +81,21 @@ def select_command(corrected_commands, settings):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
if not corrected_commands:
|
if not corrected_commands:
|
||||||
logs.failed('No fucks given', settings)
|
logs.failed('No fucks given')
|
||||||
return
|
return
|
||||||
|
|
||||||
selector = CommandSelector(corrected_commands)
|
selector = CommandSelector(corrected_commands)
|
||||||
if not settings.require_confirmation:
|
if not settings.require_confirmation:
|
||||||
logs.show_corrected_command(selector.value, settings)
|
logs.show_corrected_command(selector.value)
|
||||||
return selector.value
|
return selector.value
|
||||||
|
|
||||||
selector.on_change(lambda val: logs.confirm_text(val, settings))
|
selector.on_change(lambda val: logs.confirm_text(val))
|
||||||
for action in read_actions():
|
for action in read_actions():
|
||||||
if action == SELECT:
|
if action == SELECT:
|
||||||
sys.stderr.write('\n')
|
sys.stderr.write('\n')
|
||||||
return selector.value
|
return selector.value
|
||||||
elif action == ABORT:
|
elif action == ABORT:
|
||||||
logs.failed('\nAborted', settings)
|
logs.failed('\nAborted')
|
||||||
return
|
return
|
||||||
elif action == PREVIOUS:
|
elif action == PREVIOUS:
|
||||||
selector.previous()
|
selector.previous()
|
||||||
|
@ -12,6 +12,7 @@ import re
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
import six
|
import six
|
||||||
|
from .types import Settings
|
||||||
|
|
||||||
|
|
||||||
DEVNULL = open(os.devnull, 'w')
|
DEVNULL = open(os.devnull, 'w')
|
||||||
@ -70,7 +71,7 @@ def wrap_settings(params):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
def _wrap_settings(fn, command, settings):
|
def _wrap_settings(fn, command, settings):
|
||||||
return fn(command, settings.update(**params))
|
return fn(command, Settings(settings, **params))
|
||||||
return decorator(_wrap_settings)
|
return decorator(_wrap_settings)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user