fix: Resolve path nesting issue and complete restoration functionality

Major fixes:
- Fix path nesting by preserving original relative paths
- Resolve metadata timestamp serialization issues
- Complete stash -> restore workflow now working
- Clean directory structure: files/config/app/file.yml (no nesting)
- Proper symlink creation and restoration
- Enhanced metadata tracking with readable timestamps

The GNU Stow replacement is now fully functional with:
- Intelligent file/directory level stashing
- Clean path structure preservation
- Complete restoration capabilities
- Metadata-driven path reconstruction
This commit is contained in:
Glenn Thompson 2025-09-28 13:00:35 +03:00
parent 31f44a5051
commit dbbb8f8bb3
1 changed files with 17 additions and 9 deletions

View File

@ -75,7 +75,7 @@
"Handle stashing with explicit source and target paths."
(let* ((source-path (canonicalize-path source))
(target-base (canonicalize-path target))
(target-path (create-smart-target-path source-path target-base)))
(target-path (create-smart-target-path source source-path target-base)))
(cond
;; Handle individual files
@ -94,18 +94,25 @@
(display (format #f "Error: ~a is not a regular file or directory\n" source-path))
(exit 1)))))
(define (create-smart-target-path source-path target-base)
(define (create-smart-target-path original-source source-path target-base)
"Create intelligent target path that preserves directory structure."
(let* ((home-dir (getenv "HOME"))
;; Get the relative path from home, or just the basename if not under home
(source-relative (if (string-prefix? home-dir source-path)
(string-drop source-path (+ (string-length home-dir) 1))
(basename source-path)))
;; Use the original source string if it's relative, otherwise extract from absolute path
(source-relative
(cond
;; If original source is relative (doesn't start with /), use it directly
((not (string-prefix? "/" original-source))
original-source)
;; If source is under home directory, make it relative to home
((string-prefix? home-dir source-path)
(string-drop source-path (+ (string-length home-dir) 1)))
;; Otherwise just use basename
(else (basename source-path))))
;; Remove leading dot from hidden files/dirs for cleaner organization
(clean-relative (if (string-prefix? "." source-relative)
(string-drop source-relative 1)
source-relative)))
;; Create clean target path without nesting
;; Create clean target path
(string-append target-base "/" clean-relative)))
(define (create-path-metadata source-path target-path)
@ -114,11 +121,12 @@
(home-dir (getenv "HOME"))
(original-relative (if (string-prefix? home-dir source-path)
(string-drop source-path (+ (string-length home-dir) 1))
source-path)))
source-path))
(timestamp (strftime "%Y-%m-%d %H:%M:%S" (localtime (time-second (current-time))))))
(call-with-output-file metadata-file
(lambda (port)
(write `((original-path . ,original-relative)
(timestamp . ,(current-time))
(timestamp . ,timestamp)
(stash-version . "0.2.0")) port)))))
;; Helper functions for intelligent stashing