+++ /dev/null
-#
-# Copyright (C) 2023 Jeffery To
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=python-userpath
-PKG_VERSION:=1.9.2
-PKG_RELEASE:=1
-
-PYPI_NAME:=userpath
-PKG_HASH:=6c52288dab069257cc831846d15d48133522455d4677ee69a9781f11dbefd815
-
-PKG_LICENSE:=MIT
-PKG_LICENSE_FILES:=LICENSE.txt
-PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
-
-PKG_BUILD_DEPENDS:=python-hatchling/host
-
-include ../pypi.mk
-include $(INCLUDE_DIR)/package.mk
-include ../python3-package.mk
-
-define Package/python3-userpath
- SECTION:=lang
- CATEGORY:=Languages
- SUBMENU:=Python
- TITLE:=Cross-platform tool for modifying a user's PATH
- URL:=https://github.com/ofek/userpath
- DEPENDS:=+python3-light +python3-click +python3-psutil
-endef
-
-define Package/python3-userpath/description
-This is a tool for modifying a user's PATH.
-endef
-
-$(eval $(call Py3Package,python3-userpath))
-$(eval $(call BuildPackage,python3-userpath))
-$(eval $(call BuildPackage,python3-userpath-src))
+++ /dev/null
-From 9175a0a97c7bc2eeb995e53d50a07be6a7e834f0 Mon Sep 17 00:00:00 2001
-From: Jeffery To <jeffery.to@gmail.com>
-Date: Thu, 9 Nov 2023 14:20:58 +0800
-Subject: [PATCH] Handle OSErrors when running show path commands
-
-Bash may not always be installed, for example on OpenWrt, and attempting
-to call the show path commands for Bash will cause a FileNotFoundError
-to be raised.
-
-This wraps the subprocess call with a try statement and returns the
-empty string in the case of an OSError.
----
- userpath/utils.py | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
---- a/userpath/utils.py
-+++ b/userpath/utils.py
-@@ -30,8 +30,11 @@ def ensure_parent_dir_exists(path):
-
-
- def get_flat_output(command, sep=os.pathsep, **kwargs):
-- process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
-- output = process.communicate()[0].decode(locale.getpreferredencoding(False)).strip()
-+ try:
-+ process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
-+ output = process.communicate()[0].decode(locale.getpreferredencoding(False)).strip()
-+ except OSError:
-+ return ''
-
- # We do this because the output may contain new lines.
- lines = [line.strip() for line in output.splitlines()]
+++ /dev/null
-From dffcc1c5823bcce10b420467db41e42ec41f4702 Mon Sep 17 00:00:00 2001
-From: Jeffery To <jeffery.to@gmail.com>
-Date: Thu, 9 Nov 2023 17:48:50 +0800
-Subject: [PATCH 1/2] Use Sh as base class for Bash and Zsh
-
----
- userpath/shells.py | 41 ++++++++++++++++++++++++++---------------
- 1 file changed, 26 insertions(+), 15 deletions(-)
-
---- a/userpath/shells.py
-+++ b/userpath/shells.py
-@@ -12,24 +12,36 @@ class Shell(object):
-
-
- 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)
-+
-+ def config(self, location, front=True):
-+ contents = self._config_contents(location, front=front)
-+ return {path.join(self.home, '.profile'): contents}
-
-- return {path.join(self.home, '.profile'): 'PATH="{}"'.format(new_path)}
-+ @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 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 +62,7 @@ class Bash(Shell):
-
- @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,18 +100,17 @@ class Xonsh(Shell):
- 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 = {
+++ /dev/null
-From 7823b9b39c486aedf830783329abdc3bd9664ba4 Mon Sep 17 00:00:00 2001
-From: Jeffery To <jeffery.to@gmail.com>
-Date: Thu, 9 Nov 2023 17:51:21 +0800
-Subject: [PATCH 2/2] Add support for ash (Almquist shell)
-
----
- tests/docker/debian | 2 +-
- tests/test_ash.py | 65 +++++++++++++++++++++++++++++++++++++++++++++
- userpath/shells.py | 5 ++++
- 3 files changed, 71 insertions(+), 1 deletion(-)
- create mode 100644 tests/test_ash.py
-
---- 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
---- /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')
---- a/userpath/shells.py
-+++ b/userpath/shells.py
-@@ -37,6 +37,10 @@ class Sh(Shell):
- return [cls._interactive_login_show_path_command()]
-
-
-+class Ash(Sh):
-+ name = 'ash'
-+
-+
- class Bash(Sh):
- name = 'bash'
-
-@@ -114,6 +118,7 @@ class Zsh(Sh):
-
-
- SHELLS = {
-+ 'ash': Ash,
- 'bash': Bash,
- 'fish': Fish,
- 'sh': Sh,
+++ /dev/null
-#!/bin/sh
-
-[ "$1" = python3-userpath ] || exit 0
-
-# Test version
-userpath --version | grep -Fx "userpath, version $PKG_VERSION"
-
-# Test append and prepend (changes take effect after shell restart,
-# so only check that the commands succeed)
-TEST_DIR="/tmp/userpath-test-$$"
-userpath append "$TEST_DIR"
-
-TEST_DIR2="/tmp/userpath-test2-$$"
-userpath prepend "$TEST_DIR2"