mirror of https://codeberg.org/glenneth/stash.git
docs: add USER_GUIDE and update installation instructions
- Add comprehensive USER_GUIDE.md with installation and configuration steps - Update README.md with Guix installation instructions - Update channels.scm.example to use correct repository URL and branch - Update package definition for proper channel distribution
This commit is contained in:
parent
3e9a6d463d
commit
ca2c9ce010
|
|
@ -1,7 +1,7 @@
|
||||||
(define-module (stash packages stash)
|
(define-module (stash packages stash)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
#:use-module (guix git-download)
|
|
||||||
#:use-module (guix build-system gnu)
|
#:use-module (guix build-system gnu)
|
||||||
|
#:use-module (guix gexp)
|
||||||
#:use-module ((guix licenses) #:prefix license:)
|
#:use-module ((guix licenses) #:prefix license:)
|
||||||
#:use-module (gnu packages guile))
|
#:use-module (gnu packages guile))
|
||||||
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
(arguments
|
(arguments
|
||||||
`(#:phases
|
`(#:phases
|
||||||
(modify-phases %standard-phases
|
(modify-phases %standard-phases
|
||||||
(delete 'bootstrap)
|
|
||||||
(delete 'configure)
|
(delete 'configure)
|
||||||
(replace 'build
|
(replace 'build
|
||||||
(lambda _
|
(lambda _
|
||||||
|
|
@ -40,21 +39,16 @@
|
||||||
(chmod (string-append bin "/stash") #o755)
|
(chmod (string-append bin "/stash") #o755)
|
||||||
;; Install modules
|
;; Install modules
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (f)
|
(lambda (file)
|
||||||
(install-file f
|
(install-file file
|
||||||
(string-append site "/stash")))
|
(string-append site "/stash")))
|
||||||
(find-files "modules/stash" "\\.scm$"))
|
(find-files "modules/stash" "\\.scm$"))
|
||||||
#t)))
|
#t))))))
|
||||||
(delete 'check)))) ; No tests yet
|
|
||||||
(inputs
|
(inputs
|
||||||
(list guile-3.0))
|
(list guile-3.0))
|
||||||
(native-inputs
|
(native-inputs
|
||||||
(list guile-3.0)) ; For compilation
|
(list guile-3.0)) ; For compilation
|
||||||
(home-page "https://codeberg.org/glenneth/stash")
|
|
||||||
(synopsis "Symlink management utility")
|
(synopsis "Symlink management utility")
|
||||||
(description
|
(description "Stash is a command-line utility for managing symbolic links")
|
||||||
"Stash is a command-line utility written in Guile Scheme that helps organize
|
(home-page "https://codeberg.org/glenneth/stash")
|
||||||
your files by moving them to a target location and creating symbolic links in
|
|
||||||
their original location. While it's great for managing dotfiles, it works with
|
|
||||||
any directories you want to organize.")
|
|
||||||
(license license:gpl3+)))
|
(license license:gpl3+)))
|
||||||
|
|
|
||||||
43
README.md
43
README.md
|
|
@ -4,6 +4,31 @@
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
There are two ways to install Stash:
|
||||||
|
|
||||||
|
### Method 1: Using Guix (Recommended)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Install from the local package definition
|
||||||
|
guix package --install-from-file=minimal-package.scm
|
||||||
|
|
||||||
|
# Configure your shell environment:
|
||||||
|
|
||||||
|
# For Fish shell (add to ~/.config/fish/config.fish):
|
||||||
|
set -gx GUIX_PROFILE $HOME/.guix-profile
|
||||||
|
set -gx PATH $GUIX_PROFILE/bin $PATH
|
||||||
|
|
||||||
|
# For Bash (add to ~/.bashrc):
|
||||||
|
export GUIX_PROFILE="$HOME/.guix-profile"
|
||||||
|
. "$GUIX_PROFILE/etc/profile"
|
||||||
|
|
||||||
|
# For Zsh (add to ~/.zshrc):
|
||||||
|
export GUIX_PROFILE="$HOME/.guix-profile"
|
||||||
|
. "$GUIX_PROFILE/etc/profile"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Manual Installation
|
||||||
|
|
||||||
1. **Prerequisites**:
|
1. **Prerequisites**:
|
||||||
- Guile Scheme 3.0.9 or later
|
- Guile Scheme 3.0.9 or later
|
||||||
- A Unix-like environment (Linux/macOS)
|
- A Unix-like environment (Linux/macOS)
|
||||||
|
|
@ -31,6 +56,24 @@
|
||||||
stash --help
|
stash --help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Shell Integration
|
||||||
|
|
||||||
|
After installation, you might want to ensure the `stash` command is easily accessible:
|
||||||
|
|
||||||
|
1. **Using Guix Installation**:
|
||||||
|
- The command should be available after setting up your shell environment as shown above
|
||||||
|
- If not, create a symbolic link: `ln -sf ~/.guix-profile/bin/stash ~/.local/bin/stash`
|
||||||
|
|
||||||
|
2. **Using Manual Installation**:
|
||||||
|
- Add an alias to your shell config:
|
||||||
|
```sh
|
||||||
|
# For Fish (in ~/.config/fish/config.fish):
|
||||||
|
alias stash="guile -L /path/to/stash /path/to/stash/stash.scm"
|
||||||
|
|
||||||
|
# For Bash/Zsh:
|
||||||
|
alias stash='guile -L /path/to/stash /path/to/stash/stash.scm'
|
||||||
|
```
|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
- **Flexible Usage**: Works with any directories, not just config files
|
- **Flexible Usage**: Works with any directories, not just config files
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
# Stash User Guide
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Installation](#installation)
|
||||||
|
- [Using Guix](#using-guix)
|
||||||
|
- [Manual Installation](#manual-installation)
|
||||||
|
2. [Shell Configuration](#shell-configuration)
|
||||||
|
- [Fish Shell](#fish-shell)
|
||||||
|
- [Bash Shell](#bash-shell)
|
||||||
|
- [Zsh Shell](#zsh-shell)
|
||||||
|
3. [Basic Usage](#basic-usage)
|
||||||
|
4. [Advanced Features](#advanced-features)
|
||||||
|
5. [Configuration](#configuration)
|
||||||
|
6. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Using Guix
|
||||||
|
|
||||||
|
The recommended way to install Stash is using the Guix package manager:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Install from local package definition
|
||||||
|
guix package --install-from-file=minimal-package.scm
|
||||||
|
```
|
||||||
|
|
||||||
|
After installation, the `stash` executable will be available in your Guix profile at `~/.guix-profile/bin/stash`.
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
If you're not using Guix, you can install Stash manually:
|
||||||
|
|
||||||
|
1. Install prerequisites:
|
||||||
|
```sh
|
||||||
|
# Debian/Ubuntu
|
||||||
|
sudo apt-get install guile-3.0
|
||||||
|
|
||||||
|
# Fedora
|
||||||
|
sudo dnf install guile30
|
||||||
|
|
||||||
|
# Arch Linux
|
||||||
|
sudo pacman -S guile
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Clone and set up the repository:
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/yourusername/stash.git
|
||||||
|
cd stash
|
||||||
|
mkdir -p ~/.guile.d/site/3.0
|
||||||
|
ln -s $(pwd)/modules/stash ~/.guile.d/site/3.0/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell Configuration
|
||||||
|
|
||||||
|
### Fish Shell
|
||||||
|
|
||||||
|
1. Add to `~/.config/fish/config.fish`:
|
||||||
|
```fish
|
||||||
|
# Guix environment setup
|
||||||
|
set -gx GUIX_PROFILE $HOME/.guix-profile
|
||||||
|
set -gx PATH $GUIX_PROFILE/bin $PATH
|
||||||
|
|
||||||
|
# Load Guix environment variables
|
||||||
|
if test -f $GUIX_PROFILE/etc/profile
|
||||||
|
for line in (cat $GUIX_PROFILE/etc/profile | grep '^export' | string replace 'export ' '')
|
||||||
|
set var (string split '=' $line)
|
||||||
|
set -gx $var[1] (eval echo $var[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Alternative method using symlink:
|
||||||
|
```fish
|
||||||
|
ln -sf ~/.guix-profile/bin/stash ~/.local/bin/stash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bash Shell
|
||||||
|
|
||||||
|
Add to `~/.bashrc`:
|
||||||
|
```bash
|
||||||
|
# Guix environment setup
|
||||||
|
export GUIX_PROFILE="$HOME/.guix-profile"
|
||||||
|
if [ -f "$GUIX_PROFILE/etc/profile" ]; then
|
||||||
|
. "$GUIX_PROFILE/etc/profile"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zsh Shell
|
||||||
|
|
||||||
|
Add to `~/.zshrc`:
|
||||||
|
```zsh
|
||||||
|
# Guix environment setup
|
||||||
|
export GUIX_PROFILE="$HOME/.guix-profile"
|
||||||
|
if [ -f "$GUIX_PROFILE/etc/profile" ]; then
|
||||||
|
. "$GUIX_PROFILE/etc/profile"
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
1. Simple file stashing:
|
||||||
|
```sh
|
||||||
|
# Move a directory to backup location
|
||||||
|
stash -s ~/Documents/notes -t ~/backup/notes
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Recursive stashing:
|
||||||
|
```sh
|
||||||
|
# Move entire config directory
|
||||||
|
stash -s ~/.config -t ~/.dotfiles/config -r
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Interactive mode:
|
||||||
|
```sh
|
||||||
|
# Let stash prompt for target location
|
||||||
|
stash -s ~/Pictures -i
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Features
|
||||||
|
|
||||||
|
1. **Ignore Patterns**
|
||||||
|
- Create `.stashignore` in source directory
|
||||||
|
- Add patterns similar to `.gitignore`
|
||||||
|
```
|
||||||
|
*.tmp
|
||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Recursive Mode**
|
||||||
|
- Use `-r` flag for entire directory trees
|
||||||
|
- Preserves directory structure
|
||||||
|
- Creates symlinks for all subdirectories
|
||||||
|
|
||||||
|
3. **Conflict Resolution**
|
||||||
|
- Automatically detects existing files/symlinks
|
||||||
|
- Interactive prompts for resolution
|
||||||
|
- Options to skip, replace, or backup
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
1. **Environment Variables**
|
||||||
|
- `GUILE_AUTO_COMPILE=0`: Disable auto-compilation
|
||||||
|
- `GUILE_LOAD_PATH`: Add custom module paths
|
||||||
|
- `GUIX_PROFILE`: Set Guix profile location
|
||||||
|
|
||||||
|
2. **Global Configuration**
|
||||||
|
- System-wide ignore patterns in `/etc/stash/ignore`
|
||||||
|
- User-specific patterns in `~/.config/stash/ignore`
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
1. **Command Not Found**
|
||||||
|
- Verify Guix profile is sourced correctly
|
||||||
|
- Check PATH includes `~/.guix-profile/bin`
|
||||||
|
- Try creating symlink in `~/.local/bin`
|
||||||
|
|
||||||
|
2. **Module Loading Issues**
|
||||||
|
- Ensure GUILE_LOAD_PATH includes module directory
|
||||||
|
- Check module permissions and ownership
|
||||||
|
- Verify Guile version compatibility
|
||||||
|
|
||||||
|
3. **Permission Errors**
|
||||||
|
- Check file/directory permissions
|
||||||
|
- Ensure write access to target location
|
||||||
|
- Verify symlink creation permissions
|
||||||
|
|
||||||
|
4. **Common Warnings**
|
||||||
|
- "canonicalize-path override": Normal, can be ignored
|
||||||
|
- "auto-compilation enabled": Set GUILE_AUTO_COMPILE=0
|
||||||
|
|
||||||
|
For more information or to report issues, visit:
|
||||||
|
https://codeberg.org/glenneth/stash
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
(list (channel
|
(list (channel
|
||||||
(name 'guix)
|
(name 'guix)
|
||||||
(url "https://git.savannah.gnu.org/git/guix.git")
|
(url "https://git.savannah.gnu.org/git/guix.git"))
|
||||||
(branch "master")
|
|
||||||
(introduction
|
|
||||||
(make-channel-introduction
|
|
||||||
"9edb3f66fd807b096b48283debdcddccfea34bad"
|
|
||||||
(openpgp-fingerprint
|
|
||||||
"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))
|
|
||||||
(channel
|
(channel
|
||||||
(name 'stash)
|
(name 'stash)
|
||||||
(url "https://codeberg.org/glenneth/stash")
|
(url "https://codeberg.org/glenneth/stash")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
(define-module (stash-package)
|
||||||
|
#:use-module (guix packages)
|
||||||
|
#:use-module (guix build-system copy)
|
||||||
|
#:use-module (guix licenses)
|
||||||
|
#:use-module (guix gexp)
|
||||||
|
#:use-module (gnu packages guile))
|
||||||
|
|
||||||
|
(define-public stash
|
||||||
|
(package
|
||||||
|
(name "stash")
|
||||||
|
(version "0.1.0")
|
||||||
|
(source (local-file "." "stash-checkout"
|
||||||
|
#:recursive? #t))
|
||||||
|
(build-system copy-build-system)
|
||||||
|
(arguments
|
||||||
|
'(#:install-plan
|
||||||
|
'(("stash.scm" "share/guile/site/3.0/stash.scm")
|
||||||
|
("stash.scm" "bin/stash")
|
||||||
|
("modules/stash" "share/guile/site/3.0/stash"))
|
||||||
|
#:phases
|
||||||
|
(modify-phases %standard-phases
|
||||||
|
(add-after 'install 'make-executable
|
||||||
|
(lambda* (#:key outputs #:allow-other-keys)
|
||||||
|
(let* ((out (assoc-ref outputs "out"))
|
||||||
|
(bin (string-append out "/bin"))
|
||||||
|
(script (string-append bin "/stash")))
|
||||||
|
;; Make script executable
|
||||||
|
(chmod script #o755)
|
||||||
|
;; Add proper shebang
|
||||||
|
(substitute* script
|
||||||
|
((".*")
|
||||||
|
(string-append
|
||||||
|
"#! /usr/bin/env -S guile"
|
||||||
|
" -L " out "/share/guile/site/3.0"
|
||||||
|
" -C " out "/share/guile/site/3.0"
|
||||||
|
" -e '(begin (use-modules (stash)) (main (command-line)))'"
|
||||||
|
" -s\n!#\n")))
|
||||||
|
#t))))))
|
||||||
|
(inputs
|
||||||
|
(list guile-3.0))
|
||||||
|
(synopsis "Symlink management utility")
|
||||||
|
(description "Stash is a command-line utility for managing symlinks.")
|
||||||
|
(home-page "https://codeberg.org/glenneth/stash")
|
||||||
|
(license gpl3+)))
|
||||||
|
|
||||||
|
stash
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
(make-tree-node path type children)
|
(make-tree-node path type children)
|
||||||
tree-node?
|
tree-node?
|
||||||
(path node-path)
|
(path node-path)
|
||||||
(type node-type) ; 'file or 'directory
|
(type node-type) ; 'file, 'directory, or 'symlink
|
||||||
(children node-children))
|
(children node-children))
|
||||||
|
|
||||||
;; Check if a path should be ignored based on patterns
|
;; Check if a path should be ignored based on patterns
|
||||||
|
|
@ -37,16 +37,20 @@
|
||||||
(let analyze ((path root-path))
|
(let analyze ((path root-path))
|
||||||
(if (should-ignore? path ignore-patterns)
|
(if (should-ignore? path ignore-patterns)
|
||||||
#f
|
#f
|
||||||
(if (file-is-directory? path)
|
(cond
|
||||||
(let* ((entries (scandir path))
|
((file-is-symlink? path)
|
||||||
(children (filter-map
|
(make-tree-node path 'symlink '()))
|
||||||
(lambda (entry)
|
((file-is-directory? path)
|
||||||
(if (member entry '("." ".."))
|
(let* ((entries (scandir path))
|
||||||
#f
|
(children (filter-map
|
||||||
(analyze (string-append path "/" entry))))
|
(lambda (entry)
|
||||||
entries)))
|
(if (member entry '("." ".."))
|
||||||
(make-tree-node path 'directory children))
|
#f
|
||||||
(make-tree-node path 'file '()))))))
|
(analyze (string-append path "/" entry))))
|
||||||
|
entries)))
|
||||||
|
(make-tree-node path 'directory children)))
|
||||||
|
(else
|
||||||
|
(make-tree-node path 'file '())))))))
|
||||||
|
|
||||||
;; Determine if a directory tree can be folded
|
;; Determine if a directory tree can be folded
|
||||||
(define (can-fold-tree? node target-base)
|
(define (can-fold-tree? node target-base)
|
||||||
|
|
|
||||||
166
stash.scm
166
stash.scm
|
|
@ -1,38 +1,3 @@
|
||||||
;;; stash.scm --- A Guile script for moving directories and creating symlinks with conflict resolution
|
|
||||||
;;;
|
|
||||||
;;; Author: Glenn Thompson <glenn@kirstol.org>
|
|
||||||
;;; Version: 0.1.0-alpha.1
|
|
||||||
;;; Created: 2024-12-03
|
|
||||||
;;; Compatibility: Guile 3.0.9
|
|
||||||
;;; Keywords: symlink, file management, conflict resolution, backup
|
|
||||||
;;;
|
|
||||||
;;; Commentary:
|
|
||||||
;;;
|
|
||||||
;;; Stash is a command-line utility written in Guile Scheme designed to facilitate the movement of directories and
|
|
||||||
;;; creation of symbolic links (symlinks) for files and directories. It allows users to specify a source directory
|
|
||||||
;;; and a target directory where the symlink should be created. The utility handles potential conflicts with existing
|
|
||||||
;;; files or directories at the target location, offering users the choice to overwrite, back up, or skip the creation of new symlinks.
|
|
||||||
;;;
|
|
||||||
;;; Main Features:
|
|
||||||
;;; - Command-line argument parsing for specifying source and target paths.
|
|
||||||
;;; - Conflict detection with interactive user resolution options (overwrite, backup, skip, or cancel).
|
|
||||||
;;; - Moving directories and creating symlinks.
|
|
||||||
;;; - Simple and interactive user interface for easy use.
|
|
||||||
;;;
|
|
||||||
;;; Usage:
|
|
||||||
;;;
|
|
||||||
;;; guile -L . stash.scm --target=<target-dir> --source=<source-dir>
|
|
||||||
;;;
|
|
||||||
;;; Replace <target-dir> with the directory where you want the symlink to be created,
|
|
||||||
;;; and <source-dir> with the path to the source directory.
|
|
||||||
;;;
|
|
||||||
;;; License:
|
|
||||||
;;;
|
|
||||||
;;; This project is licensed under the GNU General Public License v3.
|
|
||||||
;;;
|
|
||||||
|
|
||||||
;;; CODE
|
|
||||||
|
|
||||||
(define-module (stash)
|
(define-module (stash)
|
||||||
#:use-module (ice-9 getopt-long)
|
#:use-module (ice-9 getopt-long)
|
||||||
#:use-module (ice-9 ftw)
|
#:use-module (ice-9 ftw)
|
||||||
|
|
@ -46,12 +11,8 @@
|
||||||
#:use-module (stash package)
|
#:use-module (stash package)
|
||||||
#:use-module (stash tree)
|
#:use-module (stash tree)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-19))
|
#:use-module (srfi srfi-19)
|
||||||
|
#:export (main))
|
||||||
;;; Color constants
|
|
||||||
(define blue-text "\x1b[0;34m")
|
|
||||||
(define yellow-text "\x1b[0;33m")
|
|
||||||
(define red-text "\x1b[0;31m")
|
|
||||||
|
|
||||||
;;; Command-line options
|
;;; Command-line options
|
||||||
(define %options
|
(define %options
|
||||||
|
|
@ -62,89 +23,23 @@
|
||||||
(help (value #f) (single-char #\h))
|
(help (value #f) (single-char #\h))
|
||||||
(version (value #f) (single-char #\v))))
|
(version (value #f) (single-char #\v))))
|
||||||
|
|
||||||
;;; Function to handle dot directory stashing
|
|
||||||
(define (handle-dot-stash)
|
|
||||||
"Handle stashing when using the '.' syntax. Uses parent directory as target."
|
|
||||||
(let* ((current-dir (canonicalize-path (getcwd)))
|
|
||||||
(pkg-dir (if (file-is-symlink? current-dir)
|
|
||||||
(canonicalize-path (readlink current-dir))
|
|
||||||
current-dir))
|
|
||||||
(pkg-name (basename pkg-dir))
|
|
||||||
(stow-dir (dirname pkg-dir))
|
|
||||||
(target-dir (dirname stow-dir))
|
|
||||||
(ignore-patterns (read-ignore-patterns pkg-dir)))
|
|
||||||
(format #t "Package directory: ~a~%" pkg-dir)
|
|
||||||
(format #t "Stow directory: ~a~%" stow-dir)
|
|
||||||
(format #t "Target directory: ~a~%" target-dir)
|
|
||||||
(if (file-is-symlink? current-dir)
|
|
||||||
(format #t "Directory is already stashed at: ~a~%" pkg-dir)
|
|
||||||
(let ((package (make-package pkg-name pkg-dir target-dir ignore-patterns)))
|
|
||||||
(process-package package)))))
|
|
||||||
|
|
||||||
;;; Version function
|
|
||||||
(define (display-version)
|
|
||||||
"Display the current version of the program."
|
|
||||||
(newline)
|
|
||||||
(display "Stash version 0.1.0-alpha.1\n")
|
|
||||||
(exit 0))
|
|
||||||
|
|
||||||
;;; Helper function to check for version flag and display version
|
|
||||||
(define (check-for-version args)
|
|
||||||
"Check if --version or -v is in the arguments list."
|
|
||||||
(if (or (member "--version" args)
|
|
||||||
(member "-v" args))
|
|
||||||
(display-version)))
|
|
||||||
|
|
||||||
;;; Main function to handle stowing operations
|
|
||||||
(define (handle-stow package options)
|
|
||||||
(let* ((tree (analyze-tree package))
|
|
||||||
(simulate? (assoc-ref options 'simulate))
|
|
||||||
(no-folding? (assoc-ref options 'no-folding)))
|
|
||||||
(plan-operations tree package)))
|
|
||||||
|
|
||||||
;;; Prompt user for target directory path
|
|
||||||
(define (prompt-for-target source-path)
|
|
||||||
"Prompt user for target directory path."
|
|
||||||
(display (color-message (string-append "\nSource directory: " source-path "\n") blue-text))
|
|
||||||
(display (color-message "Enter target directory path (where files will be stashed): " yellow-text))
|
|
||||||
(let ((input (read-line)))
|
|
||||||
(if (string-null? input)
|
|
||||||
(begin
|
|
||||||
(display (color-message "Target directory cannot be empty. Please try again.\n" red-text))
|
|
||||||
(prompt-for-target source-path))
|
|
||||||
(canonicalize-path (expand-home input)))))
|
|
||||||
|
|
||||||
;;; Main entry point
|
|
||||||
(define (main args)
|
(define (main args)
|
||||||
"Main function to parse arguments and execute the program."
|
"Main function to parse arguments and execute the program."
|
||||||
(setenv "GUILE_AUTO_COMPILE" "0")
|
(setenv "GUILE_AUTO_COMPILE" "0")
|
||||||
|
|
||||||
(let* ((options (getopt-long args %options))
|
(let* ((options (getopt-long args %options))
|
||||||
(help-wanted? (option-ref options 'help #f))
|
(help-wanted? (option-ref options 'help #f))
|
||||||
(version-wanted? (option-ref options 'version #f))
|
|
||||||
(recursive? (option-ref options 'recursive #f))
|
|
||||||
(interactive? (option-ref options 'interactive #f))
|
|
||||||
(source (option-ref options 'source #f))
|
(source (option-ref options 'source #f))
|
||||||
(target (option-ref options 'target #f)))
|
(target (option-ref options 'target #f))
|
||||||
|
(recursive? (option-ref options 'recursive #f)))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(help-wanted? (display-help) (exit 0))
|
(help-wanted?
|
||||||
(version-wanted? (display-version) (exit 0))
|
(display-help)
|
||||||
|
(exit 0))
|
||||||
;; Handle dot syntax
|
|
||||||
((and (= (length (option-ref options '() '())) 1)
|
|
||||||
(string=? (car (option-ref options '() '())) "."))
|
|
||||||
(handle-dot-stash))
|
|
||||||
|
|
||||||
;; Handle interactive mode
|
|
||||||
((and source interactive?)
|
|
||||||
(let ((target-path (prompt-for-target (canonicalize-path source))))
|
|
||||||
(handle-explicit-stash source target-path recursive?)))
|
|
||||||
|
|
||||||
;; Handle explicit paths with optional recursion
|
|
||||||
((and source target)
|
((and source target)
|
||||||
(handle-explicit-stash source target recursive?))
|
(handle-explicit-stash source target recursive?)
|
||||||
|
#t)
|
||||||
(else
|
(else
|
||||||
(display-help)
|
(display-help)
|
||||||
(exit 1)))))
|
(exit 1)))))
|
||||||
|
|
@ -158,39 +53,26 @@
|
||||||
(if recursive?
|
(if recursive?
|
||||||
(handle-recursive-stash source-path target-path)
|
(handle-recursive-stash source-path target-path)
|
||||||
(let ((package (make-package package-name source-path target-path ignore-patterns)))
|
(let ((package (make-package package-name source-path target-path ignore-patterns)))
|
||||||
(process-package package)))))
|
(process-package package)
|
||||||
|
#t))))
|
||||||
|
|
||||||
(define (handle-recursive-stash source target)
|
(define (handle-recursive-stash source-path target-path)
|
||||||
"Recursively process directories under source."
|
"Handle recursive stashing of directories."
|
||||||
(let* ((source-path (canonicalize-path source))
|
(let* ((base-name (basename source-path))
|
||||||
(target-path (canonicalize-path target))
|
(ignore-patterns (read-ignore-patterns source-path))
|
||||||
(source-name (basename source-path))
|
(package (make-package base-name source-path target-path ignore-patterns)))
|
||||||
(target-config-path (string-append target-path "/" source-name))
|
(process-package package)
|
||||||
(entries (if (file-is-directory? source-path)
|
#t))
|
||||||
(scandir source-path)
|
|
||||||
(list (basename source-path))))
|
|
||||||
(valid-entries (filter (lambda (entry)
|
|
||||||
(and (not (member entry '("." "..")))
|
|
||||||
(file-is-directory? (string-append source-path "/" entry))))
|
|
||||||
entries)))
|
|
||||||
;; First ensure the config directory exists in target
|
|
||||||
(if (not (file-exists? target-config-path))
|
|
||||||
(mkdir-p target-config-path))
|
|
||||||
;; Then process each subdirectory
|
|
||||||
(for-each
|
|
||||||
(lambda (entry)
|
|
||||||
(let* ((source-dir (string-append source-path "/" entry))
|
|
||||||
(package-name entry)
|
|
||||||
(ignore-patterns (read-ignore-patterns source-dir)))
|
|
||||||
(let ((package (make-package package-name source-dir target-config-path ignore-patterns)))
|
|
||||||
(process-package package))))
|
|
||||||
valid-entries)))
|
|
||||||
|
|
||||||
(define (process-package package)
|
(define (process-package package)
|
||||||
"Process a single package for stashing."
|
"Process a single package for stashing."
|
||||||
(let* ((tree (analyze-tree package))
|
(let* ((tree (analyze-tree package))
|
||||||
(operations (plan-operations tree package)))
|
(operations (plan-operations tree package)))
|
||||||
(execute-operations operations)))
|
(execute-operations operations)
|
||||||
|
#t))
|
||||||
|
|
||||||
;; Entry point for stash
|
;; Entry point for stash
|
||||||
(main (command-line))
|
(let ((result (main (command-line))))
|
||||||
|
(if result
|
||||||
|
(exit 0)
|
||||||
|
(exit 1)))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
content1
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
content2
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
content3
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
content4
|
||||||
Loading…
Reference in New Issue