Skip to content

Instantly share code, notes, and snippets.

@EvilSupahFly
Last active March 18, 2025 14:39
Show Gist options
  • Select an option

  • Save EvilSupahFly/fedd99fc91e893e671ebc1553555233d to your computer and use it in GitHub Desktop.

Select an option

Save EvilSupahFly/fedd99fc91e893e671ebc1553555233d to your computer and use it in GitHub Desktop.
rebuild.sh
#!/bin/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=$1 # F = failure, P = pass, N = notice (neutral), B = Blank
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
local ERR_MSG="[$timestamp] ERROR: "
local PASSMSG="[$timestamp] SUCCESS: "
local NOTEMSG="[$timestamp] NOTICE: "
local BLNKMSG=""
# Ensure color variables are defined
local output_message
local log_message # New variable for logging
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}$2${RESET}"
log_message="$ERR_MSG $2" ;; # Plain message for log
P) output_message="${GREEN}$PASSMSG ${WHITE}$2${RESET}"
log_message="$PASSMSG $2" ;; # Plain message for log
N) output_message="${YELLOW}$NOTEMSG ${WHITE}$2${RESET}"
log_message="$NOTEMSG $2" ;; # Plain message for log
B) output_message="${WHITE}$2${RESET}"
log_message="$2" ;; # 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() {
# Function to handle renaming of log files
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="$1"
local expected_checksum="$2"
# Calculate checksum of the file
actual_checksum=$(sha256sum "$file" | awk '{print $1}')
if [[ "$actual_checksum" == "$expected_checksum" ]]; then
echo "Checksum verification passed for '$file'."
else
echo "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 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
indent=$(echo "$old_file_entry" | sed 's/\S.*//') # Extract leading spaces
indent="${indent% }" # Remove trailing spaces from the indent
new_line="$indent path: $new_file_name" # Ensure no extra space is added
echo "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
echo "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
}
# Function to 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/Downloads/Amulet-Flatpak-Testing/testing"
DEFAULT_YAML="$DEFAULT_DEST/pip-gen.yaml"
DEFAULT_COPY=".tar.gz"
WRITING_LOG=false
while [[ $# -gt 0 ]]; do
case $1 in
--help)
show_help
shift
;;
--auto)
AUTO=true
report N "AUTO mode active"
shift
;;
--debug)
DEBUG=true
report N "DEBUG mode active"
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
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