diff --git a/README.rst b/README.rst index 223e1f1..bfbecb0 100644 --- a/README.rst +++ b/README.rst @@ -219,6 +219,19 @@ variable before defaulting to ``notepad`` on Windows and aws> .edit +.cd +~~~ + +You can change the current working directory of the aws-shell by using +the ``.cd`` command:: + + aws> !pwd + /usr + aws> .cd /tmp + aws> !pwd + /tmp + + Executing Shell Commands ------------------------ diff --git a/awsshell/app.py b/awsshell/app.py index 218e2b0..b8c29a7 100644 --- a/awsshell/app.py +++ b/awsshell/app.py @@ -45,6 +45,24 @@ class InputInterrupt(Exception): pass +class ChangeDirHandler(object): + def __init__(self, output=sys.stdout, err=sys.stderr, chdir=os.chdir): + self._output = output + self._err = err + self._chdir = chdir + + def run(self, command, application): + # command is a list of parsed commands + if len(command) != 2: + self._err.write("invalid syntax, must be: .cd dirname\n") + return + dirname = os.path.expandvars(os.path.expanduser(command[1])) + try: + self._chdir(dirname) + except OSError as e: + self._err.write("cd: %s\n" % e) + + class EditHandler(object): def __init__(self, popen_cls=None, env=None): if popen_cls is None: @@ -85,6 +103,7 @@ def run(self, command, application): class DotCommandHandler(object): HANDLER_CLASSES = { 'edit': EditHandler, + 'cd': ChangeDirHandler, } def __init__(self, output=sys.stdout, err=sys.stderr): diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py index 9702545..f8397a8 100644 --- a/tests/unit/test_app.py +++ b/tests/unit/test_app.py @@ -42,3 +42,26 @@ def test_prints_error_message_on_unknown_dot_command(errstream): handler = app.DotCommandHandler(err=errstream) handler.handle_cmd(".unknown foo bar", None) assert errstream.getvalue() == "Unknown dot command: .unknown\n" + + +def test_cd_handler_can_chdir(): + chdir = mock.Mock() + handler = app.ChangeDirHandler(chdir=chdir) + handler.run(['.cd', 'foo/bar'], None) + assert chdir.call_args == mock.call('foo/bar') + + +def test_chdir_syntax_error_prints_err_msg(errstream): + chdir = mock.Mock() + handler = app.ChangeDirHandler(err=errstream, chdir=chdir) + handler.run(['.cd'], None) + assert 'invalid syntax' in errstream.getvalue() + assert not chdir.called + + +def test_error_displayed_when_chdir_fails(errstream): + chdir = mock.Mock() + chdir.side_effect = OSError("FAILED") + handler = app.ChangeDirHandler(err=errstream, chdir=chdir) + handler.run(['.cd', 'foo'], None) + assert 'FAILED' in errstream.getvalue()