#!/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 . # 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