Skip to content

Commit

Permalink
Merge pull request #282 from cs50/pexpect
Browse files Browse the repository at this point in the history
removed pexpect, fixed windows
  • Loading branch information
Kareem Zidane authored Apr 3, 2020
2 parents 054dfe5 + 54e2e20 commit 9194cd2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.*
!.gitignore
!.travis.yml
help50.egg*
__pycache__/
53 changes: 37 additions & 16 deletions help50/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import re
import shlex
import sys
import tempfile
import traceback

from argparse import ArgumentParser, REMAINDER
Expand All @@ -14,6 +13,12 @@

from . import __version__, internal, Error

ON_WINDOWS = os.name == "nt"

if ON_WINDOWS:
# Fix termcolor colors on Windows
import colorama
colorama.init()

def excepthook(cls, exc, tb):
if (issubclass(cls, lib50.Error) or issubclass(cls, Error)) and exc.args:
Expand Down Expand Up @@ -60,7 +65,6 @@ def main():
"students understand error messages.")
parser.add_argument("-s", "--slug", help="identifier indicating from where to download helpers", default="cs50/helpers/master")
parser.add_argument("-d", "--dev", help="slug will be treated as a local path, useful for developing helpers (implies --verbose)", action="store_true")
parser.add_argument("-i", "--interactive", help="read command output from stdin instead of running a command", action="store_true")
parser.add_argument("-v", "--verbose", help="display the full tracebacks of any errors", action="store_true")
parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {__version__}")
parser.add_argument("command", nargs=REMAINDER,
Expand All @@ -72,25 +76,42 @@ def main():

excepthook.verbose = args.verbose

if args.command:
command = " ".join(shlex.quote(word) for word in args.command)
script = b""

# pty isn't supported on Windows
if ON_WINDOWS:
import subprocess
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for b in iter(lambda: proc.stdout.read(1), b""):
script += b
sys.stdout.buffer.write(b)
sys.stdout.flush()
else:
import pty
def master_read(fd):
nonlocal script
data = os.read(fd, 1024)
script += data
return data

old_env = os.environ.copy()

if args.interactive:
script = sys.stdin.read()
elif args.command:
# Capture stdout and stderr from process, and print it out
with tempfile.TemporaryFile(mode="r+b") as temp:
env = os.environ.copy()
# Hack to prevent some programs from wrapping their error messages
env["COLUMNS"] = "5050"
proc = pexpect.spawn(f"bash -lc \"{' '.join(shlex.quote(word) for word in args.command)}\"", env=env)
proc.logfile_read = temp
proc.interact()
proc.close()

temp.seek(0)
script = temp.read().decode().replace("\r\n", "\n")
os.environ.update({"COLUMNS": "5050"})
try:
# Run the process in a pseudo-terminal e.g., to preserve colored output
pty.spawn(["bash", "-lc", command], master_read)
finally:
os.environ.clear()
os.environ.update(old_env)

script = script.decode().replace("\r\n", "\n")
else:
raise Error("Careful, you forgot to tell me with which command you "
"need help!")

termcolor.cprint("\nAsking for help...\n", "yellow")

try:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
license="GPLv3",
description="This is help50, a command-line tool that helps students understand error messages.",
install_requires=["pexpect", "termcolor", "lib50>=1.1.10"],
install_requires=["colorama", "termcolor", "lib50>=1.1.10"],
keywords="help50",
name="help50",
packages=["help50"],
Expand All @@ -21,5 +21,5 @@
},
py_requires="3.6",
url="https://github.com/cs50/help50",
version="3.0.0"
version="3.0.1"
)

0 comments on commit 9194cd2

Please sign in to comment.