Last active
March 6, 2025 20:48
-
-
Save zudsniper/08058256b4f008eaf87bd092fe9683e0 to your computer and use it in GitHub Desktop.
make_appimage_wrapper.sh -- generate simple 'install_App.sh' scripts to install or update your appimage apps for ubuntu.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# make_appimage_wrapper.sh v2 | |
# > still wonky -- this one is gen'd by claude 3.7 sonnet, o1, o3-mini-high. | |
# Colors for terminal output | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[0;33m' | |
BLUE='\033[0;34m' | |
PURPLE='\033[0;35m' | |
CYAN='\033[0;36m' | |
NC='\033[0m' # No Color | |
# Script author | |
AUTHOR="@zudsniper (github)" | |
# Default values | |
VERBOSE=false | |
APP_NAME="" | |
ICON_PATH="" | |
SHOW_HELP=false | |
# Print banner | |
print_banner() { | |
echo -e "${CYAN}╔═════════════════════════════════════════╗${NC}" | |
echo -e "${CYAN}║ ║${NC}" | |
echo -e "${CYAN}║ ${GREEN}AppImage${CYAN} Wrapper Generator ║${NC}" | |
echo -e "${CYAN}║ ║${NC}" | |
echo -e "${CYAN}║ ${YELLOW}${AUTHOR}${CYAN} ║${NC}" | |
echo -e "${CYAN}╚═════════════════════════════════════════╝${NC}" | |
echo "" | |
} | |
# Print help message | |
print_help() { | |
echo -e "${BLUE}Usage:${NC} $0 [OPTIONS] APPIMAGE_PATH_OR_URL" | |
echo "" | |
echo -e "${BLUE}Description:${NC}" | |
echo " Create an installation script for an AppImage file that can be executed" | |
echo " to install the application with desktop integration." | |
echo "" | |
echo -e "${BLUE}Options:${NC}" | |
echo " --name, -n NAME Application name (required)" | |
echo " --icon, -i PATH Path or URL to icon image (optional; supported formats: svg, png, jpeg, jpg, ico)" | |
echo " --verbose, -v Enable verbose output" | |
echo " --help, -h Display this help message" | |
echo "" | |
echo -e "${BLUE}Example:${NC}" | |
echo " $0 --name MyApp --icon https://example.com/icon.png https://example.com/app.AppImage" | |
echo " $0 -n MyApp -i /path/to/icon.svg /path/to/app.AppImage" | |
echo "" | |
echo -e "${BLUE}Output:${NC}" | |
echo " Creates install_NAME.sh script in the current directory" | |
echo "" | |
} | |
# Log message | |
log() { | |
if [ "$VERBOSE" = true ] || [ "$1" != "verbose" ]; then | |
local level="$1" | |
local message="$2" | |
case "$level" in | |
"info") | |
echo -e "${GREEN}[INFO]${NC} $message" | |
;; | |
"warn") | |
echo -e "${YELLOW}[WARNING]${NC} $message" | |
;; | |
"error") | |
echo -e "${RED}[ERROR]${NC} $message" | |
;; | |
"verbose") | |
echo -e "${BLUE}[VERBOSE]${NC} $message" | |
;; | |
*) | |
echo -e "$message" | |
;; | |
esac | |
fi | |
} | |
# Parse command line arguments | |
parse_args() { | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--name|-n) | |
APP_NAME="$2" | |
log "verbose" "Application name set to: $APP_NAME" | |
shift 2 | |
;; | |
--icon|-i) | |
ICON_PATH="$2" | |
log "verbose" "Icon path set to: $ICON_PATH" | |
shift 2 | |
;; | |
--verbose|-v) | |
VERBOSE=true | |
log "verbose" "Verbose mode enabled" | |
shift | |
;; | |
--help|-h) | |
SHOW_HELP=true | |
shift | |
;; | |
*) | |
if [[ $1 == -* ]]; then | |
log "error" "Unknown option: $1" | |
print_help | |
exit 1 | |
else | |
APPIMAGE_PATH="$1" | |
log "verbose" "AppImage path set to: $APPIMAGE_PATH" | |
shift | |
fi | |
;; | |
esac | |
done | |
} | |
# Validate arguments | |
validate_args() { | |
# Check if help should be shown | |
if [ "$SHOW_HELP" = true ]; then | |
print_help | |
exit 0 | |
fi | |
# Check if app name is provided | |
if [ -z "$APP_NAME" ]; then | |
log "error" "Application name is required. Use --name or -n option. Use --help for more options." | |
exit 1 | |
fi | |
# Check if appimage path is provided | |
if [ -z "$APPIMAGE_PATH" ]; then | |
log "error" "AppImage path or URL is required. Use --help for more options." | |
exit 1 | |
fi | |
# Check if icon is accessible if provided as local file | |
if [ -n "$ICON_PATH" ] && [[ ! "$ICON_PATH" =~ ^https?:// ]]; then | |
if [ ! -f "$ICON_PATH" ] || [ ! -r "$ICON_PATH" ]; then | |
log "error" "The specified icon file does not exist or is not readable: $ICON_PATH" | |
exit 1 | |
fi | |
# Check if icon is a supported format | |
local ext="${ICON_PATH##*.}" | |
if [[ ! "$ext" =~ ^(svg|png|jpe?g|ico)$ ]]; then | |
log "warn" "Icon format may not be supported. Supported formats: svg, png, jpeg, jpg, ico" | |
fi | |
fi | |
# Check if appimage is accessible if provided as local file | |
if [[ ! "$APPIMAGE_PATH" =~ ^https?:// ]]; then | |
if [ ! -f "$APPIMAGE_PATH" ] || [ ! -r "$APPIMAGE_PATH" ]; then | |
log "error" "The specified AppImage file does not exist or is not readable: $APPIMAGE_PATH" | |
exit 1 | |
fi | |
# Check if AppImage is executable | |
if [ ! -x "$APPIMAGE_PATH" ]; then | |
log "warn" "The AppImage file is not executable. Permissions may need to be fixed during installation." | |
fi | |
fi | |
} | |
# Generate the installation script for the AppImage | |
generate_script() { | |
local output_file="install_${APP_NAME// /_}.sh" | |
log "info" "Generating installation script: $output_file" | |
# Compute the desktop entry path (hardcoded for use in the generated script) | |
local desktop_entry_path="/usr/share/applications/${APP_NAME// /_}.desktop" | |
# Determine if AppImage is a URL or a local file | |
local is_url=false | |
if [[ "$APPIMAGE_PATH" =~ ^https?:// ]]; then | |
is_url=true | |
log "info" "Creating auto-update script with URL: $APPIMAGE_PATH" | |
else | |
log "warn" "Using local AppImage path. Auto-update is not configured." | |
fi | |
# Create the installation script header | |
cat > "$output_file" << EOL | |
#!/bin/bash | |
# Installation script for ${APP_NAME} | |
# Generated by AppImage Wrapper Generator | |
# Author: ${AUTHOR} | |
install${APP_NAME// /}() { | |
local CUSTOM_APPIMAGE="\$1" | |
local APP_NAME="${APP_NAME}" | |
local INSTALL_PATH="/opt/${APP_NAME// /_}.appimage" | |
local ICON_INSTALL="/opt/${APP_NAME// /_}.png" | |
local DESKTOP_ENTRY_PATH="${desktop_entry_path}" | |
local TEMP_APPIMAGE="/tmp/${APP_NAME// /_}.appimage" | |
EOL | |
# Insert URL or local file assignment for the AppImage | |
if [ "$is_url" = true ]; then | |
cat >> "$output_file" << EOL | |
local APPIMAGE_URL="$APPIMAGE_PATH" | |
EOL | |
else | |
cat >> "$output_file" << EOL | |
local APPIMAGE_PATH="$APPIMAGE_PATH" | |
EOL | |
fi | |
# Insert ICON_URL assignment if an icon was provided | |
if [ -n "$ICON_PATH" ]; then | |
echo " local ICON_URL=\"$ICON_PATH\"" >> "$output_file" | |
fi | |
cat >> "$output_file" << EOL | |
# Check if the AppImage wrapper already exists and if it is running | |
if [ -f "\$INSTALL_PATH" ]; then | |
if pgrep -f "\$INSTALL_PATH" > /dev/null; then | |
echo "\${APP_NAME} is currently running." | |
read -p "Do you want to kill it and update? [y/N] " user_response | |
if [[ "\$user_response" =~ ^[Yy]\$ ]]; then | |
echo "Killing running \${APP_NAME}..." | |
pkill -f "\$INSTALL_PATH" | |
else | |
echo "Update cancelled. Exiting." | |
exit 1 | |
fi | |
fi | |
fi | |
echo "Checking for existing \${APP_NAME} installation..." | |
# Check if a custom AppImage path was provided and if it exists | |
if [ -n "\$CUSTOM_APPIMAGE" ]; then | |
if [ -f "\$CUSTOM_APPIMAGE" ] && [ -r "\$CUSTOM_APPIMAGE" ]; then | |
echo "Using provided AppImage file: \$CUSTOM_APPIMAGE" | |
TEMP_APPIMAGE="\$CUSTOM_APPIMAGE" | |
else | |
echo "Error: The specified AppImage file does not exist or is not readable: \$CUSTOM_APPIMAGE" | |
exit 1 | |
fi | |
fi | |
# Detect the user's shell | |
local SHELL_NAME=\$(basename "\$SHELL") | |
local RC_FILE="" | |
case "\$SHELL_NAME" in | |
bash) | |
RC_FILE="\$HOME/.bashrc" | |
;; | |
zsh) | |
RC_FILE="\$HOME/.zshrc" | |
;; | |
fish) | |
RC_FILE="\$HOME/.config/fish/config.fish" | |
;; | |
*) | |
echo "Unsupported shell: \$SHELL_NAME" | |
echo "Please manually add the alias to your shell configuration file." | |
return 1 | |
;; | |
esac | |
# Notify if updating an existing installation | |
if [ -f "\$INSTALL_PATH" ]; then | |
echo "\${APP_NAME} is already installed. Updating existing installation..." | |
else | |
echo "Performing a fresh installation of \${APP_NAME}..." | |
fi | |
# Install curl if not installed | |
if ! command -v curl &> /dev/null; then | |
echo "curl is not installed. Installing..." | |
sudo apt-get update | |
sudo apt-get install -y curl || { echo "Failed to install curl."; exit 1; } | |
fi | |
# If an icon is provided, ensure ImageMagick is available for conversion | |
if [ -n "\$ICON_URL" ]; then | |
if ! command -v convert &> /dev/null; then | |
echo "ImageMagick 'convert' not found. Installing imagemagick..." | |
sudo apt-get update | |
sudo apt-get install -y imagemagick || { echo "Failed to install ImageMagick."; exit 1; } | |
fi | |
fi | |
EOL | |
# Add AppImage download or copy logic | |
if [ "$is_url" = true ]; then | |
cat >> "$output_file" << EOL | |
# Download AppImage if not provided | |
if [ "\$TEMP_APPIMAGE" = "/tmp/${APP_NAME// /_}.appimage" ]; then | |
echo "Downloading \${APP_NAME} AppImage..." | |
curl -L "\$APPIMAGE_URL" -o "\$TEMP_APPIMAGE" || { echo "Failed to download AppImage."; exit 1; } | |
fi | |
EOL | |
else | |
cat >> "$output_file" << EOL | |
# Copy local AppImage if not provided | |
if [ "\$TEMP_APPIMAGE" = "/tmp/${APP_NAME// /_}.appimage" ]; then | |
echo "Copying \${APP_NAME} AppImage..." | |
cp "\$APPIMAGE_PATH" "\$TEMP_APPIMAGE" || { echo "Failed to copy AppImage."; exit 1; } | |
fi | |
EOL | |
fi | |
# Add icon processing logic if provided | |
if [ -n "$ICON_PATH" ]; then | |
cat >> "$output_file" << 'EOL' | |
echo "Processing ${APP_NAME} icon..." | |
ICON_TEMP="/tmp/${APP_NAME// /_}_icon" | |
# Determine if ICON_URL is a URL or a local file | |
if [[ "$ICON_URL" =~ ^https?:// ]]; then | |
echo "Downloading icon from URL..." | |
curl -L "$ICON_URL" -o "$ICON_TEMP" || { echo "Failed to download icon."; exit 1; } | |
else | |
echo "Copying icon from local file..." | |
cp "$ICON_URL" "$ICON_TEMP" || { echo "Failed to copy icon."; exit 1; } | |
fi | |
echo "Converting icon to 128x128 PNG..." | |
convert "$ICON_TEMP" -resize 128x128 "/tmp/${APP_NAME// /_}.png" || { echo "Icon conversion failed."; exit 1; } | |
rm "$ICON_TEMP" | |
EOL | |
fi | |
# Continue installation steps | |
cat >> "$output_file" << EOL | |
# Move to final destination | |
echo "Installing \${APP_NAME} files..." | |
sudo cp "\$TEMP_APPIMAGE" "\$INSTALL_PATH" | |
sudo chmod +x "\$INSTALL_PATH" | |
EOL | |
# Add icon installation step if provided | |
if [ -n "$ICON_PATH" ]; then | |
cat >> "$output_file" << 'EOL' | |
sudo mv "/tmp/${APP_NAME// /_}.png" "$ICON_INSTALL" | |
EOL | |
fi | |
# Create the .desktop entry using the hardcoded desktop entry path | |
cat >> "$output_file" << EOL | |
echo "Creating .desktop entry..." | |
sudo bash -c "cat > '${desktop_entry_path}'" <<INNEREOF | |
[Desktop Entry] | |
Name=${APP_NAME} | |
Exec=\$INSTALL_PATH | |
Type=Application | |
Categories=Application; | |
INNEREOF | |
EOL | |
# Add the icon line to the desktop entry if provided | |
if [ -n "$ICON_PATH" ]; then | |
cat >> "$output_file" << EOL | |
# Add icon to desktop entry | |
sudo sed -i '/Type=Application/a\\Icon=\$ICON_INSTALL' '${desktop_entry_path}' | |
EOL | |
fi | |
# Add shell alias setup | |
cat >> "$output_file" << EOL | |
# Add alias to the appropriate RC file | |
local APP_ALIAS="${APP_NAME// /_}" | |
echo "Adding \$APP_ALIAS alias to \$RC_FILE..." | |
if [ "\$SHELL_NAME" = "fish" ]; then | |
# Fish shell uses a different syntax for functions | |
if ! grep -q "function \$APP_ALIAS" "\$RC_FILE"; then | |
echo "function \$APP_ALIAS" >> "\$RC_FILE" | |
echo " \$INSTALL_PATH \\\$argv > /dev/null 2>&1 & disown" >> "\$RC_FILE" | |
echo "end" >> "\$RC_FILE" | |
else | |
echo "Alias already exists in \$RC_FILE." | |
fi | |
else | |
if ! grep -q "function \$APP_ALIAS" "\$RC_FILE"; then | |
cat >> "\$RC_FILE" <<INNEREOF | |
# ${APP_NAME} alias | |
function \$APP_ALIAS() { | |
\$INSTALL_PATH "\\\${@}" > /dev/null 2>&1 & disown | |
} | |
INNEREOF | |
else | |
echo "Alias already exists in \$RC_FILE." | |
fi | |
fi | |
# Inform the user to reload the shell | |
echo "To apply changes, please restart your terminal or run the following command:" | |
echo " source \$RC_FILE" | |
echo "\${APP_NAME} installation or update complete. You can find it in your application menu." | |
} | |
install${APP_NAME// /} "\$1" | |
EOL | |
# Make the generated installation script executable | |
chmod +x "$output_file" | |
log "info" "Installation script generated successfully: $output_file" | |
log "info" "To install ${APP_NAME}, run: ./$output_file" | |
} | |
# Main function | |
main() { | |
print_banner | |
# Parse and validate arguments | |
parse_args "$@" | |
validate_args | |
# Generate the installation script | |
generate_script | |
} | |
# Run the script | |
main "$@" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment