Class: Sxn::Core::WorktreeManager
- Inherits:
-
Object
- Object
- Sxn::Core::WorktreeManager
- Defined in:
- lib/sxn/core/worktree_manager.rb
Overview
Manages git worktree operations
Instance Method Summary collapse
- #add_worktree(project_name, branch = nil, session_name: nil) ⇒ Object
-
#execute_git_command ⇒ Object
Execute git command (mock point for tests).
- #get_worktree(project_name, session_name: nil) ⇒ Object
-
#initialize(config_manager = nil, session_manager = nil) ⇒ WorktreeManager
constructor
A new instance of WorktreeManager.
- #list_worktrees(session_name: nil) ⇒ Object
- #remove_worktree(project_name, session_name: nil) ⇒ Object
- #validate_worktree(project_name, session_name: nil) ⇒ Object
-
#validate_worktree_name(name) ⇒ Object
Validate worktree name (expected by tests).
-
#worktree_exists?(project_name, session_name: nil) ⇒ Boolean
Check if a worktree exists for a project.
-
#worktree_path(project_name, session_name: nil) ⇒ Object
Get the path to a worktree for a project.
Constructor Details
#initialize(config_manager = nil, session_manager = nil) ⇒ WorktreeManager
Returns a new instance of WorktreeManager.
11 12 13 14 15 |
# File 'lib/sxn/core/worktree_manager.rb', line 11 def initialize(config_manager = nil, session_manager = nil) @config_manager = config_manager || ConfigManager.new @session_manager = session_manager || SessionManager.new(@config_manager) @project_manager = ProjectManager.new(@config_manager) end |
Instance Method Details
#add_worktree(project_name, branch = nil, session_name: nil) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/sxn/core/worktree_manager.rb', line 17 def add_worktree(project_name, branch = nil, session_name: nil) # Use current session if not specified session_name ||= @config_manager.current_session raise Sxn::NoActiveSessionError, "No active session. Use 'sxn use <session>' first." unless session_name session = @session_manager.get_session(session_name) raise Sxn::SessionNotFoundError, "Session '#{session_name}' not found" unless session project = @project_manager.get_project(project_name) raise Sxn::ProjectNotFoundError, "Project '#{project_name}' not found" unless project # Determine branch name # If no branch specified, use session name as the branch name # If branch starts with "remote:", handle remote branch tracking if branch.nil? branch = session_name elsif branch.start_with?("remote:") remote_branch = branch.sub("remote:", "") # Fetch the remote branch first begin fetch_remote_branch(project[:path], remote_branch) branch = remote_branch rescue StandardError => e raise Sxn::WorktreeCreationError, "Failed to fetch remote branch: #{e.}" end end if ENV["SXN_DEBUG"] puts "[DEBUG] Adding worktree:" puts " Project: #{project_name}" puts " Project path: #{project[:path]}" puts " Session: #{session_name}" puts " Session path: #{session[:path]}" puts " Branch: #{branch}" end # Check if worktree already exists in this session existing_worktrees = @session_manager.get_session_worktrees(session_name) if existing_worktrees[project_name] raise Sxn::WorktreeExistsError, "Worktree for '#{project_name}' already exists in session '#{session_name}'" end # Create worktree path worktree_path = File.join(session[:path], project_name) puts " Worktree path: #{worktree_path}" if ENV["SXN_DEBUG"] begin # Handle orphaned worktree if it exists handle_orphaned_worktree(project[:path], worktree_path) # Create the worktree create_git_worktree(project[:path], worktree_path, branch) # Register worktree with session @session_manager.add_worktree_to_session(session_name, project_name, worktree_path, branch) { project: project_name, branch: branch, path: worktree_path, session: session_name } rescue StandardError => e # Clean up on failure FileUtils.rm_rf(worktree_path) raise Sxn::WorktreeCreationError, "Failed to create worktree: #{e.}" end end |
#execute_git_command ⇒ Object
Execute git command (mock point for tests)
170 171 172 |
# File 'lib/sxn/core/worktree_manager.rb', line 170 def execute_git_command(*) system(*) end |
#get_worktree(project_name, session_name: nil) ⇒ Object
146 147 148 149 |
# File 'lib/sxn/core/worktree_manager.rb', line 146 def get_worktree(project_name, session_name: nil) worktrees = list_worktrees(session_name: session_name) worktrees.find { |w| w[:project] == project_name } end |
#list_worktrees(session_name: nil) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/sxn/core/worktree_manager.rb', line 124 def list_worktrees(session_name: nil) # Use current session if not specified session_name ||= @config_manager.current_session return [] unless session_name session = @session_manager.get_session(session_name) return [] unless session worktrees_data = @session_manager.get_session_worktrees(session_name) worktrees_data.map do |project_name, worktree_info| { project: project_name, branch: worktree_info[:branch] || worktree_info["branch"], path: worktree_info[:path] || worktree_info["path"], created_at: worktree_info[:created_at] || worktree_info["created_at"], exists: File.directory?(worktree_info[:path] || worktree_info["path"]), status: get_worktree_status(worktree_info[:path] || worktree_info["path"]) } end end |
#remove_worktree(project_name, session_name: nil) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/sxn/core/worktree_manager.rb', line 88 def remove_worktree(project_name, session_name: nil) # Use current session if not specified session_name ||= @config_manager.current_session raise Sxn::NoActiveSessionError, "No active session. Use 'sxn use <session>' first." unless session_name session = @session_manager.get_session(session_name) raise Sxn::SessionNotFoundError, "Session '#{session_name}' not found" unless session worktrees = @session_manager.get_session_worktrees(session_name) worktree_info = worktrees[project_name] unless worktree_info raise Sxn::WorktreeNotFoundError, "Worktree for '#{project_name}' not found in session '#{session_name}'" end worktree_path = worktree_info[:path] || worktree_info["path"] begin # Remove git worktree project = @project_manager.get_project(project_name) if project remove_git_worktree(project[:path], worktree_path) else # Project might have been removed, try to find parent repo remove_git_worktree_by_path(worktree_path) end # Remove from session @session_manager.remove_worktree_from_session(session_name, project_name) true rescue StandardError => e raise Sxn::WorktreeRemovalError, "Failed to remove worktree: #{e.}" end end |
#validate_worktree(project_name, session_name: nil) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/sxn/core/worktree_manager.rb', line 174 def validate_worktree(project_name, session_name: nil) worktree = get_worktree(project_name, session_name: session_name) return { valid: false, issues: ["Worktree not found"] } unless worktree issues = [] # Check if directory exists issues << "Worktree directory does not exist: #{worktree[:path]}" unless File.directory?(worktree[:path]) # Check if it's a valid git worktree issues << "Directory is not a valid git worktree" unless valid_git_worktree?(worktree[:path]) # Check for git issues git_issues = check_git_status(worktree[:path]) issues.concat(git_issues) { valid: issues.empty?, issues: issues, worktree: worktree } end |
#validate_worktree_name(name) ⇒ Object
Validate worktree name (expected by tests)
163 164 165 166 167 |
# File 'lib/sxn/core/worktree_manager.rb', line 163 def validate_worktree_name(name) return true if name.match?(/\A[a-zA-Z0-9_-]+\z/) raise Sxn::WorktreeError, "Invalid worktree name: #{name}" end |
#worktree_exists?(project_name, session_name: nil) ⇒ Boolean
Check if a worktree exists for a project
152 153 154 |
# File 'lib/sxn/core/worktree_manager.rb', line 152 def worktree_exists?(project_name, session_name: nil) get_worktree(project_name, session_name: session_name) != nil end |
#worktree_path(project_name, session_name: nil) ⇒ Object
Get the path to a worktree for a project
157 158 159 160 |
# File 'lib/sxn/core/worktree_manager.rb', line 157 def worktree_path(project_name, session_name: nil) worktree = get_worktree(project_name, session_name: session_name) worktree&.fetch(:path, nil) end |