diff --git a/main.go b/main.go index 291e6a6..d08eab0 100644 --- a/main.go +++ b/main.go @@ -37,16 +37,18 @@ func main() { var includeDirFlags stringSlice var excludeDirFlags stringSlice var verbose bool + var dryRun bool flag.Var(&nameFlags, "name", "Match exact filename (can be specified multiple times)") flag.Var(&matchFlags, "match", "Match directory pattern (can be specified multiple times)") flag.Var(&includeDirFlags, "include-dir", "Only traverse directories matching pattern (can be specified multiple times)") flag.Var(&excludeDirFlags, "exclude-dir", "Skip directories matching pattern (can be specified multiple times)") flag.BoolVar(&verbose, "verbose", false, "Enable verbose output for debugging") + flag.BoolVar(&dryRun, "dry-run", false, "Show what files would be collected without creating archive") // Custom usage message flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s [--name ]... [--match ]... [--include-dir ]... [--exclude-dir ]... \n\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "Usage: %s [--name ]... [--match ]... [--include-dir ]... [--exclude-dir ]... [--dry-run] [--verbose] \n\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Collects files recursively matching specific criteria and archives them.\n\n") fmt.Fprintf(os.Stderr, "Options:\n") flag.PrintDefaults() @@ -55,6 +57,7 @@ func main() { fmt.Fprintf(os.Stderr, " %s --match 'aet-*/' ./ backup.zip\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s --name .mise.toml --name README.md --match 'test-*' ./ backup.tgz\n", os.Args[0]) fmt.Fprintf(os.Stderr, " %s --include-dir src --exclude-dir 'temp-*' --name '*.go' ./ backup.tgz\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " %s --dry-run --name .mise.toml ./ backup.tgz\n", os.Args[0]) } flag.Parse() @@ -77,11 +80,14 @@ func main() { sourceDir := args[0] outputPath := args[1] - // Determine archive format - format := collector.GetArchiveFormat(outputPath) - if format == "" { - fmt.Fprintf(os.Stderr, "Error: Unsupported archive format. Use .tar.gz, .tgz, or .zip\n") - os.Exit(exitInvalidArgs) + // Determine archive format (skip validation in dry-run mode) + var format string + if !dryRun { + format = collector.GetArchiveFormat(outputPath) + if format == "" { + fmt.Fprintf(os.Stderr, "Error: Unsupported archive format. Use .tar.gz, .tgz, or .zip\n") + os.Exit(exitInvalidArgs) + } } // Create matchers @@ -141,6 +147,17 @@ func main() { os.Exit(exitArchiveError) } + // Handle dry-run mode + if dryRun { + fmt.Printf("DRY RUN: Found %d files that would be collected:\n", len(files)) + for _, file := range files { + fmt.Printf(" %s\n", file.Path) + } + fmt.Printf("\nDRY RUN: Would create archive: %s\n", outputPath) + fmt.Printf("DRY RUN: No archive created (use without --dry-run to create archive)\n") + os.Exit(exitSuccess) + } + // Report number of files found fmt.Printf("Found %d files to archive\n", len(files)) diff --git a/test.sh b/test.sh index 9e49a23..23a4ee6 100755 --- a/test.sh +++ b/test.sh @@ -249,6 +249,37 @@ verify_output_contains "found: README.md" verify_output_contains "found: docs/README.md" verify_output_contains "found: src/main.go" +# Test 23: Dry-run shows files that would be collected without creating archive +run_test "dry-run shows files without creating archive" \ + "./collect --dry-run --name 'README.md' --name 'main.go' test/ test-dry-run.tgz" +verify_output_contains "DRY RUN: Found 3 files that would be collected:" +verify_output_contains " README.md" +verify_output_contains " docs/README.md" +verify_output_contains " src/main.go" +verify_output_contains "DRY RUN: Would create archive: test-dry-run.tgz" +verify_output_contains "DRY RUN: No archive created" + +# Verify that dry-run didn't actually create the archive +echo -n " Verifying no archive was created... " +if [ ! -f "test-dry-run.tgz" ]; then + echo -e "${GREEN}OK${NC}" +else + echo -e "${RED}FAILED${NC}" + echo " Archive was created when it shouldn't have been" + ((TESTS_FAILED++)) +fi + +# Test 24: Dry-run with verbose shows both found messages and dry-run output +run_test "dry-run with verbose shows comprehensive output" \ + "./collect --dry-run --verbose --name 'main.go' test/ test-dry-run-verbose.tgz" +verify_output_contains "found: src/main.go" +verify_output_contains "DRY RUN: Found 1 files that would be collected:" +verify_output_contains " src/main.go" + +# Test 25: Dry-run with no matching files +run_test "dry-run with no matching files" \ + "./collect --dry-run --name 'nonexistent.file' test/ test-dry-run-empty.tgz" 1 + # Summary echo -e "\n${YELLOW}=== Test Summary ===${NC}" echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"