diff --git a/AGENTS.md b/AGENTS.md index 2de078f..f4b4d6f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -278,10 +278,30 @@ Two helper functions in `newServer.go` handle context cancellation during stream - **Regular files**: streamed into tar archive with content - **Directories**: included as tar directory entries - **Symlinks**: stored as symlink entries (target path preserved). Backer never resolves or follows symlinks during directory traversal — it uses `os.Lstat` and `filepath.WalkDir` which do not follow symlinks. This means symlink cycles are impossible to occur. +- **Broken symlinks**: archived with their target path (even if target doesn't exist) - **Device files** (char/block): included with correct major/minor -- **Named pipes**: included (header only, no data) +- **Named pipes (FIFOs)**: included (header only, no data) - **Sockets**: skipped (not archivable) - **Hard links**: deduplicated — if multiple files share the same inode, only the first is stored with content, subsequent hard links are stored as link entries pointing to the original +- **GNU tar format**: archives use GNU tar format (`header.Format = tar.FormatGNU`) for compatibility with GNU tar utility + +### Archive Test Coverage + +All entity types are tested in `internal/backer/utils_test.go`: + +| Entity Type | Test Function | +|------------|---------------| +| Regular file | `TestCreateTarGzStreamBasic` | +| Empty file | `TestCreateTarGzStreamEmptyFile` | +| Directory | `TestCreateTarGzStreamDirectory` | +| Symlink | `TestCreateTarGzStreamSymlink` | +| Broken symlink | `TestCreateTarGzStreamBrokenSymlink` | +| Symlink to directory | `TestCreateTarGzStreamSymlinkToDirectory` | +| Hard link | `TestCreateTarGzStreamHardLink` | +| Character device | `TestCreateTarGzStreamDeviceFile` (falls back to char device) | +| Named pipe (FIFO) | `TestCreateTarGzStreamNamedPipe` | +| Special characters in names | `TestCreateTarGzStreamSpecialCharacters` | +| Nested files | `TestCreateTarGzStreamNestedFiles` | ### Pipe Error Recovery diff --git a/llms.txt b/llms.txt index f0cb2f1..c61b593 100644 --- a/llms.txt +++ b/llms.txt @@ -133,12 +133,18 @@ Skips files that can't be read (logs warning, continues backup). Backup filenames include timestamp and configured prefix: `backup-20060102-150405.tar.gz` (extension depends on compression_algorithm). ### Special File Types -- **Device files** (character/block) are included with correct major/minor numbers. -- **Sockets** are skipped (no entry created). -- **Symlinks** are stored as symlinks (target path stored) - uses os.Lstat, no cycles possible. -- **Named pipes** and other special files are included (tar header created). -- **Hard links** are deduplicated - first occurrence stored with content, subsequent as link entries. -- **Regular files** are compressed; other file types have no data section. +- **Regular files**: streamed into tar archive with content +- **Directories**: included as tar directory entries +- **Symlinks**: stored as symlink entries (target path preserved) - uses os.Lstat, no cycles possible +- **Broken symlinks**: archived with their target path (even if target doesn't exist) +- **Device files** (char/block): included with correct major/minor numbers +- **Named pipes (FIFOs)**: included (header only, no data) +- **Sockets**: skipped (not archivable) +- **Hard links**: deduplicated - first occurrence stored with content, subsequent as link entries +- **GNU tar format**: uses `header.Format = tar.FormatGNU` for GNU tar compatibility + +### Test Coverage +All entity types are tested: regular files, empty files, directories, symlinks, broken symlinks, symlinks to directories, hard links, device files, named pipes (FIFOs), special characters in filenames. ### Error Recovery - `writeWithContext` checks context before calling fn.