#N/A: Reorganize entrypoints
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import six
|
||||
from ..logs import warn
|
||||
from ..shells import shell
|
||||
|
||||
|
||||
def print_alias(known_args):
|
||||
if six.PY2:
|
||||
warn("The Fuck will drop Python 2 support soon, more details "
|
||||
"https://github.com/nvbn/thefuck/issues/685")
|
||||
|
||||
if known_args.enable_experimental_instant_mode:
|
||||
if six.PY2:
|
||||
warn("Instant mode not supported with Python 2")
|
||||
alias = shell.app_alias(known_args.alias)
|
||||
else:
|
||||
alias = shell.instant_mode_alias(known_args.alias)
|
||||
else:
|
||||
alias = shell.app_alias(known_args.alias)
|
||||
|
||||
print(alias)
|
||||
@@ -0,0 +1,47 @@
|
||||
from pprint import pformat
|
||||
import os
|
||||
import sys
|
||||
from difflib import SequenceMatcher
|
||||
from .. import logs, types, const
|
||||
from ..conf import settings
|
||||
from ..corrector import get_corrected_commands
|
||||
from ..exceptions import EmptyCommand
|
||||
from ..ui import select_command
|
||||
from ..utils import get_alias, get_all_executables
|
||||
|
||||
|
||||
def _get_raw_command(known_args):
|
||||
if known_args.force_command:
|
||||
return known_args.force_command
|
||||
elif not os.environ.get('TF_HISTORY'):
|
||||
return known_args.command
|
||||
else:
|
||||
history = os.environ['TF_HISTORY'].split('\n')[::-1]
|
||||
alias = get_alias()
|
||||
executables = get_all_executables()
|
||||
for command in history:
|
||||
diff = SequenceMatcher(a=alias, b=command).ratio()
|
||||
if diff < const.DIFF_WITH_ALIAS or command in executables:
|
||||
return [command]
|
||||
|
||||
|
||||
def fix_command(known_args):
|
||||
"""Fixes previous command. Used when `thefuck` called without arguments."""
|
||||
settings.init(known_args)
|
||||
with logs.debug_time('Total'):
|
||||
logs.debug(u'Run with settings: {}'.format(pformat(settings)))
|
||||
raw_command = _get_raw_command(known_args)
|
||||
|
||||
try:
|
||||
command = types.Command.from_raw_script(raw_command)
|
||||
except EmptyCommand:
|
||||
logs.debug('Empty command, nothing to do')
|
||||
return
|
||||
|
||||
corrected_commands = get_corrected_commands(command)
|
||||
selected_command = select_command(corrected_commands)
|
||||
|
||||
if selected_command:
|
||||
selected_command.run(command)
|
||||
else:
|
||||
sys.exit(1)
|
||||
@@ -0,0 +1,29 @@
|
||||
# Initialize output before importing any module, that can use colorama.
|
||||
from ..system import init_output
|
||||
|
||||
init_output()
|
||||
|
||||
import os # noqa: E402
|
||||
import sys # noqa: E402
|
||||
from .. import logs # noqa: E402
|
||||
from ..argument_parser import Parser # noqa: E402
|
||||
from ..utils import get_installation_info # noqa: E402
|
||||
from .alias import print_alias # noqa: E402
|
||||
from .fix_command import fix_command # noqa: E402
|
||||
|
||||
|
||||
def main():
|
||||
parser = Parser()
|
||||
known_args = parser.parse(sys.argv)
|
||||
|
||||
if known_args.help:
|
||||
parser.print_help()
|
||||
elif known_args.version:
|
||||
logs.version(get_installation_info().version,
|
||||
sys.version.split()[0])
|
||||
elif known_args.command or 'TF_HISTORY' in os.environ:
|
||||
fix_command(known_args)
|
||||
elif known_args.alias:
|
||||
print_alias(known_args)
|
||||
else:
|
||||
parser.print_usage()
|
||||
@@ -0,0 +1,111 @@
|
||||
# Initialize output before importing any module, that can use colorama.
|
||||
from ..system import init_output
|
||||
|
||||
init_output()
|
||||
|
||||
import os # noqa: E402
|
||||
import json # noqa: E402
|
||||
import time # noqa: E402
|
||||
import six # noqa: E402
|
||||
from psutil import Process # noqa: E402
|
||||
from .. import logs, const # noqa: E402
|
||||
from ..shells import shell # noqa: E402
|
||||
from ..conf import settings # noqa: E402
|
||||
from ..system import Path # noqa: E402
|
||||
from ..utils import get_cache_dir # noqa: E402
|
||||
|
||||
|
||||
def _get_shell_pid():
|
||||
"""Returns parent process pid."""
|
||||
proc = Process(os.getpid())
|
||||
|
||||
try:
|
||||
return proc.parent().pid
|
||||
except TypeError:
|
||||
return proc.parent.pid
|
||||
|
||||
|
||||
def _get_not_configured_usage_tracker_path():
|
||||
"""Returns path of special file where we store latest shell pid."""
|
||||
return Path(get_cache_dir()).joinpath('thefuck.last_not_configured_run')
|
||||
|
||||
|
||||
def _record_first_run():
|
||||
"""Records shell pid to tracker file."""
|
||||
info = {'pid': _get_shell_pid(),
|
||||
'time': time.time()}
|
||||
|
||||
mode = 'wb' if six.PY2 else 'w'
|
||||
with _get_not_configured_usage_tracker_path().open(mode) as tracker:
|
||||
json.dump(info, tracker)
|
||||
|
||||
|
||||
def _get_previous_command():
|
||||
history = shell.get_history()
|
||||
|
||||
if history:
|
||||
return history[-1]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def _is_second_run():
|
||||
"""Returns `True` when we know that `fuck` called second time."""
|
||||
tracker_path = _get_not_configured_usage_tracker_path()
|
||||
if not tracker_path.exists():
|
||||
return False
|
||||
|
||||
current_pid = _get_shell_pid()
|
||||
with tracker_path.open('r') as tracker:
|
||||
try:
|
||||
info = json.load(tracker)
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
if not (isinstance(info, dict) and info.get('pid') == current_pid):
|
||||
return False
|
||||
|
||||
return (_get_previous_command() == 'fuck' or
|
||||
time.time() - info.get('time', 0) < const.CONFIGURATION_TIMEOUT)
|
||||
|
||||
|
||||
def _is_already_configured(configuration_details):
|
||||
"""Returns `True` when alias already in shell config."""
|
||||
path = Path(configuration_details.path).expanduser()
|
||||
with path.open('r') as shell_config:
|
||||
return configuration_details.content in shell_config.read()
|
||||
|
||||
|
||||
def _configure(configuration_details):
|
||||
"""Adds alias to shell config."""
|
||||
path = Path(configuration_details.path).expanduser()
|
||||
with path.open('a') as shell_config:
|
||||
shell_config.write(u'\n')
|
||||
shell_config.write(configuration_details.content)
|
||||
shell_config.write(u'\n')
|
||||
|
||||
|
||||
def main():
|
||||
"""Shows useful information about how-to configure alias on a first run
|
||||
and configure automatically on a second.
|
||||
|
||||
It'll be only visible when user type fuck and when alias isn't configured.
|
||||
|
||||
"""
|
||||
settings.init()
|
||||
configuration_details = shell.how_to_configure()
|
||||
if (
|
||||
configuration_details and
|
||||
configuration_details.can_configure_automatically
|
||||
):
|
||||
if _is_already_configured(configuration_details):
|
||||
logs.already_configured(configuration_details)
|
||||
return
|
||||
elif _is_second_run():
|
||||
_configure(configuration_details)
|
||||
logs.configured_successfully(configuration_details)
|
||||
return
|
||||
else:
|
||||
_record_first_run()
|
||||
|
||||
logs.how_to_configure_alias(configuration_details)
|
||||
Reference in New Issue
Block a user