Compare commits
No commits in common. "6aa46041df77cc2e5c923c92150ec9d7e02760b7" and "3b4ee0af06cba2153e326ac5e890529530ba8232" have entirely different histories.
6aa46041df
...
3b4ee0af06
2 changed files with 0 additions and 337 deletions
153
prompt_plan.md
153
prompt_plan.md
|
|
@ -1,153 +0,0 @@
|
|||
# Phase 1: Core Tag Handling
|
||||
## Prompt 1: Tag Parsing/Validation Module
|
||||
```text
|
||||
Create a Rust module ```tag_engine``` with:
|
||||
1. Tag validation function ```validate_tag(tag: &str) -> Result<(), TagError>```
|
||||
- Checks for prohibited characters (NUL, :, /, space)
|
||||
- Validates tag is non-empty
|
||||
- Returns custom error variants
|
||||
2. Tag parsing function ```parse_tags(filename: &str) -> Result<(String, Vec<String>), ParseError>```
|
||||
- Splits filename into base name and tags using " -- " delimiter
|
||||
- Handles multiple delimiters as errors
|
||||
- Preserves file extension
|
||||
3. Unit tests covering:
|
||||
- Valid/invalid tags
|
||||
- Filename parsing edge cases
|
||||
- Error propagation
|
||||
```
|
||||
|
||||
## Prompt 2: Tag Serialization
|
||||
```text
|
||||
Extend ```tag_engine``` with:
|
||||
1. ```serialize_tags(base: &str, tags: &[String], ext: &str) -> String```
|
||||
- Combines base name, sorted tags, and extension
|
||||
- Uses " -- " delimiter only when tags exist
|
||||
- Maintains alphabetical tag order
|
||||
2. Unit tests for:
|
||||
- Roundtrip parsing/serialization
|
||||
- Empty tags handling
|
||||
- Extension preservation
|
||||
- Case sensitivity checks
|
||||
```
|
||||
|
||||
# Phase 2: Basic Commands
|
||||
## Prompt 3: List Command Implementation
|
||||
```text
|
||||
Implement ```list``` command:
|
||||
1. CLI argument parsing using clap
|
||||
2. Core logic:
|
||||
- Process each file through ```tag_engine::parse_tags```
|
||||
- Collect unique tags across all files
|
||||
- Output sorted tags line-by-line
|
||||
3. Unit tests for:
|
||||
- Multi-file tag aggregation
|
||||
- Empty input handling
|
||||
- Error propagation from tag engine
|
||||
```
|
||||
|
||||
## Prompt 4: Add Command Foundation
|
||||
```text
|
||||
Implement core of ```add``` command:
|
||||
1. Tag merging logic:
|
||||
- Combine existing and new tags
|
||||
- Remove duplicates while preserving order
|
||||
- Case-sensitive comparison
|
||||
2. Function signature:
|
||||
```fn add_tags(current: Vec<String>, new: Vec<String>) -> Vec<String>```
|
||||
3. Unit tests for:
|
||||
- Duplicate prevention
|
||||
- Order preservation
|
||||
- Case sensitivity
|
||||
```
|
||||
|
||||
## Prompt 5: Complete Add Command
|
||||
```text
|
||||
Wire up ```add``` command:
|
||||
1. File processing loop:
|
||||
- Parse existing tags
|
||||
- Merge with new tags
|
||||
- Serialize new filename
|
||||
- Atomic rename operation
|
||||
2. Error handling:
|
||||
- Clean error messages
|
||||
- Early exit on first error
|
||||
3. Integration tests:
|
||||
- Actual file renaming
|
||||
- Permission handling
|
||||
- Cross-platform path handling
|
||||
```
|
||||
|
||||
# Phase 3: Advanced Operations
|
||||
## Prompt 6: Remove Command Core
|
||||
```text
|
||||
Implement tag removal logic:
|
||||
1. Function ```filter_tags(current: Vec<String>, remove: &[String]) -> Vec<String>```
|
||||
- Remove all instances of specified tags
|
||||
- Maintain original order of remaining tags
|
||||
2. Unit tests for:
|
||||
- Multi-tag removal
|
||||
- Non-existent tag handling
|
||||
- Empty result handling
|
||||
```
|
||||
|
||||
## Prompt 7: Tree Command Structure
|
||||
```text
|
||||
Implement tree directory builder:
|
||||
1. Function ```create_tag_combinations(tags: &[String], depth: usize) -> Vec<Vec<String>>```
|
||||
- Generate all unique permutations up to specified depth
|
||||
- Maintain alphabetical order in paths
|
||||
2. Unit tests for:
|
||||
- Depth limiting
|
||||
- Combination validity
|
||||
- Order preservation
|
||||
```
|
||||
|
||||
## Prompt 8: Symlink Management
|
||||
```text
|
||||
Create symlink helper module:
|
||||
1. Function ```create_symlink_tree(paths: Vec<PathBuf>, target_dir: &Path) -> Result<()>```
|
||||
- Creates all required directories
|
||||
- Atomic symlink creation
|
||||
- Cross-platform compatibility stubs
|
||||
2. Error handling:
|
||||
- Clean path in error messages
|
||||
- Permission checks
|
||||
3. Unit tests for:
|
||||
- Directory structure validation
|
||||
- Symlink safety checks
|
||||
```
|
||||
|
||||
# Phase 4: Error Handling
|
||||
## Prompt 9: Error Type Unification
|
||||
```text
|
||||
Create unified error type:
|
||||
1. Enum ```FileTagsError``` with variants for all error cases
|
||||
2. Implement ```From``` traits for IO/parsing errors
|
||||
3. Consistent error formatting:
|
||||
- Machine-readable when needed
|
||||
- User-friendly messages
|
||||
4. Unit tests for error propagation
|
||||
```
|
||||
|
||||
# Phase 5: Final Integration
|
||||
## Prompt 10: CLI Wiring
|
||||
```text
|
||||
Integrate all components:
|
||||
1. Complete command implementations
|
||||
2. Add proper error handling
|
||||
3. Configure --help output
|
||||
4. Final integration tests:
|
||||
- All commands together
|
||||
- Cross-command file operations
|
||||
- Stress tests with large filesets
|
||||
```
|
||||
|
||||
# Phase 6: Optimization
|
||||
## Prompt 11: Performance Pass
|
||||
```text
|
||||
Optimize hot paths:
|
||||
1. Zero-copy parsing where possible
|
||||
2. Preallocate buffers
|
||||
3. Lazy evaluation of expensive operations
|
||||
4. Benchmarks for critical operations
|
||||
5. Unit test preservation
|
||||
184
spec.md
184
spec.md
|
|
@ -1,184 +0,0 @@
|
|||
# filetags-rs Technical Specification
|
||||
|
||||
## Overview
|
||||
filetags-rs is a command-line tool written in Rust for managing tags in file and directory names. Tags are embedded directly in filenames using a specific delimiter pattern.
|
||||
|
||||
## Core Constants
|
||||
- Tag delimiter: " -- " (space, double dash, space)
|
||||
- Tag separator: " " (single space)
|
||||
- Default tree depth: 3
|
||||
|
||||
## Tag Rules
|
||||
- Tags must be valid Unicode strings
|
||||
- Prohibited characters: NUL, ":", "/"
|
||||
- Tags cannot contain the tag separator (space)
|
||||
- Tags are stored in alphabetical order
|
||||
- Duplicate tags are preserved but not added again
|
||||
- Tags are case-sensitive
|
||||
|
||||
## Commands
|
||||
|
||||
### 1. List
|
||||
**Usage:** `filetags list <files...>`
|
||||
|
||||
**Behavior:**
|
||||
- Lists all unique tags found in the specified files
|
||||
- Output is just the tags themselves, one per line
|
||||
- No structural formatting (like JSON) is applied
|
||||
- Empty files (no tags) produce no output
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
$ filetags list "document -- tag1 tag2.pdf" "notes -- tag2 tag3.txt"
|
||||
tag1
|
||||
tag2
|
||||
tag3
|
||||
```
|
||||
|
||||
### 2. Add
|
||||
**Usage:** `filetags add --tag=<tag> [--tag=<tag>...] <files...>`
|
||||
|
||||
**Behavior:**
|
||||
- Adds specified tags to files
|
||||
- Merges with existing tags
|
||||
- Sorts all tags alphabetically
|
||||
- Ignores duplicate tags
|
||||
- Preserves the original file extension
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
$ filetags add --tag=work --tag=draft document.pdf
|
||||
# Result: document -- draft work.pdf
|
||||
```
|
||||
|
||||
### 3. Remove
|
||||
**Usage:** `filetags remove --tag=<tag> [--tag=<tag>...] <files...>`
|
||||
|
||||
**Behavior:**
|
||||
- Removes specified tags from files
|
||||
- Preserves remaining tags in alphabetical order
|
||||
- Silently ignores requests to remove non-existent tags
|
||||
- Preserves the original file extension
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
$ filetags remove --tag=draft "document -- draft work.pdf"
|
||||
# Result: document -- work.pdf
|
||||
```
|
||||
|
||||
### 4. Tree
|
||||
**Usage:** `filetags tree --dir=<directory> [--depth=<depth>] <files...>`
|
||||
|
||||
**Parameters:**
|
||||
- `--dir`: Target directory for creating the tree structure
|
||||
- `--depth`: Maximum depth of the tree (default: 3)
|
||||
|
||||
**Behavior:**
|
||||
- Creates a directory tree based on file tags
|
||||
- Creates symlinks at leaf nodes pointing to the original file
|
||||
- For files with no tags, creates only a root-level symlink
|
||||
- Creates all possible tag combinations up to specified depth
|
||||
- Maintains alphabetical order in path components
|
||||
|
||||
**Example:**
|
||||
For file "document -- tag1 tag2.pdf":
|
||||
```
|
||||
target_dir/
|
||||
├── document.pdf -> /path/to/document -- tag1 tag2.pdf
|
||||
├── tag1/
|
||||
│ ├── document.pdf -> /path/to/document -- tag1 tag2.pdf
|
||||
│ └── tag2/
|
||||
│ └── document.pdf -> /path/to/document -- tag1 tag2.pdf
|
||||
└── tag2/
|
||||
├── document.pdf -> /path/to/document -- tag1 tag2.pdf
|
||||
└── tag1/
|
||||
└── document.pdf -> /path/to/document -- tag1 tag2.pdf
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Validation Errors
|
||||
- Invalid characters in tags
|
||||
- Empty tags
|
||||
- Missing required arguments
|
||||
- Invalid depth value for tree command
|
||||
- Non-existent target directory
|
||||
|
||||
### Runtime Errors
|
||||
- File permission issues
|
||||
- Symlink creation failures
|
||||
- File reading/writing failures
|
||||
- Directory creation failures
|
||||
|
||||
All errors should:
|
||||
- Print clear error messages to stderr
|
||||
- Use appropriate error codes
|
||||
- Include the specific file/tag that caused the error
|
||||
- Exit with non-zero status
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
1. Tag validation
|
||||
- Character restrictions
|
||||
- Length restrictions
|
||||
- Delimiter handling
|
||||
- Separator handling
|
||||
|
||||
2. Tag operations
|
||||
- Adding tags
|
||||
- Removing tags
|
||||
- Sorting tags
|
||||
- Duplicate handling
|
||||
- Case sensitivity
|
||||
|
||||
3. Filename parsing
|
||||
- Splitting into base name and tags
|
||||
- Extension handling
|
||||
- Edge cases (no tags, multiple delimiters)
|
||||
|
||||
### Integration Tests
|
||||
1. Command execution
|
||||
- All commands with various combinations of arguments
|
||||
- Error cases
|
||||
- Edge cases
|
||||
|
||||
2. File system operations
|
||||
- File creation/modification
|
||||
- Directory operations
|
||||
- Symlink handling
|
||||
- Permission handling
|
||||
|
||||
3. Tree structure creation
|
||||
- Various depths
|
||||
- Different tag combinations
|
||||
- Edge cases (no tags, max depth)
|
||||
|
||||
### Property-Based Tests
|
||||
- Filename roundtrip (parse → modify → serialize)
|
||||
- Tag ordering invariants
|
||||
- Unicode handling
|
||||
- Path manipulation safety
|
||||
|
||||
## Performance Considerations
|
||||
- Efficient string manipulation for filename parsing
|
||||
- Minimal allocations in hot paths
|
||||
- Proper error type design to avoid allocations
|
||||
- Efficient directory traversal for tree command
|
||||
- Proper buffer sizes for file operations
|
||||
|
||||
## Security Considerations
|
||||
- Proper handling of symbolic links
|
||||
- Path traversal prevention
|
||||
- Proper permission checking
|
||||
- Safe handling of Unicode filenames
|
||||
- Proper escaping of special characters
|
||||
|
||||
## Future Considerations
|
||||
- Configurable delimiters
|
||||
- Tag hierarchies
|
||||
- Tag aliases
|
||||
- Case-insensitive option
|
||||
- Bulk operations
|
||||
- Regular expression support
|
||||
- Tag statistics and metadata
|
||||
Loading…
Add table
Add a link
Reference in a new issue