Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- uses: dagger/dagger-for-github@8.0.0
with:
Expand Down
102 changes: 102 additions & 0 deletions cmd/cm/workspace/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Package workspace provides workspace management commands for the CM CLI.
package workspace

import (
"fmt"

"github.com/lerenn/code-manager/cmd/cm/internal/cli"
cm "github.com/lerenn/code-manager/pkg/code-manager"
"github.com/lerenn/code-manager/pkg/logger"
"github.com/spf13/cobra"
)

func createAddCmd() *cobra.Command {
var workspaceName string

addCmd := &cobra.Command{
Use: "add [repository_name] [-w workspace_name]",
Short: "Add a repository to an existing workspace",
Long: getAddCommandLongDescription(),
Args: cobra.MaximumNArgs(1),
RunE: createAddCmdRunE,
}

// Add workspace flag
addCmd.Flags().StringVarP(&workspaceName, "workspace", "w", "",
"Add repository to the specified workspace (interactive selection if not provided)")

return addCmd
}

// getAddCommandLongDescription returns the long description for the add command.
func getAddCommandLongDescription() string {
return `Add a repository to an existing workspace.

This command adds a repository to an existing workspace definition in the status.yaml file.
The command will:
- Add the repository to the workspace's repository list
- Create worktrees in the new repository for all branches that already have worktrees in ALL existing repositories
- Update all existing .code-workspace files to include the new repository

You can specify the repository using:
- Repository name from status.yaml (e.g., repo1)
- Absolute path (e.g., /path/to/repo1)
- Relative path (e.g., ./repo1, ../repo2)

If no workspace name is provided, you will be prompted to select one interactively.
If no repository name is provided, you will be prompted to select one interactively.

Examples:
# Add repository to workspace
cm workspace add repo1 -w my-workspace

# Add repository with absolute path
cm ws add /path/to/repo -w my-workspace

# Interactive selection for both workspace and repository
cm workspace add`
}

// createAddCmdRunE creates the RunE function for the add command.
func createAddCmdRunE(cmd *cobra.Command, args []string) error {
// Get workspace flag
workspaceName, err := cmd.Flags().GetString("workspace")
if err != nil {
return fmt.Errorf("failed to get workspace flag: %w", err)
}

// Create CM instance
cmManager, err := cli.NewCodeManager()
if err != nil {
return fmt.Errorf("failed to create CM instance: %w", err)
}

// Set logger based on verbosity
if cli.Verbose {
cmManager.SetLogger(logger.NewVerboseLogger())
}

// Get repository name from args
repoName := ""
if len(args) > 0 {
repoName = args[0]
}

// Create add parameters (interactive selection handled in code-manager)
params := &cm.AddRepositoryToWorkspaceParams{
WorkspaceName: workspaceName,
Repository: repoName,
}

// Add repository to workspace (interactive selection handled in code-manager)
if err := cmManager.AddRepositoryToWorkspace(params); err != nil {
return err
}

// Print success message (params may have been updated by interactive selection)
if !cli.Quiet {
fmt.Printf("✓ Repository '%s' added to workspace '%s' successfully\n", params.Repository, params.WorkspaceName)
}

return nil
}
102 changes: 102 additions & 0 deletions cmd/cm/workspace/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Package workspace provides workspace management commands for the CM CLI.
package workspace

import (
"fmt"

"github.com/lerenn/code-manager/cmd/cm/internal/cli"
cm "github.com/lerenn/code-manager/pkg/code-manager"
"github.com/lerenn/code-manager/pkg/logger"
"github.com/spf13/cobra"
)

func createRemoveCmd() *cobra.Command {
var workspaceName string

removeCmd := &cobra.Command{
Use: "remove [repository_name] [-w workspace_name]",
Short: "Remove a repository from an existing workspace",
Long: getRemoveCommandLongDescription(),
Args: cobra.MaximumNArgs(1),
RunE: createRemoveCmdRunE,
}

// Add workspace flag
removeCmd.Flags().StringVarP(&workspaceName, "workspace", "w", "",
"Remove repository from the specified workspace (interactive selection if not provided)")

return removeCmd
}

// getRemoveCommandLongDescription returns the long description for the remove command.
func getRemoveCommandLongDescription() string {
return `Remove a repository from an existing workspace.

This command removes a repository from an existing workspace definition in the status.yaml file.
The command will:
- Remove the repository from the workspace's repository list
- Update all existing .code-workspace files to remove the repository folder entries
- Preserve all worktrees (they are not deleted, only removed from the workspace)

You can specify the repository using:
- Repository name from status.yaml (e.g., repo1)
- Absolute path (e.g., /path/to/repo1)
- Relative path (e.g., ./repo1, ../repo2)

If no workspace name is provided, you will be prompted to select one interactively.
If no repository name is provided, you will be prompted to select one interactively.

Examples:
# Remove repository from workspace
cm workspace remove repo1 -w my-workspace

# Remove repository with absolute path
cm ws remove /path/to/repo -w my-workspace

# Interactive selection for both workspace and repository
cm workspace remove`
}

// createRemoveCmdRunE creates the RunE function for the remove command.
func createRemoveCmdRunE(cmd *cobra.Command, args []string) error {
// Get workspace flag
workspaceName, err := cmd.Flags().GetString("workspace")
if err != nil {
return fmt.Errorf("failed to get workspace flag: %w", err)
}

// Create CM instance
cmManager, err := cli.NewCodeManager()
if err != nil {
return fmt.Errorf("failed to create CM instance: %w", err)
}

// Set logger based on verbosity
if cli.Verbose {
cmManager.SetLogger(logger.NewVerboseLogger())
}

// Get repository name from args
repoName := ""
if len(args) > 0 {
repoName = args[0]
}

// Create remove parameters (interactive selection handled in code-manager)
params := &cm.RemoveRepositoryFromWorkspaceParams{
WorkspaceName: workspaceName,
Repository: repoName,
}

// Remove repository from workspace (interactive selection handled in code-manager)
if err := cmManager.RemoveRepositoryFromWorkspace(params); err != nil {
return err
}

// Print success message (params may have been updated by interactive selection)
if !cli.Quiet {
fmt.Printf("✓ Repository '%s' removed from workspace '%s' successfully\n", params.Repository, params.WorkspaceName)
}

return nil
}
6 changes: 6 additions & 0 deletions cmd/cm/workspace/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ func CreateWorkspaceCmd() *cobra.Command {
deleteCmd := createDeleteCmd()
workspaceCmd.AddCommand(deleteCmd)

addCmd := createAddCmd()
workspaceCmd.AddCommand(addCmd)

removeCmd := createRemoveCmd()
workspaceCmd.AddCommand(removeCmd)

return workspaceCmd
}
4 changes: 4 additions & 0 deletions pkg/code-manager/code_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ type CodeManager interface {
DeleteWorkspace(params DeleteWorkspaceParams) error
// ListWorkspaces lists all workspaces from the status file.
ListWorkspaces() ([]WorkspaceInfo, error)
// AddRepositoryToWorkspace adds a repository to an existing workspace.
AddRepositoryToWorkspace(params *AddRepositoryToWorkspaceParams) error
// RemoveRepositoryFromWorkspace removes a repository from an existing workspace.
RemoveRepositoryFromWorkspace(params *RemoveRepositoryFromWorkspaceParams) error
// SetLogger sets the logger for this CM instance.
SetLogger(logger logger.Logger)
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/code-manager/consts/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const (
Clone = "Clone" // Legacy name for backward compatibility

// Workspace operations.
ListWorkspaces = "ListWorkspaces"
ListWorkspaces = "ListWorkspaces"
AddRepositoryToWorkspace = "AddRepositoryToWorkspace"
RemoveRepositoryFromWorkspace = "RemoveRepositoryFromWorkspace"

// Prompt operations.
PromptSelectTarget = "PromptSelectTarget"
Expand Down
Loading