Add --verbose flag for real-time file discovery feedback
Implement verbose mode that shows files as they are discovered during collection rather than just a summary. This provides better user feedback during the typically slow filesystem traversal phase. Features: - Real-time "found: filename" output as files are discovered - Verbose feedback during collection phase (not archiving phase) - Simple, focused output that shows filtering effects - Helps users track progress during potentially slow operations Changes: - Add --verbose boolean flag to CLI - Pass verbose flag to collector constructors - Display "found: filename" output during file collection - Add test case to verify verbose output contains expected messages - Update test suite with helper function to verify output contents
This commit is contained in:
parent
814e0650de
commit
64a2bbace4
3 changed files with 49 additions and 12 deletions
|
@ -18,21 +18,24 @@ type FileEntry struct {
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
matcher Matcher
|
matcher Matcher
|
||||||
dirFilter DirectoryFilter
|
dirFilter DirectoryFilter
|
||||||
|
verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new collector with the specified matcher
|
// New creates a new collector with the specified matcher
|
||||||
func New(matcher Matcher) *Collector {
|
func New(matcher Matcher, verbose bool) *Collector {
|
||||||
return &Collector{
|
return &Collector{
|
||||||
matcher: matcher,
|
matcher: matcher,
|
||||||
dirFilter: nil,
|
dirFilter: nil,
|
||||||
|
verbose: verbose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithDirectoryFilter creates a new collector with the specified matcher and directory filter
|
// NewWithDirectoryFilter creates a new collector with the specified matcher and directory filter
|
||||||
func NewWithDirectoryFilter(matcher Matcher, dirFilter DirectoryFilter) *Collector {
|
func NewWithDirectoryFilter(matcher Matcher, dirFilter DirectoryFilter, verbose bool) *Collector {
|
||||||
return &Collector{
|
return &Collector{
|
||||||
matcher: matcher,
|
matcher: matcher,
|
||||||
dirFilter: dirFilter,
|
dirFilter: dirFilter,
|
||||||
|
verbose: verbose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +101,11 @@ func (c *Collector) Collect(sourceDir string) ([]FileEntry, error) {
|
||||||
// Clean the relative path to ensure consistent formatting
|
// Clean the relative path to ensure consistent formatting
|
||||||
relPath = filepath.ToSlash(relPath)
|
relPath = filepath.ToSlash(relPath)
|
||||||
|
|
||||||
|
// Show verbose output when file is found
|
||||||
|
if c.verbose {
|
||||||
|
fmt.Printf("found: %s\n", relPath)
|
||||||
|
}
|
||||||
|
|
||||||
files = append(files, FileEntry{
|
files = append(files, FileEntry{
|
||||||
Path: relPath,
|
Path: relPath,
|
||||||
FullPath: path,
|
FullPath: path,
|
||||||
|
|
7
main.go
7
main.go
|
@ -36,11 +36,13 @@ func main() {
|
||||||
var matchFlags stringSlice
|
var matchFlags stringSlice
|
||||||
var includeDirFlags stringSlice
|
var includeDirFlags stringSlice
|
||||||
var excludeDirFlags stringSlice
|
var excludeDirFlags stringSlice
|
||||||
|
var verbose bool
|
||||||
|
|
||||||
flag.Var(&nameFlags, "name", "Match exact filename (can be specified multiple times)")
|
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(&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(&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.Var(&excludeDirFlags, "exclude-dir", "Skip directories matching pattern (can be specified multiple times)")
|
||||||
|
flag.BoolVar(&verbose, "verbose", false, "Enable verbose output for debugging")
|
||||||
|
|
||||||
// Custom usage message
|
// Custom usage message
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
|
@ -125,10 +127,11 @@ func main() {
|
||||||
// Create collector and collect files
|
// Create collector and collect files
|
||||||
var c *collector.Collector
|
var c *collector.Collector
|
||||||
if dirFilter != nil {
|
if dirFilter != nil {
|
||||||
c = collector.NewWithDirectoryFilter(matcher, dirFilter)
|
c = collector.NewWithDirectoryFilter(matcher, dirFilter, verbose)
|
||||||
} else {
|
} else {
|
||||||
c = collector.New(matcher)
|
c = collector.New(matcher, verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
files, err := c.Collect(sourceDir)
|
files, err := c.Collect(sourceDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||||
|
|
42
test.sh
42
test.sh
|
@ -27,15 +27,15 @@ run_test() {
|
||||||
local test_name="$1"
|
local test_name="$1"
|
||||||
local command="$2"
|
local command="$2"
|
||||||
local expected_exit_code="${3:-0}"
|
local expected_exit_code="${3:-0}"
|
||||||
|
|
||||||
echo -n "Testing $test_name... "
|
echo -n "Testing $test_name... "
|
||||||
|
|
||||||
# Run command and capture exit code
|
# Run command and capture exit code
|
||||||
set +e
|
set +e
|
||||||
eval "$command" > /tmp/test_output.txt 2>&1
|
eval "$command" > /tmp/test_output.txt 2>&1
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ $exit_code -eq $expected_exit_code ]; then
|
if [ $exit_code -eq $expected_exit_code ]; then
|
||||||
echo -e "${GREEN}PASSED${NC}"
|
echo -e "${GREEN}PASSED${NC}"
|
||||||
((TESTS_PASSED++))
|
((TESTS_PASSED++))
|
||||||
|
@ -54,9 +54,9 @@ run_test() {
|
||||||
verify_archive_contents() {
|
verify_archive_contents() {
|
||||||
local archive="$1"
|
local archive="$1"
|
||||||
local expected_files="$2"
|
local expected_files="$2"
|
||||||
|
|
||||||
echo -n " Verifying contents of $archive... "
|
echo -n " Verifying contents of $archive... "
|
||||||
|
|
||||||
if [[ "$archive" == *.tgz || "$archive" == *.tar.gz ]]; then
|
if [[ "$archive" == *.tgz || "$archive" == *.tar.gz ]]; then
|
||||||
actual_files=$(tar -tzf "$archive" | sort | tr '\n' ' ' | sed 's/ $//')
|
actual_files=$(tar -tzf "$archive" | sort | tr '\n' ' ' | sed 's/ $//')
|
||||||
elif [[ "$archive" == *.zip ]]; then
|
elif [[ "$archive" == *.zip ]]; then
|
||||||
|
@ -65,9 +65,9 @@ verify_archive_contents() {
|
||||||
echo -e "${RED}Unknown archive format${NC}"
|
echo -e "${RED}Unknown archive format${NC}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
expected_sorted=$(echo "$expected_files" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//')
|
expected_sorted=$(echo "$expected_files" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//')
|
||||||
|
|
||||||
if [ "$actual_files" = "$expected_sorted" ]; then
|
if [ "$actual_files" = "$expected_sorted" ]; then
|
||||||
echo -e "${GREEN}OK${NC}"
|
echo -e "${GREEN}OK${NC}"
|
||||||
return 0
|
return 0
|
||||||
|
@ -79,6 +79,24 @@ verify_archive_contents() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function to verify command output contains expected text
|
||||||
|
verify_output_contains() {
|
||||||
|
local expected_text="$1"
|
||||||
|
|
||||||
|
echo -n " Verifying output contains '$expected_text'... "
|
||||||
|
|
||||||
|
if grep -q "$expected_text" /tmp/test_output.txt; then
|
||||||
|
echo -e "${GREEN}OK${NC}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}FAILED${NC}"
|
||||||
|
echo " Expected to find: $expected_text"
|
||||||
|
echo " In output:"
|
||||||
|
cat /tmp/test_output.txt | sed 's/^/ /'
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
echo -e "${YELLOW}=== Collect CLI Test Suite ===${NC}\n"
|
echo -e "${YELLOW}=== Collect CLI Test Suite ===${NC}\n"
|
||||||
|
|
||||||
# Clean up any previous test artifacts
|
# Clean up any previous test artifacts
|
||||||
|
@ -223,6 +241,14 @@ run_test "combined include and exclude filters" \
|
||||||
"./collect --include-dir 'project-*' --exclude-dir 'project-two' --name 'app.go' --name 'lib.go' test/ test-include-exclude.tgz"
|
"./collect --include-dir 'project-*' --exclude-dir 'project-two' --name 'app.go' --name 'lib.go' test/ test-include-exclude.tgz"
|
||||||
verify_archive_contents "test-include-exclude.tgz" "project-one/src/app.go"
|
verify_archive_contents "test-include-exclude.tgz" "project-one/src/app.go"
|
||||||
|
|
||||||
|
# Test 22: Verbose output shows files being found
|
||||||
|
run_test "verbose output shows files being found" \
|
||||||
|
"./collect --verbose --name 'README.md' --name 'main.go' test/ test-verbose.tgz"
|
||||||
|
verify_archive_contents "test-verbose.tgz" "README.md docs/README.md src/main.go"
|
||||||
|
verify_output_contains "found: README.md"
|
||||||
|
verify_output_contains "found: docs/README.md"
|
||||||
|
verify_output_contains "found: src/main.go"
|
||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
echo -e "\n${YELLOW}=== Test Summary ===${NC}"
|
echo -e "\n${YELLOW}=== Test Summary ===${NC}"
|
||||||
echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"
|
echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"
|
||||||
|
@ -234,4 +260,4 @@ if [ $TESTS_FAILED -eq 0 ]; then
|
||||||
else
|
else
|
||||||
echo -e "\n${RED}Some tests failed!${NC}"
|
echo -e "\n${RED}Some tests failed!${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Add table
Reference in a new issue