diff --git a/pkg/code-manager/code_manager.go b/pkg/code-manager/code_manager.go index 49eebdd..aafb2c9 100644 --- a/pkg/code-manager/code_manager.go +++ b/pkg/code-manager/code_manager.go @@ -79,6 +79,10 @@ func (c *realCodeManager) VerbosePrint(msg string, args ...interface{}) { // SetLogger sets the logger for this CodeManager instance. func (c *realCodeManager) SetLogger(logger logger.Logger) { c.deps.Logger = logger + // Also set logger on status manager for verbose output + if c.deps.StatusManager != nil { + c.deps.StatusManager.SetLogger(logger) + } } // getConfig gets the configuration from the ConfigManager with fallback. diff --git a/pkg/status/mocks/status.gen.go b/pkg/status/mocks/status.gen.go index b581867..3520c82 100644 --- a/pkg/status/mocks/status.gen.go +++ b/pkg/status/mocks/status.gen.go @@ -12,6 +12,7 @@ package mocks import ( reflect "reflect" + logger "github.com/lerenn/code-manager/pkg/logger" status "github.com/lerenn/code-manager/pkg/status" gomock "go.uber.org/mock/gomock" ) @@ -213,6 +214,18 @@ func (mr *MockManagerMockRecorder) RemoveWorktree(repoURL, branch any) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveWorktree", reflect.TypeOf((*MockManager)(nil).RemoveWorktree), repoURL, branch) } +// SetLogger mocks base method. +func (m *MockManager) SetLogger(arg0 logger.Logger) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetLogger", arg0) +} + +// SetLogger indicates an expected call of SetLogger. +func (mr *MockManagerMockRecorder) SetLogger(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLogger", reflect.TypeOf((*MockManager)(nil).SetLogger), arg0) +} + // UpdateWorkspace mocks base method. func (m *MockManager) UpdateWorkspace(workspaceName string, workspace status.Workspace) error { m.ctrl.T.Helper() diff --git a/pkg/status/remove_workspace.go b/pkg/status/remove_workspace.go index 80e0a76..ed48580 100644 --- a/pkg/status/remove_workspace.go +++ b/pkg/status/remove_workspace.go @@ -2,7 +2,6 @@ package status import ( "fmt" - "log" ) // RemoveWorkspace removes a workspace entry from the status file. @@ -13,8 +12,10 @@ func (s *realManager) RemoveWorkspace(workspaceName string) error { return fmt.Errorf("failed to load status: %w", err) } - log.Printf(" [RemoveWorkspace] After load: status.Repositories[github.com/octocat/Hello-World].Worktrees = %v", - status.Repositories["github.com/octocat/Hello-World"].Worktrees) + if s.logger != nil { + s.logger.Logf(" [RemoveWorkspace] After load: status.Repositories[github.com/octocat/Hello-World].Worktrees = %v", + status.Repositories["github.com/octocat/Hello-World"].Worktrees) + } // Check if workspace exists if _, exists := status.Workspaces[workspaceName]; !exists { @@ -29,7 +30,9 @@ func (s *realManager) RemoveWorkspace(workspaceName string) error { return fmt.Errorf("failed to save status: %w", err) } - log.Printf(" [RemoveWorkspace] After save: status saved successfully") + if s.logger != nil { + s.logger.Logf(" [RemoveWorkspace] After save: status saved successfully") + } // Update internal workspaces map s.computeWorkspacesMap(status.Workspaces) diff --git a/pkg/status/remove_worktree.go b/pkg/status/remove_worktree.go index 04f0484..3e5d84d 100644 --- a/pkg/status/remove_worktree.go +++ b/pkg/status/remove_worktree.go @@ -2,54 +2,86 @@ package status import ( "fmt" - "log" ) // RemoveWorktree removes a worktree entry from the status file. func (s *realManager) RemoveWorktree(repoURL, branch string) error { - // Load current status status, err := s.loadStatus() if err != nil { return fmt.Errorf("failed to load status: %w", err) } - // Check if repository exists + repo, err := s.validateRepository(status, repoURL) + if err != nil { + return err + } + + s.logRemoveWorktreeBefore(repo.Worktrees) + + if err := s.deleteWorktreeFromRepo(&repo, branch); err != nil { + return fmt.Errorf("%w for repository %s branch %s", err, repoURL, branch) + } + + s.logRemoveWorktreeAfter(repo.Worktrees, repoURL, status) + + status.Repositories[repoURL] = repo + + if err := s.saveStatus(status); err != nil { + return fmt.Errorf("failed to save status: %w", err) + } + + s.logRemoveWorktreeSave() + + return nil +} + +// validateRepository checks if the repository exists in the status. +func (s *realManager) validateRepository(status *Status, repoURL string) (Repository, error) { repo, exists := status.Repositories[repoURL] if !exists { - return fmt.Errorf("%w: %s", ErrRepositoryNotFound, repoURL) + return Repository{}, fmt.Errorf("%w: %s", ErrRepositoryNotFound, repoURL) } + return repo, nil +} - log.Printf(" [RemoveWorktree] Before deletion: repo.Worktrees = %v", repo.Worktrees) - - // Find and remove the worktree entry - found := false +// deleteWorktreeFromRepo finds and deletes the worktree entry from the repository. +func (s *realManager) deleteWorktreeFromRepo(repo *Repository, branch string) error { for worktreeKey, worktree := range repo.Worktrees { if worktree.Branch == branch { - log.Printf(" [RemoveWorktree] Deleting worktree with key: %s, branch: %s", worktreeKey, branch) + s.logRemoveWorktreeDelete(worktreeKey, branch) delete(repo.Worktrees, worktreeKey) - found = true - break + return nil } } + return ErrWorktreeNotFound +} - if !found { - return fmt.Errorf("%w for repository %s branch %s", ErrWorktreeNotFound, repoURL, branch) +// logRemoveWorktreeBefore logs the worktrees before deletion. +func (s *realManager) logRemoveWorktreeBefore(worktrees map[string]WorktreeInfo) { + if s.logger != nil { + s.logger.Logf(" [RemoveWorktree] Before deletion: repo.Worktrees = %v", worktrees) } +} - log.Printf(" [RemoveWorktree] After deletion: repo.Worktrees = %v", repo.Worktrees) - - // Update repository - status.Repositories[repoURL] = repo - - log.Printf(" [RemoveWorktree] After update: status.Repositories[%s].Worktrees = %v", - repoURL, status.Repositories[repoURL].Worktrees) - - // Save updated status - if err := s.saveStatus(status); err != nil { - return fmt.Errorf("failed to save status: %w", err) +// logRemoveWorktreeDelete logs the deletion of a worktree. +func (s *realManager) logRemoveWorktreeDelete(worktreeKey, branch string) { + if s.logger != nil { + s.logger.Logf(" [RemoveWorktree] Deleting worktree with key: %s, branch: %s", worktreeKey, branch) } +} - log.Printf(" [RemoveWorktree] After save: status saved successfully") +// logRemoveWorktreeAfter logs the worktrees after deletion. +func (s *realManager) logRemoveWorktreeAfter(worktrees map[string]WorktreeInfo, repoURL string, status *Status) { + if s.logger != nil { + s.logger.Logf(" [RemoveWorktree] After deletion: repo.Worktrees = %v", worktrees) + s.logger.Logf(" [RemoveWorktree] After update: status.Repositories[%s].Worktrees = %v", + repoURL, status.Repositories[repoURL].Worktrees) + } +} - return nil +// logRemoveWorktreeSave logs after saving the status. +func (s *realManager) logRemoveWorktreeSave() { + if s.logger != nil { + s.logger.Logf(" [RemoveWorktree] After save: status saved successfully") + } } diff --git a/pkg/status/status.go b/pkg/status/status.go index 33c3f23..1d6a0f9 100644 --- a/pkg/status/status.go +++ b/pkg/status/status.go @@ -8,6 +8,7 @@ import ( "github.com/lerenn/code-manager/pkg/config" "github.com/lerenn/code-manager/pkg/fs" "github.com/lerenn/code-manager/pkg/issue" + "github.com/lerenn/code-manager/pkg/logger" "gopkg.in/yaml.v3" ) @@ -83,12 +84,15 @@ type Manager interface { UpdateWorkspace(workspaceName string, workspace Workspace) error // ListWorkspaces lists all workspaces in the status file. ListWorkspaces() (map[string]Workspace, error) + // SetLogger sets the logger for verbose output. + SetLogger(logger logger.Logger) } type realManager struct { fs fs.FS config config.Config workspaces map[string]map[string][]WorktreeInfo // workspace -> branch -> worktrees + logger logger.Logger } // NewManager creates a new Status Manager instance. @@ -237,11 +241,13 @@ func (s *realManager) saveStatus(status *Status) error { return fmt.Errorf("failed to marshal status: %w", err) } - // Log what we're about to save - var debugStatus Status - _ = yaml.Unmarshal(data, &debugStatus) - if repo, exists := debugStatus.Repositories["github.com/octocat/Hello-World"]; exists { - fmt.Printf(" [saveStatus] About to write: github.com/octocat/Hello-World.Worktrees = %v\n", repo.Worktrees) + // Log what we're about to save (verbose mode only) + if s.logger != nil { + var debugStatus Status + _ = yaml.Unmarshal(data, &debugStatus) + if repo, exists := debugStatus.Repositories["github.com/octocat/Hello-World"]; exists { + s.logger.Logf(" [saveStatus] About to write: github.com/octocat/Hello-World.Worktrees = %v", repo.Worktrees) + } } // Write status file atomically @@ -254,3 +260,8 @@ func (s *realManager) saveStatus(status *Status) error { return nil } + +// SetLogger sets the logger for verbose output. +func (s *realManager) SetLogger(logger logger.Logger) { + s.logger = logger +} diff --git a/pkg/status/update_workspace.go b/pkg/status/update_workspace.go index a3715a2..75781d3 100644 --- a/pkg/status/update_workspace.go +++ b/pkg/status/update_workspace.go @@ -2,7 +2,6 @@ package status import ( "fmt" - "log" ) // UpdateWorkspace updates an existing workspace entry in the status file. @@ -13,8 +12,10 @@ func (s *realManager) UpdateWorkspace(workspaceName string, workspace Workspace) return fmt.Errorf("failed to load status: %w", err) } - log.Printf(" [UpdateWorkspace] After load: status.Repositories[github.com/octocat/Hello-World].Worktrees = %v", - status.Repositories["github.com/octocat/Hello-World"].Worktrees) + if s.logger != nil { + s.logger.Logf(" [UpdateWorkspace] After load: status.Repositories[github.com/octocat/Hello-World].Worktrees = %v", + status.Repositories["github.com/octocat/Hello-World"].Worktrees) + } // Check if workspace exists if _, exists := status.Workspaces[workspaceName]; !exists { @@ -29,7 +30,9 @@ func (s *realManager) UpdateWorkspace(workspaceName string, workspace Workspace) return fmt.Errorf("failed to save status: %w", err) } - log.Printf(" [UpdateWorkspace] After save: status saved successfully") + if s.logger != nil { + s.logger.Logf(" [UpdateWorkspace] After save: status saved successfully") + } // Update internal workspaces map s.computeWorkspacesMap(status.Workspaces)