| 397 | } |
| 398 | |
| 399 | func gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo, error) { |
| 400 | dirEntries, err := os.ReadDir(path) |
| 401 | if err != nil { |
| 402 | return nil, nil, EntryInfo{}, fmt.Errorf("failed to read directory: %w", err) |
| 403 | } |
| 404 | |
| 405 | var allEntries []EntryInfo |
| 406 | uniqueIDs := make(map[string]struct{}) |
| 407 | var oldestEntry EntryInfo |
| 408 | oldestTime := time.Now().Add(100 * 365 * 24 * time.Hour) // Set to a future date to find the oldest entry |
| 409 | |
| 410 | for _, entry := range dirEntries { |
| 411 | fullPath := filepath.Join(path, entry.Name()) |
| 412 | if ignorer.IsIgnored(fullPath) { |
| 413 | continue |
| 414 | } |
| 415 | info, err := os.Stat(fullPath) |
| 416 | if err != nil { |
| 417 | fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err) |
| 418 | continue |
| 419 | } |
| 420 | |
| 421 | parentID, err := xattr.Get(fullPath, parentIDAttrName) |
| 422 | if err != nil { |
| 423 | continue // Skip if attribute doesn't exist or can't be read |
| 424 | } |
| 425 | |
| 426 | entryInfo := EntryInfo{ |
| 427 | Path: fullPath, |
| 428 | ModTime: info.ModTime(), |
| 429 | ParentID: string(parentID), |
| 430 | } |
| 431 | |
| 432 | allEntries = append(allEntries, entryInfo) |
| 433 | uniqueIDs[string(parentID)] = struct{}{} |
| 434 | |
| 435 | if entryInfo.ModTime.Before(oldestTime) { |
| 436 | oldestTime = entryInfo.ModTime |
| 437 | oldestEntry = entryInfo |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | return allEntries, uniqueIDs, oldestEntry, nil |
| 442 | } |
| 443 | |
| 444 | func setAllParentIDAttributes(entries []EntryInfo, targetID string) error { |
| 445 | fmt.Printf(" Setting all parent IDs to '%s':\n", targetID) |