diff --git a/tests/docker/debian b/tests/docker/debian index ac28094..a474499 100644 --- a/tests/docker/debian +++ b/tests/docker/debian @@ -2,7 +2,7 @@ ARG PYTHON_VERSION FROM python:${PYTHON_VERSION} RUN apt-get update \ - && apt-get --no-install-recommends -y install fish zsh + && apt-get --no-install-recommends -y install ash fish zsh COPY requirements.txt / RUN pip install -r requirements.txt diff --git a/tests/test_ash.py b/tests/test_ash.py new file mode 100644 index 0000000..91fb999 --- /dev/null +++ b/tests/test_ash.py @@ -0,0 +1,65 @@ +import pytest +import userpath + +from .utils import SKIP_WINDOWS_CI, get_random_path + +SHELL_NAME = 'ash' + +pytestmark = [SKIP_WINDOWS_CI, pytest.mark.ash] + + +@pytest.mark.usefixtures('shell_test') +class TestDebian(object): + DOCKERFILE = 'debian' + + def test_prepend(self, request, shell_test): + if shell_test is None: + location = get_random_path() + assert not userpath.in_current_path(location) + assert userpath.prepend(location, check=True) + assert userpath.in_new_path(location) + assert userpath.need_shell_restart(location) + else: + process = shell_test(request.node.name) + stdout, stderr = process.communicate() + + assert process.returncode == 0, (stdout + stderr).decode('utf-8') + + def test_prepend_multiple(self, request, shell_test): + if shell_test is None: + locations = [get_random_path(), get_random_path()] + assert not userpath.in_current_path(locations) + assert userpath.prepend(locations, check=True) + assert userpath.in_new_path(locations) + assert userpath.need_shell_restart(locations) + else: + process = shell_test(request.node.name) + stdout, stderr = process.communicate() + + assert process.returncode == 0, (stdout + stderr).decode('utf-8') + + def test_append(self, request, shell_test): + if shell_test is None: + location = get_random_path() + assert not userpath.in_current_path(location) + assert userpath.append(location, check=True) + assert userpath.in_new_path(location) + assert userpath.need_shell_restart(location) + else: + process = shell_test(request.node.name) + stdout, stderr = process.communicate() + + assert process.returncode == 0, (stdout + stderr).decode('utf-8') + + def test_append_multiple(self, request, shell_test): + if shell_test is None: + locations = [get_random_path(), get_random_path()] + assert not userpath.in_current_path(locations) + assert userpath.append(locations, check=True) + assert userpath.in_new_path(locations) + assert userpath.need_shell_restart(locations) + else: + process = shell_test(request.node.name) + stdout, stderr = process.communicate() + + assert process.returncode == 0, (stdout + stderr).decode('utf-8') diff --git a/userpath/shells.py b/userpath/shells.py index 66114d4..d8a0ae1 100644 --- a/userpath/shells.py +++ b/userpath/shells.py @@ -12,24 +12,40 @@ def __init__(self, home=None): class Sh(Shell): - def config(self, location, front=True): + name = 'sh' + + def _config_contents(self, location, front=True): head, tail = (location, '$PATH') if front else ('$PATH', location) new_path = '{}{}{}'.format(head, pathsep, tail) + return 'export PATH="{}"'.format(new_path) - return {path.join(self.home, '.profile'): 'PATH="{}"'.format(new_path)} + def config(self, location, front=True): + contents = self._config_contents(location, front=front) + return {path.join(self.home, '.profile'): contents} + + @classmethod + def _interactive_show_path_command(cls): + return [cls.name, '-i', '-c', 'echo $PATH'] + + @classmethod + def _interactive_login_show_path_command(cls): + return [cls.name, '-i', '-l', '-c', 'echo $PATH'] @classmethod def show_path_commands(cls): # TODO: Find out what file influences non-login shells. The issue may simply be our Docker setup. - return [['sh', '-i', '-l', '-c', 'echo $PATH']] + return [cls._interactive_login_show_path_command()] -class Bash(Shell): - def config(self, location, front=True): - head, tail = (location, '$PATH') if front else ('$PATH', location) - new_path = '{}{}{}'.format(head, pathsep, tail) - contents = 'export PATH="{}"'.format(new_path) +class Ash(Sh): + name = 'ash' + +class Bash(Sh): + name = 'bash' + + def config(self, location, front=True): + contents = self._config_contents(location, front=front) configs = {path.join(self.home, '.bashrc'): contents} # https://github.com/ofek/userpath/issues/3#issuecomment-492491977 @@ -50,7 +66,7 @@ def config(self, location, front=True): @classmethod def show_path_commands(cls): - return [['bash', '-i', '-c', 'echo $PATH'], ['bash', '-i', '-l', '-c', 'echo $PATH']] + return [cls._interactive_show_path_command(), cls._interactive_login_show_path_command()] class Fish(Shell): @@ -88,21 +104,21 @@ def show_path_commands(cls): return [['xonsh', '-i', '-c', command], ['xonsh', '-i', '--login', '-c', command]] -class Zsh(Shell): - def config(self, location, front=True): - head, tail = (location, '$PATH') if front else ('$PATH', location) - new_path = '{}{}{}'.format(head, pathsep, tail) - contents = 'export PATH="{}"'.format(new_path) +class Zsh(Sh): + name = 'zsh' + def config(self, location, front=True): + contents = self._config_contents(location, front=front) zdotdir = environ.get('ZDOTDIR', self.home) return {path.join(zdotdir, '.zshrc'): contents, path.join(zdotdir, '.zprofile'): contents} @classmethod def show_path_commands(cls): - return [['zsh', '-i', '-c', 'echo $PATH'], ['zsh', '-i', '-l', '-c', 'echo $PATH']] + return [cls._interactive_show_path_command(), cls._interactive_login_show_path_command()] SHELLS = { + 'ash': Ash, 'bash': Bash, 'fish': Fish, 'sh': Sh,