pcloudcc-lneely/dev/sync.sh

148 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# This script syncs the source tree in the devhost with the local
# source tree.
set -e
SOURCE_DIR="$(pwd)"
CONTAINER_USER="dev"
DEST_DIR="/src/$(basename "$SOURCE_DIR")"
SSH_PORT="2222"
get_container_ip() {
podman exec "$CONTAINER_NAME" bash -c "ip -4 addr show | grep -v '127.0.0.1' | grep 'inet ' | grep 'scope global' | head -n 1 | awk '{print \$2}' | cut -d/ -f1"
}
check_ssh_connection() {
local container_ip=$1
ssh-keyscan -p "$SSH_PORT" "$container_ip" > /dev/null 2>&1 || {
echo "Error: Unable to establish SSH connection to $container_ip:$SSH_PORT"
exit 1
}
}
sync_files() {
local container_ip=$(get_container_ip)
if [ -z "$container_ip" ]; then
echo "Error: Unable to get container IP address. Is the container running?"
exit 1
fi
check_ssh_connection "$container_ip"
echo "Syncing files to $CONTAINER_NAME ($container_ip)..."
rsync -avz --delete \
-e "ssh -p $SSH_PORT -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5" \
--exclude '.git' \
--exclude 'target' \
--exclude '*.tmp' \
--exclude '*.o' \
--exclude 'pcloudcc' \
--exclude '*.log' \
--exclude '.cache' \
"$SOURCE_DIR/" \
"${CONTAINER_USER}@${container_ip}:${DEST_DIR}/" || {
echo "Error: rsync failed. Exiting."
exit 1
}
echo "Sync completed at $(date)"
}
show_help() {
echo "Usage: $0 [OPTIONS] -c CONTAINER_NAME"
echo "Sync files to a devhost container using rsync and watchexec."
echo
echo "Options:"
echo " -c, --container CONTAINER_NAME Specify the devhost container name (required)"
echo " -s, --source DIR Specify the source directory (default: current directory)"
echo " -d, --dest DIR Specify the destination directory in the container"
echo " -u, --user USER Specify the user in the container (default: dev)"
echo " -p, --port PORT Specify the SSH port (default: 2222)"
echo " -o, --once Sync files once and exit"
echo " -w, --watch Watch for changes and sync continuously (default)"
echo " -h, --help Display this help message"
}
WATCH=true
while [[ $# -gt 0 ]]; do
case $1 in
-c|--container)
CONTAINER_NAME="$2"
shift 2
;;
-s|--source)
SOURCE_DIR="$2"
shift 2
;;
-d|--dest)
DEST_DIR="$2"
shift 2
;;
-u|--user)
CONTAINER_USER="$2"
shift 2
;;
-p|--port)
SSH_PORT="$2"
shift 2
;;
-o|--once)
WATCH=false
shift
;;
-w|--watch)
WATCH=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
done
if [ -z "$CONTAINER_NAME" ]; then
echo "Error: Devhost container name is required. Use -c or --container to specify it."
show_help
exit 1
fi
if ! command -v watchexec &> /dev/null && [ "$WATCH" = true ]; then
echo "Error: watchexec is not installed. Please install it to use the watch feature."
echo "You can install it using: cargo install watchexec-cli"
exit 1
fi
if ! command -v rsync &> /dev/null; then
echo "Error: rsync is not installed. Please install it to use this script."
exit 1
fi
if [ "$WATCH" = true ]; then
echo "Watching for changes in $SOURCE_DIR"
watchexec -w "$SOURCE_DIR" --on-busy-update=restart -- "$0" --once -c "$CONTAINER_NAME" -s "$SOURCE_DIR" -d "$DEST_DIR" -u "$CONTAINER_USER" -p "$SSH_PORT"
else
sync_files
fi