mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-18 20:11:17 +00:00
#682: Use our own shell logger, fix experimental instant mode on macos
This commit is contained in:
parent
edac010a7b
commit
d2c70bd8b8
@ -7,7 +7,8 @@ def _args(**override):
|
|||||||
args = {'alias': None, 'command': [], 'yes': False,
|
args = {'alias': None, 'command': [], 'yes': False,
|
||||||
'help': False, 'version': False, 'debug': False,
|
'help': False, 'version': False, 'debug': False,
|
||||||
'force_command': None, 'repeat': False,
|
'force_command': None, 'repeat': False,
|
||||||
'enable_experimental_instant_mode': False}
|
'enable_experimental_instant_mode': False,
|
||||||
|
'shell_logger': None}
|
||||||
args.update(override)
|
args.update(override)
|
||||||
return args
|
return args
|
||||||
|
|
||||||
@ -27,6 +28,9 @@ def _args(**override):
|
|||||||
(['thefuck', 'git', 'branch', '-a', ARGUMENT_PLACEHOLDER, '-y', '-d'],
|
(['thefuck', 'git', 'branch', '-a', ARGUMENT_PLACEHOLDER, '-y', '-d'],
|
||||||
_args(command=['git', 'branch', '-a'], yes=True, debug=True)),
|
_args(command=['git', 'branch', '-a'], yes=True, debug=True)),
|
||||||
(['thefuck', 'git', 'branch', '-a', ARGUMENT_PLACEHOLDER, '-r', '-d'],
|
(['thefuck', 'git', 'branch', '-a', ARGUMENT_PLACEHOLDER, '-r', '-d'],
|
||||||
_args(command=['git', 'branch', '-a'], repeat=True, debug=True))])
|
_args(command=['git', 'branch', '-a'], repeat=True, debug=True)),
|
||||||
|
(['thefuck', '-l', '/tmp/log'], _args(shell_logger='/tmp/log')),
|
||||||
|
(['thefuck', '--shell-logger', '/tmp/log'],
|
||||||
|
_args(shell_logger='/tmp/log'))])
|
||||||
def test_parse(argv, result):
|
def test_parse(argv, result):
|
||||||
assert vars(Parser().parse(argv)) == result
|
assert vars(Parser().parse(argv)) == result
|
||||||
|
@ -25,6 +25,10 @@ class Parser(object):
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
const=get_alias(),
|
const=get_alias(),
|
||||||
help='[custom-alias-name] prints alias for current shell')
|
help='[custom-alias-name] prints alias for current shell')
|
||||||
|
self._parser.add_argument(
|
||||||
|
'-l', '--shell-logger',
|
||||||
|
action='store',
|
||||||
|
help='log shell output to the file')
|
||||||
self._parser.add_argument(
|
self._parser.add_argument(
|
||||||
'--enable-experimental-instant-mode',
|
'--enable-experimental-instant-mode',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
@ -10,6 +10,7 @@ from ..argument_parser import Parser # noqa: E402
|
|||||||
from ..utils import get_installation_info # noqa: E402
|
from ..utils import get_installation_info # noqa: E402
|
||||||
from .alias import print_alias # noqa: E402
|
from .alias import print_alias # noqa: E402
|
||||||
from .fix_command import fix_command # noqa: E402
|
from .fix_command import fix_command # noqa: E402
|
||||||
|
from .shell_logger import shell_logger # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -25,5 +26,7 @@ def main():
|
|||||||
fix_command(known_args)
|
fix_command(known_args)
|
||||||
elif known_args.alias:
|
elif known_args.alias:
|
||||||
print_alias(known_args)
|
print_alias(known_args)
|
||||||
|
elif known_args.shell_logger:
|
||||||
|
shell_logger(known_args.shell_logger)
|
||||||
else:
|
else:
|
||||||
parser.print_usage()
|
parser.print_usage()
|
||||||
|
70
thefuck/entrypoints/shell_logger.py
Normal file
70
thefuck/entrypoints/shell_logger.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import array
|
||||||
|
import fcntl
|
||||||
|
from functools import partial
|
||||||
|
import os
|
||||||
|
import pty
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
import termios
|
||||||
|
import tty
|
||||||
|
from ..logs import warn
|
||||||
|
|
||||||
|
|
||||||
|
def _read(f, fd):
|
||||||
|
data = os.read(fd, 1024)
|
||||||
|
f.write(data)
|
||||||
|
f.flush()
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _set_pty_size(master_fd):
|
||||||
|
buf = array.array('h', [0, 0, 0, 0])
|
||||||
|
fcntl.ioctl(pty.STDOUT_FILENO, termios.TIOCGWINSZ, buf, True)
|
||||||
|
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, buf)
|
||||||
|
|
||||||
|
|
||||||
|
def _spawn(shell, master_read):
|
||||||
|
"""Create a spawned process.
|
||||||
|
|
||||||
|
Modified version of pty.spawn with terminal size support.
|
||||||
|
|
||||||
|
"""
|
||||||
|
pid, master_fd = pty.fork()
|
||||||
|
|
||||||
|
if pid == pty.CHILD:
|
||||||
|
os.execlp(shell, shell)
|
||||||
|
|
||||||
|
try:
|
||||||
|
mode = tty.tcgetattr(pty.STDIN_FILENO)
|
||||||
|
tty.setraw(pty.STDIN_FILENO)
|
||||||
|
restore = True
|
||||||
|
except tty.error: # This is the same as termios.error
|
||||||
|
restore = False
|
||||||
|
|
||||||
|
_set_pty_size(master_fd)
|
||||||
|
signal.signal(signal.SIGWINCH, lambda *_: _set_pty_size(master_fd))
|
||||||
|
|
||||||
|
try:
|
||||||
|
pty._copy(master_fd, master_read, pty._read)
|
||||||
|
except OSError:
|
||||||
|
if restore:
|
||||||
|
tty.tcsetattr(pty.STDIN_FILENO, tty.TCSAFLUSH, mode)
|
||||||
|
|
||||||
|
os.close(master_fd)
|
||||||
|
return os.waitpid(pid, 0)[1]
|
||||||
|
|
||||||
|
|
||||||
|
def shell_logger(output):
|
||||||
|
"""Logs shell output to the `output`.
|
||||||
|
|
||||||
|
Works like unix script command with `-f` flag.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not os.environ.get('SHELL'):
|
||||||
|
warn("Shell logger doesn't support your platform.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(output, 'wb') as f:
|
||||||
|
return_code = _spawn(os.environ['SHELL'], partial(_read, f))
|
||||||
|
|
||||||
|
sys.exit(return_code)
|
@ -44,7 +44,7 @@ class Bash(Generic):
|
|||||||
return '''
|
return '''
|
||||||
export THEFUCK_INSTANT_MODE=True;
|
export THEFUCK_INSTANT_MODE=True;
|
||||||
export THEFUCK_OUTPUT_LOG={log};
|
export THEFUCK_OUTPUT_LOG={log};
|
||||||
script -feq {log};
|
thefuck --shell-logger {log};
|
||||||
rm {log};
|
rm {log};
|
||||||
exit
|
exit
|
||||||
'''.format(log=log_path)
|
'''.format(log=log_path)
|
||||||
|
@ -42,7 +42,7 @@ class Zsh(Generic):
|
|||||||
return '''
|
return '''
|
||||||
export THEFUCK_INSTANT_MODE=True;
|
export THEFUCK_INSTANT_MODE=True;
|
||||||
export THEFUCK_OUTPUT_LOG={log};
|
export THEFUCK_OUTPUT_LOG={log};
|
||||||
script -feq {log};
|
thefuck --shell-logger {log};
|
||||||
rm {log};
|
rm {log};
|
||||||
exit
|
exit
|
||||||
'''.format(log=log_path)
|
'''.format(log=log_path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user