From 849d4e46a467a5e81e747d29b43fc0fdc6adad92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig-=C3=98rjan=20Smelror?= Date: Mon, 11 Mar 2024 22:15:43 +0100 Subject: [PATCH] Updated zrep script to include functions for checking updates, updating specific packages, and installing packages. Added logic to handle package installation, removal, and updating. Improved error handling and messaging for better user experience. Enhanced functionality for managing zrep packages efficiently. --- zrep | 247 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 175 insertions(+), 72 deletions(-) diff --git a/zrep b/zrep index 7400b78..4545437 100755 --- a/zrep +++ b/zrep @@ -65,7 +65,7 @@ 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 "Please see '${colors[green]}${ZSH_SCRIPT:t} help${colors[end]}'${colors[yellow]} for more info" + zrep_msg info "Please see '${colors[bold_green]}${ZSH_SCRIPT:t} help${colors[end]}'${colors[yellow]} for more info" exit } @@ -142,24 +142,34 @@ EOF } # 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}" + local author_name="${package%%/*}" + local script_name="${package#*/}" local json_data - + # Fetch JSON data from the URL json_data=$(curl -s "${url}") - # Extract author, script, and version using jq - author=$(echo "${json_data}" | jq -r '.authors[0].name') - script=$(echo "${json_data}" | jq -r '.authors[0].scripts[0].name') - version=$(echo "${json_data}" | jq -r '.authors[0].scripts[0].version') - - # Set the variables as global - export author - export script - export version + # Directly extract the details based on author_name and script_name + dlurl=$(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) | .dlurl') + 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 "$dlurl" && -n "$version" ]]; then + # Set the details as global + export author="$author_name" + export script="$script_name" + export version + export dlurl + + #echo "Download URL: ${dlurl}" + #echo "Author: ${author}, Script: ${script}, Version: ${version}" + else + echo "Package ${package} not found." + fi } # Function to write to installed.json after successful install @@ -169,20 +179,22 @@ function zrep_update_installed_json() { local version="${3}" local json_file="${config[main_zrep_install_dir]}/installed.json" - # Check if the JSON file exists and create it if not + # Ensure the JSON file exists, creating an empty object if not if [[ ! -f "${json_file}" ]]; then - echo "{}" > "${json_file}" # Initialize with an empty object + echo "{}" > "${json_file}" fi - # Proper jq command to update the JSON - jq --arg author "${author}" --arg script "${script}" --arg version "${version}" \ - 'if .[${author}] then - .[${author}] += [{"script": ${script}, "version": ${version}}] - else - .[${author}] = [{"script": ${script}, "version": ${version}}] - end' "${json_file}" > "${json_file}.tmp" && mv "${json_file}.tmp" "${json_file}" + # Correctly handle updating or adding script entries within the nested array + jq --arg author "$author" --arg script "$script" --arg version "$version" \ +'if has($author) then + .[$author] |= map(if .script == $script then .version = $version else . end) | + if .[$author] | all(.script != $script) then .[$author] += [{"script": $script, "version": $version}] else . end +else + .[$author] = [{"script": $script, "version": $version}] +end' "$json_file" > "$json_file.tmp" && mv "$json_file.tmp" "$json_file" - zrep_msg info "Package '${script}' by '${author}' version ${version} installed successfully." + + zrep_msg info " - Package '$script' by '$author' version $version installed/updated successfully." } # Function to list installed packages from installed.json @@ -199,7 +211,7 @@ function zrep_list_installed_packages() { zrep_msg sub "\nInstalled packages:" # Iterate through each author and their packages - jq -r 'to_entries | .[] | .key as ${author} | .value[] | "\(${author})/\(.script) (\(.version))"' "${installed_json}" | while IFS= read -r package_info; do + jq -r 'to_entries | .[] | .key as $author | .value[] | "\($author)/\(.script) (\(.version))"' "${installed_json}" | while IFS= read -r package_info; do local package_name=$(echo "${package_info}" | cut -d ' ' -f1) # Extract package name before the version local is_active="${colors[white]}(${colors[end]}${colors[bold_red]}Inactive${colors[end]}${colors[white]})${colors[end]}" # Set default to Inactive @@ -223,7 +235,7 @@ function zrep_list_package() { fi # Parse installed.json and concatenate package names - jq -r 'to_entries[] | .key as ${author} | .value[] | "\(${author})/\(.script) (\(.version))"' "${installed_json}" | while IFS= read -r package_info; do + jq -r 'to_entries[] | .key as $author | .value[] | "\($author)/\(.script) (\(.version))"' "${installed_json}" | while IFS= read -r package_info; do package_names+="${package_info} " done @@ -272,27 +284,27 @@ function zrep_remove_package() { # Check if installed.json exists if [[ ! -f "${installed_json}" ]]; then - echo "Error: installed.json not found." + zrep_msg debug "\nError: installed.json not found." return 1 fi - # Get package information from installed.json - local package_info - package_info=$(zrep_parse_installed_json | jq ".[] | select(.author + \"/\" + .script == \"${package_name}\")") + local author="${package_name%%/*}" + local script="${package_name#*/}" - # Check if the package is installed - if [[ -z "${package_info}" ]]; then - echo "Error: Package '${package_name}' is not installed." + # Verify if the package is installed and get its version (if any) + local installed_version=$(jq -r --arg author "$author" --arg script "$script" \ + '.[$author][] | select(.script == $script) | .version' "$installed_json") + + 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." return 1 fi - local author=$(echo "${package_info}" | jq -r '.author') - local script=$(echo "${package_info}" | jq -r '.script') - local first_letter=$(echo "${author}" | cut -c 1 | tr '[:upper:]' '[:lower:]') + local first_letter=$(echo "${author:0:1}" | tr '[:upper:]' '[:lower:]') local package_dir="${config[main_zrep_install_dir]}/${first_letter}/${author}/${script}" - echo "Package information:" - echo "${package_info}" | jq . + zrep_msg info "\nFound installed package: $package_name, version: $installed_version" # Ask user for confirmation with default response "Y" read "REPLY?Are you sure you want to remove this package? (y/n) [Y]: " @@ -303,60 +315,149 @@ function zrep_remove_package() { # Remove the package directory from disk if [[ -d "${package_dir}" ]]; then rm -rf "${package_dir}" - echo "Package directory '${package_dir}' removed successfully." + zrep_msg sub "Package directory '${package_dir}' removed successfully." else - echo "Warning: Package directory '${package_dir}' not found." - fi - - # Safely check and remove author and first letter directories if empty - local author_dir="${config[main_zrep_install_dir]}/${first_letter}/${author}" - if [[ -d "${author_dir}" && ! "$(ls -A "${author_dir}")" ]]; then - rmdir "${author_dir}" - echo "Author directory '${author_dir}' removed successfully." - fi - - if [[ -d "${config[main_zrep_install_dir]}/${first_letter}" && ! "$(ls -A "${config[main_zrep_install_dir]}/${first_letter}")" ]]; then - rmdir "${config[main_zrep_install_dir]}/${first_letter}" - echo "First letter directory '${config[main_zrep_install_dir]}/${first_letter}' removed successfully." + zrep_msg debug "Warning: Package directory '${package_dir}' not found." fi # Remove the package from installed.json - jq "del(.[] | select(.author == \"${author}\" and .script == \"${script}\"))" "${installed_json}" > "${installed_json}.tmp" && mv "${installed_json}.tmp" "${installed_json}" - echo "Package '${package_name}' removed successfully from installed.json." + jq --arg author "$author" --arg script "$script" \ + '(.[$author] |= map(select(.script != $script))) | + if .[$author] == [] then del(.[$author]) else . end' \ + "$installed_json" > "$installed_json.tmp" && mv "$installed_json.tmp" "$installed_json" + + zrep_msg sub "Package '${package_name}' removed successfully from installed.json." else - echo "Removal canceled." + zrep_msg info "Removal canceled." + fi +} + +function zrep_check_if_installed() { + local package="${1}" + local installedJson="${config[main_zrep_install_dir]}/installed.json" + + local author_name="${package%%/*}" + local script_name="${package#*/}" + + # Initialize version to an empty string + typeset -g installed_version="" + + # Check if the package is already installed and retrieve its version + installed_version=$(jq -r --arg author "$author_name" --arg script "$script_name" \ + '.[$author][] | select(.script == $script) | .version' "$installedJson") + + if [[ -n "$installed_version" && "$installed_version" != "null" ]]; then + # Package is installed, and version is stored in installed_version + # echo "Package $package is installed with version $installed_version." + return 0 # Package is installed + else + # echo "Package $package is not installed." + return 1 # Package is not installed + fi +} + +typeset -A updatesAvailable +function zrep_check_for_updates() { + local remoteFile="${config[global_repo_url]}/packages.json" + local localFile="${config[main_zrep_install_dir]}/installed.json" + local remotePackages=$(curl -s "$remoteFile") + + # Reset global variables + updatesAvailable=() + typeset -g updates=false # Global declaration, initializes to false + + # Process updates + local authorsScripts=$(jq -r '. | to_entries[] | .key as $author | .value[] | "\($author)/\(.script):\(.version)"' "$localFile") + + for entry in ${(f)authorsScripts}; do + local author="${entry%%/*}" + local rest="${entry#*/}" + local script_name="${rest%%:*}" + local installed_version="${rest##*:}" + + local remote_version=$(jq -r --arg author "$author" --arg script "$script_name" \ + '.authors[] | select(.name==$author) | .scripts[] | select(.name==$script) | .version' <<<"$remotePackages") + + if [[ "$remote_version" > "$installed_version" ]]; then + updatesAvailable[$author/$script_name]="$remote_version" + zrep_msg info "\n$author/$script_name can be updated from $installed_version to $remote_version" + updates=true # Mark that updates are available + fi + done + +} + + +function zrep_update_package() { + local specificPackage=${1} + zrep_check_for_updates + + # Check if in update mode or specific package update + if [[ -n "$specificPackage" ]]; then + # Logic for updating a specific package + # Assuming specificPackage format is "author/script" + local version=${updatesAvailable[$specificPackage]} + if [[ -n "$version" ]]; then + local author="${specificPackage%%/*}" + local script="${specificPackage#*/}" + local dlurl="${config[global_repo_url]}/download.php?a=${author}&s=${script}&v=${version}" + # echo "Updating $specificPackage to version $version..." + zrep_install_package u $author/$script + else + echo "No update available for $specificPackage." + fi + else + # 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 dlurl="${config[global_repo_url]}/download.php?a=${author}&s=${script}&v=${version}" + + # echo "Preparing to update $package to version $version..." + local install_pkg="$author/$script" + zrep_install_package u $install_pkg + done fi } # Function to install a package by unzipping it to ${config[main_zrep_install_dir]} function zrep_install_package() { - zrep_parse_remote "https://kekepower.com/zrep/packages.json" + if [[ ${1} == "u" ]]; then + updates=true + local package=${2} + # echo "zrep_install_package: package=$package" + else + updates=false + local package="${1}" + # Call zrep_check_if_installed to check if the package is already installed + if zrep_check_if_installed "$package"; then + zrep_msg info "Package ${package} is already installed." + zrep_msg info "Use 'zrep list' to see installed packages." + return 0 + fi + fi - # Construct the download URL - local dlurl="https://kekepower.com/zrep/download.php?a=${author}&s=${script}&v=${version}" + # If not installed, proceed with fetching the package information + zrep_parse_remote "${config[global_repo_url]}/packages.json" "${package}" + # echo "zrep_install_package: $dlurl" - # Get the base directory where the package will be installed - local baseDir="${config[main_zrep_install_dir]}/" - local tmpDir="${baseDir}/tmp" + #local baseDir="${config[main_zrep_install_dir]}" + local tmpDir="${config[main_zrep_install_dir]}/tmp" - # Create the directory if it doesn't exist mkdir -p "${tmpDir}" - # Download the package zip file - local zipFile="${tmpDir}/${author}_${package}_${version}.zip" + local zipFile="${tmpDir}/${author}-${script_name}-${version}.zip" curl -s -o "${zipFile}" "${dlurl}" - # Check if the download was successful if [[ $? -ne 0 ]]; then echo "Error: Failed to download the package." return 1 fi - # Unzip the package to the installation directory - unzip -q "${zipFile}" -d "${baseDir}" + unzip -q -o "${zipFile}" -d "${config[main_zrep_install_dir]}" - # Check if the unzip operation was successful if [[ $? -ne 0 ]]; then echo "Error: Failed to unzip the package." return 1 @@ -364,9 +465,7 @@ function zrep_install_package() { zrep_update_installed_json "${author}" "${script}" "${version}" fi - # Clean up: Remove the downloaded zip file - rm "${zipFile}" - + #rm "${zipFile}" } # Function to parse installed.json @@ -387,7 +486,7 @@ function zrep_parse_package_name() { addon_path="${config[main_zrep_install_dir]}/${first_letter}/${author}/${script}" # Check if the package is installed - if [[ ! -f "${installed_json}" ]] || ! jq -e --arg author "${author}" --arg script "${script}" '.[${author}] | any(.script == ${script})' "${installed_json}" &>/dev/null; then + if [[ ! -f "${installed_json}" ]] || ! jq -e --arg author "$author" --arg script "$script" '.[$author] | any(.script == $script)' "${installed_json}" &>/dev/null; then echo "Error: Package '${package_name}' is not installed." return 1 fi @@ -500,6 +599,7 @@ function zrep_help() { zrep_msg sub "\nUsage: zrep [arguments]" zrep_msg info "Available commands:" zrep_msg info " init: Initialize zrep" + zrep_msg info " check: Check for updates" zrep_msg info " install (i) : Install a package" zrep_msg info " remove (rm, delete) : Remove a package" zrep_msg info " update (u) : Update zrep package" @@ -551,8 +651,11 @@ function main() { # zrep_fpath ${config[main_zrep_install_dir]} exit ;; + check) + zrep_check_for_updates + ;; install | i) - zrep_install_package ${1} + zrep_install_package ${2} ;; remove | delete | rm) # Parse the command argument to extract the package name @@ -564,7 +667,7 @@ function main() { fi ;; update | u) - zrep_msg info "Update function here" + zrep_update_package ${2} ;; version | -v | --version) zrep_version