From a0aff000ad8da9d46ca6b95ed44e7d4dfc20bebf Mon Sep 17 00:00:00 2001 From: TapTap Date: Thu, 3 Sep 2026 16:34:18 +0200 Subject: [PATCH 1/2] feat: add rsync partial progress alias --- README.md | 1 + RSYNC_COMPAT.md | 6 +++--- src/client/client_cli.c | 6 ++++++ src/client/usage.c | 1 + tests/test_client_cli.c | 17 +++++++++++++++++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fdbd9f3..f8ec2c6 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ partial, alternate, and planned behavior. | `-p ` | SSH port (default: 22) | | `-v, --verbose` | Enable debug logging | | `--progress` | Show real-time transfer speed | +| `-P` | Alias for `--partial --progress` | | `--delete` | Delete files on receiver not present in source | | `--exclude ` | Exclude files matching glob pattern (repeatable) | | `--exclude-from ` | Read exclude patterns from a file (one per line) | diff --git a/RSYNC_COMPAT.md b/RSYNC_COMPAT.md index 4b236ec..62018ef 100644 --- a/RSYNC_COMPAT.md +++ b/RSYNC_COMPAT.md @@ -6,10 +6,10 @@ This document maps rsync's full feature set to FastSync's current implementation | Status | Count | Description | |--------|-------|-------------| -| ✅ Implemented | 34 | Feature works end-to-end | +| ✅ Implemented | 35 | Feature works end-to-end | | 🔀 Alt Arg | 3 | Functionality exists but under different flag/semantics | | ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete | -| ❌ Not Implemented | 98 | Flag not recognized or no behavior | +| ❌ Not Implemented | 97 | Flag not recognized or no behavior | | **Total** | **136** | | --- @@ -39,7 +39,7 @@ This document maps rsync's full feature set to FastSync's current implementation | `-h`, `--human-readable` | Human-readable numbers | ❌ Not Implemented | Removed because it had no effect | | `-i`, `--itemize-changes` | Per-file change summary | ❌ Not Implemented | Removed because it had no effect | | `--progress` | Show progress | ✅ Implemented | Progress callback in sender | -| `-P` | Same as --partial --progress | ❌ Not Implemented | | +| `-P` | Same as --partial --progress | ✅ Implemented | Enables both existing `--partial` and `--progress` behavior | | `--out-format=FORMAT` | Custom output format | ❌ Not Implemented | Removed because it had no effect | | `--log-file=FILE` | Log to file | ✅ Implemented | `log_file` config field | | `--log-file-format=FMT` | Log format | ❌ Not Implemented | | diff --git a/src/client/client_cli.c b/src/client/client_cli.c index 191cc07..672bd76 100644 --- a/src/client/client_cli.c +++ b/src/client/client_cli.c @@ -211,6 +211,12 @@ static int apply_table_option(Config* config, const OptionEntry* entry, const ch int parse_args(Config* config, int argc, char* argv[], int* positional_args, int* positional_count) { for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-P") == 0) { + config->partial = true; + config->show_progress = true; + continue; + } + const OptionEntry* entry = find_table_option(argv[i]); if (entry) { if (entry->kind != OPT_FLAG) { diff --git a/src/client/usage.c b/src/client/usage.c index 2f800af..746ee5c 100644 --- a/src/client/usage.c +++ b/src/client/usage.c @@ -20,6 +20,7 @@ void print_usage(void) { printf(" -n, --dry-run Show what would be transferred\n"); printf(" -p SSH port (default: 22)\n"); printf(" --progress Show transfer progress\n"); + printf(" -P Alias for --partial --progress\n"); printf(" --delete Delete files on receiver not in source\n"); printf(" --exclude Exclude files matching pattern\n"); printf(" --include Only include files matching pattern\n"); diff --git a/tests/test_client_cli.c b/tests/test_client_cli.c index 656fd40..c43b07a 100644 --- a/tests/test_client_cli.c +++ b/tests/test_client_cli.c @@ -339,6 +339,22 @@ static void test_parse_args_archive() { config_delete(cfg); } +/* Test rsync-compatible -P enables both partial files and progress output. */ +static void test_parse_args_partial_progress() { + Config* cfg = config_create(); + char* argv[] = {"fastsync", "-P", "/src", "/dst"}; + int positional_args[2]; + int positional_count = 0; + + int ret = parse_args(cfg, 4, argv, positional_args, &positional_count); + EXPECT_EQ_INT(ret, 0); + EXPECT_TRUE(cfg->partial); + EXPECT_TRUE(cfg->show_progress); + EXPECT_EQ_INT(positional_count, 2); + + config_delete(cfg); +} + void test_client_cli() { test_validate_config_required_paths(); test_validate_config_incompatible_options(); @@ -360,4 +376,5 @@ void test_client_cli() { test_parse_args_unknown_option(); test_parse_args_rejects_unimplemented_options(); test_parse_args_archive(); + test_parse_args_partial_progress(); } From f8291d895dd0ae23eed3bf75bac67a06878fdabd Mon Sep 17 00:00:00 2001 From: TapTap Date: Thu, 3 Sep 2026 21:40:07 +0200 Subject: [PATCH 2/2] fix: classify partial progress as incomplete --- README.md | 7 ++++--- RSYNC_COMPAT.md | 6 +++--- src/client/usage.c | 6 +++--- tests/test_client_cli.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f8ec2c6..51cbd3f 100644 --- a/README.md +++ b/README.md @@ -66,8 +66,9 @@ replacement for every rsync feature or protocol mode. - Owner/group, ACL, xattr, hard-link, device, and special-file handling is incomplete or unavailable. - Sparse-file handling does not yet preserve all holes correctly. -- `--partial`, `--partial-dir`, `--append`, and `--append-verify` are not yet - full rsync-style resumable transfers. +- `--partial`, `--partial-dir`, `-P`, `--append`, and `--append-verify` are not + yet full rsync-style resumable transfers. Interrupted files are not retained + for resumption. - Several rsync short options currently have FastSync-specific meanings. Do not assume every short option is interchangeable yet. @@ -95,7 +96,7 @@ partial, alternate, and planned behavior. | `-p ` | SSH port (default: 22) | | `-v, --verbose` | Enable debug logging | | `--progress` | Show real-time transfer speed | -| `-P` | Alias for `--partial --progress` | +| `-P` | Enables partial-transfer mode and progress output (partial retention is incomplete) | | `--delete` | Delete files on receiver not present in source | | `--exclude ` | Exclude files matching glob pattern (repeatable) | | `--exclude-from ` | Read exclude patterns from a file (one per line) | diff --git a/RSYNC_COMPAT.md b/RSYNC_COMPAT.md index 62018ef..da5a064 100644 --- a/RSYNC_COMPAT.md +++ b/RSYNC_COMPAT.md @@ -6,9 +6,9 @@ This document maps rsync's full feature set to FastSync's current implementation | Status | Count | Description | |--------|-------|-------------| -| ✅ Implemented | 35 | Feature works end-to-end | +| ✅ Implemented | 34 | Feature works end-to-end | | 🔀 Alt Arg | 3 | Functionality exists but under different flag/semantics | -| ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete | +| ⚠️ Partial | 2 | Flag parsed/stored but behavior incomplete | | ❌ Not Implemented | 97 | Flag not recognized or no behavior | | **Total** | **136** | | @@ -39,7 +39,7 @@ This document maps rsync's full feature set to FastSync's current implementation | `-h`, `--human-readable` | Human-readable numbers | ❌ Not Implemented | Removed because it had no effect | | `-i`, `--itemize-changes` | Per-file change summary | ❌ Not Implemented | Removed because it had no effect | | `--progress` | Show progress | ✅ Implemented | Progress callback in sender | -| `-P` | Same as --partial --progress | ✅ Implemented | Enables both existing `--partial` and `--progress` behavior | +| `-P` | Same as --partial --progress | ⚠️ Partial | Parses and enables progress, but interrupted files are not retained for resumable transfers | | `--out-format=FORMAT` | Custom output format | ❌ Not Implemented | Removed because it had no effect | | `--log-file=FILE` | Log to file | ✅ Implemented | `log_file` config field | | `--log-file-format=FMT` | Log format | ❌ Not Implemented | | diff --git a/src/client/usage.c b/src/client/usage.c index 746ee5c..55467af 100644 --- a/src/client/usage.c +++ b/src/client/usage.c @@ -20,7 +20,7 @@ void print_usage(void) { printf(" -n, --dry-run Show what would be transferred\n"); printf(" -p SSH port (default: 22)\n"); printf(" --progress Show transfer progress\n"); - printf(" -P Alias for --partial --progress\n"); + printf(" -P Partial mode with progress (retention incomplete)\n"); printf(" --delete Delete files on receiver not in source\n"); printf(" --exclude Exclude files matching pattern\n"); printf(" --include Only include files matching pattern\n"); @@ -59,8 +59,8 @@ void print_usage(void) { printf(" --stats Print transfer statistics at end\n"); printf(" --max-depth Maximum directory depth (0=unlimited)\n"); printf(" --log-file Write log messages to file\n"); - printf(" --partial Keep partial files on interrupted transfer\n"); - printf(" --partial-dir Directory for partial files\n"); + printf(" --partial Use partial-transfer mode (retention incomplete)\n"); + printf(" --partial-dir Use a separate partial-transfer directory\n"); printf(" --fastsync-server-path \n"); printf(" Path to fastsync-server on remote (default: fastsync-server)\n"); printf(" -l, --links Copy symlinks as symlinks\n"); diff --git a/tests/test_client_cli.c b/tests/test_client_cli.c index c43b07a..24cbec9 100644 --- a/tests/test_client_cli.c +++ b/tests/test_client_cli.c @@ -339,7 +339,7 @@ static void test_parse_args_archive() { config_delete(cfg); } -/* Test rsync-compatible -P enables both partial files and progress output. */ +/* Test rsync-compatible -P parsing; resumable partial-file retention is not implied. */ static void test_parse_args_partial_progress() { Config* cfg = config_create(); char* argv[] = {"fastsync", "-P", "/src", "/dst"};