2.9 KiB
2.9 KiB
Implementation Plan for Collect CLI Tool
Overview
A CLI tool that collects files recursively matching specific criteria, maintains their file structure, and archives them for backup purposes.
Language Choice: Go
- Single binary distribution
- Built-in archive support (tar/gzip and zip)
- Excellent file system traversal capabilities
- Cross-platform compatibility
- No runtime dependencies
Behavior Specifications
CLI Interface
collect [--name <filename> | --match <pattern>] <source-dir> <output-archive>
Flags
--name
: Match exact filename (e.g.,--name .mise.toml
)--match
: Match directory pattern, collect all files within (e.g.,--match aet-*/
)- Flags are mutually exclusive
File Collection
- Name matching: Find all files with exact filename match anywhere in tree
- Pattern matching: Find directories matching glob pattern, then collect all files recursively within those directories
- Symlinks are ignored
- Preserve relative paths from source directory in archive
Archive Format
- Determined by output file extension
- Supported:
.tar.gz
,.tgz
,.zip
Error Handling
- Permission errors: Log warning to stderr, skip file, continue
- No files found: Exit with code 1 and error message
- Archive creation failure: Exit with code 2
- Invalid arguments: Exit with code 3
- All errors reported to stderr
Architecture
Package Structure
collect/
├── main.go # CLI entry point and argument parsing
├── collector/
│ ├── collector.go # Core collection logic
│ └── matcher.go # File/directory matching logic
├── archiver/
│ ├── archiver.go # Archive interface
│ ├── tar.go # Tar/gzip implementation
│ └── zip.go # Zip implementation
└── go.mod # Go module definition
Core Interfaces
Collector
type Collector interface {
Collect(sourceDir string) ([]FileEntry, error)
}
type FileEntry struct {
Path string // Relative path from sourceDir
FullPath string // Absolute path for reading
}
Matcher
type Matcher interface {
ShouldInclude(path string, info os.FileInfo) bool
}
Archiver
type Archiver interface {
Create(outputPath string, files []FileEntry) error
}
Implementation Flow
- Parse and validate CLI arguments
- Create appropriate matcher (NameMatcher or PatternMatcher)
- Create collector with matcher
- Walk directory tree and collect matching files
- Check if any files were found (error if empty)
- Create appropriate archiver based on file extension
- Build archive with collected files
- Report any errors to stderr
Key Decisions
- Use
filepath.WalkDir
for efficient directory traversal - Clean all paths to ensure consistent relative paths
- Use buffered I/O for archive operations
- Pattern matching uses Go's
filepath.Match
function - Archive paths are relative to the search directory root