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