diff --git a/pkg/handlers/delete_project.go b/pkg/handlers/delete_project.go new file mode 100644 index 00000000..871c74d6 --- /dev/null +++ b/pkg/handlers/delete_project.go @@ -0,0 +1,27 @@ +package handlers + +import ( + "fmt" + "net/http" + + "github.com/artmoskvin/hide/pkg/project" +) + +type DeleteProjectHandler struct { + Manager project.Manager +} + +func (h DeleteProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + projectId := r.PathValue("id") + + // TODO: check if project exists + result := <-h.Manager.DeleteProject(projectId) + + if result.IsFailure() { + http.Error(w, fmt.Sprintf("Failed to delete project: %s", result.Error), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusNoContent) +} diff --git a/pkg/project/manager.go b/pkg/project/manager.go index 45977740..62d43fc0 100644 --- a/pkg/project/manager.go +++ b/pkg/project/manager.go @@ -73,6 +73,7 @@ type Manager interface { CreateProject(request CreateProjectRequest) <-chan result.Result[Project] GetProject(projectId ProjectId) (Project, error) GetProjects() ([]*Project, error) + DeleteProject(projectId ProjectId) <-chan result.Empty ResolveTaskAlias(projectId ProjectId, alias string) (devcontainer.Task, error) CreateTask(projectId ProjectId, command string) (TaskResult, error) Cleanup() error @@ -183,6 +184,40 @@ func (pm ManagerImpl) GetProjects() ([]*Project, error) { return projects, nil } +func (pm ManagerImpl) DeleteProject(projectId string) <-chan result.Empty { + c := make(chan result.Empty) + + go func() { + log.Printf("Deleting project %s", projectId) + + project, err := pm.GetProject(projectId) + + if err != nil { + log.Printf("Project with id %s not found", projectId) + c <- result.EmptyFailure(fmt.Errorf("Project with id %s not found", projectId)) + return + } + + if err := pm.DevContainerRunner.Stop(project.containerId); err != nil { + log.Printf("Failed to stop container %s: %s", project.containerId, err) + c <- result.EmptyFailure(fmt.Errorf("Failed to stop container: %w", err)) + return + } + + if err := pm.Store.DeleteProject(projectId); err != nil { + log.Printf("Failed to delete project %s: %s", projectId, err) + c <- result.EmptyFailure(fmt.Errorf("Failed to delete project: %w", err)) + return + } + + log.Printf("Deleted project %s", projectId) + + c <- result.EmptySuccess() + }() + + return c +} + func (pm ManagerImpl) ResolveTaskAlias(projectId string, alias string) (devcontainer.Task, error) { log.Printf("Resolving task alias %s for project %s", alias, projectId) diff --git a/pkg/project/mocks/mock_manager.go b/pkg/project/mocks/mock_manager.go index 74e868b1..a642c744 100644 --- a/pkg/project/mocks/mock_manager.go +++ b/pkg/project/mocks/mock_manager.go @@ -9,6 +9,7 @@ type MockProjectManager struct { CreateProjectFunc func(request project.CreateProjectRequest) <-chan result.Result[project.Project] GetProjectFunc func(projectId string) (project.Project, error) GetProjectsFunc func() ([]*project.Project, error) + DeleteProjectFunc func(projectId string) <-chan result.Empty ResolveTaskAliasFunc func(projectId string, alias string) (devcontainer.Task, error) CreateTaskFunc func(projectId string, command string) (project.TaskResult, error) CleanupFunc func() error @@ -26,6 +27,10 @@ func (m *MockProjectManager) GetProjects() ([]*project.Project, error) { return m.GetProjectsFunc() } +func (m *MockProjectManager) DeleteProject(projectId string) <-chan result.Empty { + return m.DeleteProjectFunc(projectId) +} + func (m *MockProjectManager) ResolveTaskAlias(projectId string, alias string) (devcontainer.Task, error) { return m.ResolveTaskAliasFunc(projectId, alias) }