108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"git.dws.rip/DWS/onyx/internal/core"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// NewSwitchCmd creates the switch command
|
|
func NewSwitchCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "switch <name>",
|
|
Short: "Switch to a different workstream",
|
|
Long: `Switch to a different workstream.
|
|
|
|
This command will:
|
|
1. Save the current ephemeral state (handled by the daemon)
|
|
2. Load the target workstream
|
|
3. Checkout the latest commit in the target workstream
|
|
4. Update the current workstream pointer
|
|
5. Restore the workspace state
|
|
|
|
The operation is logged to the action log, so you can undo it if needed.`,
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return runSwitch(args[0])
|
|
},
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
// runSwitch executes the switch command
|
|
func runSwitch(name string) error {
|
|
// Get current directory
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get current directory: %w", err)
|
|
}
|
|
|
|
// Check if this is an Onyx repository
|
|
if !core.IsOnyxRepo(cwd) {
|
|
return fmt.Errorf("not an Onyx repository")
|
|
}
|
|
|
|
// Open the repository
|
|
repo, err := core.Open(cwd)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open repository: %w", err)
|
|
}
|
|
defer repo.Close()
|
|
|
|
// Create workstream manager
|
|
wsManager := core.NewWorkstreamManager(repo)
|
|
|
|
// Get current workstream name before switching
|
|
currentName, err := wsManager.GetCurrentWorkstreamName()
|
|
if err != nil {
|
|
currentName = "none"
|
|
}
|
|
|
|
// Check if we're already on the target workstream
|
|
if currentName == name {
|
|
fmt.Printf("Already on workstream '%s'\n", name)
|
|
return nil
|
|
}
|
|
|
|
// Use ExecuteWithTransaction to capture state_before and state_after
|
|
err = core.ExecuteWithTransaction(repo, "switch", fmt.Sprintf("Switched from '%s' to '%s'", currentName, name), func() error {
|
|
return wsManager.SwitchWorkstream(name)
|
|
})
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Get the workstream we just switched to
|
|
targetWorkstream, err := wsManager.GetCurrentWorkstream()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get workstream after switch: %w", err)
|
|
}
|
|
|
|
// Display success message
|
|
fmt.Printf("Switched to workstream '%s'\n", name)
|
|
|
|
// Show workstream info
|
|
commitCount := targetWorkstream.GetCommitCount()
|
|
if commitCount == 0 {
|
|
fmt.Printf("\nThis is a new workstream based on '%s' with no commits yet.\n", targetWorkstream.BaseBranch)
|
|
fmt.Printf("Make changes and save them with 'onx save -m \"message\"'\n")
|
|
} else {
|
|
commitText := "commit"
|
|
if commitCount != 1 {
|
|
commitText = "commits"
|
|
}
|
|
fmt.Printf("\nThis workstream has %d %s.\n", commitCount, commitText)
|
|
|
|
// Show the latest commit
|
|
if latestCommit, err := targetWorkstream.GetLatestCommit(); err == nil {
|
|
fmt.Printf("Latest commit: %s\n", latestCommit.Message)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|