From 0ad314b0bf1b083168b0ab723c066812ed630dbd Mon Sep 17 00:00:00 2001 From: dormieriancitizen Date: Fri, 10 Oct 2025 16:40:40 -0400 Subject: [PATCH 01/13] Feat: package name autocompletion --- dexi/app.py | 22 +++++++++++++++++++--- dexi/commands/viewer.py | 8 ++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dexi/app.py b/dexi/app.py index 73457b0..1040b83 100644 --- a/dexi/app.py +++ b/dexi/app.py @@ -1,4 +1,5 @@ import typer +from typing_extensions import Annotated from .commands.installer import install_packages from .commands.manager import ( @@ -7,7 +8,7 @@ update_all_packages, update_package, ) -from .commands.viewer import list_packages +from .commands.viewer import autocomplete_packages, list_packages from .core.errors import Errors app = typer.Typer() @@ -31,7 +32,14 @@ def add(package: str, branch: str = "main"): @app.command() -def remove(package: str): +def remove( + package: Annotated[ + str, + typer.Argument( + help="The name of the package", autocompletion=autocomplete_packages + ), + ], +): """ Removes and uninstalls a package. @@ -46,7 +54,15 @@ def remove(package: str): @app.command() -def update(package: str | None = None): +def update( + package: Annotated[ + str, + typer.Argument( + help="The name of the package", autocompletion=autocomplete_packages + ), + ] + | None = None, +): """ Updates all packages or a specified package. diff --git a/dexi/commands/viewer.py b/dexi/commands/viewer.py index be454e6..c99bbeb 100644 --- a/dexi/commands/viewer.py +++ b/dexi/commands/viewer.py @@ -3,6 +3,14 @@ from ..core.utils import console, fetch_all_packages, fetch_pyproject, package_name +def autocomplete_packages(incomplete: str) -> list[str]: + return [ + package["git"] + for package in fetch_all_packages() + if package["git"].startswith(incomplete) + ] + + def list_packages(hide_update: bool = False): """ Displays a list of packages. From f67a2715c579b123ac02bb194cdc05ff4dfb1543 Mon Sep 17 00:00:00 2001 From: dormieriancitizen Date: Fri, 10 Oct 2025 17:17:00 -0400 Subject: [PATCH 02/13] Pathlib initial changes --- dexi/commands/installer.py | 45 ++++++++++++++++++++------------------ dexi/core/errors.py | 6 ++--- dexi/core/utils.py | 41 +++++++++++++++++++--------------- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/dexi/commands/installer.py b/dexi/commands/installer.py index f94f384..a76a614 100644 --- a/dexi/commands/installer.py +++ b/dexi/commands/installer.py @@ -1,5 +1,6 @@ import io import os +from pathlib import Path import random import shutil import zipfile @@ -50,9 +51,9 @@ def uninstall_package(package: str): if data.app is not None and not app_operations_supported(): return - desination = f"{os.getcwd()}/ballsdex/packages/{data.package.target}" + destination = Path.cwd() / "ballsdex" / "packages" / data.package.target - if not os.path.isdir(desination): + if not destination.is_dir(): return if data.app is not None: @@ -65,7 +66,7 @@ def uninstall_package(package: str): remove_list_entry("packages", f"ballsdex.packages.{data.package.target}") - shutil.rmtree(desination) + shutil.rmtree(destination) def install_package( @@ -93,16 +94,16 @@ def install_package( author, repository = repository.split("/") zip_url = f"https://github.com/{author}/{repository}/archive/refs/heads/{branch}.zip" - desination = f"{os.getcwd()}/ballsdex/packages/{data.package.target}" + destination = Path.cwd() / "ballsdex" / "packages" / data.package.target name = package_name(repository, branch) - if os.path.isdir(desination): + if destination.is_dir(): if cancel_if_exists: return False replaced = True - shutil.rmtree(desination) + shutil.rmtree(destination) if data.app is not None: if not app_operations_supported(): @@ -111,15 +112,15 @@ def install_package( f"on Ballsdex v$BD_V, please update to v{SUPPORTED_APP_VERSION}+" ) - app_desination = f"{os.getcwd()}/admin_panel/{data.app.target}" + app_destination = Path.cwd() / "admin_panel" / data.app.target - if os.path.isdir(app_desination): + if app_destination.is_dir(): replaced = True - shutil.rmtree(app_desination) + shutil.rmtree(app_destination) - os.makedirs(app_desination, exist_ok=True) + app_destination.mkdir(parents=True, exist_ok=True) - os.makedirs(desination, exist_ok=True) + destination.mkdir(parents=True, exist_ok=True) response = requests.get(zip_url) @@ -131,10 +132,7 @@ def install_package( for member in z.namelist(): if member[-7:] in ["LICENSE", "LICENCE"]: - with ( - z.open(member) as src, - open(f"{desination}/{member[-7:]}", "wb") as dst, - ): + with z.open(member) as src, (destination / member[-7:]).open("wb") as dst: shutil.copyfileobj(src, dst) continue @@ -147,7 +145,7 @@ def install_package( if not relative_path or relative_path in data.package.exclude: continue - target_path = os.path.join(desination, relative_path) + target_path = destination / relative_path if member.endswith("/"): os.makedirs(target_path, exist_ok=True) @@ -159,7 +157,12 @@ def install_package( shutil.copyfileobj(src, dst) if data.app is not None: # I'll refactor this later - app_desination = cast(str, app_desination) # type: ignore + if not app_destination: + # something has gone remarkably wrong + # (shouldnt be possible) + raise Exception( + "Somehow app_destination has gone missing while copying files" + ) for member in z.namelist(): if not member.startswith(f"{base_folder}{data.app.source}/"): @@ -170,15 +173,15 @@ def install_package( if not relative_path: continue - target_path = os.path.join(app_desination, relative_path) + target_path = app_destination / relative_path if member.endswith("/"): - os.makedirs(target_path, exist_ok=True) + target_path.mkdir(parents=True, exist_ok=True) continue - os.makedirs(os.path.dirname(target_path), exist_ok=True) + target_path.parent.mkdir(parents=True, exist_ok=True) - with z.open(member) as src, open(target_path, "wb") as dst: + with z.open(member) as src, target_path.open("wb") as dst: shutil.copyfileobj(src, dst) add_list_entry( diff --git a/dexi/core/errors.py b/dexi/core/errors.py index 89cd1e0..3400235 100644 --- a/dexi/core/errors.py +++ b/dexi/core/errors.py @@ -1,9 +1,9 @@ -import os from dataclasses import dataclass, field from packaging.version import parse as parse_version from .utils import error, fetch_ballsdex_version +from pathlib import Path SUPPORTED_VERSION = "2.22.0" @@ -18,14 +18,14 @@ class Errors: @staticmethod def invalid_project() -> None: - if os.path.isdir("ballsdex") and os.path.isfile("pyproject.toml"): + if Path("ballsdex").is_dir() and Path("pyproject.toml").is_file(): return error("Attempted to use DexI command on an invalid project") @staticmethod def no_config_found() -> None: - if os.path.isfile("config.yml"): + if Path("config.yml").is_file(): return error("No 'config.yml' file detected") diff --git a/dexi/core/utils.py b/dexi/core/utils.py index 8528a9d..c2b6906 100644 --- a/dexi/core/utils.py +++ b/dexi/core/utils.py @@ -1,4 +1,5 @@ import os +from pathlib import Path import re import sys from typing import cast @@ -50,7 +51,7 @@ def fetch_pyproject(package: str, branch: str) -> dict: return data -def parse_pyproject(path: str | None = None) -> TOMLDocument: +def parse_pyproject(path: Path | None = None) -> TOMLDocument: """ Parses a pyproject file and returns it. @@ -60,14 +61,14 @@ def parse_pyproject(path: str | None = None) -> TOMLDocument: The path that holds the pyproject file. """ if path is None: - path = os.getcwd() + path = Path.cwd() - path = f"{path}/pyproject.toml" + path = path / "pyproject.toml" - if not os.path.isfile(path): + if not path.is_file(): error("Failed to find [red]pyproject.toml[/red] in the current directory") - with open(path) as file: + with path.open() as file: return parse(file.read()) @@ -78,7 +79,7 @@ def app_operations_supported() -> bool: return parse_version(fetch_ballsdex_version()) >= parse_version(SUPPORTED_APP_VERSION) -def fetch_ballsdex_version(path: str | None = None) -> str: +def fetch_ballsdex_version(path: Path | None = None) -> str: """ Returns the Ballsdex version. @@ -88,14 +89,14 @@ def fetch_ballsdex_version(path: str | None = None) -> str: The path that will be checked. """ if path is None: - path = os.getcwd() + path = Path.cwd() - path = f"{path}/ballsdex/__init__.py" + path = path / "ballsdex/__init__.py" - if not os.path.isfile(path): + if not path.is_file(): error("Failed to find [red]ballsdex/__init__.py[/red] in the current directory") - with open(path) as file: + with path.open() as file: return file.read().replace('__version__ = "', "").rstrip()[:-1] @@ -150,7 +151,7 @@ def fetch_all_packages() -> list[PackageEntry]: return cast(list[PackageEntry], packages) -def add_list_entry(section: str, entry: str, path: str | None = None): +def add_list_entry(section: str, entry: str, path: Path | None = None): """ Adds an item to a list in the config file. @@ -164,9 +165,11 @@ def add_list_entry(section: str, entry: str, path: str | None = None): The config file path. """ if path is None: - path = os.getcwd() + path = Path.cwd() - with open(f"{path}/config.yml") as file: + path = path / "config.yml" + + with path.open() as file: lines = file.readlines() item = f" - {entry}\n" @@ -179,11 +182,11 @@ def add_list_entry(section: str, entry: str, path: str | None = None): lines.insert(i + 1, item) break - with open(f"{path}/config.yml", "w") as file: + with path.open("w") as file: file.writelines(lines) -def remove_list_entry(section: str, entry: str, path: str | None = None): +def remove_list_entry(section: str, entry: str, path: Path | None = None): """ Removes an item from a list in the config file. @@ -197,9 +200,11 @@ def remove_list_entry(section: str, entry: str, path: str | None = None): The config file path. """ if path is None: - path = os.getcwd() + path = Path.cwd() + + path = path / "config.yml" - with open(f"{path}/config.yml") as file: + with path.open() as file: lines = file.readlines() item = f" - {entry}\n" @@ -209,7 +214,7 @@ def remove_list_entry(section: str, entry: str, path: str | None = None): lines.remove(item) - with open(f"{path}/config.yml", "w") as file: + with path.open("w") as file: file.writelines(lines) From cfe75724f43811291f7828aa1258293ba5e41100 Mon Sep 17 00:00:00 2001 From: dormieriancitizen Date: Fri, 10 Oct 2025 17:27:23 -0400 Subject: [PATCH 03/13] I forgot to ruff --- dexi/commands/installer.py | 2 +- dexi/core/errors.py | 2 +- dexi/core/utils.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dexi/commands/installer.py b/dexi/commands/installer.py index a76a614..704d43e 100644 --- a/dexi/commands/installer.py +++ b/dexi/commands/installer.py @@ -1,9 +1,9 @@ import io import os -from pathlib import Path import random import shutil import zipfile +from pathlib import Path from typing import cast import requests diff --git a/dexi/core/errors.py b/dexi/core/errors.py index 3400235..74e044f 100644 --- a/dexi/core/errors.py +++ b/dexi/core/errors.py @@ -1,9 +1,9 @@ from dataclasses import dataclass, field +from pathlib import Path from packaging.version import parse as parse_version from .utils import error, fetch_ballsdex_version -from pathlib import Path SUPPORTED_VERSION = "2.22.0" diff --git a/dexi/core/utils.py b/dexi/core/utils.py index c2b6906..53a3b5d 100644 --- a/dexi/core/utils.py +++ b/dexi/core/utils.py @@ -1,7 +1,6 @@ -import os -from pathlib import Path import re import sys +from pathlib import Path from typing import cast import requests From 8e78d31b2894a1a78e7755e2d39be53f6e76f8e7 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Fri, 10 Oct 2025 18:26:17 -0400 Subject: [PATCH 04/13] Fix missing error checking --- CHANGELOG.md | 4 ++++ dexi/app.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e49e4f5..ed8df52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.1.0 (DEV) + +- Fixed missing error checking for `dexi update` + ## 1.0.0 (2025-10-08) - Released DexI version 1.0.0 diff --git a/dexi/app.py b/dexi/app.py index 73457b0..9b028f2 100644 --- a/dexi/app.py +++ b/dexi/app.py @@ -56,7 +56,7 @@ def update(package: str | None = None): The package you want to update. Automatically updates all packages if not specified. """ - Errors(["invalid_project", "invalid_version", "no_config_found"]).check + Errors(["invalid_project", "invalid_version", "no_config_found"]).check() if package is None: update_all_packages() From 755750431e094becc1fa48ced5ab1c6a8e1cbb92 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Fri, 10 Oct 2025 19:00:46 -0400 Subject: [PATCH 05/13] Update changelog --- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed8df52..cd4fe56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,15 @@ ## 1.1.0 (DEV) +- Add package name autocomplete for `dexi remove` and `dexi update` ([#8](https://github.com/Dotsian/DexI/pull/8)) +- Use pathlib for path manipulation ([#7](https://github.com/Dotsian/DexI/pull/7)) +- Replace default installation method with uv - Fixed missing error checking for `dexi update` +### Contributors + +- [@dormieriancitizen](https://github.com/dormieriancitizen) + ## 1.0.0 (2025-10-08) - Released DexI version 1.0.0 diff --git a/README.md b/README.md index abca6e3..26f5736 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,10 @@ Using DexI over the traditional method for package management is far better, as ## Installation -You can install and update DexI using [pip](https://www.python.org/downloads/): +You can install and update DexI using [uv](https://docs.astral.sh/uv/getting-started/installation/): ```bash -pip install git+https://github.com/Dotsian/DexI.git +uv tool install git+https://github.com/Dotsian/DexI ``` ## Usage From dc1e1eb18407f7938ad638da3aa7e2d38e0b5bb5 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Fri, 10 Oct 2025 19:04:52 -0400 Subject: [PATCH 06/13] minor changes --- CHANGELOG.md | 4 ++-- README.md | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd4fe56..5d640ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Add package name autocomplete for `dexi remove` and `dexi update` ([#8](https://github.com/Dotsian/DexI/pull/8)) - Use pathlib for path manipulation ([#7](https://github.com/Dotsian/DexI/pull/7)) - Replace default installation method with uv -- Fixed missing error checking for `dexi update` +- Fix missing error checking for `dexi update` ### Contributors @@ -13,4 +13,4 @@ ## 1.0.0 (2025-10-08) -- Released DexI version 1.0.0 +- Release DexI version 1.0.0 diff --git a/README.md b/README.md index 26f5736..873814b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![CI](https://github.com/Dotsian/DexI/actions/workflows/CI.yml/badge.svg)](https://github.com/Dotsian/DexI/actions/workflows/CI.yml) [![Issues](https://img.shields.io/github/issues/Dotsian/DexI)](https://github.com/Dotsian/DexI/issues) -[![Version](https://img.shields.io/badge/version-1.0.0-blue)](https://github.com/Dotsian/DexI/blob/master/CHANGELOG.md) +[![Version](https://img.shields.io/badge/version-1.1.0-blue)](https://github.com/Dotsian/DexI/blob/master/CHANGELOG.md) Dex Inventory "DexI" is a Ballsdex package manager developed by DotZZ that provides developers with package control and easily allows users to add, remove, install, and update third-party packages. @@ -18,12 +18,18 @@ Using DexI over the traditional method for package management is far better, as ## Installation -You can install and update DexI using [uv](https://docs.astral.sh/uv/getting-started/installation/): +You can install DexI using [uv](https://docs.astral.sh/uv/getting-started/installation/): ```bash uv tool install git+https://github.com/Dotsian/DexI ``` +Updating DexI with uv: + +```bash +uv tool upgrade dexi +``` + ## Usage > [!WARNING] From a0a7467ebc61066a402157423464ead9f39e7b18 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Fri, 10 Oct 2025 20:27:54 -0400 Subject: [PATCH 07/13] Bump version --- dexi/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dexi/__init__.py b/dexi/__init__.py index 1c11a6e..eee00e3 100644 --- a/dexi/__init__.py +++ b/dexi/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0" +__version__ = "1.1.0" diff --git a/pyproject.toml b/pyproject.toml index 4c24bf2..0e28f99 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "DexI" -version = "1.0.0" +version = "1.1.0" description = 'Dex Inventory "DexI" package manager for Ballsdex' requires-python = ">=3.12" license = "MIT" From f2aec4293c492e8e4e24c49bed8dcb959192d637 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Sat, 11 Oct 2025 13:15:12 -0400 Subject: [PATCH 08/13] Fix `exclude` error --- CHANGELOG.md | 1 + dexi/core/package.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d640ac..4d2fef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Add package name autocomplete for `dexi remove` and `dexi update` ([#8](https://github.com/Dotsian/DexI/pull/8)) - Use pathlib for path manipulation ([#7](https://github.com/Dotsian/DexI/pull/7)) - Replace default installation method with uv +- Fix error when installing a package that omits the `exclude` attribute - Fix missing error checking for `dexi update` ### Contributors diff --git a/dexi/core/package.py b/dexi/core/package.py index 452f2c3..3b36736 100644 --- a/dexi/core/package.py +++ b/dexi/core/package.py @@ -59,7 +59,7 @@ def from_git(cls, package: str, branch: str) -> Self: error(f"Could not locate {package_name(package, branch)}") package_config = PackageConfig( - dexi_package["source"], dexi_package["target"], dexi_package.get("exclude") + dexi_package["source"], dexi_package["target"], dexi_package.get("exclude", []) ) fields = { From 7dd781f36fdc5b1cbfbd846b3589c489920958e6 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Sat, 11 Oct 2025 13:16:06 -0400 Subject: [PATCH 09/13] Fix ruff --- dexi/core/package.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dexi/core/package.py b/dexi/core/package.py index 3b36736..a61100a 100644 --- a/dexi/core/package.py +++ b/dexi/core/package.py @@ -59,7 +59,9 @@ def from_git(cls, package: str, branch: str) -> Self: error(f"Could not locate {package_name(package, branch)}") package_config = PackageConfig( - dexi_package["source"], dexi_package["target"], dexi_package.get("exclude", []) + dexi_package["source"], + dexi_package["target"], + dexi_package.get("exclude", []) ) fields = { From cd6c84942fa33a824313b02361ebe1ea49d5746d Mon Sep 17 00:00:00 2001 From: ethan Date: Sat, 11 Oct 2025 12:23:46 -0600 Subject: [PATCH 10/13] #2 Adds "red" rich styling for remaining error messages on any word that references a package or the exact reason for the error message. --- dexi/commands/installer.py | 8 ++++---- dexi/commands/manager.py | 14 +++++++------- dexi/core/errors.py | 6 +++--- dexi/core/package.py | 7 +++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/dexi/commands/installer.py b/dexi/commands/installer.py index 704d43e..2069ab9 100644 --- a/dexi/commands/installer.py +++ b/dexi/commands/installer.py @@ -43,7 +43,7 @@ def uninstall_package(package: str): found_package = fetch_package(package, dexi_tool["packages"]) if found_package is None: - error(f"Could not find '{package}' package") + error(f"Could not find [red]'{package}'[/red] package") return data = Package.from_git(found_package["git"], found_package["branch"]) @@ -108,8 +108,8 @@ def install_package( if data.app is not None: if not app_operations_supported(): error( - f"DexI packages with Django apps are not supported " - f"on Ballsdex v$BD_V, please update to v{SUPPORTED_APP_VERSION}+" + f"[red]DexI packages[/red] with Django apps are not supported " + f"on [red]Ballsdex v$BD_V[/red], please update to v{SUPPORTED_APP_VERSION}+" ) app_destination = Path.cwd() / "admin_panel" / data.app.target @@ -125,7 +125,7 @@ def install_package( response = requests.get(zip_url) if not response.ok: - error(f"Failed to fetch {name}") + error(f"Failed to fetch [red]{name}[/red]") with zipfile.ZipFile(io.BytesIO(response.content)) as z: base_folder = f"{repository}-{branch}/" diff --git a/dexi/commands/manager.py b/dexi/commands/manager.py index ad61dfe..d21da26 100644 --- a/dexi/commands/manager.py +++ b/dexi/commands/manager.py @@ -46,9 +46,9 @@ def add_package(package: str, branch: str): if installed_version not in specifier: error( - f"Ballsdex version requirement for '{package}' is set to " - f"'{data.ballsdex_version}', while this instance is on " - f"version '{ballsdex}'" + f"Ballsdex version requirement for [red]'{package}'[/red] is set to " + f"[red]'{data.ballsdex_version}'[/red], while this instance is on " + f"version [red]'{ballsdex}'[/red]" ) project = parse_pyproject() @@ -58,7 +58,7 @@ def add_package(package: str, branch: str): dexi = tool.setdefault("dexi", table()) if not initialized and fetch_package(package, fetch_all_packages()) is not None: - error("This package has already been added") + error("This [red]package[/red] has already been added") package_array = dexi.setdefault("packages", array().multiline(True)) @@ -113,7 +113,7 @@ def remove_package(package: str): package_entry = fetch_package(package, dexi_tool["packages"]) if package_entry is None: - error(f"Could not find '{package}' package") + error(f"Could not find [red]'{package}'[/red] package") return uninstall_package(package) @@ -176,12 +176,12 @@ def update_package(package: str | PackageEntry): dexi_project = parse_pyproject() if "tool" not in dexi_project or "dexi" not in dexi_project["tool"]: # type: ignore - error("pyproject.toml contains invalid DexI data") + error("[red]pyproject.toml[/red] contains invalid [red]DexI data[/red]") dexi_tool = dexi_project["tool"]["dexi"] # type: ignore if "packages" not in dexi_tool: # type: ignore - error("pyproject.toml contains invalid DexI data") + error("[[red]pyproject.toml[/red] contains invalid [red]DexI data[/red]") packages = dexi_tool["packages"] # type: ignore diff --git a/dexi/core/errors.py b/dexi/core/errors.py index 74e044f..edac371 100644 --- a/dexi/core/errors.py +++ b/dexi/core/errors.py @@ -21,14 +21,14 @@ def invalid_project() -> None: if Path("ballsdex").is_dir() and Path("pyproject.toml").is_file(): return - error("Attempted to use DexI command on an invalid project") + error("Attempted to use [red]DexI[/red] command on an [red]invalid project[/red]") @staticmethod def no_config_found() -> None: if Path("config.yml").is_file(): return - error("No 'config.yml' file detected") + error("No [red]'config.yml'[/red] file detected") @staticmethod def invalid_version() -> None: @@ -36,7 +36,7 @@ def invalid_version() -> None: return error( - "DexI does not support Ballsdex v$BD_V, please update to " + "DexI does not support [red]Ballsdex v$BD_V[/red], please update to " f"v{SUPPORTED_VERSION}+" ) diff --git a/dexi/core/package.py b/dexi/core/package.py index a61100a..9b00663 100644 --- a/dexi/core/package.py +++ b/dexi/core/package.py @@ -3,7 +3,6 @@ from .utils import error, fetch_pyproject, package_name - @dataclass class PackageConfig: """ @@ -44,19 +43,19 @@ class Package: def from_git(cls, package: str, branch: str) -> Self: if package.count("/") != 1: error( - "Invalid GitHub repository identifier entered; Expected " + "Invalid GitHub repository identifier entered; Expected [red][/red]" ) data = fetch_pyproject(package, branch) if not data or "tool" not in data or "dexi" not in data["tool"]: - error(f"Could not locate {package_name(package, branch)}") + error(f"Could not locate [red]{package_name(package, branch)}[/red]") dexi_tool = data["tool"]["dexi"] dexi_package = dexi_tool["package"] if not dexi_tool.get("public", False): - error(f"Could not locate {package_name(package, branch)}") + error(f"Could not locate [red]{package_name(package, branch)}[/red]") package_config = PackageConfig( dexi_package["source"], From 4474a9cc1434d238c90bc0a72488a39035ba2daf Mon Sep 17 00:00:00 2001 From: Dotsian Date: Sun, 19 Oct 2025 05:12:24 -0400 Subject: [PATCH 11/13] Add #9 to changelog and fix checks --- CHANGELOG.md | 2 ++ dexi/commands/installer.py | 4 ++-- dexi/core/package.py | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d2fef4..3b39805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add package name autocomplete for `dexi remove` and `dexi update` ([#8](https://github.com/Dotsian/DexI/pull/8)) - Use pathlib for path manipulation ([#7](https://github.com/Dotsian/DexI/pull/7)) +- Stylized error messages ([#9](https://github.com/Dotsian/DexI/pull/9)) - Replace default installation method with uv - Fix error when installing a package that omits the `exclude` attribute - Fix missing error checking for `dexi update` @@ -11,6 +12,7 @@ ### Contributors - [@dormieriancitizen](https://github.com/dormieriancitizen) +- [@ethanthopkins](https://github.com/ethanthopkins) ## 1.0.0 (2025-10-08) diff --git a/dexi/commands/installer.py b/dexi/commands/installer.py index 2069ab9..4689d97 100644 --- a/dexi/commands/installer.py +++ b/dexi/commands/installer.py @@ -108,8 +108,8 @@ def install_package( if data.app is not None: if not app_operations_supported(): error( - f"[red]DexI packages[/red] with Django apps are not supported " - f"on [red]Ballsdex v$BD_V[/red], please update to v{SUPPORTED_APP_VERSION}+" + f"[red]DexI packages[/red] with Django apps are not supported on " + f"red]Ballsdex v$BD_V[/red], please update to v{SUPPORTED_APP_VERSION}+" ) app_destination = Path.cwd() / "admin_panel" / data.app.target diff --git a/dexi/core/package.py b/dexi/core/package.py index 9b00663..6c3659c 100644 --- a/dexi/core/package.py +++ b/dexi/core/package.py @@ -3,6 +3,7 @@ from .utils import error, fetch_pyproject, package_name + @dataclass class PackageConfig: """ @@ -43,7 +44,8 @@ class Package: def from_git(cls, package: str, branch: str) -> Self: if package.count("/") != 1: error( - "Invalid GitHub repository identifier entered; Expected [red][/red]" + "Invalid GitHub repository identifier entered; " + "Expected [red][/red]" ) data = fetch_pyproject(package, branch) From 05526f2d6c6c95d44fbf231c99a8ab109c6d3623 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Tue, 21 Oct 2025 22:03:31 -0400 Subject: [PATCH 12/13] Update notice --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 873814b..0ddc9f2 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Dex Inventory "DexI" is a Ballsdex package manager developed by DotZZ that provides developers with package control and easily allows users to add, remove, install, and update third-party packages. -_**App support will only be available after Ballsdex v2.29.4**_ +_**Packages with Django apps can only be downloaded from Ballsdex v2.29.5+**_ ## DexI vs. the Traditional Method From a5f2ed1d1aa4b474188c7cf395931ca3348fa378 Mon Sep 17 00:00:00 2001 From: Dotsian Date: Tue, 21 Oct 2025 22:07:07 -0400 Subject: [PATCH 13/13] Prepare for release --- CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b39805..35e4c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,20 @@ # Changelog -## 1.1.0 (DEV) +## 1.1.0 (2025-10-21) -- Add package name autocomplete for `dexi remove` and `dexi update` ([#8](https://github.com/Dotsian/DexI/pull/8)) -- Use pathlib for path manipulation ([#7](https://github.com/Dotsian/DexI/pull/7)) -- Stylized error messages ([#9](https://github.com/Dotsian/DexI/pull/9)) +- Add package name autocomplete for `dexi remove` and `dexi update` ([#8]()) +- Use pathlib for path manipulation ([#7]()) +- Stylize error messages ([#9]()) - Replace default installation method with uv - Fix error when installing a package that omits the `exclude` attribute - Fix missing error checking for `dexi update` ### Contributors -- [@dormieriancitizen](https://github.com/dormieriancitizen) -- [@ethanthopkins](https://github.com/ethanthopkins) +- [@dormieriancitizen]() +- [@ethanthopkins]() ## 1.0.0 (2025-10-08) - Release DexI version 1.0.0 +