Scripts: add recursion support to psyncup

This commit is contained in:
Akemi Izuko 2025-03-27 14:13:37 -06:00
parent 816f3d9301
commit c808afc884
Signed by: akemi
GPG key ID: 8DE0764E1809E9FC

View file

@ -4,6 +4,7 @@ import datetime as dt
import json
import os
import subprocess
import sys
from pathlib import Path
CONFIG_NAME = ".psyncup.json"
@ -45,6 +46,11 @@ parser.add_argument(
action="store_true",
help="Runs the rsync, without writing any changes to local or remote",
)
parser.add_argument(
"--recurse-up",
action="store_true",
help=f"Checks for {CONFIG_NAME} in all parent directories as well",
)
parser.add_argument(
"--no-compress",
action="store_true",
@ -58,7 +64,7 @@ parser.add_argument(
parser.add_argument(
"--exec",
type=str,
help="Run command on remote machine after sync",
help="Run command on remote, after sync is complete"
)
group = parser.add_mutually_exclusive_group(required=True)
@ -111,11 +117,17 @@ def get_config():
if config["remote_dir"][-1] == "/" and config["remote_dir"] != "/":
config["remote_dir"] = config["remote_dir"][:-1]
except FileNotFoundError:
print(f"ERROR: {CONFIG_NAME} file was not found in this directory")
print(
f"ERROR: {CONFIG_NAME} file was not found in this directory",
file=sys.stderr
)
print(epilog)
exit(1)
except KeyError as e:
print(f"ERROR: {CONFIG_NAME} is missing required key {e}")
print(
f"ERROR: {CONFIG_NAME} is missing required key {e}",
file=sys.stderr
)
exit(1)
return config
@ -208,13 +220,13 @@ def run_check(ssh_cmd, config):
try:
remote_config_str = check.communicate(timeout=6)[0].decode("utf-8")
except subprocess.TimeoutExpired:
print("Failed to connect to remote (timed out)")
print("Failed to connect to remote (timed out)", file=sys.stderr)
exit(1)
try:
remote_config = json.loads(remote_config_str)
except json.JSONDecodeError:
print(f"Failed to read remote {CONFIG_NAME}")
print(f"Failed to read remote {CONFIG_NAME}", file=sys.stderr)
exit(1)
if not remote_config.get("update_date"):
@ -242,7 +254,7 @@ def run_up(rsync_cmd, remote_dir_str, config):
rsync_code = subprocess.call(rsync_cmd)
if rsync_code != 0:
print(f"Rsync exited with code {rsync_code}")
print(f"Rsync exited with code {rsync_code}", file=sys.stderr)
exit(1)
@ -257,13 +269,8 @@ def run_down(rsync_cmd, remote_dir_str):
exit(1)
def run_exec(cmd, config):
if config.get("ssh_jump") is not None:
ssh_cmd = ["ssh", "-t", "-J", config["ssh_jump"], config["ssh_remote"], cmd]
else:
ssh_cmd = ["ssh", "-t", config["ssh_remote"], cmd]
subprocess.run(["ssh", "-t", config["ssh_remote"], cmd])
def run_remote_exec(cmd, config):
subprocess.call(["ssh", "-t", config["ssh_remote"], cmd])
if __name__ == "__main__":
@ -271,6 +278,19 @@ if __name__ == "__main__":
run_init()
exit(0)
if args.recurse_up:
while True:
if Path(CONFIG_NAME).exists():
break
elif os.getcwd() == '/':
print(
f"Error: No {CONFIG_NAME} found in any parent directory",
file=sys.stderr
)
exit(1)
else:
os.chdir('..')
if args.pull:
run_pull(args.pull, args.debug)
args.down = True
@ -285,7 +305,7 @@ if __name__ == "__main__":
run_up(rsync_cmd, remote_dir_str, config)
if args.exec:
run_exec(args.exec, config)
run_remote_exec(args.exec, config)
elif args.down:
rsync_cmd, _, remote_dir_str = build_commands(args, config)
run_down(rsync_cmd, remote_dir_str)