Добавлена поддержка скачивания последней версии скрипта

main
ilyukhin 2 months ago
parent 8b96ffeeaf
commit 1cba81dae8

@ -1,11 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Install dsync from https://git.ai.infran.ru/ilyukhin/dsync.git # Install dsync from https://git.ai.infran.ru/ilyukhin/dsync.git
# #
# Behavior:
# - Fetch latest dsync from repo (git shallow clone or raw download main/master).
# - Compare VERSION in remote vs locally installed (DEST_PATH).
# * If equal and no --force: say "already up to date" and exit 0.
# * If remote newer: update.
# * If local newer and no --force: warn and exit 1 (avoid accidental downgrade).
#
# Usage: # Usage:
# ./install_dsync.sh # install to ~/.local/bin (default) # ./install_dsync.sh # install to ~/.local/bin (default)
# ./install_dsync.sh --system # install to /usr/local/bin (requires sudo) # ./install_dsync.sh --system # install to /usr/local/bin (requires sudo)
# ./install_dsync.sh -d DIR # install to custom DIR # ./install_dsync.sh -d DIR # install to custom DIR
# ./install_dsync.sh -f # force overwrite if target exists # ./install_dsync.sh -f # force overwrite (also allows downgrade/reinstall)
# ./install_dsync.sh -h # show help # ./install_dsync.sh -h # show help
set -euo pipefail set -euo pipefail
@ -23,12 +30,58 @@ Install dsync from ${REPO_URL}
Options: Options:
-s, --system install into /usr/local/bin (system-wide; may use sudo) -s, --system install into /usr/local/bin (system-wide; may use sudo)
-d DIR, --dest DIR install into DIR -d DIR, --dest DIR install into DIR
-f, --force overwrite existing file without asking -f, --force overwrite existing file; also bypasses version equality/downgrade checks
-h, --help show this help -h, --help show this help
EOF EOF
} }
# parse options # --- version helpers ----------------------------------------------------------
extract_version() {
# Parse VERSION from a dsync file (Python). Prints version or nothing.
# Accepts forms like: VERSION = "0.2.1"
local f="$1"
[[ -f "$f" ]] || { echo ""; return 1; }
# get line with VERSION=
local line
line="$(grep -E '^[[:space:]]*VERSION[[:space:]]*=' "$f" | head -1 || true)"
[[ -n "$line" ]] || { echo ""; return 1; }
# strip up to '='
line="${line#*=}"
# trim spaces
line="$(echo "$line" | sed -E 's/^[[:space:]]+|[[:space:]]+$//g')"
# drop trailing comments
line="${line%%#*}"
# strip quotes
line="${line%\"}"; line="${line#\"}"
line="${line%\'}"; line="${line#\'}"
# keep only semver-ish chars
line="$(echo "$line" | sed -E 's/[^0-9A-Za-z\.\-\+].*$//')"
echo "$line"
}
compare_versions() {
# Compare two dotted numeric versions: echoes 1 if $1 > $2, -1 if $1 < $2, 0 if equal.
# Non-numeric segments beyond dots are ignored (basic semver compare).
local a="$1" b="$2"
# fallback: if either empty, consider different
[[ -n "$a" && -n "$b" ]] || { [[ "$a" == "$b" ]] && echo 0 || echo 1; return; }
IFS=. read -r -a av <<< "$a"
IFS=. read -r -a bv <<< "$b"
local len="${#av[@]}"
(( ${#bv[@]} > len )) && len="${#bv[@]}"
local i ai bi
for ((i=0;i<len;i++)); do
ai="${av[i]:-0}"; bi="${bv[i]:-0}"
# force base-10 (avoid octal)
if (( 10#$ai > 10#$bi )); then echo 1; return; fi
if (( 10#$ai < 10#$bi )); then echo -1; return; fi
done
echo 0
}
# --- parse options ------------------------------------------------------------
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
-s|--system) -s|--system)
@ -68,13 +121,13 @@ done
DEST_PATH="$DEST_DIR/dsync" DEST_PATH="$DEST_DIR/dsync"
# create temporary dir and ensure cleanup # --- prepare dirs -------------------------------------------------------------
TMPDIR="$(mktemp -d)" TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT trap 'rm -rf "$TMPDIR"' EXIT
echo "Installing dsync to: $DEST_DIR" echo "Installing dsync to: $DEST_DIR"
# ensure target directory exists (create with sudo if system dir)
if [[ ! -d "$DEST_DIR" ]]; then if [[ ! -d "$DEST_DIR" ]]; then
echo "Target directory $DEST_DIR does not exist — attempting to create it..." echo "Target directory $DEST_DIR does not exist — attempting to create it..."
if ! mkdir -p "$DEST_DIR" 2>/dev/null; then if ! mkdir -p "$DEST_DIR" 2>/dev/null; then
@ -89,29 +142,30 @@ fi
FOUND="" FOUND=""
# 1) Try to clone repo with git (if git available) # --- fetch from git (preferred) ----------------------------------------------
if command -v git >/dev/null 2>&1; then if command -v git >/dev/null 2>&1; then
echo "git found — attempting shallow clone..." echo "git found — attempting shallow clone..."
if git clone --depth 1 "$REPO_URL" "$TMPDIR/repo" >/dev/null 2>&1; then if git clone --quiet --depth 1 "$REPO_URL" "$TMPDIR/repo" >/dev/null 2>&1; then
echo "Repository cloned." echo "Repository cloned."
else else
echo "Shallow clone failed, attempting normal clone (may show output)..." echo "Shallow clone failed, attempting normal clone (may show output)..."
git clone --depth 1 "$REPO_URL" "$TMPDIR/repo" || true git clone --depth 1 "$REPO_URL" "$TMPDIR/repo" || true
fi fi
if [[ -d "$TMPDIR/repo" ]]; then if [[ -d "$TMPDIR/repo" ]]; then
# try to locate the dsync file
FOUND="$(find "$TMPDIR/repo" -maxdepth 6 -type f -name dsync -print -quit || true)" FOUND="$(find "$TMPDIR/repo" -maxdepth 6 -type f -name dsync -print -quit || true)"
fi fi
fi fi
# 2) If git did not find the file, try to download raw file via curl (main/master) # --- fallback: raw download from main/master ---------------------------------
if [[ -z "$FOUND" ]]; then if [[ -z "$FOUND" ]]; then
if command -v curl >/dev/null 2>&1; then if command -v curl >/dev/null 2>&1; then
for BR in main master; do for BR in main master; do
RAW_URL="$RAW_BASE/$BR/dsync" RAW_URL="$RAW_BASE/$BR/dsync"
echo "Trying to download raw file: $RAW_URL" echo "Trying to download raw file: $RAW_URL"
if curl --fail -L --max-redirs 5 -o "$TMPDIR/dsync" "$RAW_URL"; then if curl --fail -L --max-redirs 5 -o "$TMPDIR/dsync" "$RAW_URL"; then
# check that downloaded file looks like text/script, not HTML error
if file "$TMPDIR/dsync" | grep -qE 'text|python|ASCII'; then if file "$TMPDIR/dsync" | grep -qE 'text|python|ASCII'; then
FOUND="$TMPDIR/dsync" FOUND="$TMPDIR/dsync"
break break
@ -136,13 +190,47 @@ fi
echo "Found source file at: $FOUND" echo "Found source file at: $FOUND"
# Warn if target exists # --- version comparison logic -------------------------------------------------
if [[ -e "$DEST_PATH" && "$FORCE" -ne 1 ]]; then
echo "Error: $DEST_PATH already exists. Use --force to overwrite." >&2 REMOTE_VER="$(extract_version "$FOUND" || true)"
exit 1 LOCAL_VER=""
if [[ -e "$DEST_PATH" ]]; then
LOCAL_VER="$(extract_version "$DEST_PATH" || true)"
fi fi
# copy into destination (use sudo if target dir is not writable) if [[ "$FORCE" -eq 0 && -e "$DEST_PATH" ]]; then
if [[ -n "$REMOTE_VER" && -n "$LOCAL_VER" ]]; then
CMP="$(compare_versions "$REMOTE_VER" "$LOCAL_VER")"
if [[ "$CMP" -eq 0 ]]; then
echo "dsync is already up to date (version $LOCAL_VER). Use --force to reinstall."
exit 0
elif [[ "$CMP" -lt 0 ]]; then
echo "Installed dsync ($LOCAL_VER) is newer than remote ($REMOTE_VER)."
echo "Use --force to downgrade or reinstall."
exit 1
else
echo "Updating dsync: $LOCAL_VER -> $REMOTE_VER"
fi
else
echo "Version check inconclusive (remote='$REMOTE_VER', local='$LOCAL_VER')."
echo "Proceeding with install (use --force to bypass version checks explicitly)."
fi
elif [[ -e "$DEST_PATH" && "$FORCE" -eq 1 ]]; then
if [[ -n "$REMOTE_VER" && -n "$LOCAL_VER" ]]; then
echo "Reinstalling (forced): $LOCAL_VER -> $REMOTE_VER"
else
echo "Reinstalling (forced)."
fi
else
if [[ -n "$REMOTE_VER" ]]; then
echo "Installing dsync version $REMOTE_VER"
else
echo "Installing dsync (version unknown)"
fi
fi
# --- install/copy -------------------------------------------------------------
if touch "$DEST_DIR/.write_test" >/dev/null 2>&1; then if touch "$DEST_DIR/.write_test" >/dev/null 2>&1; then
rm -f "$DEST_DIR/.write_test" rm -f "$DEST_DIR/.write_test"
cp -f "$FOUND" "$DEST_PATH" cp -f "$FOUND" "$DEST_PATH"
@ -159,7 +247,8 @@ else
echo "Installed (via sudo): $DEST_PATH" echo "Installed (via sudo): $DEST_PATH"
fi fi
# quick PATH check # --- final PATH hint ----------------------------------------------------------
echo echo
echo "PATH check:" echo "PATH check:"
if command -v dsync >/dev/null 2>&1; then if command -v dsync >/dev/null 2>&1; then

Loading…
Cancel
Save