1
0
Fork 0

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:
Andrew Tomaka 2025-06-12 22:39:32 -04:00
parent 814e0650de
commit 64a2bbace4
3 changed files with 49 additions and 12 deletions

View file

@ -18,21 +18,24 @@ type FileEntry struct {
type Collector struct {
matcher Matcher
dirFilter DirectoryFilter
verbose bool
}
// New creates a new collector with the specified matcher
func New(matcher Matcher) *Collector {
func New(matcher Matcher, verbose bool) *Collector {
return &Collector{
matcher: matcher,
dirFilter: nil,
verbose: verbose,
}
}
// 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{
matcher: matcher,
dirFilter: dirFilter,
verbose: verbose,
}
}
@ -98,6 +101,11 @@ func (c *Collector) Collect(sourceDir string) ([]FileEntry, error) {
// Clean the relative path to ensure consistent formatting
relPath = filepath.ToSlash(relPath)
// Show verbose output when file is found
if c.verbose {
fmt.Printf("found: %s\n", relPath)
}
files = append(files, FileEntry{
Path: relPath,
FullPath: path,

View file

@ -36,11 +36,13 @@ func main() {
var matchFlags stringSlice
var includeDirFlags stringSlice
var excludeDirFlags stringSlice
var verbose 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")
// Custom usage message
flag.Usage = func() {
@ -125,10 +127,11 @@ func main() {
// Create collector and collect files
var c *collector.Collector
if dirFilter != nil {
c = collector.NewWithDirectoryFilter(matcher, dirFilter)
c = collector.NewWithDirectoryFilter(matcher, dirFilter, verbose)
} else {
c = collector.New(matcher)
c = collector.New(matcher, verbose)
}
files, err := c.Collect(sourceDir)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)

42
test.sh
View file

@ -27,15 +27,15 @@ run_test() {
local test_name="$1"
local command="$2"
local expected_exit_code="${3:-0}"
echo -n "Testing $test_name... "
# Run command and capture exit code
set +e
eval "$command" > /tmp/test_output.txt 2>&1
local exit_code=$?
set -e
if [ $exit_code -eq $expected_exit_code ]; then
echo -e "${GREEN}PASSED${NC}"
((TESTS_PASSED++))
@ -54,9 +54,9 @@ run_test() {
verify_archive_contents() {
local archive="$1"
local expected_files="$2"
echo -n " Verifying contents of $archive... "
if [[ "$archive" == *.tgz || "$archive" == *.tar.gz ]]; then
actual_files=$(tar -tzf "$archive" | sort | tr '\n' ' ' | sed 's/ $//')
elif [[ "$archive" == *.zip ]]; then
@ -65,9 +65,9 @@ verify_archive_contents() {
echo -e "${RED}Unknown archive format${NC}"
return 1
fi
expected_sorted=$(echo "$expected_files" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//')
if [ "$actual_files" = "$expected_sorted" ]; then
echo -e "${GREEN}OK${NC}"
return 0
@ -79,6 +79,24 @@ verify_archive_contents() {
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"
# 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"
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
echo -e "\n${YELLOW}=== Test Summary ===${NC}"
echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"
@ -234,4 +260,4 @@ if [ $TESTS_FAILED -eq 0 ]; then
else
echo -e "\n${RED}Some tests failed!${NC}"
exit 1
fi
fi