Class: Ace::Git::Worktree::Molecules::CurrentTaskLinker

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git/worktree/molecules/current_task_linker.rb

Overview

Creates and manages the _current symlink pointing to the active task directory

This molecule provides quick access to the current working task without needing to remember task IDs. The symlink is created at project root.

Examples:

Create symlink to task directory

linker = CurrentTaskLinker.new(project_root: "/project")
result = linker.link("/project/.ace-task/v.0.9.0/tasks/145-feat/")
# => { success: true, symlink_path: "/project/_current", target: "..." }

Remove symlink

linker.unlink
# => { success: true }

Constant Summary collapse

"_current"

Instance Method Summary collapse

Constructor Details

#initialize(project_root: nil, symlink_name: DEFAULT_SYMLINK_NAME) ⇒ CurrentTaskLinker

Initialize a new CurrentTaskLinker

Parameters:

  • project_root (String, nil) (defaults to: nil)

    Project root directory (defaults to Dir.pwd)

  • symlink_name (String) (defaults to: DEFAULT_SYMLINK_NAME)

    Name of the symlink (default: “_current”)



31
32
33
34
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 31

def initialize(project_root: nil, symlink_name: DEFAULT_SYMLINK_NAME)
  @project_root = project_root || Dir.pwd
  @symlink_name = symlink_name
end

Instance Method Details

#current_absolute_pathString?

Get the absolute path to the current task directory

Returns:

  • (String, nil)

    Absolute path or nil if symlink doesn’t exist



108
109
110
111
112
113
114
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 108

def current_absolute_path
  return nil unless exists?

  File.realpath(symlink_path)
rescue Errno::ENOENT
  nil
end

#current_targetString?

Get the target of the current symlink

Returns:

  • (String, nil)

    Target path or nil if symlink doesn’t exist



99
100
101
102
103
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 99

def current_target
  return nil unless exists?

  File.readlink(symlink_path)
end

#exists?Boolean

Check if symlink exists

Returns:

  • (Boolean)

    true if symlink exists



92
93
94
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 92

def exists?
  File.symlink?(symlink_path)
end

Create symlink to task directory

Creates a symlink at project root pointing to the given task directory. Uses relative paths for portability. Removes existing symlink if present.

Parameters:

  • task_directory (String)

    Absolute path to task directory

Returns:

  • (Hash)

    Result with :success, :symlink_path, :target, :relative_target, :error



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 43

def link(task_directory)
  return {success: false, error: "Task directory is required"} if task_directory.nil? || task_directory.empty?
  return {success: false, error: "Task directory does not exist: #{task_directory}"} unless Dir.exist?(task_directory)

  symlink_path = File.join(@project_root, @symlink_name)

  # Remove existing symlink or file if present
  remove_existing(symlink_path)

  # Calculate relative path from project root to task directory
  relative_target = calculate_relative_path(task_directory)

  # Create the symlink
  File.symlink(relative_target, symlink_path)

  {
    success: true,
    symlink_path: symlink_path,
    target: task_directory,
    relative_target: relative_target
  }
rescue => e
  {success: false, error: "Failed to create symlink: #{e.message}"}
end

Get the path to the current symlink

Returns:

  • (String)

    Path to the symlink



85
86
87
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 85

def symlink_path
  File.join(@project_root, @symlink_name)
end

Remove the _current symlink

Returns:

  • (Hash)

    Result with :success, :error



71
72
73
74
75
76
77
78
79
80
# File 'lib/ace/git/worktree/molecules/current_task_linker.rb', line 71

def unlink
  symlink_path = File.join(@project_root, @symlink_name)

  return {success: true, existed: false} unless File.symlink?(symlink_path)

  FileUtils.rm_f(symlink_path)
  {success: true, existed: true}
rescue => e
  {success: false, error: "Failed to remove symlink: #{e.message}"}
end