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
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ builds:
- main: .
binary: wt
ldflags:
- -s -w -X main.version={{.Version}}
- -s -w -X github.com/timvw/wt/cmd.Version={{.Version}}
env:
- CGO_ENABLED=0
goos:
Expand Down
5 changes: 3 additions & 2 deletions checkout.go → cmd/checkout.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand All @@ -7,6 +7,7 @@ import (

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"github.com/timvw/wt/internal/fuzzy"
)

var checkoutCmd = &cobra.Command{
Expand All @@ -33,7 +34,7 @@ var checkoutCmd = &cobra.Command{
prompt := promptui.Select{
Label: "Select branch to checkout",
Items: branches,
Searcher: fuzzySearcher(branches),
Searcher: fuzzy.Searcher(branches),
StartInSearchMode: true,
}
_, result, err := prompt.Run()
Expand Down
2 changes: 1 addition & 1 deletion cleanup.go → cmd/cleanup.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion cleanup_test.go → cmd/cleanup_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"os"
Expand Down
2 changes: 1 addition & 1 deletion config.go → cmd/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion config_cmd.go → cmd/config_cmd.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion config_test.go → cmd/config_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bytes"
Expand Down
2 changes: 1 addition & 1 deletion create.go → cmd/create.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion default.go → cmd/default.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion default_test.go → cmd/default_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"strings"
Expand Down
4 changes: 2 additions & 2 deletions e2e_interactive_test.go → cmd/e2e_interactive_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bytes"
Expand Down Expand Up @@ -1380,7 +1380,7 @@ func buildWtBinary(t *testing.T, tmpDir string) string {
}

builtWtBinaryPath = filepath.Join(buildDir, binaryName)
cmd := exec.Command("go", "build", "-o", builtWtBinaryPath, ".")
cmd := exec.Command("go", "build", "-o", builtWtBinaryPath, "github.com/timvw/wt")
if output, err := cmd.CombinedOutput(); err != nil {
builtWtBinaryErr = fmt.Errorf("failed to build wt binary: %v\nOutput: %s", err, output)
return
Expand Down
2 changes: 1 addition & 1 deletion examples.go → cmd/examples.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion examples_test.go → cmd/examples_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bytes"
Expand Down
2 changes: 1 addition & 1 deletion hooks.go → cmd/hooks.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion info.go → cmd/info.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion init.go → cmd/init.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion init_test.go → cmd/init_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion list.go → cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"os"
Expand Down
2 changes: 1 addition & 1 deletion main_test.go → cmd/main_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion migrate.go → cmd/migrate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion migrate_test.go → cmd/migrate_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion output.go → cmd/output.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion output_test.go → cmd/output_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"bytes"
Expand Down
7 changes: 4 additions & 3 deletions pr.go → cmd/pr.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand All @@ -8,6 +8,7 @@ import (

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"github.com/timvw/wt/internal/fuzzy"
)

var prCmd = &cobra.Command{
Expand Down Expand Up @@ -43,7 +44,7 @@ Examples:
prompt := promptui.Select{
Label: "Select Pull Request",
Items: labels,
Searcher: fuzzySearcher(labels),
Searcher: fuzzy.Searcher(labels),
StartInSearchMode: true,
}
idx, _, err := prompt.Run()
Expand Down Expand Up @@ -92,7 +93,7 @@ Examples:
prompt := promptui.Select{
Label: "Select Merge Request",
Items: labels,
Searcher: fuzzySearcher(labels),
Searcher: fuzzy.Searcher(labels),
StartInSearchMode: true,
}
idx, _, err := prompt.Run()
Expand Down
2 changes: 1 addition & 1 deletion prune.go → cmd/prune.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
5 changes: 3 additions & 2 deletions remove.go → cmd/remove.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand All @@ -8,6 +8,7 @@ import (

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"github.com/timvw/wt/internal/fuzzy"
)

var removeForce bool
Expand Down Expand Up @@ -37,7 +38,7 @@ var removeCmd = &cobra.Command{
prompt := promptui.Select{
Label: "Select worktree to remove",
Items: branches,
Searcher: fuzzySearcher(branches),
Searcher: fuzzy.Searcher(branches),
StartInSearchMode: true,
}
_, result, err := prompt.Run()
Expand Down
2 changes: 1 addition & 1 deletion remove_cleanup_test.go → cmd/remove_cleanup_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion remove_force_test.go → cmd/remove_force_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"os"
Expand Down
2 changes: 1 addition & 1 deletion repo.go → cmd/repo.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"encoding/json"
Expand Down
142 changes: 142 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package cmd

import (
"bytes"
"fmt"
"os"

"github.com/spf13/cobra"
)

var (
Version = "dev"
worktreeRoot string
worktreeStrategy string
worktreePattern string
worktreeSeparator string
)

func init() {
loadWorktreeConfig()
rootCmd.Long = buildRootCmdLong()
}

// Execute runs the root command. Called by main().
func Execute() {
// Re-load config after cobra parses flags so --config is available
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
if err := validateOutputFormat(); err != nil {
return err
}
if configFlag != "" {
loadWorktreeConfig()
rootCmd.Long = buildRootCmdLong()
}
return nil
}
if err := rootCmd.Execute(); err != nil {
if isJSONOutput() {
_ = emitJSONError(rootCmd, err)
} else {
fmt.Fprintln(os.Stderr, err)
}
os.Exit(1)
}
}

var rootCmd = &cobra.Command{
Use: "wt",
Short: "Git worktree helper with organized directory structure",
Long: "",
SilenceErrors: true,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
return printCommandHelp(cmd)
},
}

func printCommandHelp(cmd *cobra.Command) error {
return cmd.Help()
}

func init() {
rootCmd.PersistentFlags().StringVar(&configFlag, "config", "", "Path to config file (default: ~/.config/wt/config.toml)")
rootCmd.PersistentFlags().StringVar(&outputFormat, "format", formatText, "Output format: text or json")

defaultHelp := rootCmd.HelpFunc()
rootCmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
if !isJSONOutput() {
defaultHelp(cmd, args)
return
}

buf := bytes.NewBuffer(nil)
origOut := cmd.OutOrStdout()
origErr := cmd.ErrOrStderr()
cmd.SetOut(buf)
cmd.SetErr(buf)
defaultHelp(cmd, args)
cmd.SetOut(origOut)
cmd.SetErr(origErr)

_ = emitJSONSuccess(cmd, map[string]any{"help": buf.String()})
})

rootCmd.AddCommand(checkoutCmd)
rootCmd.AddCommand(createCmd)
rootCmd.AddCommand(prCmd)
rootCmd.AddCommand(mrCmd)
rootCmd.AddCommand(listCmd)
rootCmd.AddCommand(removeCmd)
rootCmd.AddCommand(pruneCmd)
rootCmd.AddCommand(cleanupCmd)
rootCmd.AddCommand(migrateCmd)
rootCmd.AddCommand(shellenvCmd)
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(initCmd)
rootCmd.AddCommand(infoCmd)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(examplesCmd)
rootCmd.AddCommand(defaultCmd)
rootCmd.AddCommand(statusCmd)
statusCmd.Flags().BoolVar(&statusCI, "ci", false, "Show CI/CD pipeline status for each branch (requires gh or glab CLI)")
removeCmd.Flags().BoolVarP(&removeForce, "force", "f", false, "Force removal even if worktree has modifications")
cleanupCmd.Flags().BoolVar(&cleanupDryRun, "dry-run", false, "Preview what would be removed without making changes")
cleanupCmd.Flags().BoolVarP(&cleanupForce, "force", "f", false, "Remove all merged worktrees without confirmation")
cleanupCmd.Flags().BoolVar(&cleanupStale, "stale", false, "Also detect worktrees with deleted remote branches or old commits")
cleanupCmd.Flags().IntVar(&cleanupStaleDays, "stale-days", 30, "Threshold in days for considering a worktree inactive")
migrateCmd.Flags().BoolVarP(&migrateForce, "force", "f", false, "Force migration when target path exists and is non-empty")
initCmd.Flags().BoolVar(&initDryRun, "dry-run", false, "Preview changes without modifying files")
initCmd.Flags().BoolVar(&initUninstall, "uninstall", false, "Remove wt configuration from shell")
initCmd.Flags().BoolVar(&initNoPrompt, "no-prompt", false, "Skip activation instructions (for automated installs)")
configInitCmd.Flags().BoolVar(&configInitForce, "force", false, "Overwrite existing config file")
}

func init() {
configCmd.AddCommand(configInitCmd)
configCmd.AddCommand(configShowCmd)
configCmd.AddCommand(configPathCmd)
}

func buildRootCmdLong() string {
pattern, err := resolveWorktreePattern()
if err != nil {
pattern = worktreePattern
if pattern == "" {
pattern = "unknown"
}
}

return fmt.Sprintf(`Git-like worktree management with organized directory structure.

Strategy: %s
Pattern: %s
Root: %s

Run 'wt info' to see available strategies and pattern variables.
Set WORKTREE_ROOT, WORKTREE_STRATEGY, and WORKTREE_PATTERN to customize.`,
worktreeStrategy,
pattern,
worktreeRoot,
)
}
2 changes: 1 addition & 1 deletion shellenv.go → cmd/shellenv.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cmd

import (
"fmt"
Expand Down
Loading