diff --git a/dotfiles/.chezmoidata/binaries.toml b/dotfiles/.chezmoidata/binaries.toml index 3548ab2..487c723 100644 --- a/dotfiles/.chezmoidata/binaries.toml +++ b/dotfiles/.chezmoidata/binaries.toml @@ -7,11 +7,13 @@ # version_regex (optional): A custom regex to extract the version from `binary --version`. # required_architecture (optional): The architecture required for the binary. If the current architecture does not match, the binary will not be installed. Must match .chezmoi.arch. # install_filter (optional): Filters to use when installing the package. Must match the name of a filter in .chezmoi.data - ie "dev_computer", "personal_computer", "homelab_member". +# remove_from_release (optional): A regex used to filter out releases. Useful when more than one release is available for your platform. [binaries] [binaries.bottom] install_filter = "" name = "bottom" + remove_from_release = "" repository = "ClementTsang/bottom" required_architecture = "" systems = ["linux"] @@ -20,6 +22,7 @@ [binaries.doggo] install_filter = "" name = "doggo" + remove_from_release = "_web_" repository = "mr-karan/doggo" required_architecture = "" systems = ["linux"] @@ -28,6 +31,7 @@ [binaries.git-delta] install_filter = "" name = "delta" + remove_from_release = "" repository = "dandavison/delta" required_architecture = "" systems = ["linux"] @@ -36,6 +40,7 @@ [binaries.lazygit] install_filter = "dev_computer" name = "lazygit" + remove_from_release = "" repository = "jesseduffield/lazygit" required_architecture = "" systems = ["linux"] @@ -44,6 +49,7 @@ [binaries.otree] install_filter = "" name = "otree" + remove_from_release = "" repository = "fioncat/otree" required_architecture = "amd64" systems = ["linux"] @@ -52,6 +58,7 @@ [binaries.rip2] install_filter = "" name = "rip" + remove_from_release = "" repository = "MilesCranmer/rip2" required_architecture = "" systems = ["darwin", "linux"] @@ -60,6 +67,7 @@ [binaries.zoxide] install_filter = "" name = "zoxide" + remove_from_release = "" repository = "ajeetdsouza/zoxide" required_architecture = "" systems = ["linux"] diff --git a/dotfiles/.chezmoiscripts/run_after_30_install-non-pkg-mngr-binaries.tmpl b/dotfiles/.chezmoiscripts/run_after_30_install-non-pkg-mngr-binaries.tmpl index 559770e..245b3bc 100644 --- a/dotfiles/.chezmoiscripts/run_after_30_install-non-pkg-mngr-binaries.tmpl +++ b/dotfiles/.chezmoiscripts/run_after_30_install-non-pkg-mngr-binaries.tmpl @@ -55,7 +55,7 @@ if [[ ! -e ${INSTALL_SCRIPT} ]] then fi -uv run -q "${INSTALL_SCRIPT}" --binary-name="{{ $binary.name }}" --repository="{{ $binary.repository }}" --version-regex="{{ $binary.version_regex }}" +uv run -q "${INSTALL_SCRIPT}" --binary-name="{{ $binary.name }}" --repository="{{ $binary.repository }}" --version-regex="{{ $binary.version_regex }}" --remove-from-release="{{ $binary.remove_from_release }}" {{ end }} diff --git a/dotfiles/bin/executable_install-binary.py b/dotfiles/bin/executable_install-binary.py index aa70c9e..5cb4496 100755 --- a/dotfiles/bin/executable_install-binary.py +++ b/dotfiles/bin/executable_install-binary.py @@ -160,13 +160,20 @@ def instantiate_logger( class BinaryUpdater: """Class to check for updates to a binary and install the update if available.""" - def __init__(self, binary_name: str, repository: str, version_regex: str = ""): + def __init__( + self, + binary_name: str, + repository: str, + version_regex: str = "", + remove_from_release: str = "", + ): """Initialize the BinaryUpdater class. Args: binary_name (str): Name of the binary available in the PATH repository (str): GitHub repository in the format 'owner/repo' version_regex (str): Custom regex to identify the version in the binary --version output + remove_from_release (str): Regex used to filter out releases. Useful when more than one release is available. """ # Initialize instance attributes self._release_info: dict = {} @@ -181,6 +188,7 @@ def __init__(self, binary_name: str, repository: str, version_regex: str = ""): self.binary_name = binary_name self.repository = repository self.version_regex = version_regex + self.remove_from_release = remove_from_release # Get the latest release information self.latest_version: str = self.release_info["name"].replace("v", "").strip() @@ -289,7 +297,7 @@ def need_install(self) -> bool: console.print(f"{self.latest_version=}") raise typer.Exit(1) from e - def _find_deb_release(self, architecture: str) -> list[dict]: + def _find_deb_release(self, architecture: str, remove_from_release: str) -> list[dict]: """Find a .deb release for the host system based on the specified architecture. This method searches through the available assets to find .deb packages that match @@ -297,6 +305,7 @@ def _find_deb_release(self, architecture: str) -> list[dict]: Args: architecture (str): The architecture of the host system (e.g., 'x86_64', 'arm64'). + remove_from_release (str): A regex pattern to filter out releases. Returns: list[dict]: A list of dictionaries representing the .deb assets that match the specified architecture. @@ -312,6 +321,9 @@ def _find_deb_release(self, architecture: str) -> list[dict]: if not a["name"].endswith(".deb"): continue + if remove_from_release and re.search(remove_from_release, a["name"].lower()): + continue + try: if not re.search(Arches[architecture.upper()].value, a["name"].lower()): continue @@ -335,7 +347,9 @@ def _find_deb_release(self, architecture: str) -> list[dict]: return possible_assets - def _find_packaged_release(self, operating_system: str, architecture: str) -> list[dict]: + def _find_packaged_release( + self, operating_system: str, architecture: str, remove_from_release: str + ) -> list[dict]: """Find a packaged release for the host system based on the operating system and architecture. This method filters the available assets to find those that match the specified operating system @@ -344,6 +358,7 @@ def _find_packaged_release(self, operating_system: str, architecture: str) -> li Args: operating_system (str): The operating system of the host (e.g., 'linux', 'windows'). architecture (str): The architecture of the host (e.g., 'x86_64', 'arm'). + remove_from_release (str): A regex pattern to filter out releases. Returns: list[dict]: A list of dictionaries representing the possible assets that match the criteria. @@ -358,6 +373,9 @@ def _find_packaged_release(self, operating_system: str, architecture: str) -> li if not a["name"].endswith(".tar.gz"): continue + if remove_from_release and re.search(remove_from_release, a["name"].lower()): + continue + if not re.search(operating_system.lower(), a["name"].lower()): continue @@ -413,11 +431,13 @@ def download_url(self) -> str: possible_releases = [] if host_platform.system.lower() == "linux": - possible_releases = self._find_deb_release(host_platform.machine) + possible_releases = self._find_deb_release( + host_platform.machine, self.remove_from_release + ) if not possible_releases: possible_releases = self._find_packaged_release( - host_platform.system, host_platform.machine + host_platform.system, host_platform.machine, self.remove_from_release ) if not possible_releases: @@ -615,6 +635,13 @@ def main( show_default=False, ), ] = "", + remove_from_release: Annotated[ + str, + typer.Option( + help="Regex used to filter out releases. Useful when more than one release is available.", + show_default=False, + ), + ] = "", log_file: Annotated[ Path, typer.Option( @@ -663,7 +690,10 @@ def main( ) binary = BinaryUpdater( - binary_name=binary_name, repository=repository, version_regex=version_regex + binary_name=binary_name, + repository=repository, + version_regex=version_regex, + remove_from_release=remove_from_release, ) logger.log("SECONDARY", f"Repository: https://github.com/{binary.repository}")