fix: complete quiet option handling
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 34s
CI / lint (pull_request) Successful in 11s
CI / sanitizers (address) (pull_request) Successful in 37s
CI / sanitizers (undefined) (pull_request) Successful in 36s
CI / fuzz-build (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 31s
CI / build-and-test (pull_request) Successful in 1m15s
CI / valgrind (pull_request) Successful in 34s
This commit is contained in:
+2
-2
@@ -6,11 +6,11 @@ This document maps rsync's full feature set to FastSync's current implementation
|
|||||||
|
|
||||||
| Status | Count | Description |
|
| 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 |
|
| 🔀 Alt Arg | 3 | Functionality exists but under different flag/semantics |
|
||||||
| ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete |
|
| ⚠️ Partial | 1 | Flag parsed/stored but behavior incomplete |
|
||||||
| ❌ Not Implemented | 98 | Flag not recognized or no behavior |
|
| ❌ Not Implemented | 98 | Flag not recognized or no behavior |
|
||||||
| **Total** | **136** | |
|
| **Total** | **137** | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ static int apply_table_option(Config* config, const OptionEntry* entry, const ch
|
|||||||
/* Parse CLI arguments into config. Returns 0 on success, -1 on error, 1 for help/clean-exit. */
|
/* Parse CLI arguments into config. Returns 0 on success, -1 on error, 1 for help/clean-exit. */
|
||||||
int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
||||||
int* positional_count) {
|
int* positional_count) {
|
||||||
|
bool verbose = false;
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
const OptionEntry* entry = find_table_option(argv[i]);
|
const OptionEntry* entry = find_table_option(argv[i]);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
@@ -350,10 +351,9 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
0)
|
0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if (opt_is(argv[i], "-v", "--verbose")) {
|
} else if (opt_is(argv[i], "-v", "--verbose")) {
|
||||||
set_log_level(LOG_LEVEL_DEBUG);
|
verbose = true;
|
||||||
} else if (opt_is(argv[i], "-q", "--quiet")) {
|
} else if (opt_is(argv[i], "-q", "--quiet")) {
|
||||||
config->quiet = true;
|
config->quiet = true;
|
||||||
set_log_level(LOG_LEVEL_ERROR);
|
|
||||||
} else if (opt_is(argv[i], "-T", NULL) && i + 1 < argc) {
|
} else if (opt_is(argv[i], "-T", NULL) && i + 1 < argc) {
|
||||||
if (set_positive_int_option(&config->timeout, argv[++i], "-T") != 0)
|
if (set_positive_int_option(&config->timeout, argv[++i], "-T") != 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -378,6 +378,7 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_log_level(config->quiet ? LOG_LEVEL_ERROR : (verbose ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ void print_usage(void) {
|
|||||||
printf(" -s Enable chunk serialization\n");
|
printf(" -s Enable chunk serialization\n");
|
||||||
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
printf(" -f Enable sendfile (TCP only, not with -c or -s)\n");
|
||||||
printf(" -v, --verbose Enable debug logging\n");
|
printf(" -v, --verbose Enable debug logging\n");
|
||||||
printf(" -q, --quiet Suppress non-error output\n");
|
printf(" -q, --quiet Suppress non-error output\n");
|
||||||
printf(" -M, --preserve Preserve file metadata\n");
|
printf(" -M, --preserve Preserve file metadata\n");
|
||||||
printf(" --chunk-size <n> Chunk size in bytes (default: %d)\n", DEFAULT_CHUNK_SIZE);
|
printf(" --chunk-size <n> Chunk size in bytes (default: %d)\n", DEFAULT_CHUNK_SIZE);
|
||||||
printf(" --source-dir <path> Source directory\n");
|
printf(" --source-dir <path> Source directory\n");
|
||||||
|
|||||||
@@ -52,6 +52,22 @@ class TestDryRun:
|
|||||||
assert result.returncode != 0
|
assert result.returncode != 0
|
||||||
assert result.stderr != ""
|
assert result.stderr != ""
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("flags", [["-q", "-v"], ["-v", "-q"]])
|
||||||
|
def test_quiet_successful_transfer_and_verbose_order(self, shared_server, flags):
|
||||||
|
clean_dir(DEST_DIR)
|
||||||
|
result, dur = run_client(
|
||||||
|
SOURCE_DIR, DEST_DIR,
|
||||||
|
flags=flags,
|
||||||
|
port=shared_server.port,
|
||||||
|
)
|
||||||
|
assert result.returncode == 0, f"Exit {result.returncode}: {result.stderr[:100]}"
|
||||||
|
assert result.stdout == ""
|
||||||
|
assert result.stderr == ""
|
||||||
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
|
assert not missing, f"Missing: {missing}"
|
||||||
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
|
|
||||||
class TestArchiveMode:
|
class TestArchiveMode:
|
||||||
def test_archive_mode(self, shared_server):
|
def test_archive_mode(self, shared_server):
|
||||||
|
|||||||
@@ -321,16 +321,17 @@ static void test_parse_args_rejects_unimplemented_options() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test both rsync-compatible quiet spellings. */
|
/* Test both rsync-compatible quiet spellings and option ordering. */
|
||||||
static void test_parse_args_quiet() {
|
static void test_parse_args_quiet() {
|
||||||
static const char* const options[] = {"-q", "--quiet"};
|
static const char* const options[][2] = {
|
||||||
|
{"-q", "-v"}, {"-v", "-q"}, {"--quiet", "-v"}, {"-v", "--quiet"}};
|
||||||
for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
for (size_t i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
||||||
Config* cfg = config_create();
|
Config* cfg = config_create();
|
||||||
char* argv[] = {"fastsync", (char*)options[i], "/src", "/dst"};
|
char* argv[] = {"fastsync", (char*)options[i][0], (char*)options[i][1], "/src", "/dst"};
|
||||||
int positional_args[2];
|
int positional_args[2];
|
||||||
int positional_count = 0;
|
int positional_count = 0;
|
||||||
|
|
||||||
EXPECT_EQ_INT(parse_args(cfg, 4, argv, positional_args, &positional_count), 0);
|
EXPECT_EQ_INT(parse_args(cfg, 5, argv, positional_args, &positional_count), 0);
|
||||||
EXPECT_TRUE(cfg->quiet);
|
EXPECT_TRUE(cfg->quiet);
|
||||||
config_delete(cfg);
|
config_delete(cfg);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user