--- /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:=pipx
+PKG_VERSION:=1.2.1
+PKG_RELEASE:=1
+
+PYPI_NAME:=pipx
+PKG_HASH:=698777c05a97cca81df4dc6a71d9ca4ece2184c6f91dc7a0e4802ac51d86d32a
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/pipx
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Install/Run Python Applications in Isolated Environments
+ URL:=https://github.com/pypa/pipx
+ DEPENDS:= \
+ +python3-light \
+ +python3-logging \
+ +python3-urllib \
+ +python3-venv \
+ +python3-argcomplete \
+ +python3-packaging \
+ +python3-userpath
+endef
+
+define Package/pipx/description
+pipx is a tool to help you install and run end-user applications written
+in Python. It's roughly similar to macOS's brew, JavaScript's npx, and
+Linux's apt.
+
+It's closely related to pip. In fact, it uses pip, but is focused on
+installing and managing Python packages that can be run from the command
+line directly as applications.
+endef
+
+$(eval $(call Py3Package,pipx))
+$(eval $(call BuildPackage,pipx))
+$(eval $(call BuildPackage,pipx-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = pipx ] || exit 0
+
+pipx --version | grep -Fx "$PKG_VERSION"
--- /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-argcomplete
+PKG_VERSION:=3.1.4
+PKG_RELEASE:=1
+
+PYPI_NAME:=argcomplete
+PKG_HASH:=72558ba729e4c468572609817226fb0a6e7e9a0a7d477b882be168c0b4a62b94
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE.rst
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-setuptools-scm/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-argcomplete
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Bash tab completion for argparse
+ URL:=https://github.com/kislyuk/argcomplete
+ DEPENDS:=+python3-light
+endef
+
+define Package/python3-argcomplete/description
+Argcomplete provides easy, extensible command line tab completion of
+arguments for your Python application.
+endef
+
+$(eval $(call Py3Package,python3-argcomplete))
+$(eval $(call BuildPackage,python3-argcomplete))
+$(eval $(call BuildPackage,python3-argcomplete-src))
--- /dev/null
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -1,5 +1,5 @@
+ [build-system]
+-requires = ["setuptools>=67.7.2", "setuptools_scm[toml]>=6.2"]
++requires = ["setuptools", "setuptools_scm[toml]>=6.2"]
+ build-backend = "setuptools.build_meta"
+
+ [project]
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-argcomplete ] || exit 0
+
+python3 -c 'import argcomplete'
include $(TOPDIR)/rules.mk
PKG_NAME:=python-hatch-vcs
-PKG_VERSION:=0.3.0
+PKG_VERSION:=0.4.0
PKG_RELEASE:=1
PYPI_NAME:=hatch-vcs
PYPI_SOURCE_NAME:=hatch_vcs
-PKG_HASH:=cec5107cfce482c67f8bc96f18bbc320c9aa0d068180e14ad317bbee5a153fee
+PKG_HASH:=093810748fe01db0d451fabcf2c1ac2688caefd232d4ede967090b1c1b07d9f7
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=python-mako
-PKG_VERSION:=1.2.4
+PKG_VERSION:=1.3.0
PKG_RELEASE:=1
PYPI_NAME:=Mako
-PKG_HASH:=d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34
+PKG_HASH:=e3a9d388fd00e87043edbe8792f45880ac0114e9c4adc69f6e9bfb2c55e3b11b
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=python-poetry-core
-PKG_VERSION:=1.7.0
+PKG_VERSION:=1.8.1
PKG_RELEASE:=1
PYPI_NAME:=poetry-core
PYPI_SOURCE_NAME:=poetry_core
-PKG_HASH:=8f679b83bd9c820082637beca1204124d5d2a786e4818da47ec8acefd0353b74
+PKG_HASH:=67a76c671da2a70e55047cddda83566035b701f7e463b32a2abfeac6e2a16376
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-trove-classifiers
-PKG_VERSION:=2023.10.18
+PKG_VERSION:=2023.11.9
PKG_RELEASE:=1
PYPI_NAME:=trove-classifiers
-PKG_HASH:=2cdfcc7f31f7ffdd57666a9957296089ac72daad4d11ab5005060e5cd7e29939
+PKG_HASH:=0542bc03d151f8af84f0eb0e74aa931b374b6f9c8ed8fbf7ee41989fb9d40f1d
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-twisted
-PKG_VERSION:=23.8.0
+PKG_VERSION:=23.10.0
PKG_RELEASE:=1
PYPI_NAME:=Twisted
PYPI_SOURCE_NAME:=twisted
-PKG_HASH:=3c73360add17336a622c0d811c2a2ce29866b6e59b1125fd6509b17252098a24
+PKG_HASH:=987847a0790a2c597197613686e2784fd54167df3a55d0fb17c8412305d76ce5
PKG_BUILD_DEPENDS:=libtirpc
--- a/pyproject.toml
+++ b/pyproject.toml
-@@ -150,7 +150,6 @@ ckeygen = "twisted.conch.scripts.ckeygen
+@@ -138,7 +138,6 @@ ckeygen = "twisted.conch.scripts.ckeygen
conch = "twisted.conch.scripts.conch:run"
mailmail = "twisted.mail.scripts.mailmail:run"
pyhtmlizer = "twisted.scripts.htmlizer:run"
--- a/pyproject.toml
+++ b/pyproject.toml
-@@ -194,6 +194,7 @@ exclude = [
+@@ -182,6 +182,7 @@ exclude = [
"*.pxi",
"*.pyx",
"build.bat",
--- /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.1
+PKG_RELEASE:=1
+
+PYPI_NAME:=userpath
+PKG_HASH:=ce8176728d98c914b6401781bf3b23fccd968d1647539c8788c7010375e02796
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_MAINTAINER:=Jeffery To <jeffery.to@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
+
+userpath --version | grep -Fx "userpath, version $PKG_VERSION"
include $(TOPDIR)/rules.mk
PKG_NAME:=python-wheel
-PKG_VERSION:=0.41.2
+PKG_VERSION:=0.41.3
PKG_RELEASE:=1
PYPI_NAME:=wheel
-PKG_HASH:=0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985
+PKG_HASH:=4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=crowdsec
-PKG_VERSION:=1.5.4
+PKG_VERSION:=1.5.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/crowdsecurity/crowdsec/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=afa4021f77e9cb87d7fd11cd86146770836dc15cad1ae8a4edce1314b14be98a
+PKG_HASH:=ec7b2815405be4c3a1c9c3dcb1110030c29b7408dbf2a82d25537843c8831329
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_NAME:=freeradius3
PKG_VERSION:=3.0.26
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=freeradius-server-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://github.com/FreeRADIUS/freeradius-server/releases/download/release_$(subst .,_,$(PKG_VERSION))/
define Package/freeradius3-common
$(call Package/freeradius3/Default)
TITLE:=common files
- DEPENDS:=+USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +libcap +libpcap +libncurses +libpcre2 +libreadline +libtalloc +libatomic
+ DEPENDS:=+USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +libcap +libpcap +libncurses +libreadline +libtalloc +libatomic
endef
define Package/freeradius3-default
--with-radacctdir=/var/db/radacct \
--with-logdir=/var/log \
--without-edir \
+ --without-pcre \
--without-snmp \
--without-rlm_cache \
--without-rlm_cache_memcached \
include $(TOPDIR)/rules.mk
PKG_NAME:=sing-box
-PKG_VERSION:=1.6.3
+PKG_VERSION:=1.6.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=3bebd23dd5d4734a90fb8821b3c2c0be0fd34800d10e6a4e0db95e06578cca1c
+PKG_HASH:=3b1008d8a4d0cb0c41841531b1845b9b859a5d8f73af2c9a137fec4c7ad1f18f
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=LICENSE
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-only
+#
+# Copyright (C) 2023 Facundo Acevedo
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dysk
+PKG_VERSION:=2.8.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/Canop/dysk/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=3e0f3a470539721748d7bc1acc867bdddcb824695b2f766e3a1f230ebac28c2c
+
+PKG_MAINTAINER:=Facundo Acevedo <facevedo@disroot.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENCE
+
+PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/rust/rust-package.mk
+
+define Package/dysk
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Utility for efficient file and directory management
+ DEPENDS:=$(RUST_ARCH_DEPENDS)
+ URL:=https://dystroy.org/dysk
+endef
+
+define Package/dysk/description
+ Dysk is a command-line tool designed for efficient file and
+ directory management in Unix-like environments. It offers a
+ streamlined approach to organizing and manipulating files,
+ potentially simplifying various file-related tasks.
+endef
+
+$(eval $(call RustBinPackage,dysk))
+$(eval $(call BuildPackage,dysk))