Skip to content

Commit f394693

Browse files
timvwclaude
andcommitted
fix: make shellenv OS-specific and fix Windows binary path
Two critical fixes for e2e test failures: 1. **Make shellenv output OS-specific** (main.go:628-676) - Windows: Output only PowerShell code - Unix (macOS/Linux): Output only bash/zsh code - Previous approach mixed PowerShell and bash syntax causing parse errors - PowerShell syntax `if ($PSVersionTable)` broke bash/zsh sourcing - Error: "Auto-cd failed" because wt function wasn't defined 2. **Fix Windows binary path** (e2e_test.go:245-249) - Add .exe extension to binary name on Windows - Detect Windows via filepath.Separator == '\\\\' - Previous code built "wt.exe" but returned "wt" path - Error: "Cannot bind argument to parameter 'Command' because it is null" - PowerShell couldn't find/execute the binary Root causes: - macOS tests failed because shellenv output contained unparseable PowerShell syntax - Windows tests failed because binary path was missing .exe extension 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4ee220a commit f394693

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

e2e_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,13 @@ func setupTestRepo(t *testing.T, repoDir string) {
242242
func buildWtBinary(t *testing.T, tmpDir string) string {
243243
t.Helper()
244244

245-
binaryPath := filepath.Join(tmpDir, "wt")
245+
binaryName := "wt"
246+
// On Windows, executables need .exe extension
247+
if filepath.Separator == '\\' {
248+
binaryName = "wt.exe"
249+
}
250+
251+
binaryPath := filepath.Join(tmpDir, binaryName)
246252
cmd := exec.Command("go", "build", "-o", binaryPath, ".")
247253
if output, err := cmd.CombinedOutput(); err != nil {
248254
t.Fatalf("Failed to build wt binary: %v\nOutput: %s", err, output)

main.go

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os/exec"
77
"path/filepath"
88
"regexp"
9+
"runtime"
910
"strings"
1011

1112
"github.com/manifoldco/promptui"
@@ -626,52 +627,57 @@ This enables:
626627
- Automatic cd to worktree after checkout/create/pr/mr commands
627628
- Tab completion for commands and branch names`,
628629
Run: func(cmd *cobra.Command, args []string) {
629-
fmt.Print(`# PowerShell integration
630-
if ($PSVersionTable) {
631-
function wt {
632-
$output = & (Get-Command -CommandType Application wt).Source @args
633-
$exitCode = $LASTEXITCODE
634-
Write-Output $output
635-
if ($exitCode -eq 0) {
636-
$cdPath = $output | Select-String -Pattern "^TREE_ME_CD:" | ForEach-Object { $_.Line.Substring(11) }
637-
if ($cdPath) {
638-
Set-Location $cdPath
639-
}
630+
// Output OS-specific shell integration
631+
// On Windows, default to PowerShell. On Unix, output bash/zsh.
632+
if runtime.GOOS == "windows" {
633+
// PowerShell integration for Windows
634+
fmt.Print(`# PowerShell integration
635+
function wt {
636+
$output = & (Get-Command -CommandType Application wt).Source @args
637+
$exitCode = $LASTEXITCODE
638+
Write-Output $output
639+
if ($exitCode -eq 0) {
640+
$cdPath = $output | Select-String -Pattern "^TREE_ME_CD:" | ForEach-Object { $_.Line.Substring(11) }
641+
if ($cdPath) {
642+
Set-Location $cdPath
640643
}
641-
$global:LASTEXITCODE = $exitCode
642644
}
645+
$global:LASTEXITCODE = $exitCode
646+
}
643647
644-
# PowerShell completion
645-
Register-ArgumentCompleter -CommandName wt -ScriptBlock {
646-
param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
648+
# PowerShell completion
649+
Register-ArgumentCompleter -CommandName wt -ScriptBlock {
650+
param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
647651
648-
$commands = @('checkout', 'co', 'create', 'pr', 'mr', 'list', 'ls', 'remove', 'rm', 'prune', 'help', 'shellenv')
652+
$commands = @('checkout', 'co', 'create', 'pr', 'mr', 'list', 'ls', 'remove', 'rm', 'prune', 'help', 'shellenv')
649653
650-
# Get the position in the command line
651-
$position = $commandAst.CommandElements.Count - 1
654+
# Get the position in the command line
655+
$position = $commandAst.CommandElements.Count - 1
652656
653-
if ($position -eq 0) {
654-
# Complete commands
655-
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
656-
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
657+
if ($position -eq 0) {
658+
# Complete commands
659+
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
660+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
661+
}
662+
} elseif ($position -eq 1) {
663+
$subCommand = $commandAst.CommandElements[1].Value
664+
if ($subCommand -in @('checkout', 'co', 'remove', 'rm')) {
665+
# Complete branch names from worktree list
666+
$branches = git worktree list 2>$null | Select-Object -Skip 1 | ForEach-Object {
667+
if ($_ -match '\[([^\]]+)\]') { $matches[1] }
657668
}
658-
} elseif ($position -eq 1) {
659-
$subCommand = $commandAst.CommandElements[1].Value
660-
if ($subCommand -in @('checkout', 'co', 'remove', 'rm')) {
661-
# Complete branch names from worktree list
662-
$branches = git worktree list 2>$null | Select-Object -Skip 1 | ForEach-Object {
663-
if ($_ -match '\[([^\]]+)\]') { $matches[1] }
664-
}
665-
$branches | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
666-
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
667-
}
669+
$branches | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
670+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
668671
}
669672
}
670673
}
671-
return
672674
}
675+
`)
676+
return
677+
}
673678

674-
wt() {
679+
// Bash/Zsh integration for Unix systems
680+
fmt.Print(`wt() {
675681
# All commands (including interactive) need output capture for auto-cd
676682
local output
677683
output=$(command wt "$@")

0 commit comments

Comments
 (0)