From 359c250101a8e2568371a3c01b0cbfa85b52e58e Mon Sep 17 00:00:00 2001 From: kumar vaibhav Date: Fri, 19 Dec 2025 20:13:03 +0530 Subject: [PATCH] symlink fixed ! --- README.md | 22 ++++++++++-------- forge | 68 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index dba85a0..7d4d29c 100644 --- a/README.md +++ b/README.md @@ -118,10 +118,10 @@ wget # Dotfiles to manage with symlinks # Format: "target_path" = "source_path" # target_path: where the symlink should be created (relative to home directory) -# source_path: where the actual file is stored (relative to forge directory) -".bashrc" = "dotfiles/.bashrc" -".config/vimrc" = "dotfiles/vimrc" -".config/alacritty/alacritty.yml" = "dotfiles/alacritty.yml" +# source_path: where the actual file is stored (relative to dotfiles directory) +".bashrc" = ".bashrc" +".config/vimrc" = "vimrc" +".config/alacritty/alacritty.yml" = "alacritty.yml" [options] # Additional options @@ -166,7 +166,8 @@ To remove a package, simply delete the line containing the package name. #### `[dotfiles]` Dotfile mappings using symlinks: - **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]` Additional configuration options: @@ -205,9 +206,10 @@ Packages are managed through the `[packages]` section in `forge.toml`: ### Dotfile Management Forge uses symlinks to manage 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 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 Before creating symlinks, Forge: @@ -239,7 +241,7 @@ mkdir -p ~/.config/forge/dotfiles echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc # Add to [dotfiles] section: -".bashrc" = "dotfiles/.bashrc" +".bashrc" = ".bashrc" # Apply configuration ./forge switch @@ -248,14 +250,14 @@ echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc ### Managing Application Configurations ```bash # Add alacritty configuration -mkdir -p ~/.config/forge/dotfiles/.config/alacritty -cp ~/.config/alacritty/alacritty.yml ~/.config/forge/dotfiles/.config/alacritty/ +mkdir -p ~/.config/forge/dotfiles +cp ~/.config/alacritty/alacritty.yml ~/.config/forge/dotfiles/ # Edit forge.toml nano ~/.config/forge/forge.toml # Add to [dotfiles] section: -".config/alacritty/alacritty.yml" = "dotfiles/.config/alacritty/alacritty.yml" +".config/alacritty/alacritty.yml" = "alacritty.yml" # Apply changes ./forge switch diff --git a/forge b/forge index 5e2df11..3b3c8a9 100755 --- a/forge +++ b/forge @@ -70,9 +70,11 @@ last_switch = null # Format: "target_path" = "source_path" # target_path: where the symlink should be created (relative to home directory) # source_path: where the actual file is stored (relative to forge directory) +# Note: source_path automatically prefixed with "dotfiles/" if not present # Examples: -# ".bashrc" = "dotfiles/.bashrc" -# ".config/vimrc" = "dotfiles/vimrc" +# ".bashrc" = ".bashrc" +# ".config/vimrc" = "vimrc" +# ".config/alacritty/alacritty.yml" = "alacritty.yml" [options] # Additional options @@ -218,6 +220,7 @@ deploy_dotfiles() { log_info "Deploying dotfiles..." local dotfiles_deployed=false + local dotfiles_dir="$FORGE_DIR/dotfiles" while IFS='=' read -r entry; do local section="${entry%%:*}" @@ -228,34 +231,61 @@ deploy_dotfiles() { if [[ "$section" == "dotfiles" ]]; then 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 source_path="$FORGE_DIR/$source" - # Create source directory if it doesn't exist - local source_dir=$(dirname "$source_path") - mkdir -p "$source_dir" + # Verify source file exists + if [[ ! -f "$source_path" && ! -d "$source_path" ]]; then + log_error "Source file not found: $source_path" + continue + fi # Create target directory if it doesn't exist local target_dir=$(dirname "$target_path") mkdir -p "$target_dir" - # Backup existing file if it exists and is not a symlink - if [[ -f "$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 "$target_path" "$backup_path" - log_info "Backed up $target_path to $backup_path" + # Handle existing file/symlink + if [[ -e "$target_path" || -L "$target_path" ]]; then + # Check if it's already a correct symlink + if [[ -L "$target_path" ]]; then + local current_target=$(readlink "$target_path") + if [[ "$current_target" == "$source_path" ]]; then + 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 - # Remove existing file/symlink - rm -f "$target_path" - - # Create symlink - if ln -s "$source_path" "$target_path"; then - log_success "Created symlink: $target_path -> $source_path" + # Create relative symlink for better portability + local relative_source + if [[ -d "$source_path" ]]; then + relative_source=$(realpath --relative-to="$target_dir" "$source_path") 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 done < <(parse_toml)