feat(cli): integrate embedded rsync for remote sync

Replace local file copy with embedded rsync binary for actual remote
synchronization to the server. The embedded rsync is extracted from
assets/ at runtime - no external dependencies required.

Changes:
- Re-add rsync_embedded.zig import
- Replace manual file copying with rsync.sync() call
- Construct remote path as api_key@host:worker_base/commit_id/files/
- Update JSON output to include commit_id

Build verified: zig build --release=fast
This commit is contained in:
Jeremie Fraeys 2026-02-18 13:45:50 -05:00
parent c31055be30
commit 55b4b23645
No known key found for this signature in database

View file

@ -2,6 +2,7 @@ const std = @import("std");
const colors = @import("../utils/colors.zig");
const Config = @import("../config.zig").Config;
const crypto = @import("../utils/crypto.zig");
const rsync = @import("../utils/rsync_embedded.zig");
const ws = @import("../net/ws/client.zig");
const logging = @import("../utils/logging.zig");
@ -51,60 +52,21 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void {
const commit_id = try crypto.hashDirectory(allocator, path);
defer allocator.free(commit_id);
// Content-addressed storage optimization
// try cas.deduplicateDirectory(path);
// Use local file operations instead of rsync for testing
const local_path = try std.fmt.allocPrint(
// Construct remote destination path
const remote_path = try std.fmt.allocPrint(
allocator,
"{s}/{s}/files/",
.{ config.worker_base, commit_id },
"{s}@{s}:{s}/{s}/files/",
.{ config.api_key, config.worker_host, config.worker_base, commit_id },
);
defer allocator.free(local_path);
defer allocator.free(remote_path);
// Create directory and copy files locally
try std.fs.cwd().makePath(local_path);
var src_dir = try std.fs.cwd().openDir(path, .{ .iterate = true });
defer src_dir.close();
var dest_dir = try std.fs.cwd().openDir(local_path, .{ .iterate = true });
defer dest_dir.close();
var walker = try src_dir.walk(allocator);
defer walker.deinit();
while (try walker.next()) |entry| {
if (!json) {
std.debug.print("Processing entry: {s}\n", .{entry.path});
}
if (entry.kind == .file) {
const rel_path = try allocator.dupe(u8, entry.path);
defer allocator.free(rel_path);
if (!json) {
std.debug.print("Copying file: {s}\n", .{rel_path});
}
const src_file = try src_dir.openFile(rel_path, .{});
defer src_file.close();
const dest_file = try dest_dir.createFile(rel_path, .{});
defer dest_file.close();
const src_contents = try src_file.readToEndAlloc(allocator, 1024 * 1024);
defer allocator.free(src_contents);
try dest_file.writeAll(src_contents);
if (!json) {
colors.printSuccess("Successfully copied: {s}\n", .{rel_path});
}
}
}
// Sync using embedded rsync (no external binary needed)
try rsync.sync(allocator, path, remote_path, config.worker_port);
if (json) {
std.debug.print("{\"ok\":true,\"action\":\"sync\"}\n", .{});
std.debug.print("{\"ok\":true,\"action\":\"sync\",\"commit_id\":\"{s}\"}\n", .{commit_id});
} else {
colors.printSuccess("✓ Files synced successfully\n", .{});
colors.printSuccess("✓ Files synced to server\n", .{});
}
// If queue flag is set, queue the job