symlink fixed !

This commit is contained in:
kumar vaibhav 2025-12-19 20:13:03 +05:30
parent 8128e92311
commit 359c250101
2 changed files with 61 additions and 29 deletions

View file

@ -118,10 +118,10 @@ wget
# Dotfiles to manage with symlinks # Dotfiles to manage with symlinks
# Format: "target_path" = "source_path" # Format: "target_path" = "source_path"
# target_path: where the symlink should be created (relative to home directory) # target_path: where the symlink should be created (relative to home directory)
# source_path: where the actual file is stored (relative to forge directory) # source_path: where the actual file is stored (relative to dotfiles directory)
".bashrc" = "dotfiles/.bashrc" ".bashrc" = ".bashrc"
".config/vimrc" = "dotfiles/vimrc" ".config/vimrc" = "vimrc"
".config/alacritty/alacritty.yml" = "dotfiles/alacritty.yml" ".config/alacritty/alacritty.yml" = "alacritty.yml"
[options] [options]
# Additional options # Additional options
@ -166,7 +166,8 @@ To remove a package, simply delete the line containing the package name.
#### `[dotfiles]` #### `[dotfiles]`
Dotfile mappings using symlinks: Dotfile mappings using symlinks:
- **Key**: Target path where symlink should be created (relative to home directory) - **Key**: Target path where symlink should be created (relative to home directory)
- **Value**: Source path where actual file is stored (relative to forge directory) - **Value**: Source path where actual file is stored (relative to dotfiles directory)
- Note: Source path automatically prefixed with "dotfiles/" if not present
#### `[options]` #### `[options]`
Additional configuration options: Additional configuration options:
@ -205,9 +206,10 @@ Packages are managed through the `[packages]` section in `forge.toml`:
### Dotfile Management ### Dotfile Management
Forge uses symlinks to manage dotfiles: Forge uses symlinks to manage dotfiles:
1. Your actual dotfiles are stored in `~/.config/forge/dotfiles/` 1. Your actual dotfiles are stored in `~/.config/forge/dotfiles/`
2. Symlinks are created from your home directory to these files 2. Symlinks are created from your home directory to these files using relative paths
3. This allows you to version control your dotfiles in one place 3. This allows you to version control your dotfiles in one place
4. Changes to the source files are immediately reflected in your home directory 4. Changes to the source files are immediately reflected in your home directory
5. Source paths are automatically prefixed with "dotfiles/" for convenience
### Backup System ### Backup System
Before creating symlinks, Forge: Before creating symlinks, Forge:
@ -239,7 +241,7 @@ mkdir -p ~/.config/forge/dotfiles
echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc
# Add to [dotfiles] section: # Add to [dotfiles] section:
".bashrc" = "dotfiles/.bashrc" ".bashrc" = ".bashrc"
# Apply configuration # Apply configuration
./forge switch ./forge switch
@ -248,14 +250,14 @@ echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc
### Managing Application Configurations ### Managing Application Configurations
```bash ```bash
# Add alacritty configuration # Add alacritty configuration
mkdir -p ~/.config/forge/dotfiles/.config/alacritty mkdir -p ~/.config/forge/dotfiles
cp ~/.config/alacritty/alacritty.yml ~/.config/forge/dotfiles/.config/alacritty/ cp ~/.config/alacritty/alacritty.yml ~/.config/forge/dotfiles/
# Edit forge.toml # Edit forge.toml
nano ~/.config/forge/forge.toml nano ~/.config/forge/forge.toml
# Add to [dotfiles] section: # Add to [dotfiles] section:
".config/alacritty/alacritty.yml" = "dotfiles/.config/alacritty/alacritty.yml" ".config/alacritty/alacritty.yml" = "alacritty.yml"
# Apply changes # Apply changes
./forge switch ./forge switch

68
forge
View file

@ -70,9 +70,11 @@ last_switch = null
# Format: "target_path" = "source_path" # Format: "target_path" = "source_path"
# target_path: where the symlink should be created (relative to home directory) # target_path: where the symlink should be created (relative to home directory)
# source_path: where the actual file is stored (relative to forge directory) # source_path: where the actual file is stored (relative to forge directory)
# Note: source_path automatically prefixed with "dotfiles/" if not present
# Examples: # Examples:
# ".bashrc" = "dotfiles/.bashrc" # ".bashrc" = ".bashrc"
# ".config/vimrc" = "dotfiles/vimrc" # ".config/vimrc" = "vimrc"
# ".config/alacritty/alacritty.yml" = "alacritty.yml"
[options] [options]
# Additional options # Additional options
@ -218,6 +220,7 @@ deploy_dotfiles() {
log_info "Deploying dotfiles..." log_info "Deploying dotfiles..."
local dotfiles_deployed=false local dotfiles_deployed=false
local dotfiles_dir="$FORGE_DIR/dotfiles"
while IFS='=' read -r entry; do while IFS='=' read -r entry; do
local section="${entry%%:*}" local section="${entry%%:*}"
@ -228,34 +231,61 @@ deploy_dotfiles() {
if [[ "$section" == "dotfiles" ]]; then if [[ "$section" == "dotfiles" ]]; then
dotfiles_deployed=true dotfiles_deployed=true
# Normalize source path - if it doesn't start with dotfiles/, add it
if [[ ! "$source" =~ ^dotfiles/ ]]; then
source="dotfiles/$source"
fi
local target_path="$HOME/$target" local target_path="$HOME/$target"
local source_path="$FORGE_DIR/$source" local source_path="$FORGE_DIR/$source"
# Create source directory if it doesn't exist # Verify source file exists
local source_dir=$(dirname "$source_path") if [[ ! -f "$source_path" && ! -d "$source_path" ]]; then
mkdir -p "$source_dir" log_error "Source file not found: $source_path"
continue
fi
# Create target directory if it doesn't exist # Create target directory if it doesn't exist
local target_dir=$(dirname "$target_path") local target_dir=$(dirname "$target_path")
mkdir -p "$target_dir" mkdir -p "$target_dir"
# Backup existing file if it exists and is not a symlink # Handle existing file/symlink
if [[ -f "$target_path" && ! -L "$target_path" ]]; then if [[ -e "$target_path" || -L "$target_path" ]]; then
local backup_dir="$FORGE_DIR/backup" # Check if it's already a correct symlink
mkdir -p "$backup_dir" if [[ -L "$target_path" ]]; then
local backup_path="$backup_dir/$(basename "$target").$(date +%Y%m%d_%H%M%S).bak" local current_target=$(readlink "$target_path")
cp "$target_path" "$backup_path" if [[ "$current_target" == "$source_path" ]]; then
log_info "Backed up $target_path to $backup_path" log_info "Symlink already correct: $target_path"
continue
fi
fi
# Backup existing file if it exists and is not a symlink
if [[ -e "$target_path" && ! -L "$target_path" ]]; then
local backup_dir="$FORGE_DIR/backup"
mkdir -p "$backup_dir"
local backup_path="$backup_dir/$(basename "$target").$(date +%Y%m%d_%H%M%S).bak"
cp -r "$target_path" "$backup_path"
log_info "Backed up $target_path to $backup_path"
fi
# Remove existing file/symlink
rm -rf "$target_path"
fi fi
# Remove existing file/symlink # Create relative symlink for better portability
rm -f "$target_path" local relative_source
if [[ -d "$source_path" ]]; then
# Create symlink relative_source=$(realpath --relative-to="$target_dir" "$source_path")
if ln -s "$source_path" "$target_path"; then
log_success "Created symlink: $target_path -> $source_path"
else else
log_error "Failed to create symlink: $target_path -> $source_path" relative_source=$(realpath --relative-to="$target_dir" "$source_path")
fi
# Create symlink using relative path
if ln -s "$relative_source" "$target_path"; then
log_success "Created symlink: $target_path -> $relative_source"
else
log_error "Failed to create symlink: $target_path -> $relative_source"
fi fi
fi fi
done < <(parse_toml) done < <(parse_toml)