Skip to content

Instantly share code, notes, and snippets.

@EvilSupahFly
Created March 26, 2025 05:18
Show Gist options
  • Save EvilSupahFly/d678316364c5716c7fe0b1026e5a9c40 to your computer and use it in GitHub Desktop.
Save EvilSupahFly/d678316364c5716c7fe0b1026e5a9c40 to your computer and use it in GitHub Desktop.
rebuild.sh
#!/usr/bin/env bash
# Check if terminal supports colour output
supports_colour() {
if [ -t 1 ] && command -v tput &> /dev/null; then
local colours
colours=$(tput colors 2>/dev/null)
if [[ -n "$colours" && "$colours" -ge 8 ]]; then
return 0 # Colour support detected
fi
fi
return 1 # Colour not supported
}
# Display status messages with colours
report() {
local status
local message
local timestamp
local ERR_MSG
local PASSMSG
local NOTEMSG
local output_message
local log_message
status=$1 # F = failure, P = pass, N = notice (neutral), B = Blank
message="$2"
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
ERR_MSG="[$timestamp] ERROR: "
PASSMSG="[$timestamp] SUCCESS: "
NOTEMSG="[$timestamp] NOTICE: "
# Ensure color variables are defined
if [[ -z "$RED" ]]; then
output_message="[$timestamp] $message"
log_message="[$timestamp] $message" # Plain message for log
else
case "$status" in
F) output_message="${RED}$ERR_MSG ${WHITE}$message${RESET}"
log_message="$ERR_MSG $message" ;; # Plain message for log
P) output_message="${GREEN}$PASSMSG ${WHITE}$message${RESET}"
log_message="$PASSMSG $message" ;; # Plain message for log
N) output_message="${YELLOW}$NOTEMSG ${WHITE}$message${RESET}"
log_message="$NOTEMSG $message" ;; # Plain message for log
B) output_message="${WHITE}$message${RESET}"
log_message="$message" ;; # Plain message for log
*) output_message="${RED}$ERR_MSG ${WHITE}$status is an unsupported status flag.${RESET}"
log_message="$ERR_MSG $status is an unsupported status flag." ;; # Plain message for log
esac
fi
# Output to terminal
echo -e "$output_message"
# Log to run.log
#doLog "rebuild" "$log_message" # Log the plain message
}
#doLog() {
# # Handle renaming of log files
# local base_name
# local log_message
# local log_file
# local backup_file
# local LOGCHECK
#
# local base_name="$1"
# local log_message="$2"
# local log_file="${base_name}.log"
# local backup_file="${base_name}.bak"
# local LOGCHECK=false
#
# if [ "$3" == "--check" ]; then
# AUTO=true
# LOGCHECK=true
# echo -e "Checking log file status...\n"; sleep 2
# fi
# if [ "$WRITING_LOG" == "false" ]; then
# # Check if the log file already exists
# if [ -e "$log_file" ]; then
# # Check if the backup file already exists
# if [ -e "$backup_file" ]; then
# if [ "$AUTO" = "false" ]; then
# echo "${backup_file} already exists. Do you want to rename it? (y/n) "; read -r response
# else
# response="n"
# fi
# if [[ "$response" == "y" ]]; then
# echo "Please enter a new name for the backup file: "; read -r new_name
# mv -v "$backup_file" "$new_name"
# echo -e "Renamed existing backup file to $new_name\n"
# else
# rm "$backup_file"
# echo -e "Deleted existing backup file ${backup_file}\n"
# fi
# fi
# # Rename existing log file to .bak
# mv -v "$log_file" "$backup_file"
# echo -e "Renamed existing log file to ${backup_file}\n"
# fi
# if [ "$LOGCHECK" == "false" ]; then
# # Write the log message to the new log file
# echo "$log_message" > "$log_file" || echo "Failed to write to ${log_file}."
# fi
# WRITING_LOG=true # Set to true after the first write
# else
# if [ "$LOGCHECK" == "false" ]; then
# # Write the log message to the existing log file
# echo "$log_message" >> "$log_file" || echo "Failed to write to ${log_file}."
# fi
# fi
# if [ "$LOGCHECK" == "true" ]; then
# AUTO=false
# LOGCHECK=false
# fi
#}
#doLog "rebuild" "Clean-up log." "--check"
# Verify checksum of copied file
verify_checksum() {
local file
local expected_checksum
file="$1"
expected_checksum="$2"
# Calculate checksum of the file
actual_checksum=$(sha256sum "$file" | awk '{print $1}')
if [[ "$actual_checksum" == "$expected_checksum" ]]; then
report P "Checksum verification passed for '$file'."
else
report F "Checksum mismatch for '$file'. Expected: $expected_checksum, Found: $actual_checksum"
fi
}
# Update SHA256 checksum in YAML file
#update_yaml_sha256() {
# local yaml_file="$1"
# local file_name="$2"
# local new_sha256="$3"
#
# # Check if the YAML file exists
# if [[ ! -f "$yaml_file" ]]; then
# report F "YAML file '$yaml_file' does not exist."
# exit 1
# fi
#
# echo "Checking for '$file_name' in '$yaml_file'"
#
# # Look for references to the file with 'url:' or 'path:'
# file_reference=$(grep -E "url:|path:" "$yaml_file" | grep "$file_name")
#
# if [[ -n "$file_reference" ]]; then
# echo "Found reference to '$file_name' in YAML file."
#
# # Show the original line (before 'url:' change)
# echo "Original line: '$file_reference'"
#
# # Replace 'url:' with 'path:' if found
# if [[ "$file_reference" =~ ^[[:space:]]*url: ]]; then
# indent=$(echo "$file_reference" | sed 's/\S.*//') # Extract leading spaces
# indent="${indent% }" # Remove trailing spaces from the indent
# new_line="$indent path: $file_name" # Ensure no extra space is added
#
# # Show the proposed new line
# echo "Proposed change: '$new_line'"
#
# # Confirm change before applying
# if [ "$AUTO" = false ]; then
# read -p "Do you want to apply this change to 'url:' -> 'path:'? (y/n): " confirm
# else
# confirm="y"
# fi
#
# if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
# sed -i "s|$file_reference|$new_line|" "$yaml_file"
# report N "Replaced 'url:' with 'path:' for $file_name."
# else
# report N "Skipped modifying the line for '$file_name'."
# fi
# fi
#
# # Find the old checksum if it exists
# old_sha256=$(grep -A 1 "$file_name" "$yaml_file" | grep "sha256:" | awk '{print $2}')
#
# if [[ -n "$old_sha256" ]]; then
# # Show the old checksum
# echo "Old SHA256: $old_sha256"
#
# # Show the proposed new checksum
# echo "Proposed SHA256 change: $new_sha256"
#
# # Confirm checksum change before applying
# if [ "$AUTO" = false ]; then
# read -p "Do you want to update the SHA256 for '$file_name'? (y/n): " confirm_checksum
# else
# confirm_checksum="y"
# fi
#
# if [[ "$confirm_checksum" == "y" || "$confirm_checksum" == "Y" ]]; then
# sed -i "s|sha256: $old_sha256|sha256: $new_sha256|" "$yaml_file"
# report N "SHA256 for '$file_name' updated to $new_sha256."
# else
# report N "Skipped updating the SHA256 for '$file_name'."
# fi
# else
# # If no checksum exists, show the proposed new checksum
# echo "No existing SHA256 found for '$file_name'. Proposed SHA256: $new_sha256"
# read -p "Do you want to add the SHA256 for '$file_name'? (y/n): " confirm_add_sha256
# if [[ "$confirm_add_sha256" == "y" || "$confirm_add_sha256" == "Y" ]]; then
# # Add the new SHA256 if not found
# sed -i "/$file_name/a\ \ sha256: $new_sha256" "$yaml_file"
# report N "SHA256 added for '$file_name': $new_sha256."
# else
# report N "Skipped adding the SHA256 for '$file_name'."
# fi
# fi
#
# # Verify checksum
# verify_checksum "$DEST/$(basename "$file_name")" "$new_sha256"
#
# else
# echo "No reference found for '$file_name' in YAML file."
# fi
#}
# Update SHA256 checksum in YAML file
#update_yaml_sha256() {
# local yaml_file="$1"
# local new_file_name="$2"
# local new_sha256="$3"
#
# # Extract base name (without version) from the new file name
# local base_name=$(echo "$new_file_name" | sed -E 's/-[0-9]+\.[0-9]+\.[0-9]+.*//')
#
# # Check if the YAML file exists
# if [[ ! -f "$yaml_file" ]]; then
# report F "YAML file '$yaml_file' does not exist."
# exit 1
# fi
#
# echo "Checking for entries matching '$base_name' in '$yaml_file'"
#
# # Find the existing file entry ignoring version numbers
# old_file_entry=$(grep -E "url:|path:" "$yaml_file" | grep "$base_name")
#
# if [[ -n "$old_file_entry" ]]; then
# echo "Found reference to '$base_name' in YAML file."
#
# # Extract the full old file name (including version and extension)
# old_file_name=$(echo "$old_file_entry" | awk '{print $2}')
#
# echo "Old file reference: '$old_file_name'"
# echo "New file reference: '$new_file_name'"
#
# # Replace 'url:' with 'path:' if found
# if [[ "$old_file_entry" =~ ^[[:space:]]*url: ]]; then
# # Extract leading spaces (indentation)
# indent="${old_file_entry%%[^[:space:]]*}"
#
# # Construct the new line correctly
# if [[ "$old_file_entry" =~ ^[[:space:]]*url: ]]; then
# new_line="${indent}path: $file_name" # Replace 'url:' with 'path:'
# else
# new_line="${indent}${old_file_entry#* } $file_name" # Preserve original key (path:)
# fi
#
# # Use an exact match replacement
# sed -i "s|^$old_file_entry\$|$new_line|" "$yaml_file"
#
# report N "Proposed change: '$new_line'"
#
# if [ "$AUTO" = false ]; then
# read -p "Apply change to 'url:' -> 'path:'? (y/n): " confirm
# else
# confirm="y"
# fi
#
# if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
# sed -i "s|$old_file_name|$new_file_name|" "$yaml_file"
# report N "Replaced '$old_file_name' with '$new_file_name'."
# else
# report N "Skipped modifying the line for '$base_name'."
# fi
# fi
#
# # Find and update the old checksum
# old_sha256=$(grep -A 1 "$old_file_name" "$yaml_file" | grep "sha256:" | awk '{print $2}')
#
# if [[ -n "$old_sha256" ]]; then
# echo "Old SHA256: $old_sha256"
# echo "New SHA256: $new_sha256"
#
# if [ "$AUTO" = false ]; then
# read -p "Update SHA256 for '$new_file_name'? (y/n): " confirm_checksum
# else
# confirm_checksum="y"
# fi
#
# if [[ "$confirm_checksum" == "y" || "$confirm_checksum" == "Y" ]]; then
# sed -i "s|sha256: $old_sha256|sha256: $new_sha256|" "$yaml_file"
# report N "SHA256 for '$new_file_name' updated to $new_sha256."
# else
# report N "Skipped updating the SHA256 for '$new_file_name'."
# fi
# else
# echo "No existing SHA256 found for '$old_file_name'. Proposed SHA256: $new_sha256"
# read -p "Add SHA256 for '$new_file_name'? (y/n): " confirm_add_sha256
# if [[ "$confirm_add_sha256" == "y" || "$confirm_add_sha256" == "Y" ]]; then
# sed -i "/$old_file_name/a\ \ sha256: $new_sha256" "$yaml_file"
# report N "SHA256 added for '$new_file_name': $new_sha256."
# else
# report N "Skipped adding the SHA256 for '$new_file_name'."
# fi
# fi
#
# # Verify checksum
# verify_checksum "$DEST/$(basename "$new_file_name")" "$new_sha256"
# else
# report F "No reference found for '$base_name' in YAML file."
# fi
#}
update_yaml_sha256() {
local yaml_file="$1"
local new_file_name="$2"
local new_sha256="$3"
# Extract base name by removing version numbers and extensions
local base_name=$(echo "$new_file_name" | sed -E 's/-[0-9]+\.[0-9]+\.[0-9]+.*//')
if [[ ! -f "$yaml_file" ]]; then
report F "Line $LINENO: YAML file '$yaml_file' does not exist."
exit 1
fi
report N "Checking for entries matching '$base_name' in '$yaml_file'"
# Escape special characters for sed
escaped_old_file_name=$(printf '%s\n' "$old_file_name" | sed 's/[.[\*^$]/\\&/g')
escaped_new_file_name=$(printf '%s\n' "$new_file_name" | sed 's/[.[\*^$]/\\&/g')
# Find the existing entry (either `url:` or `path:`) and preserve indentation
old_file_entry=$(grep -E "^[[:space:]]*(url|path): .*$escaped_old_file_name" "$yaml_file")
if [[ -n "$old_file_entry" ]]; then
indent="${old_file_entry%%[^[:space:]]*}" # Extract leading whitespace
# If it's a `url:`, replace with `path:`, otherwise just update filename
if [[ "$old_file_entry" =~ ^[[:space:]]*url: ]]; then
new_line="${indent}path: $new_file_name"
else
new_line="${indent}path: $new_file_name"
fi
# Replace in YAML file
sed -i "s|$escaped_old_file_name|$escaped_new_file_name|" "$yaml_file"
report N "Updated entry: $old_file_entry -> $new_line"
fi
# Update the SHA256 checksum
old_sha256_entry=$(grep -A 1 "$escaped_old_file_name" "$yaml_file" | grep "sha256:")
if [[ -n "$old_sha256_entry" ]]; then
indent="${old_sha256_entry%%[^[:space:]]*}" # Preserve indentation
old_sha256_value=$(echo "$old_sha256_entry" | awk '{print $2}')
# Use sed to replace the old sha256 value with the new one
sed -i "s|sha256: $old_sha256_value|sha256: $new_sha256|" "$yaml_file"
report N "Updated SHA256: $new_sha256"
else
report F "No reference found for '$base_name' in YAML file."
fi
}
# Remove old file or directory
remove_obj() {
if [ -e "$1" ]; then
report N "Removing old version of $1..."
rm -rf "$1" # Handles both files and directories
report N "Done."
fi
}
# Ensure script is run in a Python virtual environment
check_virtual_env() {
[[ -z "$VIRTUAL_ENV" ]] && { echo -e "\nThis script must be run in a Python virtual environment.\n"; exit 1; }
}
# Ensure the specified directory exists
check_directory() {
[[ ! -d "$1" ]] && { report F "Directory '$1' does not exist."; exit 1; }
}
# Ensure the 'build' module is installed
ensure_build_installed() {
report N "Inspecting Python environment..."; sleep 2
if ! pip show build > /dev/null; then
report N "'build' module not found. Installing..."
pip install build
fi
report P "'build' module confirmed."
}
# Build the project
build_project() {
report N "Attempting to run 'python -m build $PROJ_DIR'..."
if ! python -m build -s -w $1 > /dev/null; then
report F "Project build for $1 failed."
exit 1
else
report P "Project build for $1 succeeded."
fi
}
# List SHA256 values of files in 'dist'
list_sha256() {
report B "SHA256 values of files in 'dist':"
for file in "${files[@]}"; do
sha256=$(sha256sum "$file" | awk '{print $1}')
report B "$sha256 $file"
sha256_values["$file"]="$sha256" # Store SHA256 in the associative array
done
report B "SHA256 Values in \$sha256_values:"
for file in "${!sha256_values[@]}"; do
report B "$file: ${sha256_values[$file]}"
done
}
# Copy .tar.gz (or other) files to a destination directory
copy_files() {
local dest="$1"
mkdir -p "$dest"
# Prompt for file type if no .tar.gz files are found
if [ "$AUTO" = false ]; then
read -p "Enter file extension to copy (e.g., .tar.gz, .whl, .zip): " file_ext
else
file_ext=$DEFAULT_COPY
fi
if [[ -z "$file_ext" ]]; then
report F "No file extension provided. Exiting."
exit 1
fi
# Filter files based on extension
files_to_copy=()
for file in "${files[@]}"; do
if [[ "$file" == *"$file_ext" ]]; then
files_to_copy+=("$file")
fi
done
# If no files found, ask user if they want to try a different extension
if [ ${#files_to_copy[@]} -eq 0 ]; then
report F "No $file_ext files found in 'dist'."
exit 1
fi
# Confirm each file for copying
for file in "${files_to_copy[@]}"; do
if [ "$AUTO" = false ]; then
read -p "Are you sure you want to copy '$file' to '$dest'? (y/n): " confirm
else
confirm="y"
fi
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
cp -v "$file" "$dest"
report P "File '$file' copied to '$dest'."; sleep 2
else
report N "Skipped copying '$file'."; sleep 2
fi
done
}
# Display help
show_help() {
report B ""
report B "Usage: $0 [folder] [--auto] [--help] [--debug]"
report B "Options:"
report B " folder Required folder name."
report B " --auto Optional flag to enable automatic mode."
report B " --help Display this message and quit (overrides all other options)."
exit 1
}
# Define colours if supported by the terminal
if supports_colour; then
RED=$(tput bold; tput setaf 9) # Bright Red
GREEN=$(tput bold; tput setaf 10) # Bright Green
YELLOW=$(tput bold; tput setaf 11) # Bright Yellow
BLUE=$(tput bold; tput setaf 12) # Bright Blue
CYAN=$(tput bold; tput setaf 14) # Bright Cyan
WHITE=$(tput bold; tput setaf 15) # Bright White
RESET=$(tput sgr0) # Reset colours
else
RED=""; GREEN=""; YELLOW=""; BLUE=""; CYAN=""; WHITE=""; RESET=""
fi
# Check for command-line arguments
if [[ $# -eq 0 ]]; then
report F "Folder name cannot be blank."
show_help
fi
# Declare the associative array for SHA256 values
declare -A sha256_values
LAUNCH_DIR=$(dirname "$(readlink -f "$0")")
PROJ_DIR=""
AUTO=false
DEBUG=false
SKIP_DO_THIS=false
DEFAULT_DEST="/home/seann/Amulet-Flatpak-Testing/testing"
DEFAULT_YAML="${DEFAULT_DEST}/pip-gen.yaml"
DEFAULT_COPY=".tar.gz"
WRITING_LOG=false
while [[ "$1" != "" ]]; do
case "$1" in
--help)
show_help
shift
;;
--auto)
AUTO=true
report N "AUTO mode active"
shift
;;
--yaml=*)
DO_THIS_YAML="${1#*=}"
DEFAULT_YAML="${DEFAULT_DEST}/${DO_THIS_YAML}"
report N "YAML manifest ${DEFAULT_YAML} will be used."
shift
;;
--skip-do-this)
SKIP_DO_THIS=true
report N "Skipping 'do_this.sh'"
shift
;;
*)
if [[ -z $PROJ_DIR ]]; then
PROJ_DIR=$1
else
report F "Error: Only one folder name is allowed."
show_help
fi
shift
;;
esac
done
# Main script execution
report N "Verifying VENV..."; sleep 2
check_virtual_env #; report N "\n check_virtual_env: LINE: $LINENO\n"
report P "VENV confirmed."; sleep 2 #; report N "\n LINE: $LINENO\n"
report N "Verifying $PROJ_DIR..."; sleep 2
check_directory "$PROJ_DIR" #; report N "\n check_directory \"$PROJ_DIR\" LINE: $LINENO\n"
report P "$PROJ_DIR confirmed."; sleep 2
remove_obj "$PROJ_DIR/dist" #; report N "\n remove_obj \"$PROJ_DIR/dist\" LINE: $LINENO\n"
ensure_build_installed #; report N "\n ensure_build_installed LINE: $LINENO\n"
build_project "$PROJ_DIR" #; report N "\n build_project \"$PROJ_DIR\" LINE: $LINENO\n"
# Collect files in 'dist'
files=($PROJ_DIR/dist/*)
report B "Files found in '$PROJ_DIR/dist':"
for dfile in "${files[@]}"; do
report B "$dfile"; sleep 1
done
# List SHA256 values
list_sha256 #; report N "\n list_sha256 LINE: $LINENO\n"
# Prompt for destination directory
if [ "$AUTO" = false ]; then
read -p "Enter destination directory to copy files ('q' to quit, default: '$DEFAULT_DEST'): " DEST
fi
if [[ "$DEST" == "q" ]]; then
report F "Exiting without copying files."
exit 0
fi
DEST="${DEST:-$DEFAULT_DEST}"
report N "\n\n copy_files \"$DEST\" LINE: $LINENO\n\n"
copy_files "$DEST"
# Prompt for YAML file
if [ "$AUTO" = false ]; then
read -p "Enter path to YAML file (default: '$DEFAULT_YAML'): " yaml_dest
fi
yaml_dest="${yaml_dest:-$DEFAULT_YAML}"
# Ensure YAML file exists
if [[ ! -f "$yaml_dest" ]]; then
report F "YAML file '$yaml_dest' does not exist."
exit 1
fi
# Update SHA256 in YAML for each file
for nfile in "${files[@]}"; do
bname=$(basename "$file")
new_sha256="${sha256_values[$nfile]}"
report N "\n\n update_yaml_sha256 \"$yaml_dest\" \"$bname\" \"$new_sha256\" LINE: $LINENO\n\n"
update_yaml_sha256 "$yaml_dest" "$bname" "$new_sha256"; sleep 1
report B ""
done
if [ "$SKIP_DO_THIS" = true ]; then
exit 0
else
echo -e "\a"; echo -e "\a"
if [ -f "${DEST}/do_this.sh" ]; then
cd $DEST
if [ "$AUTO" = false ]; then
read -p "do_this.sh located at '$DEST' - run it now?: " do_this
else
do_this="y"
fi
if [ $do_this = "y" ]; then
./do_this.sh --auto --debug --yaml="$DEFAULT_YAML"
fi
else
echo "Script do_this.sh does not exist in $DEST - skipping launch."
fi
cd $LAUNCH_DIR
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment