|
1 | 1 | import argparse |
2 | 2 | import os |
3 | 3 | import subprocess |
4 | | -from typing import List, Optional |
5 | 4 |
|
6 | 5 | from dt_shell import DTCommandAbs, dtslogger |
7 | 6 | from utils.cli_utils import ensure_command_is_installed |
8 | 7 | from utils.docker_utils import DEFAULT_MACHINE |
9 | 8 | from utils.misc_utils import sanitize_hostname |
10 | 9 | from utils.multi_command_utils import MultiCommand |
11 | | -from utils.mutagen_sync import MutagenSync, MutagenError, ensure_min_version, sanitize_session_name |
12 | | -from utils.ssh_setup import ensure_ssh_for_host |
13 | | -from devel.run.command import REMOTE_USER as DEFAULT_REMOTE_USER |
14 | 10 |
|
15 | | -# Default host path on the robot to mirror code into (bind-mount this in containers) |
16 | | -REMOTE_SYNC_CODE_LOCATION = "/code" |
17 | | - |
18 | | -# Default ignore patterns for sync (by default .git is ignored; can be included via --include-git) |
19 | | -DEFAULT_IGNORE: List[str] = [ |
20 | | - ".git/", |
21 | | - ".cache/", |
22 | | - "**/__pycache__/", |
23 | | - "build/", |
24 | | - "install/", |
25 | | - "log/", |
26 | | - ".vscode-server/", |
27 | | -] |
| 11 | +DEFAULT_REMOTE_USER = "duckie" |
| 12 | +REMOTE_RSYNC_CODE_LOCATION = "/tmp/code" |
28 | 13 |
|
29 | 14 |
|
30 | 15 | class DTCommand(DTCommandAbs): |
@@ -53,97 +38,25 @@ def command(shell, args: list, **kwargs): |
53 | 38 | # --- |
54 | 39 | # sync |
55 | 40 | if parsed.machine == DEFAULT_MACHINE: |
56 | | - # only allowed when targeting a remote machine |
57 | | - dtslogger.error("This command requires -H/--machine to specify the remote host") |
| 41 | + # only allowed when mounting remotely |
| 42 | + dtslogger.error("The option -s/--sync can only be used together with -H/--machine") |
58 | 43 | exit(2) |
59 | | - # Ensure SSH key-based auth is configured for the target |
60 | | - robot_name: Optional[str] = None |
61 | | - # If the given machine is like NAME.local, derive NAME |
62 | | - try: |
63 | | - if parsed.machine.endswith('.local'): |
64 | | - robot_name = parsed.machine.split('.', 1)[0] |
65 | | - elif '.' not in parsed.machine: |
66 | | - # likely MagicDNS short name |
67 | | - robot_name = parsed.machine |
68 | | - except Exception: |
69 | | - pass |
70 | | - try: |
71 | | - ensure_ssh_for_host(parsed.machine, user=DEFAULT_REMOTE_USER, robot_name=robot_name) |
72 | | - except Exception as e: |
73 | | - # Non-fatal: we proceed; SSH may still prompt if needed |
74 | | - dtslogger.warning(f"SSH setup encountered an issue: {e}") |
75 | | - # make sure Mutagen is installed |
76 | | - ensure_command_is_installed( |
77 | | - "mutagen", |
78 | | - dependant="dts devel run", |
79 | | - custom_msg=( |
80 | | - "Please install it with:\n" |
81 | | - " curl -sS https://webi.sh/mutagen | sh\n" |
82 | | - " source ~/.config/envman/PATH.env\n" |
83 | | - "and try again." |
84 | | - ), |
85 | | - ) |
86 | | - # pre-flight version check |
87 | | - try: |
88 | | - ensure_min_version("0.17.0") |
89 | | - except MutagenError as e: |
90 | | - # Older Mutagen versions work with plain-text parsing; continue with a warning |
91 | | - dtslogger.warning(str(e)) |
92 | | - dtslogger.info(f"Ensuring Mutagen sync to {parsed.machine.replace('.local', '')}...") |
| 44 | + # make sure rsync is installed |
| 45 | + ensure_command_is_installed("rsync") |
| 46 | + dtslogger.info(f"Syncing code with {parsed.machine.replace('.local', '')}...") |
| 47 | + remote_path = f"{DEFAULT_REMOTE_USER}@{parsed.machine}:{REMOTE_RSYNC_CODE_LOCATION}/" |
93 | 48 | # get projects' locations |
94 | 49 | projects_to_sync = [parsed.workdir] if parsed.mount is True else [] |
95 | 50 | # sync secondary projects |
96 | 51 | if isinstance(parsed.mount, str): |
97 | 52 | projects_to_sync.extend( |
98 | 53 | [os.path.abspath(os.path.join(os.getcwd(), p.strip())) for p in parsed.mount.split(",")] |
99 | 54 | ) |
100 | | - # create or reuse sessions |
101 | | - sessions = [] |
| 55 | + # run rsync |
102 | 56 | for project_path in projects_to_sync: |
103 | | - project_path = os.path.abspath(project_path) |
104 | | - project_name = os.path.basename(project_path.rstrip("/")) |
105 | | - session_name = sanitize_session_name(f"dts-sync-{project_name}-{parsed.machine}") |
106 | | - # ensure remote directory exists |
107 | | - remote_host_dir = os.path.join(REMOTE_SYNC_CODE_LOCATION, project_name) |
108 | | - _run_cmd([ |
109 | | - "ssh", |
110 | | - f"{DEFAULT_REMOTE_USER}@{parsed.machine}", |
111 | | - f"mkdir -p '{remote_host_dir}'" |
112 | | - ]) |
113 | | - # build Mutagen endpoints |
114 | | - alpha = project_path |
115 | | - beta = f"ssh://{DEFAULT_REMOTE_USER}@{parsed.machine}//{remote_host_dir.lstrip('/')}" |
116 | | - try: |
117 | | - sync = MutagenSync(name=session_name) |
118 | | - # Determine ignore paths (optionally include .git) |
119 | | - ignore_paths = list(DEFAULT_IGNORE) |
120 | | - if getattr(parsed, "include_git", False): |
121 | | - ignore_paths = [p for p in ignore_paths if p != ".git/"] |
122 | | - session = sync.ensure_session( |
123 | | - alpha=alpha, |
124 | | - beta=beta, |
125 | | - ignore_paths=ignore_paths, |
126 | | - max_staging_file_size="64MiB", |
127 | | - ) |
128 | | - dtslogger.info(f"Session ready: {session.name} ({session.identifier})") |
129 | | - sessions.append((sync, session)) |
130 | | - except MutagenError as e: |
131 | | - dtslogger.error(str(e)) |
132 | | - exit(2) |
133 | | - # optional flush |
134 | | - if parsed.flush_direction: |
135 | | - for sync, _ in sessions: |
136 | | - try: |
137 | | - sync.flush(parsed.flush_direction) |
138 | | - except MutagenError as e: |
139 | | - dtslogger.warning(f"Flush failed for {sync.name}: {e}") |
140 | | - dtslogger.info(f"One-shot flush requested: {parsed.flush_direction}") |
141 | | - # optional monitor (monitor the first session) |
142 | | - if parsed.monitor and sessions: |
143 | | - dtslogger.info("Monitoring Mutagen session. Press Ctrl-C to stop...") |
144 | | - sessions[0][0].monitor() |
145 | | - else: |
146 | | - dtslogger.info("Mutagen sync configured. Use 'mutagen sync monitor' to watch events.") |
| 57 | + cmd = f"rsync --archive {project_path} {remote_path}" |
| 58 | + _run_cmd(cmd, shell=True) |
| 59 | + dtslogger.info(f"Code synced!") |
147 | 60 |
|
148 | 61 | @staticmethod |
149 | 62 | def complete(shell, word, line): |
|
0 commit comments