Skip to content

Commit

Permalink
Improve the shell command
Browse files Browse the repository at this point in the history
  • Loading branch information
sdispater committed Sep 20, 2019
1 parent 9b28630 commit de5839d
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 2 deletions.
23 changes: 22 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion poetry/console/commands/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ def handle(self):
# Setting this to avoid spawning unnecessary nested shells
environ["POETRY_ACTIVE"] = "1"
shell = Shell.get()
self.env.execute(shell.path)
shell.activate(self.env)
environ.pop("POETRY_ACTIVE")
54 changes: 54 additions & 0 deletions poetry/utils/shell.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import os
import signal
import sys

import pexpect

from clikit.utils.terminal import Terminal
from shellingham import detect_shell
from shellingham import ShellDetectionFailure

from ._compat import WINDOWS
from .env import VirtualEnv


class Shell:
"""
Expand Down Expand Up @@ -40,5 +48,51 @@ def get(cls): # type: () -> Shell

return cls._shell

def activate(self, env): # type: (VirtualEnv) -> None
if WINDOWS:
return env.execute(self.path)

terminal = Terminal()
with env.temp_environ():
c = pexpect.spawn(
self._path, ["-i"], dimensions=(terminal.height, terminal.width)
)

c.setecho(False)
activate_script = self._get_activate_script()
bin_dir = "Scripts" if WINDOWS else "bin"
activate_path = env.path / bin_dir / activate_script
c.sendline("{} {}".format(self._get_source_command(), activate_path))

def resize(sig, data):
terminal = Terminal()
c.setwinsize(terminal.height, terminal.width)

signal.signal(signal.SIGWINCH, resize)

# Interact with the new shell.
c.interact(escape_character=None)
c.close()

sys.exit(c.exitstatus)

def _get_activate_script(self):
if "fish" == self._name:
suffix = ".fish"
elif "csh" == self._name:
suffix = ".csh"
else:
suffix = ""

return "activate" + suffix

def _get_source_command(self):
if "fish" == self._name:
return "source"
elif "csh" == self._name:
return "source"

return "."

def __repr__(self): # type: () -> str
return '{}("{}", "{}")'.format(self.__class__.__name__, self._name, self._path)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pkginfo = "^1.4"
html5lib = "^1.0"
shellingham = "^1.1"
tomlkit = "^0.5.5"
pexpect = "^4.7.0"

# The typing module is not in the stdlib in Python 2.7 and 3.4
typing = { version = "^3.6", python = "~2.7 || ~3.4" }
Expand Down

0 comments on commit de5839d

Please sign in to comment.