9 Commits

Author SHA1 Message Date
58438a5fdf fix: improve initialization process and error handling
- Add dependency checking for jq and downloaders
- Improve directory creation and error handling
- Better zini installation and configuration
- Enhanced user feedback during setup
- Version bump to 0.1.0
2025-05-18 13:07:54 +02:00
36b81d6657 Fix a few bugs preventing the download of scripts 2024-07-01 09:42:36 +02:00
0372eba263 Title: Refactor zrep_download_package function and introduce zrep_global_downloader
- Refactored zrep_download_package to use zrep_global_downloader for unified downloading
- Removed duplicate code for downloading files
- Added support for retries and error handling in zrep_global_downloader
2024-04-07 19:21:05 +02:00
d0136a9b19 Update downloader commands in zrep_global_downloader and zrep_download_package functions. Fixed ZSH_SCRIPT variable usage. 2024-04-07 19:06:55 +02:00
933b27b167 Update zrep functions to use function keyword for consistency.
- Updated `zrep_load_theme` to use `function` keyword.
- Updated `zrep_search_url_encode` to use `function` keyword.
- Updated `zrep_search` to use `function` keyword.
2024-04-07 01:28:51 +02:00
2ccef547a8 Update zpi version to 0.0.9
- Updated version to 0.0.9
- Updated URLs to point to zpi instead of zrep
- Updated initialization messages to refer to zpi
- Updated messages to reflect zpi instead of zrep
2024-04-06 18:43:49 +02:00
30ffb0f6bb Update zpi tool with new features and improvements:
- Updated tool name to "Zrep Package Installer"
- Modified installation directory prompt
- Renamed commands related to zrep to zpi
- Updated help messages and usage instructions
- Improved package management functionality
2024-04-06 00:24:26 +02:00
8569de68ec Update package manager name from zrep to zpi and adjust related text and commands accordingly. 2024-04-05 22:01:39 +02:00
aee45ba2ee Added zsh functions for managing zrep packages. Fixed bugs in zrep functions. Updated zrep version to 0.0.7. 2024-04-05 21:43:51 +02:00
3 changed files with 280 additions and 206 deletions

View File

@ -1,39 +1,39 @@
<img src="zrep-logo.png" width="150" align="left">
# Zsh Repository Tool (zrep)
# Zrep Package Installer (zpi)
zrep is a powerful and user-friendly package manager for the Zsh shell. It allows you to easily install, manage, and share Zsh packages, such as plugins, themes, and scripts, directly from a central repository.
zpi is a powerful and user-friendly package manager for the Zsh shell. It allows you to easily install, manage, and share Zsh packages, such as plugins, themes, and scripts, directly from a central repository.
## What is it?
`zrep` in and of itself is the command line tool that you use to install and manage scripts that are placed in `$fpath` used by Zsh. The packages are available on [the zrep website](https://zrep.kekepower.com) where you can, if you want to share your own scripts, register for an account. By sharing your scripts with the community, you are probably making somebody's day easier.
`zpi` in and of itself is the command line tool that you use to install and manage scripts that are placed in `$fpath` used by Zsh. The packages are available on [the zrep website](https://zrep.kekepower.com) where you can, if you want to share your own scripts, register for an account. By sharing your scripts with the community, you are probably making somebody's day easier.
You can read more in the Wiki.
## Key Features
- **Easy Installation**: zrep simplifies the process of installing Zsh packages. With a single command, you can install packages from the zrep repository.
- **Easy Installation**: zpi simplifies the process of installing Zsh packages. With a single command, you can install packages from the zrep repository.
- **Package Management**: zrep provides a set of commands to manage your installed packages. You can list, enable, disable, update, and remove packages effortlessly.
- **Package Management**: zpi provides a set of commands to manage your installed packages. You can list, enable, disable, update, and remove packages effortlessly.
- **Centralized Repository**: All packages are stored in a central repository, making it convenient to discover and share Zsh packages with the community.
- **Automatic Setup**: zrep automatically sets up the necessary configuration files and directories, ensuring a smooth integration with your Zsh environment.
- **Automatic Setup**: zpi automatically sets up the necessary configuration files and directories, ensuring a smooth integration with your Zsh environment.
- **Customizable**: zrep allows you to customize the installation directory and other settings through a configuration file.
- **Customizable**: zpi allows you to customize the installation directory and other settings through a configuration file.
## Getting Started
To start using zrep, simply run the `zrep init` command to initialize the tool. zrep will guide you through the setup process and create the required configuration files.
To start using zpi, simply run the `zpi init` command to initialize the tool. zpi will guide you through the setup process and create the required configuration files.
Use the search function on **[the zrep website](https://zrep.kekepower.com)** to find useful scripts until a search function is added to the `zrep` script some time in the future.
Use the search function on **[the zrep website](https://zrep.kekepower.com)** to find useful scripts until a search function is added to the `zpi` script some time in the future.
Once initialized, you can explore and install packages using commands like `zrep install <author/package>`, `zrep list`, and `zrep enable <author/package>`.
Once initialized, you can explore and install packages using commands like `zpi install <author/package>`, `zpi list`, and `zpi enable <author/package>`.
## Contributing
zrep is an open-source project, and contributions are welcome! If you have any ideas, bug reports, or feature requests, please open an issue on the GitHub repository.
zpi is an open-source project, and contributions are welcome! If you have any ideas, bug reports, or feature requests, please open an issue on the GitHub repository.
## License
zrep is released under the MIT License.
zpi is released under the MIT License.

34
t
View File

@ -1,34 +0,0 @@
#!/usr/bin/zsh
function zrep_fpath_2() {
local base_dir="${1}"
# Ensure globbing finds dotfiles and nullglob avoids empty directory issues
setopt local_options dotglob nullglob
# Check if the base directory exists
if [[ ! -d "${base_dir}" ]]; then
echo "Error: Base directory '${base_dir}' does not exist."
return 1
fi
# Iterate over directories within $base_dir with exactly one character
for one_char_dir in ${base_dir}/?; do
# Check if it's indeed a directory
[[ -d "${one_char_dir}" ]] || continue
# Recursively find all final directories under one_char_dir with the pattern first_letter/author/script
for script_dir in ${one_char_dir}/*/*(/); do
local script_name=$(basename "${script_dir}")
local matching_files=("${script_dir}/${script_name}")
# Check if there's at least one file matching the script directory's name
if (( ${#matching_files} )); then
echo "${script_dir}"
fi
done
done
}
zrep_fpath_2 /home/stig/.zrep

View File

@ -2,8 +2,8 @@
setopt extendedglob
VERSION="0.0.7" # Fri-2024-04-05
ZREP="Zsh Repository Tool"
VERSION="0.1.0" # Sat-2025-05-18
ZREP="Zrep Package Installer"
# Define the default path to .zreprc
ZREP_CONFIG="${HOME}/.zreprc"
@ -84,13 +84,13 @@ typeset -A base_colors=(
# Define the global associative array to hold the current theme
declare -A current_theme
zrep_load_theme() {
function zrep_load_theme() {
local theme_name="$1"
local theme_file="${config[main_zrep_install_dir]}/themes/${theme_name}"
local theme_file="/home/stig/.zrep/themes/${theme_name}"
if [[ ! -f "$theme_file" ]]; then
echo "Error: Theme file for '${theme_name}' not found. Falling back to the 'classic' theme."
theme_file="${config[main_zrep_install_dir]}/themes/classic"
theme_file="/home/stig/.zrep/themes/classic"
fi
# Source the theme file, which should define 'theme_colors'
@ -109,7 +109,7 @@ function zrep_main_version_string() {
function zrep_version() {
zrep_msg info "\nCreated by kekePower - 2024"
zrep_msg info "License: MIT"
zrep_msg info "https://git.kekepower.com/kekePower/zrep/"
zrep_msg info "https://git.kekepower.com/kekePower/zpi/"
zrep_msg info "Please see '${base_colors[${current_theme[help]}]}${ZSH_SCRIPT:t} help${base_colors[end]}${base_colors[${current_theme[info]}]}' for more info${base_colors[end]}"
exit
}
@ -137,7 +137,7 @@ function zrep_msg() {
#################################################################################################
# Function to URL-encode strings in Zsh
zrep_search_url_encode() {
function zrep_search_url_encode() {
local string="${1}"
local strlen=${#string}
local encoded=""
@ -156,13 +156,13 @@ zrep_search_url_encode() {
}
# Function to perform a search query and process JSON response
zrep_search() {
function zrep_search() {
local searchTerm="${@}"
local encodedSearch=$(zrep_search_url_encode "${searchTerm}")
# Use the global_repo_url from the config associative array
local response=$(curl -s -A "zrep ${VERSION} (curl)" "${config[global_repo_url]}/find.php?s=${encodedSearch}")
local response=$(curl -s -A "${ZSH_SCRIPT:t} ${VERSION} (curl)" "${config[global_repo_url]}/find.php?s=${encodedSearch}")
# Determine if the JSON response is an object indicating "No scripts found"
local jsonType=$(echo "$response" | jq -r 'type')
@ -223,6 +223,31 @@ function zrep_check_for_deps() {
done
}
# Function to check for required dependencies
function zrep_check_deps() {
local missing_deps=()
# Check for jq
if ! command -v jq &> /dev/null; then
missing_deps+=("jq")
fi
# Check for downloader (curl/wget)
if ! command -v curl &> /dev/null && ! command -v wget &> /dev/null; then
missing_deps+=("curl or wget")
fi
if [[ ${#missing_deps[@]} -ne 0 ]]; then
echo "The following dependencies are required but not installed:"
for dep in "${missing_deps[@]}"; do
echo " - ${dep}"
done
echo "Please install them and try again."
return 1
fi
return 0
}
# The first step after downloading zrep.
# Here we create the default file and directory structure
function zrep_init() {
@ -230,23 +255,32 @@ function zrep_init() {
local zrep_addons="${HOME}/.zrep_addons"
local install_dir
# Check for required dependencies
if ! zrep_check_deps; then
return 1
fi
# Check if .zreprc exists
if [[ ! -f ${ZREP_CONFIG} ]]; then
echo "${ZREP_CONFIG} not found. Creating it..."
# Prompt user for install directory
read "install_dir?Enter zrep installation directory [${HOME}/.zrep]: "
read "install_dir?Enter zpi installation directory [${HOME}/.zrep]: "
install_dir=${install_dir:-"${HOME}/.zrep"}
mkdir -p ${install_dir}
read "downloader?Choose command to download packages [curl, wget, wget2]: "
if [[ ${downloader} != curl && ${downloader} != wget && ${downloader} != wget2 ]]; then
echo "Invalid choice: '$downloader'. Try again."
read "downloader?Choose command to download packages [curl, wget, wget2] "
if [[ ${downloader} != curl && ${downloader} != wget && ${downloader} != wget2 ]]; then
echo "Invalid choice: '$downloader'. Exiting."
exit
fi
mkdir -p "${install_dir}" || {
echo "Failed to create directory: ${install_dir}"
return 1
}
# Choose downloader
local downloader=""
if command -v curl &> /dev/null; then
downloader="curl"
elif command -v wget &> /dev/null; then
downloader="wget"
fi
echo "Using ${downloader} for downloads"
# Write to .zreprc
cat > "${ZREP_CONFIG}" <<EOF
[main]
@ -257,33 +291,86 @@ repo_url = https://zrep.kekepower.com
theme = classic
downloader = ${downloader}
EOF
echo "The file '${ZREP_CONFIG}' has been created."
echo "The file '${ZREP_CONFIG}' has been created."
else
zrep_fpath ${HOME}/.zrep/functions
autoload -Uz zini
echo "Loading configuration from ${ZREP_CONFIG}"
zini ${ZREP_CONFIG}
# install_dir=${config[main_zrep_install_dir]}
# Ensure the install directory exists
install_dir=${HOME}/.zrep # Default value
if [[ -f ${ZREP_CONFIG} ]]; then
# Extract the install directory from the config file if it exists
local config_install_dir=$(grep -m 1 '^zrep_install_dir' "${ZREP_CONFIG}" | cut -d'=' -f2 | tr -d '[:space:]')
if [[ -n "${config_install_dir}" ]]; then
install_dir="${config_install_dir}"
fi
mkdir -p "${install_dir}" || {
echo "Failed to create directory: ${install_dir}"
return 1
}
fi
# Load zini if available
if [[ -f "${install_dir}/functions/zini/zini" ]]; then
fpath=("${install_dir}/functions/zini" $fpath)
autoload -Uz zini
zini ${ZREP_CONFIG}
fi
fi
if [[ $(zrep_find_string zini) -eq 0 ]]; then
mkdir -p "${install_dir}/functions/zini"
zrep_global_downloader https://raw.githubusercontent.com/kekePower/zini/main/zini -o "${install_dir}/functions/zini/zini"
echo "Adding 'zini' path to fpath in ${zshrc_file}"
echo "fpath=(${install_dir}/functions/zini \$fpath)" >> ${zshrc_file}
# Create necessary directories
local dirs=(
"${install_dir}/functions"
"${install_dir}/themes"
"${install_dir}/packages"
)
for dir in "${dirs[@]}"; do
if [[ ! -d "${dir}" ]]; then
echo "Creating directory: ${dir}"
mkdir -p "${dir}" || {
echo "Failed to create directory: ${dir}"
return 1
}
fi
done
# Install zini if not found
if [[ ! -f "${install_dir}/functions/zini/zini" ]]; then
echo "Installing zini..."
mkdir -p "${install_dir}/functions/zini" || {
echo "Failed to create directory: ${install_dir}/functions/zini"
return 1
}
if ! zrep_global_downloader https://raw.githubusercontent.com/kekePower/zini/main/zini -o "${install_dir}/functions/zini/zini"; then
echo "Failed to download zini"
return 1
fi
# Add zini to fpath in .zshrc if not already present
if ! grep -q "${install_dir}/functions/zini" "${zshrc_file}" 2>/dev/null; then
echo "Adding 'zini' path to fpath in ${zshrc_file}"
echo "fpath=('${install_dir}/functions/zini' \$fpath)" >> "${zshrc_file}"
fi
# Ensure zini is loaded
fpath=("${install_dir}/functions/zini" $fpath)
autoload -Uz zini
fi
# Check if .zshrc already sources .zrep_addons, if not, add it
if [[ $(zrep_find_string "source ${zrep_addons}") -eq 0 ]]; then
echo "Adding source command for .zrep_addons to .zshrc..."
echo "source ${zrep_addons}" >> "${zshrc_file}"
# Load the config
if [[ -f "${ZREP_CONFIG}" ]]; then
zini "${ZREP_CONFIG}"
fi
fi
# Create or update the .zrep_addons file
if [[ ! -f ${zrep_addons} ]]; then
echo "Configuring zrep addons..."
if [[ ! -f "${zrep_addons}" ]]; then
echo "Creating file ${zrep_addons}..."
touch ${install_dir}/.addons
touch "${install_dir}/.addons" || {
echo "Failed to create: ${install_dir}/.addons"
return 1
}
cat > "${zrep_addons}" <<EOF
# Source the .addons file from the zrep installation directory
source "${install_dir}/.addons"
@ -291,29 +378,55 @@ source "${install_dir}/.addons"
# If addons array is defined and not empty, add its elements to fpath
if [[ -n \${addons[@]} ]]; then
for addon in "\${addons[@]}"; do
if [[ -d \${addon} ]] && [[ ! " \${fpath[*]} " =~ " \${addon} " ]]; then
fpath=(\${addon} "\${fpath[@]}") # Prepend the new addon to fpath
if [[ -d "\${addon}" ]] && [[ ! " \${fpath[*]} " =~ " \${addon} " ]]; then
fpath=("\${addon}" "\${fpath[@]}") # Prepend the new addon to fpath
fi
autoload -Uz \$(basename \${addon})
autoload -Uz \$(basename "\${addon}")
done
else
echo "zrep: No addons enabled."
echo "zpi: No addons enabled. Use 'zpi enable <package>' to enable addons."
fi
EOF
echo "File .zrep_addons created and configured."
echo "File ${zrep_addons} created and configured."
else
echo "File .zrep_addons already exists. Review manually if update is needed."
echo "File ${zrep_addons} already exists. Review manually if update is needed."
fi
if [[ ! -d ${install_dir}/themes ]]; then
echo "Installing the Classic theme to ${install_dir}/themes"
mkdir -p ${install_dir}/themes
zrep_global_downloader https://git.kekepower.com/kekePower/zrep/raw/branch/main/themes/classic -o ${install_dir}/themes/classic
# Add source to .zshrc if not present
if ! grep -q "source \"${zrep_addons}\"" "${zshrc_file}" 2>/dev/null; then
echo "Adding source command for ${zrep_addons} to ${zshrc_file}..."
echo -e "\n# Source zrep addons\nsource \"${zrep_addons}\"" >> "${zshrc_file}"
fi
echo "zrep initialization complete."
echo "You should copy 'zrep' to a path in you 'PATH' so that it's accessible."
echo "For example '${HOME}/bin'"
echo "Remember to 'source ${zshrc_file}' to load the 'zrep' settings."
# Install default theme if not present
if [[ ! -f "${install_dir}/themes/classic" ]]; then
echo "Installing the Classic theme to ${install_dir}/themes"
if ! zrep_global_downloader https://git.kekepower.com/kekePower/zpi/raw/branch/main/themes/classic -o "${install_dir}/themes/classic"; then
echo "Warning: Failed to download classic theme"
fi
fi
# Create a symlink if not in PATH
local bin_dir="${HOME}/bin"
if [[ ! -d "${bin_dir}" ]]; then
mkdir -p "${bin_dir}" && chmod 755 "${bin_dir}" || {
echo "Warning: Could not create ${bin_dir}"
bin_dir=""
}
fi
if [[ -n "${bin_dir}" && ! -f "${bin_dir}/zpi" ]]; then
echo "Creating symlink in ${bin_dir}"
ln -sf "$(pwd)/zpi" "${bin_dir}/zpi"
fi
echo -e "\n${base_colors[bold_green]}zpi initialization complete!${base_colors[end]}"
if [[ "${PATH}" != *"${bin_dir}"* ]]; then
echo -e "\n${base_colors[bold_yellow]}Note:${base_colors[end]} Add ${bin_dir} to your PATH by adding this to your ~/.zshrc:"
echo " export PATH=\"${bin_dir}:\$PATH\""
fi
echo -e "\nTo start using zpi, run: ${base_colors[bold_white]}source ${zshrc_file}${base_colors[end]}"
echo "Then try: ${base_colors[bold_white]}zpi help${base_colors[end]} to see available commands"
}
function zrep_installed_json() {
@ -332,6 +445,7 @@ function zrep_installed_json() {
# Function to parse remote JSON data and extract author, script, and version
# and return the correct download url
function zrep_parse_remote() {
local url="${1}"
local package="${2}"
@ -339,19 +453,21 @@ function zrep_parse_remote() {
local script_name="${package#*/}"
local json_data
# Print the URL being used for debugging
echo "Fetching URL: ${url}"
# Fetch JSON data from the URL
json_data=$(zrep_global_downloader "${url}")
# Print the fetched JSON data for debugging
echo "Fetched JSON data: ${json_data}"
# Directly extract the details based on author_name and script_name
version=$(echo "${json_data}" | jq -r --arg author_name "$author_name" --arg script_name "$script_name" '.authors[] | select(.name==$author_name) | .scripts[] | select(.name==$script_name) | .version')
# Check if the dlurl and version are found
if [[ -n "$version" ]]; then
# Set the details as global
#export author="$author_name"
#export script="$script_name"
export version
#export dlurl
else
zrep_msg debug "\nPackage ${package} not found.\n"
exit 1
@ -379,7 +495,7 @@ else
.[$author] = [{"script": $script, "version": $version}]
end' "$installed_json" > "$installed_json.tmp" && mv "$installed_json.tmp" "$installed_json"
zrep_msg info " - Package '$script' by '$author' version $version installed/updated successfully."
zrep_msg info "\n - Package '$author/$script' version $version installed/updated successfully."
}
# Function to list installed packages from installed.json
@ -444,7 +560,7 @@ function zrep_load_config() {
zini "${ZREP_CONFIG}"
zrep_fpath ${config[main_zrep_install_dir]} zrep_load
else
echo "${ZREP_CONFIG} not found. Run 'zrep init' to set up."
echo "${ZREP_CONFIG} not found. Run 'zpi init' to set up."
exit 1
fi
@ -463,7 +579,7 @@ function zrep_remove_package() {
if [[ -z "$installed_version" || "$installed_version" == "null" ]]; then
zrep_msg debug "\nError: Package '${package_name}' is not installed."
zrep_msg info "Please see 'zrep list' for installed packages."
zrep_msg info "Please see 'zpi list' for installed packages."
return 1
fi
@ -521,23 +637,70 @@ function zrep_check_if_installed() {
}
function zrep_global_downloader() {
local downloadURL="${1}"
local outputFile="${2:-}" # Optional, used for downloading files
local cmd
local retries=5
local delay=5
local attempt=0
case ${config[global_downloader]} in
curl)
dloader="curl -s -A \"zrep ${VERSION} (curl)\""
if [[ -n $outputFile ]]; then
cmd="curl -s -L -A \"${ZSH_SCRIPT:t} ${VERSION} (curl)\" -w \"%{http_code}\" -o \"$outputFile\" \"$downloadURL\""
else
cmd="curl -s -L -A \"${ZSH_SCRIPT:t} ${VERSION} (curl)\" -w \"%{http_code}\" \"$downloadURL\""
fi
;;
wget)
dloader="wget -q -U \"zrep ${VERSION} (wget)\""
;;
wget2)
dloader="wget2 -q -U \"zrep ${VERSION} (wget2)\""
wget|wget2)
if [[ -n $outputFile ]]; then
cmd="${config[global_downloader]} -q -L -U \"${ZSH_SCRIPT:t} ${VERSION} (${config[global_downloader]})\" -O \"$outputFile\" \"$downloadURL\""
else
cmd="${config[global_downloader]} -q -L -U \"${ZSH_SCRIPT:t} ${VERSION} (${config[global_downloader]})\" \"$downloadURL\""
fi
;;
*)
echo "Invalid Downloader."
exit
echo "Unsupported downloader."
return 1
;;
esac
eval ${dloader} "${1}"
while (( ++attempt <= retries )); do
if [[ ${config[global_downloader]} == "curl" ]]; then
local response
response=$(eval $cmd)
local http_status="${response: -3}"
local json_data="${response:0: -3}"
if [[ $http_status -eq 200 ]]; then
[[ -z $outputFile ]] && echo "$json_data"
return 0
else
echo "HTTP Status: $http_status"
return 1
fi
else
eval $cmd
exit_status=$?
if [[ $exit_status -eq 0 ]]; then
[[ -n $outputFile ]] && cat "$outputFile"
return 0
fi
fi
sleep $delay
done
echo "Download failed after $retries attempts."
return 1
}
function zrep_process_updates() {
for package in ${(k)updatesAvailable}; do
local updateDetails=(${(s/|/)updatesAvailable[${package}]})
local author=${updateDetails[1]}
local script=${updateDetails[2]}
local version=${updateDetails[3]}
echo "Updating ${author}/${script} to version ${version}..."
zrep_install_package u "${author}/${script}" "${version}"
done
}
typeset -A updatesAvailable
@ -567,7 +730,9 @@ function zrep_check_for_updates() {
'.authors[] | select(.name==$author) | .scripts[] | select(.name==$script) | .version' <<<"$remotePackages")
if [[ "${remote_version}" > "${installed_version}" ]]; then
updatesAvailable[${author}/${script}]="${remote_version}"
# updatesAvailable[${author}/${script}]="${remote_version}"
# Store author, script, and version in a single string, separated by "|"
updatesAvailable[${author}/${script}]="${author}|${script}|${remote_version}"
zrep_msg info "\n${author}/${script} can be updated from ${installed_version} to ${remote_version}"
updates=true # Mark that updates are available
fi
@ -598,8 +763,8 @@ function zrep_update_package() {
else
if [[ ${updates} == "true" ]]; then
# Prompt the user only if updates are available
echo "New updates are available. Do you want to proceed with updating? (Y/n): "
read -q "response?"
zrep_msg sub "New updates are available. Do you want to proceed with updating? (Y/n): \c"
read "response"
echo # Move to a new line
# Set the default response to 'Y' if no input is entered
@ -607,14 +772,8 @@ function zrep_update_package() {
# Proceed with update if the response is 'Y' or 'y'
if [[ $response =~ ^[Yy]$ ]]; then
# General update mode: update all packages listed in updatesAvailable
for package in ${(k)updatesAvailable}; do
local author=${package%%/*}
local script=${package#*/}
local version=${updatesAvailable[${package}]}
local install_pkg="${author}/${script}"
zrep_install_package u ${install_pkg}
done
# Call zrep_process_updates to handle all updates.
zrep_process_updates
else
zrep_msg info "Update canceled."
fi
@ -622,75 +781,21 @@ function zrep_update_package() {
fi
}
# Enhanced zrep_downloader function with error handling and retry logic.
# It attempts to download a file from a given URL to a specified zip file using curl, wget, or wget2 based on the global configuration.
# This function supports retries and delays between attempts for robust error handling.
#
# Usage: zrep_download_package ZipFile DownloadURL
#
# Parameters:
# DownloadURL: The URL from which to download the file.
# ZipFile: The name of the file to save the downloaded content to.
function zrep_download_package() {
local ZipFile="${1}"
local DownloadURL="${2}"
local retries=5
local delay=5
local attempt=1
local downloader=""
local http_status
local cmd
local exit_status
local ZipFile="${1}"
local DownloadURL="${2}"
case "${config[global_downloader]}" in
curl)
downloader="curl"
cmd="curl -L -A \"zrep ${VERSION} (curl)\" -s -o \"$ZipFile\" \"$DownloadURL\" -w \"%{http_code}\""
;;
wget)
downloader="wget"
cmd="wget -L -U \"zrep ${VERSION} (wget)\" -q -O \"$ZipFile\" \"$DownloadURL\""
;;
wget2)
downloader="wget2"
cmd="wget2 -L -U \"zrep ${VERSION} (wget2)\" -q -O \"$ZipFile\" \"$DownloadURL\""
;;
*)
zrep_msg debug "Unsupported or unspecified downloader: '${config[global_downloader]}'."
return 1
;;
esac
while (( attempt <= retries )); do
# zrep_msg sub "Attempt $attempt of $retries: Downloading using $downloader..."
if [[ $downloader == "curl" ]]; then
http_status=$(eval $cmd)
exit_status=$?
# For curl, check HTTP status is 200 and exit status is 0
if [[ $exit_status -eq 0 && $http_status -eq 200 ]]; then
# zrep_msg sub "a.Download successful."
return 0
fi
else # wget or wget2
eval $cmd
exit_status=$?
# For wget/wget2, just check exit status is 0
if [[ $exit_status -eq 0 ]]; then
# zrep_msg sub "b.Download successful."
return 0
fi
# Now simply call the unified downloader function
if zrep_global_downloader "$DownloadURL" "$ZipFile"; then
zrep_msg std "\nDownload successful."
else
zrep_msg debug "\nDownload failed."
return 1
fi
sleep $delay
((attempt++))
done
zrep_msg debug "Error: The download failed after $retries attempts."
return 1
}
# Function to install a package by unzipping it to ${config[main_zrep_install_dir]}
function zrep_install_package() {
if [[ ${1} == "u" ]]; then
@ -708,25 +813,28 @@ function zrep_install_package() {
# Call zrep_check_if_installed to check if the package is already installed
if zrep_check_if_installed "${package}"; then
zrep_msg debug "\nPackage ${package} is already installed."
zrep_msg info "Use 'zrep list' to see installed packages."
zrep_msg info "Use 'zpi list' to see installed packages."
return 0
fi
zrep_parse_remote "${config[global_repo_url]}/getver.php?p=${package}" ${package}
fi
# If not installed, proceed with fetching the package information
# Using the new zrep API to get the package version
zrep_parse_remote "${config[global_repo_url]}/getver.php\?p\=${package}" ${package}
local tmpDir="${config[main_zrep_install_dir]}/tmp"
mkdir -p "${tmpDir}"
author="${package%/*}"
script="${package#*/}"
local zipFile="${tmpDir}/${author}-${script}-${version}.zip"
dlurl="${config[global_repo_url]}/download/${package}/${version}"
zrep_download_package "${zipFile}" "${dlurl}"
local dlurl="${config[global_repo_url]}/download/${package}/${version}"
echo "Download URL: ${dlurl}" # Print the download URL for debugging
if ! zrep_download_package "${zipFile}" "${dlurl}"; then
zrep_msg debug "\nError: Failed to download the package."
return 1
fi
unzip -q -o "${zipFile}" -d "${config[main_zrep_install_dir]}"
if [[ $? -ne 0 ]]; then
zrep_msg debug "\nError: Failed to unzip the package."
return 1
@ -843,25 +951,25 @@ function zrep_disable() {
echo ")"
} > ${config[main_zrep_install_dir]}/.addons
zrep_msg info "\nPackage '${package_name} (${script})' has been disabled and removed from fpath."
zrep_msg info "\nPackage '${package_name}' has been disabled and removed from fpath."
zrep_msg info "You may have to run 'source ~/.zrep_addons' to remove it from your shell."
}
# Help function to display available options
function zrep_help() {
zrep_msg sub "\nUsage: zrep <command> [arguments]"
zrep_msg sub "\nUsage: ${ZSH_SCRIPT:t} <command> [arguments]"
zrep_msg info "Available commands:"
if [[ ! -f ${ZREP_CONFIG} ]]; then
zrep_msg info " init: Initialize zrep"
fi
if [[ ! -f ${ZREP_CONFIG} ]]; then
zrep_msg info " init: Initialize zpi"
fi
zrep_msg info " install (i) <author/package>:\t\t\tInstall a package"
zrep_msg info " remove (rm, delete, del) <author/package>:\tRemove a package"
zrep_msg info " update (u) <author/package>:\t\t\tUpdate zrep package"
zrep_msg info " enable <author/package>:\t\t\tEnable zrep package"
zrep_msg info " disable <author/package>:\t\t\tDisable zrep package"
zrep_msg info " update (u) <author/package>:\t\t\tUpdate zpi package"
zrep_msg info " enable <author/package>:\t\t\tEnable zpi package"
zrep_msg info " disable <author/package>:\t\t\tDisable zpi package"
zrep_msg info " search 'search term':\t\t\t\tSearch for authors, packages or description"
zrep_msg info " version:\t\t\t\t\tDisplay zrep version"
zrep_msg info " version:\t\t\t\t\tDisplay zpi version"
zrep_msg info " list:\t\t\t\t\t\tList installed packages"
zrep_msg info " <author/package> help:\t\t\tDisplay help for package (if available)"
@ -945,7 +1053,7 @@ function main() {
# Parse the command argument to extract the package name
zrep_remove_package_name="${2:-}"
if [[ -z "${zrep_remove_package_name}" ]]; then
zrep_msg info "\nUsage: zrep ${1} author/package"
zrep_msg info "\nUsage: zpi ${1} author/package"
else
zrep_remove_package "${zrep_remove_package_name}"
fi