From 804a499754f5fec2db465effb174448d924e344e Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 7 May 2026 17:42:30 +0200 Subject: rename mkhintfile.sh to mkhint, add --delete/-d option - Rename script and completion file to mkhint/mkhint.bash-completion - Add --delete/-d flag to remove one or more hint files (and .bak if present) - Fix bash completion: correct hint_dir path, use find for nested .info files, add --delete completion, add flag name completion - Update all references in CLAUDE.md, README.md, and source files Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 20 +-- README.md | 8 +- mkhint | 378 +++++++++++++++++++++++++++++++++++++++++++++ mkhint.bash-completion | 37 +++++ mkhintfile.bash-completion | 33 ---- mkhintfile.sh | 335 --------------------------------------- 6 files changed, 429 insertions(+), 382 deletions(-) create mode 100755 mkhint create mode 100644 mkhint.bash-completion delete mode 100644 mkhintfile.bash-completion delete mode 100755 mkhintfile.sh diff --git a/CLAUDE.md b/CLAUDE.md index 2ee689b..ea3e883 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,11 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## What This Is -`mkhintfile.sh` — bash utility for managing [slackrepo](https://idlemoor.github.io/slackrepo/) hint files. Hint files override build variables (version, download URL, checksum) for SlackBuilds. +`mkhint` — bash utility for managing [slackrepo](https://idlemoor.github.io/slackrepo/) hint files. Hint files override build variables (version, download URL, checksum) for SlackBuilds. ## Configuration -Two paths hardcoded near top of `mkhintfile.sh` (lines 16–17): +Two paths hardcoded near top of `mkhint` (lines 16–17): ```bash REPO_DIR="/var/lib/sbopkg/SBo-danix/" # SBo repository with .info files @@ -22,12 +22,12 @@ Bash completion script has its own hardcoded copies (lines 8–9) — keep in sy No build step. Direct execution: ```bash -bash mkhintfile.sh --help -bash mkhintfile.sh --list -bash mkhintfile.sh --version 2.0.1 --hintfile mypackage -bash mkhintfile.sh --version 1.2.3 --new mypackage -bash mkhintfile.sh --new mypackage # empty hint, no version -bash mkhintfile.sh --clean +bash mkhint --help +bash mkhint --list +bash mkhint --version 2.0.1 --hintfile mypackage +bash mkhint --version 1.2.3 --new mypackage +bash mkhint --new mypackage # empty hint, no version +bash mkhint --clean ``` No test suite exists. Test manually against real `REPO_DIR`/`HINT_DIR` or with mock directories. @@ -52,6 +52,6 @@ No test suite exists. Test manually against real `REPO_DIR`/`HINT_DIR` or with m ## Installation ```bash -sudo cp mkhintfile.sh /usr/local/bin/mkhintfile -sudo cp mkhintfile.bash-completion /etc/bash-completion.d/mkhintfile +sudo cp mkhint /usr/local/bin/mkhint +sudo cp mkhint.bash-completion /etc/bash-completion.d/mkhint ``` diff --git a/README.md b/README.md index 5d04899..ffb5f85 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# mkhintfile.sh +# mkhint Manage hint files for slackrepo scripts. Updates version strings and download checksums, or creates new hint files from repository .info files. @@ -7,18 +7,18 @@ Manage hint files for slackrepo scripts. Updates version strings and download ch ### Script ```bash -sudo cp mkhintfile.sh /usr/local/bin/mkhintfile +sudo cp mkhint /usr/local/bin/mkhint ``` ### Bash Completion ```bash -sudo cp mkhintfile.bash-completion /etc/bash-completion.d/mkhintfile +sudo cp mkhint.bash-completion /etc/bash-completion.d/mkhint ``` ### Configuration -Edit the paths at the top of mkhintfile.sh to match your setup: +Edit the paths at the top of mkhint to match your setup (lines 16–17): ```bash REPO_DIR="/var/lib/sbopkg/SBo-danix" # Repository containing .info files diff --git a/mkhint b/mkhint new file mode 100755 index 0000000..b3ccc75 --- /dev/null +++ b/mkhint @@ -0,0 +1,378 @@ +#!/bin/bash + +# mkhint - Manage hint files for slackrepo scripts +# +# Usage: +# ./mkhint --version VERSION --hintfile FILE Update existing hint file +# ./mkhint --version VERSION --new FILE Create new hint file +# ./mkhint --new FILE Create new hint file (no version) +# ./mkhint --list List hint files +# ./mkhint --clean Remove .bak files from HINT_DIR +# ./mkhint --delete FILE Delete a hint file (and .bak if present) +# ./mkhint --help Show this help + +set -e + +# Default configuration +REPO_DIR="/var/lib/sbopkg/SBo-danix/" +HINT_DIR="/etc/slackrepo/SBo-danix/hintfiles/" +TMP_DIR="/tmp/mkhint" + +# create the temp dir if not existing +if [[ ! -d $TMP_DIR ]]; then + mkdir $TMP_DIR +fi + +# Variables +VERSION="" +HINT_FILE="" +NEW_HINT_FILE="" +DELETE_HINT_FILES=() +COMMAND="" + +# Show help message +show_help() { + cat <&2 + exit 2 + fi + + echo "Hint files in: $HINT_DIR" + echo "=======================================================" + printf "%-40s %10s %10s %-20s %s\n" "File" "HintVer" "SBOVer" "Category" "Created" + echo "-------------------------------------------------------" + + local count=0 + for file in "$HINT_DIR"/*.hint; do + if [[ -f "$file" ]]; then + local VER=$(grep "^VERSION" "$file" |cut -d '"' -f2) + local name=$(basename "$file") + local pkg="${name%.hint}" + local info_file + info_file=$(find "$REPO_DIR" -mindepth 2 -name "${pkg}.info" 2>/dev/null | head -1) + local SBO_VER="" + local category="" + if [[ -f "$info_file" ]]; then + SBO_VER=$(grep "^VERSION" "$info_file" | cut -d '"' -f2) + category=$(basename "$(dirname "$(dirname "$info_file")")") + fi + local date=$(stat -c "%y" "$file" | cut -d'.' -f1) + printf "%-40s %10s %10s %-20s %s\n" "$name" "$VER" "$SBO_VER" "$category" "$date" + count=$((count + 1)) + fi + done + + if [[ $count -eq 0 ]]; then + echo " (no hint files found)" + fi + + echo "=======================================================" + echo "Total: $count file(s)" +} + +# Validate wget availability +check_wget() { + if ! command -v wget &> /dev/null; then + echo "Error: wget is not installed. Please install wget first." >&2 + exit 4 + fi +} + +# download files +download_file() { + local url="$1" + local dlfile="${TMP_DIR}/download" + + if [[ -f $dlfile ]]; then + rm $dlfile + fi + + # Download the file + if [[ ! -z $1 ]]; then + wget -O "$dlfile" "$url" || return 1 + fi + + # calculate md5 + local md5=$(md5sum "$dlfile" | awk '{print $1}') + rm $dlfile + echo $md5 +} + +# Create new hint file +create_new_hint_file() { + cd $HINT_DIR + local file="$1" + local normalized_file="${file}" + + if [[ "$file" != *.hint ]]; then + normalized_file="${file}.hint" + fi + + # search repository for .info file + info=$(find $REPO_DIR -mindepth 2 -name ${normalized_file%.hint}.info) + + # Check if file exists + if [[ ! -f "$normalized_file" ]]; then + # the hint file we want to create doesn't exists, so we can check + # the sbo repository for a .info file and use that as hint + if [[ -n $info ]]; then + cp $info $normalized_file + # remove unwanted lines from hint file + sed -i -e "/^PRGNAM=/d" \ + -e "/^HOMEPAGE=/d" \ + -e "/^MAINTAINER=/d" \ + -e "/^EMAIL=/d" \ + -e "s/^REQUIRES=/#REQUIRES=/" \ + "${normalized_file}" + + if grep -q '^ARCH=' $normalized_file; then + sed -i 's/^ARCH=.*/ARCH="x86_64"/' $normalized_file + else + echo 'ARCH="x86_64"' >> $normalized_file + fi + + echo "generated $normalized_file from $(basename $info)." + echo "Check variables before using." + fi + else + echo "Hint file exists: $normalized_file" >&2 + mv "$normalized_file" "${normalized_file}.bak" + echo "Backed up to: ${normalized_file}.bak" >&2 + # Create new hint file with empty variables + cat > "$normalized_file" <&2 + exit 2 + fi + + # Force backup as precaution before modifying + echo "Hint file exists: $normalized_file" >&2 + cp "$normalized_file" "${normalized_file}.bak" + echo "Backed up to: ${normalized_file}.bak" >&2 + + # Extract current version from hint file + old_version=$(grep '^VERSION=' "$normalized_file" | sed 's/VERSION="//;s/"$//') + + # Use sed for global replacement of OLD_VERSION in all variables + sed -i "s/${old_version}/${new_version}/g" "$normalized_file" + + download=$(grep '^DOWNLOAD=' "$normalized_file" | sed 's/DOWNLOAD="//;s/"$//') + if [[ -n "$download" ]]; then + if [[ $download != "UNSUPPORTED" && $download != "UNTESTED" ]]; then + # we skip for unsupported or untested arch + sum=$(download_file ${download}) + sed -i "/^MD5SUM=/s/MD5SUM=\"[^\"]*\"/MD5SUM=\"$sum\"/" "$normalized_file" + fi + fi + + # we should repeat the check for x86_64 DOWNLOAD + download_x64=$(grep '^DOWNLOAD_x86_64=' "$normalized_file" | sed 's/DOWNLOAD_x86_64="//;s/"$//') + if [[ -n "$download_x64" ]]; then + if [[ $download_x64 != "UNSUPPORTED" && $download_x64 != "UNTESTED" ]]; then + # we skip for unsupported or untested arch + sum64=$(download_file ${download_x64}) + sed -i "/^MD5SUM_x86_64=/s/MD5SUM_x86_64=\"[^\"]*\"/MD5SUM_x86_64=\"$sum64\"/" "$normalized_file" + fi + fi + + hf=$(cat $normalized_file) + echo "Updated hint file: $normalized_file" + echo "==========================================" + echo -n "$hf" + echo; echo "==========================================" +} + +# Delete a hint file (and .bak if present) +delete_hint_file() { + local file="$1" + local normalized_file="${file}" + + if [[ "$file" != *.hint ]]; then + normalized_file="${file}.hint" + fi + + local full_path="${HINT_DIR}/${normalized_file}" + + if [[ ! -f "$full_path" ]]; then + echo "Error: Hint file does not exist: $full_path" >&2 + exit 2 + fi + + rm "$full_path" + echo "Deleted: $full_path" + + local bak_path="${full_path}.bak" + if [[ -f "$bak_path" ]]; then + rm "$bak_path" + echo "Deleted: $bak_path" + fi +} + +# Clean .bak files from HINT_DIR +clean_bak_files() { + if [[ ! -d "$HINT_DIR" ]]; then + echo "Error: Hint directory does not exist: $HINT_DIR" >&2 + exit 2 + fi + + local count=0 + for bakfile in "$HINT_DIR"/*.bak; do + if [[ -f "$bakfile" ]]; then + rm "$bakfile" + count=$((count + 1)) + fi + done + + echo "Removed $count .bak file(s) from $HINT_DIR" +} + +# Main function +main() { + # Parse command line arguments directly + while [[ $# -gt 0 ]]; do + case "$1" in + --version|-v) + VERSION="$2" + shift 2 + ;; + --hintfile|-f) + HINT_FILE="$2" + shift 2 + ;; + --new|-n) + NEW_HINT_FILE="$2" + shift 2 + ;; + --list|-l) + COMMAND="list" + shift + ;; + --clean|-c) + COMMAND="clean" + shift + ;; + --delete|-d) + shift + while [[ $# -gt 0 && "$1" != -* ]]; do + DELETE_HINT_FILES+=("$1") + shift + done + ;; + --help|-h) + COMMAND="help" + shift + ;; + *) + echo "Unknown option: $1" >&2 + show_help + exit 1 + ;; + esac + done + + if [[ -z "$COMMAND" ]]; then + # Default to update hint file if VERSION and HINT_FILE are provided + if [[ -n "$VERSION" && -n "$HINT_FILE" ]]; then + COMMAND="update" + elif [[ -n "$NEW_HINT_FILE" ]]; then + COMMAND="new" + elif [[ ${#DELETE_HINT_FILES[@]} -gt 0 ]]; then + COMMAND="delete" + fi + fi + + case "$COMMAND" in + help) + show_help + ;; + list) + list_hint_files + ;; + clean) + clean_bak_files + ;; + update) + check_wget + update_hint_file "$HINT_FILE" "$VERSION" + ;; + new) + create_new_hint_file "$NEW_HINT_FILE" + ;; + delete) + for f in "${DELETE_HINT_FILES[@]}"; do + delete_hint_file "$f" + done + ;; + *) + echo "Error: Unknown command: $COMMAND" >&2 + show_help + exit 1 + ;; + esac +} + +main "$@" diff --git a/mkhint.bash-completion b/mkhint.bash-completion new file mode 100644 index 0000000..43a64ae --- /dev/null +++ b/mkhint.bash-completion @@ -0,0 +1,37 @@ +# bash completion for mkhint +# Install: sudo cp mkhint.bash-completion /etc/bash-completion.d/mkhint + +_mkhintfile_completions() { + local cur prev repo_dir hint_dir + _init_completion || return + + repo_dir="/var/lib/sbopkg/SBo-danix" + hint_dir="/etc/slackrepo/SBo-danix/hintfiles" + + local all_flags="--version --hintfile --new --list --clean --delete --help" + + case "$prev" in + --new|-n) + local -a words=() + while IFS= read -r f; do + words+=("$(basename "${f%.info}")") + done < <(find "$repo_dir" -mindepth 2 -maxdepth 2 -name "*.info" 2>/dev/null) + COMPREPLY=($(compgen -W "${words[*]}" -- "$cur")) + ;; + --hintfile|-f|--delete|-d) + local -a words=() + for f in "$hint_dir"/*.hint; do + [[ -f "$f" ]] && words+=("$(basename "${f%.hint}")") + done + COMPREPLY=($(compgen -W "${words[*]}" -- "$cur")) + ;; + --version|-v) + # no completion, raw text + ;; + *) + COMPREPLY=($(compgen -W "$all_flags" -- "$cur")) + ;; + esac +} + +complete -F _mkhintfile_completions mkhintfile.sh mkhintfile diff --git a/mkhintfile.bash-completion b/mkhintfile.bash-completion deleted file mode 100644 index e217edf..0000000 --- a/mkhintfile.bash-completion +++ /dev/null @@ -1,33 +0,0 @@ -# bash completion for mkhintfile.sh -# Install: sudo cp mkhintfile.bash-completion /etc/bash-completion.d/mkhintfile - -_mkhintfile_completions() { - local cur prev repo_dir hint_dir - _init_completion || return - - repo_dir="/var/lib/sbopkg/SBo-danix" - hint_dir="/tmp/hintdir" - - case "$prev" in - --new|-n) - local -a words=() - for f in "$repo_dir"/*.info; do - [[ -f "$f" ]] && words+=("$(basename "${f%.info}")") - done - COMPREPLY=($(compgen -W "${words[*]}" -- "$cur")) - ;; - --hintfile|-f) - local -a words=() - for f in "$hint_dir"/*.hint; do - [[ -f "$f" ]] && words+=("$(basename "${f%.hint}")") - done - COMPREPLY=($(compgen -W "${words[*]}" -- "$cur")) - ;; - # --version (no completion, raw text) - # --list, --help (no value completion, flags only) - *) - ;; - esac -} - -complete -F _mkhintfile_completions mkhintfile.sh diff --git a/mkhintfile.sh b/mkhintfile.sh deleted file mode 100755 index 3b433b3..0000000 --- a/mkhintfile.sh +++ /dev/null @@ -1,335 +0,0 @@ -#!/bin/bash - -# mkhintfile.sh - Manage hint files for slackrepo scripts -# -# Usage: -# ./mkhintfile.sh --version VERSION --hintfile FILE Update existing hint file -# ./mkhintfile.sh --version VERSION --new FILE Create new hint file -# ./mkhintfile.sh --new FILE Create new hint file (no version) -# ./mkhintfile.sh --list List hint files -# ./mkhintfile.sh --clean Remove .bak files from HINT_DIR -# ./mkhintfile.sh --help Show this help - -set -e - -# Default configuration -REPO_DIR="/var/lib/sbopkg/SBo-danix/" -HINT_DIR="/etc/slackrepo/SBo-danix/hintfiles/" -TMP_DIR="/tmp/mkhint" - -# create the temp dir if not existing -if [[ ! -d $TMP_DIR ]]; then - mkdir $TMP_DIR -fi - -# Variables -VERSION="" -HINT_FILE="" -NEW_HINT_FILE="" -COMMAND="" - -# Show help message -show_help() { - cat <&2 - exit 2 - fi - - echo "Hint files in: $HINT_DIR" - echo "=======================================================" - printf "%-40s %10s %10s %-20s %s\n" "File" "HintVer" "SBOVer" "Category" "Created" - echo "-------------------------------------------------------" - - local count=0 - for file in "$HINT_DIR"/*.hint; do - if [[ -f "$file" ]]; then - local VER=$(grep "^VERSION" "$file" |cut -d '"' -f2) - local name=$(basename "$file") - local pkg="${name%.hint}" - local info_file - info_file=$(find "$REPO_DIR" -mindepth 2 -name "${pkg}.info" 2>/dev/null | head -1) - local SBO_VER="" - local category="" - if [[ -f "$info_file" ]]; then - SBO_VER=$(grep "^VERSION" "$info_file" | cut -d '"' -f2) - category=$(basename "$(dirname "$(dirname "$info_file")")") - fi - local date=$(stat -c "%y" "$file" | cut -d'.' -f1) - printf "%-40s %10s %10s %-20s %s\n" "$name" "$VER" "$SBO_VER" "$category" "$date" - count=$((count + 1)) - fi - done - - if [[ $count -eq 0 ]]; then - echo " (no hint files found)" - fi - - echo "=======================================================" - echo "Total: $count file(s)" -} - -# Validate wget availability -check_wget() { - if ! command -v wget &> /dev/null; then - echo "Error: wget is not installed. Please install wget first." >&2 - exit 4 - fi -} - -# download files -download_file() { - local url="$1" - local dlfile="${TMP_DIR}/download" - - if [[ -f $dlfile ]]; then - rm $dlfile - fi - - # Download the file - if [[ ! -z $1 ]]; then - wget -O "$dlfile" "$url" || return 1 - fi - - # calculate md5 - local md5=$(md5sum "$dlfile" | awk '{print $1}') - rm $dlfile - echo $md5 -} - -# Create new hint file -create_new_hint_file() { - cd $HINT_DIR - local file="$1" - local normalized_file="${file}" - - if [[ "$file" != *.hint ]]; then - normalized_file="${file}.hint" - fi - - # search repository for .info file - info=$(find $REPO_DIR -mindepth 2 -name ${normalized_file%.hint}.info) - - # Check if file exists - if [[ ! -f "$normalized_file" ]]; then - # the hint file we want to create doesn't exists, so we can check - # the sbo repository for a .info file and use that as hint - if [[ -n $info ]]; then - cp $info $normalized_file - # remove unwanted lines from hint file - sed -i -e "/^PRGNAM=/d" \ - -e "/^HOMEPAGE=/d" \ - -e "/^MAINTAINER=/d" \ - -e "/^EMAIL=/d" \ - -e "s/^REQUIRES=/#REQUIRES=/" \ - "${normalized_file}" - - if grep -q '^ARCH=' $normalized_file; then - sed -i 's/^ARCH=.*/ARCH="x86_64"/' $normalized_file - else - echo 'ARCH="x86_64"' >> $normalized_file - fi - - echo "generated $normalized_file from $(basename $info)." - echo "Check variables before using." - fi - else - echo "Hint file exists: $normalized_file" >&2 - mv "$normalized_file" "${normalized_file}.bak" - echo "Backed up to: ${normalized_file}.bak" >&2 - # Create new hint file with empty variables - cat > "$normalized_file" <&2 - exit 2 - fi - - # Force backup as precaution before modifying - echo "Hint file exists: $normalized_file" >&2 - cp "$normalized_file" "${normalized_file}.bak" - echo "Backed up to: ${normalized_file}.bak" >&2 - - # Extract current version from hint file - old_version=$(grep '^VERSION=' "$normalized_file" | sed 's/VERSION="//;s/"$//') - - # Use sed for global replacement of OLD_VERSION in all variables - sed -i "s/${old_version}/${new_version}/g" "$normalized_file" - - download=$(grep '^DOWNLOAD=' "$normalized_file" | sed 's/DOWNLOAD="//;s/"$//') - if [[ -n "$download" ]]; then - if [[ $download != "UNSUPPORTED" && $download != "UNTESTED" ]]; then - # we skip for unsupported or untested arch - sum=$(download_file ${download}) - sed -i "/^MD5SUM=/s/MD5SUM=\"[^\"]*\"/MD5SUM=\"$sum\"/" "$normalized_file" - fi - fi - - # we should repeat the check for x86_64 DOWNLOAD - download_x64=$(grep '^DOWNLOAD_x86_64=' "$normalized_file" | sed 's/DOWNLOAD_x86_64="//;s/"$//') - if [[ -n "$download_x64" ]]; then - if [[ $download_x64 != "UNSUPPORTED" && $download_x64 != "UNTESTED" ]]; then - # we skip for unsupported or untested arch - sum64=$(download_file ${download_x64}) - sed -i "/^MD5SUM_x86_64=/s/MD5SUM_x86_64=\"[^\"]*\"/MD5SUM_x86_64=\"$sum64\"/" "$normalized_file" - fi - fi - - hf=$(cat $normalized_file) - echo "Updated hint file: $normalized_file" - echo "==========================================" - echo -n "$hf" - echo; echo "==========================================" -} - -# Clean .bak files from HINT_DIR -clean_bak_files() { - if [[ ! -d "$HINT_DIR" ]]; then - echo "Error: Hint directory does not exist: $HINT_DIR" >&2 - exit 2 - fi - - local count=0 - for bakfile in "$HINT_DIR"/*.bak; do - if [[ -f "$bakfile" ]]; then - rm "$bakfile" - count=$((count + 1)) - fi - done - - echo "Removed $count .bak file(s) from $HINT_DIR" -} - -# Main function -main() { - # Parse command line arguments directly - while [[ $# -gt 0 ]]; do - case "$1" in - --version|-v) - VERSION="$2" - shift 2 - ;; - --hintfile|-f) - HINT_FILE="$2" - shift 2 - ;; - --new|-n) - NEW_HINT_FILE="$2" - shift 2 - ;; - --list|-l) - COMMAND="list" - shift - ;; - --clean|-c) - COMMAND="clean" - shift - ;; - --help|-h) - COMMAND="help" - shift - ;; - *) - echo "Unknown option: $1" >&2 - show_help - exit 1 - ;; - esac - done - - if [[ -z "$COMMAND" ]]; then - # Default to update hint file if VERSION and HINT_FILE are provided - if [[ -n "$VERSION" && -n "$HINT_FILE" ]]; then - COMMAND="update" - elif [[ -n "$NEW_HINT_FILE" ]]; then - COMMAND="new" - fi - fi - - case "$COMMAND" in - help) - show_help - ;; - list) - list_hint_files - ;; - clean) - clean_bak_files - ;; - update) - check_wget - update_hint_file "$HINT_FILE" "$VERSION" - ;; - new) - create_new_hint_file "$NEW_HINT_FILE" - ;; - *) - echo "Error: Unknown command: $COMMAND" >&2 - show_help - exit 1 - ;; - esac -} - -main "$@" -- cgit v1.2.3